From 6c7c3bfa639e8a52fb04b13fa0c7726fd2f61fc9 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Thu, 13 Aug 2026 09:56:34 -0400 Subject: [PATCH] Add emoji prefix. --- README.md | 63 +- build.zig | 17 +- src/TabSettingsDialog.zig | 411 ++++++++ src/Window.zig | 185 +++- src/emoji.zig | 2086 +++++++++++++++++++++++++++++++++++++ src/style.css | 88 ++ tools/gen-emoji.py | 509 +++++++++ 7 files changed, 3328 insertions(+), 31 deletions(-) create mode 100644 src/TabSettingsDialog.zig create mode 100644 src/emoji.zig create mode 100755 tools/gen-emoji.py diff --git a/README.md b/README.md index 1f0f2f1..4fbe15a 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,8 @@ key.zig GDK keyval -> libghostty-vt key mapping theme.zig colors libghostty-vt has no opinion about, per scheme Settings.zig preferences: model, JSON on disk SettingsDialog.zig the settings page +TabSettingsDialog.zig one tab's own settings, and the emoji picker +emoji.zig generated: every emoji the picker offers, and the search over them ``` A tab is a **view**, and a view holds one or more **panes** arranged in a @@ -325,8 +327,12 @@ in principle, but a terminal grid is small. - **Pane status in the tab strip**, driven by OSC 9;4, so a tab can say whether it is working, waiting on you, or finished and still unanswered. See [Agent status](#agent-status) -- **Renaming a tab**: `Ctrl+Shift+R`, right-click or double-click a tab row. - A typed name pins the label; clearing it hands the label back to the panes +- **Renaming a tab**: `Ctrl+Shift+R`, double-click a tab row, or **Rename** in + its right-click menu. A typed name pins the label; clearing it hands the + label back to the panes +- **An emoji in place of a tab's icon**, from **Settings** in the same + right-click menu, picked out of the full emoji set with keyword search. See + [Tab settings](#tab-settings) - **Zooming a pane** to fill its tab and back, from the header button or `Ctrl+Shift+Z`. Nothing closes and nothing moves — hidden panes keep running and the split comes back exactly as it was. See [Zoom](#zoom) @@ -383,6 +389,46 @@ that zoom is hiding. Closing the zoomed pane leaves zoom; a *different* pane closing — a background shell exiting, say — does not, since what you are looking at is still there. +## Tab settings + +Right-clicking a tab row opens a small menu: **Rename**, which is the same +one-field popover `Ctrl+Shift+R` opens, and **Settings…**, which opens a window +belonging to that one tab. Double-clicking a row still goes straight to renaming +— it is the thing you do far more often than the other. + +The window holds one setting today, **Emoji Label**: a glyph that stands in for +the pane icon in that tab's sidebar row. It replaces the icon rather than joining +it, since a row has one slot for "what is this tab" and the label needs the rest +of the width. **Use the pane icon** puts the icon back. + +Picking one is a search box over a grid of the whole emoji set — 1906 glyphs, in +Unicode's own order and grouping, so it reads the way any other emoji keyboard +does. A glyph's tooltip is its name, for the ones you can't quite make out at +grid size. + +Every whitespace-separated word in the query has to match, in any order, so +`green circle` and `circle green` both land on 🟢 while `circle` alone brings back +the whole family. Keywords are CLDR's, which is where `grin` finding 😀 comes +from, plus the group and subgroup each glyph belongs to — `fruit`, `arrow` and +`flags` each bring back a shelf — plus a table of synonyms for the words a +terminal user actually types: `deploy` finds 🚀, `hotfix` finds 🩹, `docker` finds +🐳, `rust` finds 🦀. + +`src/emoji.zig` is generated by `tools/gen-emoji.py` from Unicode's +`emoji-test.txt` and CLDR's English annotations; run that rather than editing the +table, and add to its `SYNONYMS` when a glyph should answer to a word the data +files don't know. Two things it leaves out. Skin-tone variants, because just over +half of Unicode's 3944 sequences are the same gesture in five tones and a grid of +them is longer to look through rather than more complete — every base glyph is +there. And anything newer than emoji 16.0, because colour fonts trail Unicode by +a year or two and a glyph the font has never heard of draws as a hex-digit box, +which in a picker reads as a bug; `--max-version` raises the cutoff once fonts +have caught up. + +The choice lives on the tab and not on disk, the same as a typed name: it lasts +as long as the tab does. Saving the tab as a layout does not carry it, since a +layout describes an arrangement of panes rather than what a row looks like. + ## Agent status Playpen is mostly used to keep several Claude Code sessions side by side, and @@ -627,9 +673,16 @@ emit from and the client never sees it. Anything reachable only by clicking has to be reached another way — a keyboard shortcut, or `zig build test` if the thing being checked is logic rather than pixels. -`zig build test` runs the unit tests, which cover layout parsing and the -parameter/`$(...)` substitution pipeline. They are rooted at `Layouts.zig` so -the test binary never links GTK. +`zig build test` runs the unit tests, which cover layout parsing, the +parameter/`$(...)` substitution pipeline, and the emoji table and its search. +They build as two binaries, rooted at `Layouts.zig` and `emoji.zig`, so neither +links GTK — a test binary has one root, and those are the two files worth +testing in isolation that have nothing to do with each other. + +`tools/gen-emoji.py` regenerates `src/emoji.zig` from Unicode's `emoji-test.txt` +and CLDR's annotations. It is not part of the build — its output is committed, so +a build never needs the network — and `--check` reports whether what is committed +is what it would write. See [Tab settings](#tab-settings). Web panes need an EGL display and the headless compositor has no GPU, so `shot.sh` forces the dev shell's mesa down to its software rasterizer. The mesa diff --git a/build.zig b/build.zig index 667e71e..7e36263 100644 --- a/build.zig +++ b/build.zig @@ -82,6 +82,19 @@ pub fn build(b: *std.Build) void { }); tests.root_module.addImport("glib", gobject.module("glib2")); - const run_tests = b.addRunArtifact(tests); - b.step("test", "Run the tests").dependOn(&run_tests.step); + const test_step = b.step("test", "Run the tests"); + test_step.dependOn(&b.addRunArtifact(tests).step); + + // A second root for the same reason, one step further out: `emoji.zig` is a + // table and a search over it, and it imports nothing at all. It cannot hang + // off the root above because a test binary has exactly one root, and + // Layouts.zig has no reason to reach for the emoji table. + const emoji_tests = b.addTest(.{ + .root_module = b.createModule(.{ + .root_source_file = b.path("src/emoji.zig"), + .target = target, + .optimize = optimize, + }), + }); + test_step.dependOn(&b.addRunArtifact(emoji_tests).step); } diff --git a/src/TabSettingsDialog.zig b/src/TabSettingsDialog.zig new file mode 100644 index 0000000..115b1fc --- /dev/null +++ b/src/TabSettingsDialog.zig @@ -0,0 +1,411 @@ +//! Per-tab settings: the preferences that belong to one tab rather than to the +//! whole app. +//! +//! Built in the same hand-rolled shape as `SettingsDialog`, and for the same +//! reason — a stock preferences window in the middle of a window this heavily +//! restyled reads as something belonging to a different program. Changes apply +//! the moment you make them, so there is no confirm button: picking an emoji +//! redraws the sidebar row behind the dialog, which makes the setting its own +//! preview. +//! +//! Only one is open at a time, and opening it for a second tab retargets it +//! rather than stacking a second window. Two of these side by side would both +//! be titled after their tab and otherwise identical, which is a good way to +//! change the wrong tab's emoji. + +const std = @import("std"); +const gtk = @import("gtk"); + +const emoji = @import("emoji.zig"); + +const TabSettingsDialog = @This(); + +/// Told that the tab's emoji changed. Null means "go back to the pane's icon". +/// +/// The glyph handed over points into `emoji.table`, so it is static: the +/// receiver may hold onto it without copying it and without ever freeing it. +pub const Callback = *const fn (ctx: ?*anyopaque, glyph: ?[:0]const u8) void; + +pub const Options = struct { + /// What the tab's row is showing, so the window can say which tab this is. + tab_name: []const u8, + + /// The emoji the tab is wearing now, if any. + emoji: ?[]const u8, +}; + +/// How much of the search box we read. Long enough for any real query: matching +/// is per-word, so past a few terms every further one can only narrow the result +/// to nothing. +const query_max = 96; + +/// The side of one cell in the picker's grid, in pixels. Comfortably wider than +/// a glyph at the size the CSS draws it, so the square rather than the glyph is +/// what decides the column width. +const cell_size = 30; + +alloc: std.mem.Allocator, +window: *gtk.Window, + +/// The picker's grid, one child per entry in `emoji.table` and in that order, +/// which is what lets a child's index stand in for the entry it shows. +grid: *gtk.FlowBox, + +/// Large rendering of the current choice, or "None" when there isn't one. +preview: *gtk.Label, + +/// The box that filters it. Held so the window can open with the cursor already +/// in it: the grid is two thousand glyphs deep, and typing is the way in. +search: *gtk.SearchEntry, + +/// Shown in the grid's place when a search matches nothing, so an empty grid +/// reads as "no matches" rather than as a broken picker. +empty: *gtk.Label, + +/// Drops back to the pane's icon. Insensitive when there is no emoji to drop. +clear: *gtk.Button, + +/// The search text, as typed. `emoji.matches` folds case itself, so this is +/// stored verbatim rather than lowercased on the way in. +query_buf: [query_max]u8 = undefined, +query_len: usize = 0, + +/// Index into `emoji.table` of the chosen glyph, or null for the pane's icon. +chosen: ?usize, + +on_changed: Callback, + +/// Whose tab this is. Also the identity `closeFor` matches on. +ctx: ?*anyopaque, + +/// The open dialog, if there is one. +var open: ?*TabSettingsDialog = null; + +pub fn present( + alloc: std.mem.Allocator, + parent: *gtk.Window, + opts: Options, + on_changed: Callback, + ctx: ?*anyopaque, +) !void { + if (open) |existing| { + if (existing.ctx == ctx) { + existing.window.present(); + return; + } + // A different tab: the whole window is about that tab, so there is + // nothing worth keeping. Destroying it clears `open` through its own + // destroy handler. + existing.window.destroy(); + } + + const self = try alloc.create(TabSettingsDialog); + errdefer alloc.destroy(self); + + self.* = .{ + .alloc = alloc, + .window = gtk.Window.new(), + .grid = gtk.FlowBox.new(), + .preview = gtk.Label.new(null), + .search = gtk.SearchEntry.new(), + .empty = gtk.Label.new("No emoji match that search."), + .clear = gtk.Button.newWithLabel("Use the pane icon"), + .chosen = indexOf(opts.emoji), + .on_changed = on_changed, + .ctx = ctx, + }; + + var title_buf: [160]u8 = undefined; + const title = std.fmt.bufPrintZ(&title_buf, "Tab settings — {s}", .{ + clip(opts.tab_name, 96), + }) catch "Tab settings"; + + self.window.setTitle(title); + self.window.setTransientFor(parent); + self.window.setModal(1); + self.window.setDefaultSize(430, 620); + self.window.as(gtk.Widget).addCssClass("playpen-dialog"); + + const content = gtk.Box.new(.vertical, 12); + content.as(gtk.Widget).addCssClass("playpen-dialog-content"); + content.as(gtk.Widget).setVexpand(1); + content.append(self.buildEmojiGroup()); + + const buttons = gtk.Box.new(.horizontal, 8); + buttons.as(gtk.Widget).setHalign(.end); + buttons.as(gtk.Widget).addCssClass("playpen-dialog-actions"); + + // "Close" rather than "OK", as in the app's own settings: every change here + // has already been applied, so there is nothing to confirm. + const close = gtk.Button.newWithLabel("Close"); + _ = gtk.Button.signals.clicked.connect(close, *TabSettingsDialog, &onClose, self, .{}); + buttons.append(close.as(gtk.Widget)); + + const outer = gtk.Box.new(.vertical, 0); + outer.append(content.as(gtk.Widget)); + outer.append(buttons.as(gtk.Widget)); + self.window.setChild(outer.as(gtk.Widget)); + + _ = gtk.Widget.signals.destroy.connect( + self.window, + *TabSettingsDialog, + &onDestroy, + self, + .{}, + ); + + open = self; + self.window.present(); + _ = self.search.as(gtk.Widget).grabFocus(); +} + +/// Close the dialog if it belongs to `ctx`. +/// +/// Called when a tab goes away. The dialog holds the tab as an opaque pointer +/// and would otherwise happily write an emoji into freed memory the next time +/// someone clicked a glyph. +pub fn closeFor(ctx: ?*anyopaque) void { + const existing = open orelse return; + if (existing.ctx != ctx) return; + existing.window.destroy(); +} + +/// `text` cut to at most `limit` bytes, never mid-codepoint. +/// +/// The tab name comes off a terminal title, so it is any length and any script. +/// A cut through the middle of a UTF-8 sequence would hand GTK a string it +/// refuses, and the window would end up with no title at all rather than a +/// shortened one. +fn clip(text: []const u8, limit: usize) []const u8 { + if (text.len <= limit) return text; + + var end = limit; + while (end > 0 and text[end] & 0xc0 == 0x80) end -= 1; + return text[0..end]; +} + +/// Where a glyph sits in `emoji.table`, which is how the dialog carries "the +/// current choice" without carrying a string. +/// +/// A glyph that isn't in the table reads as no choice at all. That can only +/// happen if the table loses an entry it used to have, and the honest answer +/// then is that the picker no longer offers what the tab is wearing. +fn indexOf(glyph: ?[]const u8) ?usize { + const wanted = glyph orelse return null; + for (emoji.table, 0..) |entry, i| { + if (std.mem.eql(u8, entry.glyph, wanted)) return i; + } + return null; +} + +/// The whole Emoji Label section: what is set now, then the picker for +/// changing it. +fn buildEmojiGroup(self: *TabSettingsDialog) *gtk.Widget { + const group = gtk.Box.new(.vertical, 10); + group.as(gtk.Widget).addCssClass("playpen-settings-group"); + group.as(gtk.Widget).setVexpand(1); + + const title = gtk.Label.new("Emoji Label"); + title.setXalign(0); + title.as(gtk.Widget).addCssClass("playpen-settings-title"); + group.append(title.as(gtk.Widget)); + + // Across the section rather than beside the preview: at this width a + // sentence squeezed into the gap between a swatch and a button wraps to four + // lines, and four lines of hint is louder than the thing it explains. + const hint = gtk.Label.new( + "Stands in for the pane's icon in the sidebar, for this tab only.", + ); + hint.setXalign(0); + hint.setWrap(1); + hint.as(gtk.Widget).addCssClass("playpen-dialog-sublabel"); + group.append(hint.as(gtk.Widget)); + + group.append(self.buildCurrent()); + group.append(self.buildPicker()); + + return group.as(gtk.Widget); +} + +/// The current choice, spelled out large enough to check at a glance, with the +/// way back to the icon across from it. +fn buildCurrent(self: *TabSettingsDialog) *gtk.Widget { + const row = gtk.Box.new(.horizontal, 12); + + self.preview.as(gtk.Widget).addCssClass("playpen-emoji-preview"); + self.preview.as(gtk.Widget).setValign(.center); + row.append(self.preview.as(gtk.Widget)); + + self.clear.as(gtk.Widget).setHexpand(1); + self.clear.as(gtk.Widget).setHalign(.end); + self.clear.as(gtk.Widget).setValign(.center); + _ = gtk.Button.signals.clicked.connect( + self.clear, + *TabSettingsDialog, + &onClear, + self, + .{}, + ); + row.append(self.clear.as(gtk.Widget)); + + return row.as(gtk.Widget); +} + +/// Search box over a scrolling grid of every glyph in the table. +/// +/// The grid is built once and filtered in place rather than rebuilt per +/// keystroke. Two thousand widgets is a fair amount to keep around, but GTK only +/// lays out and draws the ones on screen, and re-running a filter over them is +/// cheap where building them again between one letter and the next would not be. +fn buildPicker(self: *TabSettingsDialog) *gtk.Widget { + const box = gtk.Box.new(.vertical, 8); + box.as(gtk.Widget).setVexpand(1); + + const search = self.search; + search.setPlaceholderText("Search emoji — try \"rocket\" or \"green circle\""); + _ = gtk.SearchEntry.signals.search_changed.connect( + search, + *TabSettingsDialog, + &onSearchChanged, + self, + .{}, + ); + box.append(search.as(gtk.Widget)); + + self.grid.setSelectionMode(.single); + self.grid.setActivateOnSingleClick(1); + self.grid.setMaxChildrenPerLine(12); + self.grid.setRowSpacing(2); + self.grid.setColumnSpacing(2); + self.grid.as(gtk.Widget).setValign(.start); + self.grid.as(gtk.Widget).addCssClass("playpen-emoji-grid"); + self.grid.setFilterFunc(&filter, self, null); + _ = gtk.FlowBox.signals.child_activated.connect( + self.grid, + *TabSettingsDialog, + &onEmojiActivated, + self, + .{}, + ); + + for (emoji.table) |entry| { + const label = gtk.Label.new(entry.glyph); + label.as(gtk.Widget).addCssClass("playpen-emoji-cell"); + + // Every cell asks for the same square, which is what keeps the grid in + // columns. `setHomogeneous` would have done it too, but it sizes every + // cell to the widest child, and a handful of the ZWJ sequences fall + // apart into two or three glyphs on a font that can't compose them — + // one of those in the table and the whole grid inherits its width. This + // way the odd wide one is wide on its own. + label.as(gtk.Widget).setSizeRequest(cell_size, cell_size); + + const child = gtk.FlowBoxChild.new(); + child.setChild(label.as(gtk.Widget)); + + // Names a glyph you can't quite make out at this size — which, at this + // size and across two thousand of them, is a good few. + child.as(gtk.Widget).setTooltipText(entry.name); + + self.grid.append(child.as(gtk.Widget)); + } + + const scroller = gtk.ScrolledWindow.new(); + scroller.setPolicy(.never, .automatic); + scroller.as(gtk.Widget).setVexpand(1); + scroller.as(gtk.Widget).addCssClass("playpen-emoji-scroller"); + scroller.setChild(self.grid.as(gtk.Widget)); + box.append(scroller.as(gtk.Widget)); + + self.empty.as(gtk.Widget).addCssClass("playpen-dialog-hint"); + self.empty.as(gtk.Widget).setVisible(0); + box.append(self.empty.as(gtk.Widget)); + + // Only now that the grid has its children can the current choice be + // highlighted in it. + self.refreshCurrent(); + + return box.as(gtk.Widget); +} + +/// The search text as typed. +fn query(self: *const TabSettingsDialog) []const u8 { + return self.query_buf[0..self.query_len]; +} + +/// Whether one grid child should show. Runs per child on every keystroke. +fn filter(child: *gtk.FlowBoxChild, data: ?*anyopaque) callconv(.c) c_int { + const self: *TabSettingsDialog = @ptrCast(@alignCast(data.?)); + + const index = child.getIndex(); + if (index < 0 or index >= emoji.table.len) return 1; + + return @intFromBool(emoji.matches(emoji.table[@intCast(index)], self.query())); +} + +fn onSearchChanged(entry: *gtk.SearchEntry, self: *TabSettingsDialog) callconv(.c) void { + const typed = std.mem.span(entry.as(gtk.Editable).getText()); + self.query_len = @min(typed.len, self.query_buf.len); + @memcpy(self.query_buf[0..self.query_len], typed[0..self.query_len]); + + self.grid.invalidateFilter(); + + // Asked of the table rather than of the grid: GTK has no count of what + // survived a filter, and the table is the thing the filter is reading. + const any = for (emoji.table) |candidate| { + if (emoji.matches(candidate, self.query())) break true; + } else false; + self.empty.as(gtk.Widget).setVisible(@intFromBool(!any)); +} + +fn onEmojiActivated( + _: *gtk.FlowBox, + child: *gtk.FlowBoxChild, + self: *TabSettingsDialog, +) callconv(.c) void { + const index = child.getIndex(); + if (index < 0 or index >= emoji.table.len) return; + self.choose(@intCast(index)); +} + +fn onClear(_: *gtk.Button, self: *TabSettingsDialog) callconv(.c) void { + self.choose(null); +} + +/// Apply a choice: update what the dialog shows, then tell the tab. +fn choose(self: *TabSettingsDialog, index: ?usize) void { + self.chosen = index; + self.refreshCurrent(); + self.on_changed(self.ctx, if (index) |i| emoji.table[i].glyph else null); +} + +fn refreshCurrent(self: *TabSettingsDialog) void { + if (self.chosen) |i| { + self.preview.setText(emoji.table[i].glyph); + self.preview.as(gtk.Widget).removeCssClass("playpen-emoji-preview-none"); + // Selecting the child rather than only filling the preview, so that a + // glyph already in force is findable in the grid it came from. + if (self.grid.getChildAtIndex(@intCast(i))) |child| self.grid.selectChild(child); + } else { + self.preview.setText("None"); + self.preview.as(gtk.Widget).addCssClass("playpen-emoji-preview-none"); + self.grid.unselectAll(); + } + + self.clear.as(gtk.Widget).setSensitive(@intFromBool(self.chosen != null)); +} + +fn onClose(_: *gtk.Button, self: *TabSettingsDialog) callconv(.c) void { + self.window.destroy(); +} + +fn onDestroy(_: *gtk.Window, self: *TabSettingsDialog) callconv(.c) void { + if (open == self) open = null; + + // The filter func outlives nothing here — the grid goes down with the + // window — but dropping it makes that explicit rather than relying on + // teardown order. + self.grid.setFilterFunc(null, null, null); + + self.alloc.destroy(self); +} diff --git a/src/Window.zig b/src/Window.zig index cd8524a..b8ff244 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -19,6 +19,7 @@ const OpenLayoutDialog = @import("OpenLayoutDialog.zig"); const Pane = @import("Pane.zig"); const SaveLayoutDialog = @import("SaveLayoutDialog.zig"); const SettingsDialog = @import("SettingsDialog.zig"); +const TabSettingsDialog = @import("TabSettingsDialog.zig"); const Terminal = @import("Terminal.zig"); const View = @import("View.zig"); const appearance = @import("appearance.zig"); @@ -80,6 +81,14 @@ const Tab = struct { /// the sidebar without reading the title. icon: *gtk.Image, + /// An emoji the user picked, shown in the icon's place. Unlike `custom_name` + /// this is not owned: the glyph points into `emoji.table`, which is static, + /// so there is nothing here to copy and nothing to free. + emoji: ?[:0]const u8 = null, + + /// The widget that draws that emoji, sharing the icon's slot in the row. + emoji_label: *gtk.Label, + /// Status dot, hidden unless the tab has something to report. dot: *gtk.Image, @@ -87,6 +96,9 @@ const Tab = struct { /// Null means the label tracks the content, which is the default. custom_name: ?[]u8 = null, + /// The row's right-click menu, parented to this tab's row. + menu_popover: *gtk.Popover, + /// Popover holding the rename entry, parented to this tab's row. rename_popover: *gtk.Popover, rename_entry: *gtk.Entry, @@ -312,7 +324,9 @@ fn newTabEmpty(self: *Window) !*Tab { .row = gtk.ListBoxRow.new(), .label = gtk.Label.new("shell"), .icon = gtk.Image.newFromIconName("utilities-terminal-symbolic"), + .emoji_label = gtk.Label.new(null), .dot = gtk.Image.newFromIconName(Pane.status_icon), + .menu_popover = gtk.Popover.new(), .rename_popover = gtk.Popover.new(), .rename_entry = gtk.Entry.new(), .name = undefined, @@ -325,7 +339,13 @@ fn newTabEmpty(self: *Window) !*Tab { const row_box = gtk.Box.new(.horizontal, 6); row_box.as(gtk.Widget).addCssClass("playpen-row"); + // Both live in the row, and `refreshLabel` shows exactly one of them. The + // emoji is given the icon's width so that a sidebar of mixed rows still + // has its labels starting in one column. row_box.append(tab.icon.as(gtk.Widget)); + tab.emoji_label.as(gtk.Widget).addCssClass("playpen-tab-emoji"); + tab.emoji_label.as(gtk.Widget).setVisible(0); + row_box.append(tab.emoji_label.as(gtk.Widget)); tab.label.setXalign(0); tab.label.setEllipsize(.end); @@ -345,6 +365,7 @@ fn newTabEmpty(self: *Window) !*Tab { row_box.append(close.as(gtk.Widget)); tab.row.setChild(row_box.as(gtk.Widget)); + self.buildRowMenu(tab, row_box); self.buildRename(tab, row_box); self.list.append(tab.row.as(gtk.Widget)); @@ -355,6 +376,122 @@ fn newTabEmpty(self: *Window) !*Tab { return tab; } +// ------------------------------------------------------------------------- +// The row menu +// +// Right-clicking a row opens a menu rather than going straight to the rename +// entry, which is where it used to land. Renaming was the only thing a row +// could do, so it was reasonable for the gesture to *be* renaming; now that a +// row also has settings behind it, a gesture that silently picks one of the two +// would make the other one unreachable by the route people try first. +// +// It does not select the row it belongs to. Renaming a tab, or giving it an +// emoji, is not a reason to go and look at it — often it is the opposite, since +// the tab you are labelling is the one you are about to leave alone for a while. + +/// Attach the row's context menu and the right-click that opens it. +fn buildRowMenu(self: *Window, tab: *Tab, anchor: *gtk.Box) void { + _ = self; + + const box = gtk.Box.new(.vertical, 2); + box.as(gtk.Widget).addCssClass("playpen-row-menu"); + box.append(menuItem("Rename", &onMenuRename, tab)); + box.append(menuItem("Settings…", &onMenuSettings, tab)); + + tab.menu_popover.setChild(box.as(gtk.Widget)); + tab.menu_popover.setHasArrow(0); + tab.menu_popover.as(gtk.Widget).setParent(anchor.as(gtk.Widget)); + + const secondary = gtk.GestureClick.new(); + secondary.as(gtk.GestureSingle).setButton(3); + _ = gtk.GestureClick.signals.pressed.connect( + secondary, + *Tab, + &onRowSecondary, + tab, + .{}, + ); + anchor.as(gtk.Widget).addController(secondary.as(gtk.EventController)); +} + +/// One line of the row menu, styled like the layout menu's rows so the two +/// popovers read as the same kind of thing. +fn menuItem( + text: [:0]const u8, + handler: *const fn (*gtk.Button, *Tab) callconv(.c) void, + tab: *Tab, +) *gtk.Widget { + const button = gtk.Button.newWithLabel(text); + button.as(gtk.Widget).addCssClass("flat"); + button.setHasFrame(0); + if (button.getChild()) |child| child.setHalign(.start); + _ = gtk.Button.signals.clicked.connect(button, *Tab, handler, tab, .{}); + return button.as(gtk.Widget); +} + +/// Open the menu where the pointer is, rather than centred on the row: with one +/// popover per row anchored to the whole row, a fixed position would put the +/// menu somewhere you weren't pointing. +fn onRowSecondary( + _: *gtk.GestureClick, + _: c_int, + x: f64, + y: f64, + tab: *Tab, +) callconv(.c) void { + const at: gdk.Rectangle = .{ + .f_x = @intFromFloat(x), + .f_y = @intFromFloat(y), + .f_width = 1, + .f_height = 1, + }; + tab.menu_popover.setPointingTo(&at); + tab.menu_popover.popup(); +} + +fn onMenuRename(_: *gtk.Button, tab: *Tab) callconv(.c) void { + tab.menu_popover.popdown(); + tab.window.beginRename(tab); +} + +fn onMenuSettings(_: *gtk.Button, tab: *Tab) callconv(.c) void { + tab.menu_popover.popdown(); + tab.window.openTabSettings(tab); +} + +// ------------------------------------------------------------------------- +// Per-tab settings + +/// Open the settings for one tab. +/// +/// The tab is handed over as the dialog's opaque context and resolved again on +/// the way back, so the dialog never holds a pointer into anything it owns. What +/// it does hold is the tab itself, which is why `closeTab` closes it. +fn openTabSettings(self: *Window, tab: *Tab) void { + var buf: [128]u8 = undefined; + + TabSettingsDialog.present( + self.alloc, + self.window.as(gtk.Window), + .{ + .tab_name = self.tabName(tab, &buf), + .emoji = tab.emoji, + }, + &onTabEmojiChanged, + tab, + ) catch |err| { + std.log.err("failed to open tab settings: {s}", .{@errorName(err)}); + }; +} + +/// The picker chose a glyph, or cleared the choice. The glyph is static, so +/// there is nothing to copy and nothing to release. +fn onTabEmojiChanged(ctx: ?*anyopaque, glyph: ?[:0]const u8) void { + const tab: *Tab = @ptrCast(@alignCast(ctx.?)); + tab.emoji = glyph; + tab.window.refreshLabel(tab); +} + // ------------------------------------------------------------------------- // Renaming // @@ -393,19 +530,10 @@ fn buildRename(self: *Window, tab: *Tab, anchor: *gtk.Box) void { tab.rename_popover.as(gtk.Widget).addCssClass("playpen-rename-popover"); tab.rename_popover.as(gtk.Widget).setParent(anchor.as(gtk.Widget)); - // Right-click is the discoverable route; double-click matches how tab - // strips elsewhere behave. Both land in the same place. - const secondary = gtk.GestureClick.new(); - secondary.as(gtk.GestureSingle).setButton(3); - _ = gtk.GestureClick.signals.pressed.connect( - secondary, - *Tab, - &onRowSecondary, - tab, - .{}, - ); - anchor.as(gtk.Widget).addController(secondary.as(gtk.EventController)); - + // Double-click still goes straight here, without passing through the menu: + // it matches how tab strips elsewhere behave, and it is the shortcut worth + // keeping for the one thing you rename a tab far more often than you + // configure it. const double = gtk.GestureClick.new(); double.as(gtk.GestureSingle).setButton(1); _ = gtk.GestureClick.signals.pressed.connect( @@ -456,16 +584,6 @@ fn onRenameActivate(_: *gtk.Entry, tab: *Tab) callconv(.c) void { self.refreshLabel(tab); } -fn onRowSecondary( - _: *gtk.GestureClick, - _: c_int, - _: f64, - _: f64, - tab: *Tab, -) callconv(.c) void { - tab.window.beginRename(tab); -} - fn onRowDoubleClick( _: *gtk.GestureClick, n_press: c_int, @@ -731,8 +849,12 @@ fn closeTab(self: *Window, tab: *Tab) void { self.stack.remove(tab.view.widget()); + // The dialog holds this tab as an opaque pointer, so it has to go first. + TabSettingsDialog.closeFor(tab); + // A popover attached with setParent is not an ordinary child, so it has // to be detached by hand; letting the row take it down warns instead. + tab.menu_popover.as(gtk.Widget).unparent(); tab.rename_popover.as(gtk.Widget).unparent(); self.list.remove(tab.row.as(gtk.Widget)); @@ -838,7 +960,19 @@ fn refreshLabel(self: *Window, tab: *Tab) void { tab.label.setText(buf[0..text.len :0]); tab.label.as(gtk.Widget).setTooltipText(buf[0..text.len :0]); - tab.icon.setFromIconName(tab.view.iconName()); + + // An emoji replaces the icon rather than joining it. The row has one slot + // for "what is this tab", and filling it twice would spend twice the width + // saying it once — width the label is short of already. + if (tab.emoji) |glyph| { + tab.emoji_label.setText(glyph); + tab.emoji_label.as(gtk.Widget).setVisible(1); + tab.icon.as(gtk.Widget).setVisible(0); + } else { + tab.emoji_label.as(gtk.Widget).setVisible(0); + tab.icon.as(gtk.Widget).setVisible(1); + tab.icon.setFromIconName(tab.view.iconName()); + } self.refreshStatus(tab); } @@ -890,6 +1024,9 @@ fn onDestroy(_: *adw.ApplicationWindow, self: *Window) callconv(.c) void { // Each terminal owns a session, which owns a PTY and its child process. // Dropping them here reaps the children rather than orphaning them. for (self.tabs.items) |tab| { + // As in closeTab: the tab settings dialog is not a child of this + // window, so nothing else takes it down before the tab it points at. + TabSettingsDialog.closeFor(tab); tab.view.destroy(); if (tab.custom_name) |name| self.alloc.free(name); self.alloc.destroy(tab); diff --git a/src/emoji.zig b/src/emoji.zig new file mode 100644 index 0000000..65380a1 --- /dev/null +++ b/src/emoji.zig @@ -0,0 +1,2086 @@ +//! Every emoji a tab can wear in place of its icon, and the search that finds +//! them. +//! +//! Generated — run `tools/gen-emoji.py` rather than editing this file. It reads +//! Unicode's `emoji-test.txt` (currently version 17.0) for the set and its +//! ordering, and CLDR's English annotations for the keywords, so the picker is +//! laid out and searchable the same way every other emoji keyboard is. +//! +//! 1906 entries: the RGI set up to emoji 16.0, minus skin-tone variants. +//! Unicode lists nearly twice this many fully-qualified sequences and the +//! difference is almost entirely the same gesture in five tones, which makes a +//! grid longer to look through without making it more complete. The version +//! cutoff is there because colour emoji fonts trail Unicode, and a glyph the +//! font has never heard of draws as a hex-digit box; the generator's header +//! explains how to raise it. +//! +//! Keywords are CLDR's, plus the group and subgroup a glyph belongs to — so +//! "fruit", "arrow" and "flags" each bring back a whole shelf — plus a table of +//! synonyms in the generator for the words a terminal user would actually type: +//! a rocket answers to "deploy", a bandage to "hotfix", a whale to "docker". + +const std = @import("std"); + +pub const Emoji = struct { + /// The glyph itself, NUL-terminated so it can go straight into a label. + glyph: [:0]const u8, + + /// CLDR's short name — "red apple", "flag: Kenya" — as the picker shows it + /// in a tooltip. NUL-terminated for the same reason as the glyph, and kept + /// apart from `keywords` because a name is one phrase and a keyword list is + /// twenty words: readable in a tooltip, and unreadable in one. + name: [:0]const u8, + + /// Space-separated search terms, lowercase, the name's own words among them. + keywords: []const u8, +}; + +/// Whether `emoji` should show for `query`. +/// +/// Every whitespace-separated term has to match somewhere, which is what makes +/// "red circle" and "circle red" both land on the same glyph while "red" alone +/// still brings back the whole family. An empty query matches everything, so +/// the unfiltered grid falls out of the same path as a filtered one. +pub fn matches(emoji: Emoji, query: []const u8) bool { + var terms = std.mem.tokenizeAny(u8, query, " \t"); + while (terms.next()) |term| { + if (std.ascii.indexOfIgnoreCase(emoji.keywords, term) == null) return false; + } + return true; +} + +/// Every emoji the picker offers, in Unicode's order. +pub const table = [_]Emoji{ + // ---- Smileys & Emotion ------------------------------------------- + .{ .glyph = "😀", .name = "grinning face", .keywords = "grinning face cheerful cheery grin happy laugh nice smile smiling teeth smileys emotion" }, + .{ .glyph = "😃", .name = "grinning face with big eyes", .keywords = "grinning face with big eyes awesome grin happy mouth open smile smiling teeth yay smileys emotion" }, + .{ .glyph = "😄", .name = "grinning face with smiling eyes", .keywords = "grinning face with smiling eyes eye grin happy laugh lol mouth open smile smileys emotion" }, + .{ .glyph = "😁", .name = "beaming face with smiling eyes", .keywords = "beaming face with smiling eyes eye grin grinning happy nice smile teeth smileys emotion" }, + .{ .glyph = "😆", .name = "grinning squinting face", .keywords = "grinning squinting face closed eyes haha hahaha happy laugh lol mouth open rofl smile smiling smileys emotion" }, + .{ .glyph = "😅", .name = "grinning face with sweat", .keywords = "grinning face with sweat cold dejected excited mouth nervous open smile smiling stress stressed smileys emotion" }, + .{ .glyph = "🤣", .name = "rolling on the floor laughing", .keywords = "rolling on the floor laughing crying face funny haha happy hehe hilarious joy laugh lmao lol rofl roflmao tear smiling smileys emotion" }, + .{ .glyph = "😂", .name = "face with tears of joy", .keywords = "face with tears of joy crying feels funny haha happy hehe hilarious laugh lmao lol rofl roflmao tear smiling smileys emotion" }, + .{ .glyph = "🙂", .name = "slightly smiling face", .keywords = "slightly smiling face happy smile smileys emotion" }, + .{ .glyph = "🙃", .name = "upside-down face", .keywords = "upside down face hehe smile smiling smileys emotion" }, + .{ .glyph = "🫠", .name = "melting face", .keywords = "melting face disappear dissolve embarrassed haha heat hot liquid lol melt sarcasm sarcastic smiling smileys emotion" }, + .{ .glyph = "😉", .name = "winking face", .keywords = "winking face flirt heartbreaker sexy slide tease wink winks smiling smileys emotion" }, + .{ .glyph = "😊", .name = "smiling face with smiling eyes", .keywords = "smiling face with eyes blush eye glad satisfied smile smileys emotion" }, + .{ .glyph = "😇", .name = "smiling face with halo", .keywords = "smiling face with halo angel angelic angels blessed fairy fairytale fantasy happy innocent peaceful smile spirit tale smileys emotion" }, + .{ .glyph = "🥰", .name = "smiling face with hearts", .keywords = "smiling face with hearts 3 adore crush heart ily love romance smile you affection smileys emotion" }, + .{ .glyph = "😍", .name = "smiling face with heart-eyes", .keywords = "smiling face with heart eyes 143 bae eye feels hearts ily kisses love romance romantic smile xoxo affection smileys emotion" }, + .{ .glyph = "🤩", .name = "star-struck", .keywords = "star struck excited eyes face grinning smile starry eyed wow affection smileys emotion" }, + .{ .glyph = "😘", .name = "face blowing a kiss", .keywords = "face blowing a kiss adorbs bae flirt heart ily love lover miss muah romantic smooch xoxo you affection smileys emotion" }, + .{ .glyph = "😗", .name = "kissing face", .keywords = "kissing face 143 date dating flirt ily kiss love smooch smooches xoxo you affection smileys emotion" }, + .{ .glyph = "☺️", .name = "smiling face", .keywords = "smiling face happy outlined relaxed smile affection smileys emotion" }, + .{ .glyph = "😚", .name = "kissing face with closed eyes", .keywords = "kissing face with closed eyes 143 bae blush date dating eye flirt ily kisses smooches xoxo affection smileys emotion" }, + .{ .glyph = "😙", .name = "kissing face with smiling eyes", .keywords = "kissing face with smiling eyes 143 closed date dating eye flirt ily kiss kisses love night smile affection smileys emotion" }, + .{ .glyph = "🥲", .name = "smiling face with tear", .keywords = "smiling face with tear glad grateful happy joy pain proud relieved smile smiley touched affection smileys emotion" }, + .{ .glyph = "😋", .name = "face savoring food", .keywords = "face savoring food delicious eat full hungry savor smile smiling tasty um yum yummy tongue smileys emotion" }, + .{ .glyph = "😛", .name = "face with tongue", .keywords = "face with tongue awesome cool nice party stuck out sweet smileys emotion" }, + .{ .glyph = "😜", .name = "winking face with tongue", .keywords = "winking face with tongue crazy epic eye funny joke loopy nutty party stuck out wacky weirdo wink yolo smileys emotion" }, + .{ .glyph = "🤪", .name = "zany face", .keywords = "zany face crazy eye eyes goofy large small tongue smileys emotion" }, + .{ .glyph = "😝", .name = "squinting face with tongue", .keywords = "squinting face with tongue closed eye eyes gross horrible omg stuck out taste whatever yolo smileys emotion" }, + .{ .glyph = "🤑", .name = "money-mouth face", .keywords = "money mouth face paid tongue smileys emotion" }, + .{ .glyph = "🤗", .name = "smiling face with open hands", .keywords = "smiling face with open hands hug hugging hand smileys emotion" }, + .{ .glyph = "🤭", .name = "face with hand over mouth", .keywords = "face with hand over mouth giggle giggling oops realization secret shock sudden surprise whoops smileys emotion" }, + .{ .glyph = "🫢", .name = "face with open eyes and hand over mouth", .keywords = "face with open eyes and hand over mouth amazement awe disbelief embarrass gasp omg quiet scared shock surprise smileys emotion" }, + .{ .glyph = "🫣", .name = "face with peeking eye", .keywords = "face with peeking eye captivated embarrass hide hiding peek peep scared shy stare hand smileys emotion" }, + .{ .glyph = "🤫", .name = "shushing face", .keywords = "shushing face quiet shh shush hand smileys emotion" }, + .{ .glyph = "🤔", .name = "thinking face", .keywords = "thinking face chin consider hmm ponder pondering wondering hand smileys emotion" }, + .{ .glyph = "🫡", .name = "saluting face", .keywords = "saluting face good luck ma’am ok respect salute sir troops yes hand smileys emotion" }, + .{ .glyph = "🤐", .name = "zipper-mouth face", .keywords = "zipper mouth face keep quiet secret shut zip neutral skeptical smileys emotion" }, + .{ .glyph = "🤨", .name = "face with raised eyebrow", .keywords = "face with raised eyebrow disapproval disbelief distrust emoji hmm mild skeptic skeptical skepticism surprise what neutral smileys emotion" }, + .{ .glyph = "😐", .name = "neutral face", .keywords = "neutral face awkward blank deadpan expressionless fine jealous meh oh shade straight unamused unhappy unimpressed whatever skeptical smileys emotion" }, + .{ .glyph = "😑", .name = "expressionless face", .keywords = "expressionless face awkward dead fine inexpressive jealous meh not oh omg straight uh unhappy unimpressed whatever neutral skeptical smileys emotion" }, + .{ .glyph = "😶", .name = "face without mouth", .keywords = "face without mouth awkward blank expressionless mouthless mute quiet secret silence silent speechless neutral skeptical smileys emotion" }, + .{ .glyph = "🫥", .name = "dotted line face", .keywords = "dotted line face depressed disappear hidden hide introvert invisible meh whatever wtv neutral skeptical smileys emotion" }, + .{ .glyph = "😶‍🌫️", .name = "face in clouds", .keywords = "face in clouds absentminded fog head neutral skeptical smileys emotion" }, + .{ .glyph = "😏", .name = "smirking face", .keywords = "smirking face boss dapper flirt homie kidding leer shade slick sly smirk smug snicker suave suspicious swag neutral skeptical smileys emotion" }, + .{ .glyph = "😒", .name = "unamused face", .keywords = "unamused face ... bored fine jealous jel jelly pissed smh ugh uhh unhappy weird whatever neutral skeptical smileys emotion" }, + .{ .glyph = "🙄", .name = "face with rolling eyes", .keywords = "face with rolling eyes eyeroll shade ugh whatever neutral skeptical smileys emotion" }, + .{ .glyph = "😬", .name = "grimacing face", .keywords = "grimacing face awk awkward dentist grimace grinning smile smiling neutral skeptical smileys emotion" }, + .{ .glyph = "😮‍💨", .name = "face exhaling", .keywords = "face exhaling blow blowing exhale exhausted gasp groan relief sigh smiley smoke whisper whistle neutral skeptical smileys emotion" }, + .{ .glyph = "🤥", .name = "lying face", .keywords = "lying face liar lie pinocchio neutral skeptical smileys emotion" }, + .{ .glyph = "🫨", .name = "shaking face", .keywords = "shaking face crazy daze earthquake omg panic shock surprise vibrate whoa wow neutral skeptical smileys emotion" }, + .{ .glyph = "🙂‍↔️", .name = "head shaking horizontally", .keywords = "head shaking horizontally no shake face neutral skeptical smileys emotion" }, + .{ .glyph = "🙂‍↕️", .name = "head shaking vertically", .keywords = "head shaking vertically nod yes face neutral skeptical smileys emotion" }, + .{ .glyph = "😌", .name = "relieved face", .keywords = "relieved face calm peace relief zen sleepy smileys emotion" }, + .{ .glyph = "😔", .name = "pensive face", .keywords = "pensive face awful bored dejected died disappointed losing lost sad sucks sleepy smileys emotion" }, + .{ .glyph = "😪", .name = "sleepy face", .keywords = "sleepy face crying good night sad sleep sleeping tired smileys emotion" }, + .{ .glyph = "🤤", .name = "drooling face", .keywords = "drooling face sleepy smileys emotion" }, + .{ .glyph = "😴", .name = "sleeping face", .keywords = "sleeping face bed bedtime good goodnight nap night sleep tired whatever yawn zzz sleepy smileys emotion" }, + .{ .glyph = "🫩", .name = "face with bags under eyes", .keywords = "face with bags under eyes bored exhausted fatigued late sleepy tired weary smileys emotion" }, + .{ .glyph = "😷", .name = "face with medical mask", .keywords = "face with medical mask cold dentist dermatologist doctor dr germs medicine sick unwell smileys emotion" }, + .{ .glyph = "🤒", .name = "face with thermometer", .keywords = "face with thermometer ill sick unwell smileys emotion" }, + .{ .glyph = "🤕", .name = "face with head-bandage", .keywords = "face with head bandage hurt injury ouch unwell smileys emotion" }, + .{ .glyph = "🤢", .name = "nauseated face", .keywords = "nauseated face gross nasty sick vomit unwell smileys emotion" }, + .{ .glyph = "🤮", .name = "face vomiting", .keywords = "face vomiting barf ew gross puke sick spew throw up vomit unwell smileys emotion" }, + .{ .glyph = "🤧", .name = "sneezing face", .keywords = "sneezing face fever flu gesundheit sick sneeze unwell smileys emotion" }, + .{ .glyph = "🥵", .name = "hot face", .keywords = "hot face dying feverish heat panting red faced stroke sweating tongue unwell smileys emotion" }, + .{ .glyph = "🥶", .name = "cold face", .keywords = "cold face blue faced freezing frostbite icicles subzero teeth unwell smileys emotion" }, + .{ .glyph = "🥴", .name = "woozy face", .keywords = "woozy face dizzy drunk eyes intoxicated mouth tipsy uneven wavy unwell smileys emotion" }, + .{ .glyph = "😵", .name = "face with crossed-out eyes", .keywords = "face with crossed out eyes dead dizzy feels knocked sick tired unwell smileys emotion" }, + .{ .glyph = "😵‍💫", .name = "face with spiral eyes", .keywords = "face with spiral eyes confused dizzy hypnotized omg smiley trouble whoa woah woozy unwell smileys emotion" }, + .{ .glyph = "🤯", .name = "exploding head", .keywords = "exploding head blown explode mind mindblown no shocked way face unwell smileys emotion" }, + .{ .glyph = "🤠", .name = "cowboy hat face", .keywords = "cowboy hat face cowgirl smileys emotion" }, + .{ .glyph = "🥳", .name = "partying face", .keywords = "partying face bday birthday celebrate celebration excited happy hat hooray horn party smileys emotion" }, + .{ .glyph = "🥸", .name = "disguised face", .keywords = "disguised face disguise eyebrow glasses incognito moustache mustache nose person spy tache tash hat smileys emotion" }, + .{ .glyph = "😎", .name = "smiling face with sunglasses", .keywords = "smiling face with sunglasses awesome beach bright bro chilling cool rad relaxed shades slay smile style swag win glasses smileys emotion" }, + .{ .glyph = "🤓", .name = "nerd face", .keywords = "nerd face brainy clever expert geek gifted glasses intelligent smart smileys emotion" }, + .{ .glyph = "🧐", .name = "face with monocle", .keywords = "face with monocle classy fancy rich stuffy wealthy glasses smileys emotion" }, + .{ .glyph = "😕", .name = "confused face", .keywords = "confused face befuddled confusing dunno frown hm meh not sad sorry sure concerned smileys emotion" }, + .{ .glyph = "🫤", .name = "face with diagonal mouth", .keywords = "face with diagonal mouth confused confusion disappointed doubt doubtful frustrated frustration meh skeptical unsure whatever wtv concerned smileys emotion" }, + .{ .glyph = "😟", .name = "worried face", .keywords = "worried face anxious butterflies nerves nervous sad stress stressed surprised worry concerned smileys emotion" }, + .{ .glyph = "🙁", .name = "slightly frowning face", .keywords = "slightly frowning face frown sad concerned smileys emotion" }, + .{ .glyph = "☹️", .name = "frowning face", .keywords = "frowning face frown sad concerned smileys emotion" }, + .{ .glyph = "😮", .name = "face with open mouth", .keywords = "face with open mouth believe forgot omg shocked surprised sympathy unbelievable unreal whoa wow you concerned smileys emotion" }, + .{ .glyph = "😯", .name = "hushed face", .keywords = "hushed face epic omg stunned surprised whoa woah concerned smileys emotion" }, + .{ .glyph = "😲", .name = "astonished face", .keywords = "astonished face cost no omg shocked totally way concerned smileys emotion" }, + .{ .glyph = "😳", .name = "flushed face", .keywords = "flushed face amazed awkward crazy dazed dead disbelief embarrassed geez heat hot impressed jeez what wow concerned smileys emotion" }, + .{ .glyph = "🥺", .name = "pleading face", .keywords = "pleading face begging big eyes mercy not please pretty puppy sad why concerned smileys emotion" }, + .{ .glyph = "🥹", .name = "face holding back tears", .keywords = "face holding back tears admiration aww cry embarrassed feelings grateful gratitude joy please proud resist sad concerned smileys emotion" }, + .{ .glyph = "😦", .name = "frowning face with open mouth", .keywords = "frowning face with open mouth caught frown guard scared scary surprise what wow concerned smileys emotion" }, + .{ .glyph = "😧", .name = "anguished face", .keywords = "anguished face forgot scared scary stressed surprise unhappy what wow concerned smileys emotion" }, + .{ .glyph = "😨", .name = "fearful face", .keywords = "fearful face afraid anxious blame fear scared worried concerned smileys emotion" }, + .{ .glyph = "😰", .name = "anxious face with sweat", .keywords = "anxious face with sweat blue cold eek mouth nervous open rushed scared yikes concerned smileys emotion" }, + .{ .glyph = "😥", .name = "sad but relieved face", .keywords = "sad but relieved face anxious call close complicated disappointed not sweat time whew concerned smileys emotion" }, + .{ .glyph = "😢", .name = "crying face", .keywords = "crying face awful cry feels miss sad tear triste unhappy concerned smileys emotion" }, + .{ .glyph = "😭", .name = "loudly crying face", .keywords = "loudly crying face bawling cry sad sob tear tears unhappy concerned smileys emotion" }, + .{ .glyph = "😱", .name = "face screaming in fear", .keywords = "face screaming in fear epic fearful munch scared scream screamer shocked surprised woah concerned smileys emotion" }, + .{ .glyph = "😖", .name = "confounded face", .keywords = "confounded face annoyed confused cringe distraught feels frustrated mad sad concerned smileys emotion" }, + .{ .glyph = "😣", .name = "persevering face", .keywords = "persevering face concentrate concentration focus headache persevere concerned smileys emotion" }, + .{ .glyph = "😞", .name = "disappointed face", .keywords = "disappointed face awful blame dejected fail losing sad unhappy concerned smileys emotion" }, + .{ .glyph = "😓", .name = "downcast face with sweat", .keywords = "downcast face with sweat close cold feels headache nervous sad scared yikes concerned smileys emotion" }, + .{ .glyph = "😩", .name = "weary face", .keywords = "weary face crying fail feels hungry mad nooo sad sleepy tired unhappy concerned smileys emotion" }, + .{ .glyph = "😫", .name = "tired face", .keywords = "tired face cost feels nap sad sneeze concerned smileys emotion" }, + .{ .glyph = "🥱", .name = "yawning face", .keywords = "yawning face bedtime bored goodnight nap night sleep sleepy tired whatever yawn zzz concerned smileys emotion" }, + .{ .glyph = "😤", .name = "face with steam from nose", .keywords = "face with steam from nose anger angry feels fume fuming furious fury mad triumph unhappy won negative smileys emotion" }, + .{ .glyph = "😡", .name = "enraged face", .keywords = "enraged face anger angry feels mad maddening pouting rage red shade unhappy upset negative smileys emotion" }, + .{ .glyph = "😠", .name = "angry face", .keywords = "angry face anger blame feels frustrated mad maddening rage shade unhappy upset negative smileys emotion" }, + .{ .glyph = "🤬", .name = "face with symbols on mouth", .keywords = "face with symbols on mouth censor cursing cussing mad pissed swearing negative smileys emotion" }, + .{ .glyph = "😈", .name = "smiling face with horns", .keywords = "smiling face with horns demon devil evil fairy fairytale fantasy purple shade smile tale negative smileys emotion" }, + .{ .glyph = "👿", .name = "angry face with horns", .keywords = "angry face with horns demon devil evil fairy fairytale fantasy imp mischievous purple shade tale negative smileys emotion" }, + .{ .glyph = "💀", .name = "skull", .keywords = "skull body dead death face fairy fairytale i’m lmao monster tale yolo negative smileys emotion deprecated killed" }, + .{ .glyph = "☠️", .name = "skull and crossbones", .keywords = "skull and crossbones bone dead death face monster negative smileys emotion" }, + .{ .glyph = "💩", .name = "pile of poo", .keywords = "pile of poo bs comic doo dung face fml monster poop smelly smh stink stinks stinky turd costume smileys emotion" }, + .{ .glyph = "🤡", .name = "clown face", .keywords = "clown face costume smileys emotion" }, + .{ .glyph = "👹", .name = "ogre", .keywords = "ogre creature devil face fairy fairytale fantasy mask monster scary tale costume smileys emotion" }, + .{ .glyph = "👺", .name = "goblin", .keywords = "goblin angry creature face fairy fairytale fantasy mask mean monster tale costume smileys emotion" }, + .{ .glyph = "👻", .name = "ghost", .keywords = "ghost boo creature excited face fairy fairytale fantasy halloween haunting monster scary silly tale costume smileys emotion" }, + .{ .glyph = "👽", .name = "alien", .keywords = "alien creature extraterrestrial face fairy fairytale fantasy monster space tale ufo costume smileys emotion" }, + .{ .glyph = "👾", .name = "alien monster", .keywords = "alien monster creature extraterrestrial face fairy fairytale fantasy game gamer games pixelated space tale ufo costume smileys emotion" }, + .{ .glyph = "🤖", .name = "robot", .keywords = "robot face monster costume smileys emotion bot agent ai automation claude" }, + .{ .glyph = "😺", .name = "grinning cat", .keywords = "grinning cat animal face mouth open smile smiling smileys emotion" }, + .{ .glyph = "😸", .name = "grinning cat with smiling eyes", .keywords = "grinning cat with smiling eyes animal eye face grin smile smileys emotion" }, + .{ .glyph = "😹", .name = "cat with tears of joy", .keywords = "cat with tears of joy animal face laugh laughing lol tear smileys emotion" }, + .{ .glyph = "😻", .name = "smiling cat with heart-eyes", .keywords = "smiling cat with heart eyes animal eye face love smile smileys emotion" }, + .{ .glyph = "😼", .name = "cat with wry smile", .keywords = "cat with wry smile animal face ironic smileys emotion" }, + .{ .glyph = "😽", .name = "kissing cat", .keywords = "kissing cat animal closed eye eyes face kiss smileys emotion" }, + .{ .glyph = "🙀", .name = "weary cat", .keywords = "weary cat animal face oh surprised smileys emotion" }, + .{ .glyph = "😿", .name = "crying cat", .keywords = "crying cat animal cry face sad tear smileys emotion" }, + .{ .glyph = "😾", .name = "pouting cat", .keywords = "pouting cat animal face smileys emotion" }, + .{ .glyph = "🙈", .name = "see-no-evil monkey", .keywords = "see no evil monkey embarrassed face forbidden forgot gesture hide omg prohibited scared secret smh watch smileys emotion" }, + .{ .glyph = "🙉", .name = "hear-no-evil monkey", .keywords = "hear no evil monkey animal ears face forbidden gesture listen not prohibited secret shh tmi smileys emotion" }, + .{ .glyph = "🙊", .name = "speak-no-evil monkey", .keywords = "speak no evil monkey animal face forbidden gesture not oops prohibited quiet secret stealth smileys emotion" }, + .{ .glyph = "💌", .name = "love letter", .keywords = "love letter heart mail romance valentine smileys emotion" }, + .{ .glyph = "💘", .name = "heart with arrow", .keywords = "heart with arrow 143 adorbs cupid date emotion ily love romance valentine smileys" }, + .{ .glyph = "💝", .name = "heart with ribbon", .keywords = "heart with ribbon 143 anniversary emotion ily kisses valentine xoxo smileys" }, + .{ .glyph = "💖", .name = "sparkling heart", .keywords = "sparkling heart 143 emotion excited good ily kisses morning night sparkle xoxo smileys" }, + .{ .glyph = "💗", .name = "growing heart", .keywords = "growing heart 143 emotion excited heartpulse ily kisses muah nervous pulse xoxo smileys" }, + .{ .glyph = "💓", .name = "beating heart", .keywords = "beating heart 143 cardio emotion heartbeat ily love pulsating pulse smileys" }, + .{ .glyph = "💞", .name = "revolving hearts", .keywords = "revolving hearts 143 adorbs anniversary emotion heart smileys" }, + .{ .glyph = "💕", .name = "two hearts", .keywords = "two hearts 143 anniversary date dating emotion heart ily kisses love loving xoxo smileys" }, + .{ .glyph = "💟", .name = "heart decoration", .keywords = "heart decoration 143 emotion hearth purple white smileys" }, + .{ .glyph = "❣️", .name = "heart exclamation", .keywords = "heart exclamation bang heavy mark punctuation smileys emotion" }, + .{ .glyph = "💔", .name = "broken heart", .keywords = "broken heart break crushed emotion heartbroken lonely sad smileys" }, + .{ .glyph = "❤️‍🔥", .name = "heart on fire", .keywords = "heart on fire burn love lust sacred smileys emotion" }, + .{ .glyph = "❤️‍🩹", .name = "mending heart", .keywords = "mending heart healthier improving recovering recuperating well smileys emotion" }, + .{ .glyph = "❤️", .name = "red heart", .keywords = "red heart emotion love smileys" }, + .{ .glyph = "🩷", .name = "pink heart", .keywords = "pink heart 143 adorable cute emotion ily like love special sweet smileys" }, + .{ .glyph = "🧡", .name = "orange heart", .keywords = "orange heart 143 smileys emotion" }, + .{ .glyph = "💛", .name = "yellow heart", .keywords = "yellow heart 143 cardiac emotion ily love smileys" }, + .{ .glyph = "💚", .name = "green heart", .keywords = "green heart 143 emotion ily love romantic smileys" }, + .{ .glyph = "💙", .name = "blue heart", .keywords = "blue heart 143 emotion ily love romance smileys" }, + .{ .glyph = "🩵", .name = "light blue heart", .keywords = "light blue heart 143 cute cyan emotion ily like love sky special teal smileys" }, + .{ .glyph = "💜", .name = "purple heart", .keywords = "purple heart 143 bestest emotion ily love smileys" }, + .{ .glyph = "🤎", .name = "brown heart", .keywords = "brown heart 143 smileys emotion" }, + .{ .glyph = "🖤", .name = "black heart", .keywords = "black heart evil wicked smileys emotion" }, + .{ .glyph = "🩶", .name = "grey heart", .keywords = "grey heart 143 emotion gray ily love silver slate special smileys" }, + .{ .glyph = "🤍", .name = "white heart", .keywords = "white heart 143 smileys emotion" }, + .{ .glyph = "💋", .name = "kiss mark", .keywords = "kiss mark dating emotion heart kissing lips romance sexy smileys" }, + .{ .glyph = "💯", .name = "hundred points", .keywords = "hundred points 100 a+ agree clearly definitely faithful fleek full keep perfect point score true truth yup emotion smileys" }, + .{ .glyph = "💢", .name = "anger symbol", .keywords = "anger symbol angry comic mad upset emotion smileys" }, + .{ .glyph = "💥", .name = "collision", .keywords = "collision bomb boom collide comic explode emotion smileys crash broke" }, + .{ .glyph = "💫", .name = "dizzy", .keywords = "dizzy comic shining shooting star stars emotion smileys" }, + .{ .glyph = "💦", .name = "sweat droplets", .keywords = "sweat droplets comic drip droplet drops splashing squirt water wet work workout emotion smileys" }, + .{ .glyph = "💨", .name = "dashing away", .keywords = "dashing away cloud comic dash fart fast go gone gotta running smoke emotion smileys" }, + .{ .glyph = "🕳️", .name = "hole", .keywords = "hole emotion smileys" }, + .{ .glyph = "💬", .name = "speech balloon", .keywords = "speech balloon bubble comic dialog message sms talk text typing emotion smileys" }, + .{ .glyph = "👁️‍🗨️", .name = "eye in speech bubble", .keywords = "eye in speech bubble balloon witness emotion smileys" }, + .{ .glyph = "🗨️", .name = "left speech bubble", .keywords = "left speech bubble balloon dialog emotion smileys" }, + .{ .glyph = "🗯️", .name = "right anger bubble", .keywords = "right anger bubble angry balloon mad emotion smileys" }, + .{ .glyph = "💭", .name = "thought balloon", .keywords = "thought balloon bubble cartoon cloud comic daydream decisions dream idea invent invention realize think thoughts wonder emotion smileys" }, + .{ .glyph = "💤", .name = "ZZZ", .keywords = "zzz comic good goodnight night sleep sleeping sleepy tired emotion smileys" }, + + // ---- People & Body ----------------------------------------------- + .{ .glyph = "👋", .name = "waving hand", .keywords = "waving hand bye cya g2g greetings gtg hello hey hi later outtie ttfn ttyl wave yo you fingers open people body" }, + .{ .glyph = "🤚", .name = "raised back of hand", .keywords = "raised back of hand backhand fingers open people body" }, + .{ .glyph = "🖐️", .name = "hand with fingers splayed", .keywords = "hand with fingers splayed finger raised stop open people body" }, + .{ .glyph = "✋", .name = "raised hand", .keywords = "raised hand 5 five high stop fingers open people body" }, + .{ .glyph = "🖖", .name = "vulcan salute", .keywords = "vulcan salute finger hand hands fingers open people body" }, + .{ .glyph = "🫱", .name = "rightwards hand", .keywords = "rightwards hand handshake hold reach right rightward shake fingers open people body" }, + .{ .glyph = "🫲", .name = "leftwards hand", .keywords = "leftwards hand handshake hold left leftward reach shake fingers open people body" }, + .{ .glyph = "🫳", .name = "palm down hand", .keywords = "palm down hand dismiss drop dropped pick shoo up fingers open people body" }, + .{ .glyph = "🫴", .name = "palm up hand", .keywords = "palm up hand beckon catch come hold know lift me offer tell fingers open people body" }, + .{ .glyph = "🫷", .name = "leftwards pushing hand", .keywords = "leftwards pushing hand block five halt high hold leftward pause push refuse slap stop wait fingers open people body" }, + .{ .glyph = "🫸", .name = "rightwards pushing hand", .keywords = "rightwards pushing hand block five halt high hold pause push refuse rightward slap stop wait fingers open people body" }, + .{ .glyph = "👌", .name = "OK hand", .keywords = "ok hand awesome bet dope fleek fosho got gotcha legit okay pinch rad sure sweet three fingers partial people body" }, + .{ .glyph = "🤌", .name = "pinched fingers", .keywords = "pinched fingers gesture hand hold huh interrogation patience relax sarcastic ugh what zip partial people body" }, + .{ .glyph = "🤏", .name = "pinching hand", .keywords = "pinching hand amount bit fingers little small sort partial people body" }, + .{ .glyph = "✌️", .name = "victory hand", .keywords = "victory hand peace v fingers partial people body" }, + .{ .glyph = "🤞", .name = "crossed fingers", .keywords = "crossed fingers cross finger hand luck partial people body" }, + .{ .glyph = "🫰", .name = "hand with index finger and thumb crossed", .keywords = "hand with index finger and thumb crossed <3 expensive heart love money snap fingers partial people body" }, + .{ .glyph = "🤟", .name = "love-you gesture", .keywords = "love you gesture fingers hand ily three partial people body" }, + .{ .glyph = "🤘", .name = "sign of the horns", .keywords = "sign of the horns finger hand rock on fingers partial people body" }, + .{ .glyph = "🤙", .name = "call me hand", .keywords = "call me hand hang loose shaka fingers partial people body" }, + .{ .glyph = "👈", .name = "backhand index pointing left", .keywords = "backhand index pointing left finger hand point single people body" }, + .{ .glyph = "👉", .name = "backhand index pointing right", .keywords = "backhand index pointing right finger hand point single people body" }, + .{ .glyph = "👆", .name = "backhand index pointing up", .keywords = "backhand index pointing up finger hand point single people body" }, + .{ .glyph = "🖕", .name = "middle finger", .keywords = "middle finger hand single people body" }, + .{ .glyph = "👇", .name = "backhand index pointing down", .keywords = "backhand index pointing down finger hand point single people body" }, + .{ .glyph = "☝️", .name = "index pointing up", .keywords = "index pointing up finger hand point this single people body" }, + .{ .glyph = "🫵", .name = "index pointing at the viewer", .keywords = "index pointing at the viewer finger hand poke you single people body" }, + .{ .glyph = "👍", .name = "thumbs up", .keywords = "thumbs up +1 good hand like thumb yes fingers closed people body" }, + .{ .glyph = "👎", .name = "thumbs down", .keywords = "thumbs down 1 bad dislike good hand no nope thumb fingers closed people body" }, + .{ .glyph = "✊", .name = "raised fist", .keywords = "raised fist clenched hand punch solidarity fingers closed people body" }, + .{ .glyph = "👊", .name = "oncoming fist", .keywords = "oncoming fist absolutely agree boom bro bruh bump clenched correct hand knuckle pound punch rock ttyl fingers closed people body" }, + .{ .glyph = "🤛", .name = "left-facing fist", .keywords = "left facing fist leftwards hand fingers closed people body" }, + .{ .glyph = "🤜", .name = "right-facing fist", .keywords = "right facing fist rightwards hand fingers closed people body" }, + .{ .glyph = "👏", .name = "clapping hands", .keywords = "clapping hands applause approval awesome clap congrats congratulations excited good great hand homie job nice prayed well yay people body" }, + .{ .glyph = "🙌", .name = "raising hands", .keywords = "raising hands celebration gesture hand hooray praise raised people body" }, + .{ .glyph = "🫶", .name = "heart hands", .keywords = "heart hands <3 love you people body" }, + .{ .glyph = "👐", .name = "open hands", .keywords = "open hands hand hug jazz swerve people body" }, + .{ .glyph = "🤲", .name = "palms up together", .keywords = "palms up together cupped dua hands pray prayer wish people body" }, + .{ .glyph = "🤝", .name = "handshake", .keywords = "handshake agreement deal hand meeting shake hands people body" }, + .{ .glyph = "🙏", .name = "folded hands", .keywords = "folded hands appreciate ask beg blessed bow cmon five gesture hand high please pray thanks thx people body" }, + .{ .glyph = "✍️", .name = "writing hand", .keywords = "writing hand write prop people body" }, + .{ .glyph = "💅", .name = "nail polish", .keywords = "nail polish bored care cosmetics done makeup manicure whatever hand prop people body" }, + .{ .glyph = "🤳", .name = "selfie", .keywords = "selfie camera phone hand prop people body" }, + .{ .glyph = "💪", .name = "flexed biceps", .keywords = "flexed biceps arm beast bench bodybuilder bro curls flex gains gym jacked muscle press ripped strong weightlift body parts people" }, + .{ .glyph = "🦾", .name = "mechanical arm", .keywords = "mechanical arm accessibility prosthetic body parts people" }, + .{ .glyph = "🦿", .name = "mechanical leg", .keywords = "mechanical leg accessibility prosthetic body parts people" }, + .{ .glyph = "🦵", .name = "leg", .keywords = "leg bent foot kick knee limb body parts people" }, + .{ .glyph = "🦶", .name = "foot", .keywords = "foot ankle feet kick stomp body parts people" }, + .{ .glyph = "👂", .name = "ear", .keywords = "ear body ears hear hearing listen listening sound parts people" }, + .{ .glyph = "🦻", .name = "ear with hearing aid", .keywords = "ear with hearing aid accessibility hard body parts people" }, + .{ .glyph = "👃", .name = "nose", .keywords = "nose body noses nosey odor smell smells parts people" }, + .{ .glyph = "🧠", .name = "brain", .keywords = "brain intelligent smart body parts people think reasoning" }, + .{ .glyph = "🫀", .name = "anatomical heart", .keywords = "anatomical heart beat cardiology heartbeat organ pulse real red body parts people" }, + .{ .glyph = "🫁", .name = "lungs", .keywords = "lungs breath breathe exhalation inhalation lung organ respiration body parts people" }, + .{ .glyph = "🦷", .name = "tooth", .keywords = "tooth dentist pearly teeth white body parts people" }, + .{ .glyph = "🦴", .name = "bone", .keywords = "bone bones dog skeleton wishbone body parts people" }, + .{ .glyph = "👀", .name = "eyes", .keywords = "eyes body eye face googly look looking omg peep see seeing parts people review watch" }, + .{ .glyph = "👁️", .name = "eye", .keywords = "eye 1 body one parts people" }, + .{ .glyph = "👅", .name = "tongue", .keywords = "tongue body lick slurp parts people" }, + .{ .glyph = "👄", .name = "mouth", .keywords = "mouth beauty body kiss kissing lips lipstick parts people" }, + .{ .glyph = "🫦", .name = "biting lip", .keywords = "biting lip anxious bite fear flirt flirting kiss lipstick nervous sexy uncomfortable worried worry body parts people" }, + .{ .glyph = "👶", .name = "baby", .keywords = "baby babies children goo infant newborn pregnant young person people body" }, + .{ .glyph = "🧒", .name = "child", .keywords = "child bright eyed grandchild kid young younger person people body" }, + .{ .glyph = "👦", .name = "boy", .keywords = "boy bright eyed child grandson kid son young younger person people body" }, + .{ .glyph = "👧", .name = "girl", .keywords = "girl bright eyed child daughter granddaughter kid virgo young younger zodiac person people body" }, + .{ .glyph = "🧑", .name = "person", .keywords = "person adult people body" }, + .{ .glyph = "👱", .name = "person: blond hair", .keywords = "person blond hair haired human people body" }, + .{ .glyph = "👨", .name = "man", .keywords = "man adult bro person people body" }, + .{ .glyph = "🧔", .name = "person: beard", .keywords = "person beard bearded whiskers people body" }, + .{ .glyph = "🧔‍♂️", .name = "man: beard", .keywords = "man beard bearded whiskers person people body" }, + .{ .glyph = "🧔‍♀️", .name = "woman: beard", .keywords = "woman beard bearded whiskers person people body" }, + .{ .glyph = "👨‍🦰", .name = "man: red hair", .keywords = "man red hair adult bro person people body" }, + .{ .glyph = "👨‍🦱", .name = "man: curly hair", .keywords = "man curly hair adult bro person people body" }, + .{ .glyph = "👨‍🦳", .name = "man: white hair", .keywords = "man white hair adult bro person people body" }, + .{ .glyph = "👨‍🦲", .name = "man: bald", .keywords = "man bald adult bro person people body" }, + .{ .glyph = "👩", .name = "woman", .keywords = "woman adult lady person people body" }, + .{ .glyph = "👩‍🦰", .name = "woman: red hair", .keywords = "woman red hair adult lady person people body" }, + .{ .glyph = "🧑‍🦰", .name = "person: red hair", .keywords = "person red hair adult people body" }, + .{ .glyph = "👩‍🦱", .name = "woman: curly hair", .keywords = "woman curly hair adult lady person people body" }, + .{ .glyph = "🧑‍🦱", .name = "person: curly hair", .keywords = "person curly hair adult people body" }, + .{ .glyph = "👩‍🦳", .name = "woman: white hair", .keywords = "woman white hair adult lady person people body" }, + .{ .glyph = "🧑‍🦳", .name = "person: white hair", .keywords = "person white hair adult people body" }, + .{ .glyph = "👩‍🦲", .name = "woman: bald", .keywords = "woman bald adult lady person people body" }, + .{ .glyph = "🧑‍🦲", .name = "person: bald", .keywords = "person bald adult people body" }, + .{ .glyph = "👱‍♀️", .name = "woman: blond hair", .keywords = "woman blond hair haired blonde person people body" }, + .{ .glyph = "👱‍♂️", .name = "man: blond hair", .keywords = "man blond hair haired person people body" }, + .{ .glyph = "🧓", .name = "older person", .keywords = "older person adult elderly grandparent old wise people body" }, + .{ .glyph = "👴", .name = "old man", .keywords = "old man adult bald elderly gramps grandfather grandpa wise person people body" }, + .{ .glyph = "👵", .name = "old woman", .keywords = "old woman adult elderly grandma grandmother granny lady wise person people body" }, + .{ .glyph = "🙍", .name = "person frowning", .keywords = "person frowning annoyed disappointed disgruntled disturbed frown frustrated gesture irritated upset people body" }, + .{ .glyph = "🙍‍♂️", .name = "man frowning", .keywords = "man frowning annoyed disappointed disgruntled disturbed frown frustrated gesture irritated upset person people body" }, + .{ .glyph = "🙍‍♀️", .name = "woman frowning", .keywords = "woman frowning annoyed disappointed disgruntled disturbed frown frustrated gesture irritated upset person people body" }, + .{ .glyph = "🙎", .name = "person pouting", .keywords = "person pouting disappointed downtrodden frown grimace scowl sulk upset whine gesture people body" }, + .{ .glyph = "🙎‍♂️", .name = "man pouting", .keywords = "man pouting disappointed downtrodden frown grimace scowl sulk upset whine person gesture people body" }, + .{ .glyph = "🙎‍♀️", .name = "woman pouting", .keywords = "woman pouting disappointed downtrodden frown grimace scowl sulk upset whine person gesture people body" }, + .{ .glyph = "🙅", .name = "person gesturing NO", .keywords = "person gesturing no forbidden gesture hand not prohibit people body" }, + .{ .glyph = "🙅‍♂️", .name = "man gesturing NO", .keywords = "man gesturing no forbidden gesture hand not prohibit person people body" }, + .{ .glyph = "🙅‍♀️", .name = "woman gesturing NO", .keywords = "woman gesturing no forbidden gesture hand not prohibit person people body" }, + .{ .glyph = "🙆", .name = "person gesturing OK", .keywords = "person gesturing ok exercise gesture hand omg people body" }, + .{ .glyph = "🙆‍♂️", .name = "man gesturing OK", .keywords = "man gesturing ok exercise gesture hand omg person people body" }, + .{ .glyph = "🙆‍♀️", .name = "woman gesturing OK", .keywords = "woman gesturing ok exercise gesture hand omg person people body" }, + .{ .glyph = "💁", .name = "person tipping hand", .keywords = "person tipping hand fetch flick flip gossip sarcasm sarcastic sassy seriously whatever gesture people body" }, + .{ .glyph = "💁‍♂️", .name = "man tipping hand", .keywords = "man tipping hand fetch flick flip gossip sarcasm sarcastic sassy seriously whatever person gesture people body" }, + .{ .glyph = "💁‍♀️", .name = "woman tipping hand", .keywords = "woman tipping hand fetch flick flip gossip sarcasm sarcastic sassy seriously whatever person gesture people body" }, + .{ .glyph = "🙋", .name = "person raising hand", .keywords = "person raising hand gesture here know me pick question raise people body" }, + .{ .glyph = "🙋‍♂️", .name = "man raising hand", .keywords = "man raising hand gesture here know me pick question raise person people body" }, + .{ .glyph = "🙋‍♀️", .name = "woman raising hand", .keywords = "woman raising hand gesture here know me pick question raise person people body" }, + .{ .glyph = "🧏", .name = "deaf person", .keywords = "deaf person accessibility ear gesture hear people body" }, + .{ .glyph = "🧏‍♂️", .name = "deaf man", .keywords = "deaf man accessibility ear gesture hear person people body" }, + .{ .glyph = "🧏‍♀️", .name = "deaf woman", .keywords = "deaf woman accessibility ear gesture hear person people body" }, + .{ .glyph = "🙇", .name = "person bowing", .keywords = "person bowing apology ask beg bow favor forgive gesture meditate meditation pity regret sorry people body" }, + .{ .glyph = "🙇‍♂️", .name = "man bowing", .keywords = "man bowing apology ask beg bow favor forgive gesture meditate meditation pity regret sorry person people body" }, + .{ .glyph = "🙇‍♀️", .name = "woman bowing", .keywords = "woman bowing apology ask beg bow favor forgive gesture meditate meditation pity regret sorry person people body" }, + .{ .glyph = "🤦", .name = "person facepalming", .keywords = "person facepalming again bewilder disbelief exasperation facepalm no not oh omg shock smh gesture people body" }, + .{ .glyph = "🤦‍♂️", .name = "man facepalming", .keywords = "man facepalming again bewilder disbelief exasperation facepalm no not oh omg shock smh person gesture people body" }, + .{ .glyph = "🤦‍♀️", .name = "woman facepalming", .keywords = "woman facepalming again bewilder disbelief exasperation facepalm no not oh omg shock smh person gesture people body" }, + .{ .glyph = "🤷", .name = "person shrugging", .keywords = "person shrugging doubt dunno guess idk ignorance indifference knows maybe shrug whatever who gesture people body" }, + .{ .glyph = "🤷‍♂️", .name = "man shrugging", .keywords = "man shrugging doubt dunno guess idk ignorance indifference knows maybe shrug whatever who person gesture people body" }, + .{ .glyph = "🤷‍♀️", .name = "woman shrugging", .keywords = "woman shrugging doubt dunno guess idk ignorance indifference knows maybe shrug whatever who person gesture people body" }, + .{ .glyph = "🧑‍⚕️", .name = "health worker", .keywords = "health worker doctor healthcare nurse therapist person role people body" }, + .{ .glyph = "👨‍⚕️", .name = "man health worker", .keywords = "man health worker doctor healthcare nurse therapist person role people body" }, + .{ .glyph = "👩‍⚕️", .name = "woman health worker", .keywords = "woman health worker doctor healthcare nurse therapist person role people body" }, + .{ .glyph = "🧑‍🎓", .name = "student", .keywords = "student graduate person role people body" }, + .{ .glyph = "👨‍🎓", .name = "man student", .keywords = "man student graduate person role people body" }, + .{ .glyph = "👩‍🎓", .name = "woman student", .keywords = "woman student graduate person role people body" }, + .{ .glyph = "🧑‍🏫", .name = "teacher", .keywords = "teacher instructor lecturer professor person role people body" }, + .{ .glyph = "👨‍🏫", .name = "man teacher", .keywords = "man teacher instructor lecturer professor person role people body" }, + .{ .glyph = "👩‍🏫", .name = "woman teacher", .keywords = "woman teacher instructor lecturer professor person role people body" }, + .{ .glyph = "🧑‍⚖️", .name = "judge", .keywords = "judge justice law scales person role people body" }, + .{ .glyph = "👨‍⚖️", .name = "man judge", .keywords = "man judge justice law scales person role people body" }, + .{ .glyph = "👩‍⚖️", .name = "woman judge", .keywords = "woman judge justice law scales person role people body" }, + .{ .glyph = "🧑‍🌾", .name = "farmer", .keywords = "farmer gardener rancher person role people body" }, + .{ .glyph = "👨‍🌾", .name = "man farmer", .keywords = "man farmer gardener rancher person role people body" }, + .{ .glyph = "👩‍🌾", .name = "woman farmer", .keywords = "woman farmer gardener rancher person role people body" }, + .{ .glyph = "🧑‍🍳", .name = "cook", .keywords = "cook chef person role people body" }, + .{ .glyph = "👨‍🍳", .name = "man cook", .keywords = "man cook chef person role people body" }, + .{ .glyph = "👩‍🍳", .name = "woman cook", .keywords = "woman cook chef person role people body" }, + .{ .glyph = "🧑‍🔧", .name = "mechanic", .keywords = "mechanic electrician plumber tradesperson person role people body" }, + .{ .glyph = "👨‍🔧", .name = "man mechanic", .keywords = "man mechanic electrician plumber tradesperson person role people body" }, + .{ .glyph = "👩‍🔧", .name = "woman mechanic", .keywords = "woman mechanic electrician plumber tradesperson person role people body" }, + .{ .glyph = "🧑‍🏭", .name = "factory worker", .keywords = "factory worker assembly industrial person role people body" }, + .{ .glyph = "👨‍🏭", .name = "man factory worker", .keywords = "man factory worker assembly industrial person role people body" }, + .{ .glyph = "👩‍🏭", .name = "woman factory worker", .keywords = "woman factory worker assembly industrial person role people body" }, + .{ .glyph = "🧑‍💼", .name = "office worker", .keywords = "office worker architect business manager white collar person role people body" }, + .{ .glyph = "👨‍💼", .name = "man office worker", .keywords = "man office worker architect business manager white collar person role people body" }, + .{ .glyph = "👩‍💼", .name = "woman office worker", .keywords = "woman office worker architect business manager white collar person role people body" }, + .{ .glyph = "🧑‍🔬", .name = "scientist", .keywords = "scientist biologist chemist engineer mathematician physicist person role people body" }, + .{ .glyph = "👨‍🔬", .name = "man scientist", .keywords = "man scientist biologist chemist engineer mathematician physicist person role people body" }, + .{ .glyph = "👩‍🔬", .name = "woman scientist", .keywords = "woman scientist biologist chemist engineer mathematician physicist person role people body" }, + .{ .glyph = "🧑‍💻", .name = "technologist", .keywords = "technologist coder computer developer inventor software person role people body dev engineer coding" }, + .{ .glyph = "👨‍💻", .name = "man technologist", .keywords = "man technologist coder computer developer inventor software person role people body" }, + .{ .glyph = "👩‍💻", .name = "woman technologist", .keywords = "woman technologist coder computer developer inventor software person role people body" }, + .{ .glyph = "🧑‍🎤", .name = "singer", .keywords = "singer actor entertainer rock rockstar star person role people body" }, + .{ .glyph = "👨‍🎤", .name = "man singer", .keywords = "man singer actor entertainer rock rockstar star person role people body" }, + .{ .glyph = "👩‍🎤", .name = "woman singer", .keywords = "woman singer actor entertainer rock rockstar star person role people body" }, + .{ .glyph = "🧑‍🎨", .name = "artist", .keywords = "artist palette person role people body" }, + .{ .glyph = "👨‍🎨", .name = "man artist", .keywords = "man artist palette person role people body" }, + .{ .glyph = "👩‍🎨", .name = "woman artist", .keywords = "woman artist palette person role people body" }, + .{ .glyph = "🧑‍✈️", .name = "pilot", .keywords = "pilot plane person role people body" }, + .{ .glyph = "👨‍✈️", .name = "man pilot", .keywords = "man pilot plane person role people body" }, + .{ .glyph = "👩‍✈️", .name = "woman pilot", .keywords = "woman pilot plane person role people body" }, + .{ .glyph = "🧑‍🚀", .name = "astronaut", .keywords = "astronaut rocket space person role people body" }, + .{ .glyph = "👨‍🚀", .name = "man astronaut", .keywords = "man astronaut rocket space person role people body" }, + .{ .glyph = "👩‍🚀", .name = "woman astronaut", .keywords = "woman astronaut rocket space person role people body" }, + .{ .glyph = "🧑‍🚒", .name = "firefighter", .keywords = "firefighter fire firetruck person role people body" }, + .{ .glyph = "👨‍🚒", .name = "man firefighter", .keywords = "man firefighter fire firetruck person role people body" }, + .{ .glyph = "👩‍🚒", .name = "woman firefighter", .keywords = "woman firefighter fire firetruck person role people body" }, + .{ .glyph = "👮", .name = "police officer", .keywords = "police officer apprehend arrest citation cop law over pulled undercover person role people body" }, + .{ .glyph = "👮‍♂️", .name = "man police officer", .keywords = "man police officer apprehend arrest citation cop law over pulled undercover person role people body" }, + .{ .glyph = "👮‍♀️", .name = "woman police officer", .keywords = "woman police officer apprehend arrest citation cop law over pulled undercover person role people body" }, + .{ .glyph = "🕵️", .name = "detective", .keywords = "detective sleuth spy person role people body" }, + .{ .glyph = "🕵️‍♂️", .name = "man detective", .keywords = "man detective sleuth spy person role people body" }, + .{ .glyph = "🕵️‍♀️", .name = "woman detective", .keywords = "woman detective sleuth spy person role people body" }, + .{ .glyph = "💂", .name = "guard", .keywords = "guard buckingham helmet london palace person role people body" }, + .{ .glyph = "💂‍♂️", .name = "man guard", .keywords = "man guard buckingham helmet london palace person role people body" }, + .{ .glyph = "💂‍♀️", .name = "woman guard", .keywords = "woman guard buckingham helmet london palace person role people body" }, + .{ .glyph = "🥷", .name = "ninja", .keywords = "ninja assassin fight fighter hidden person secret skills sly soldier stealth war role people body" }, + .{ .glyph = "👷", .name = "construction worker", .keywords = "construction worker build fix hardhat hat man person rebuild remodel repair work role people body" }, + .{ .glyph = "👷‍♂️", .name = "man construction worker", .keywords = "man construction worker build fix hardhat hat rebuild remodel repair work person role people body" }, + .{ .glyph = "👷‍♀️", .name = "woman construction worker", .keywords = "woman construction worker build fix hardhat hat man rebuild remodel repair work person role people body" }, + .{ .glyph = "🫅", .name = "person with crown", .keywords = "person with crown monarch noble regal royal royalty role people body" }, + .{ .glyph = "🤴", .name = "prince", .keywords = "prince crown fairy fairytale fantasy king royal royalty tale person role people body" }, + .{ .glyph = "👸", .name = "princess", .keywords = "princess crown fairy fairytale fantasy queen royal royalty tale person role people body" }, + .{ .glyph = "👳", .name = "person wearing turban", .keywords = "person wearing turban role people body" }, + .{ .glyph = "👳‍♂️", .name = "man wearing turban", .keywords = "man wearing turban person role people body" }, + .{ .glyph = "👳‍♀️", .name = "woman wearing turban", .keywords = "woman wearing turban person role people body" }, + .{ .glyph = "👲", .name = "person with skullcap", .keywords = "person with skullcap cap chinese gua guapi hat mao pi role people body" }, + .{ .glyph = "🧕", .name = "woman with headscarf", .keywords = "woman with headscarf bandana head hijab kerchief mantilla tichel person role people body" }, + .{ .glyph = "🤵", .name = "person in tuxedo", .keywords = "person in tuxedo formal wedding role people body" }, + .{ .glyph = "🤵‍♂️", .name = "man in tuxedo", .keywords = "man in tuxedo formal groom wedding person role people body" }, + .{ .glyph = "🤵‍♀️", .name = "woman in tuxedo", .keywords = "woman in tuxedo formal wedding person role people body" }, + .{ .glyph = "👰", .name = "person with veil", .keywords = "person with veil wedding role people body" }, + .{ .glyph = "👰‍♂️", .name = "man with veil", .keywords = "man with veil wedding person role people body" }, + .{ .glyph = "👰‍♀️", .name = "woman with veil", .keywords = "woman with veil bride wedding person role people body" }, + .{ .glyph = "🤰", .name = "pregnant woman", .keywords = "pregnant woman person role people body" }, + .{ .glyph = "🫃", .name = "pregnant man", .keywords = "pregnant man belly bloated full overeat person role people body" }, + .{ .glyph = "🫄", .name = "pregnant person", .keywords = "pregnant person belly bloated full overeat stuffed role people body" }, + .{ .glyph = "🤱", .name = "breast-feeding", .keywords = "breast feeding baby mom mother nursing woman person role people body" }, + .{ .glyph = "👩‍🍼", .name = "woman feeding baby", .keywords = "woman feeding baby feed mom mother nanny newborn nursing person role people body" }, + .{ .glyph = "👨‍🍼", .name = "man feeding baby", .keywords = "man feeding baby dad father feed nanny newborn nursing person role people body" }, + .{ .glyph = "🧑‍🍼", .name = "person feeding baby", .keywords = "person feeding baby feed nanny newborn nursing parent role people body" }, + .{ .glyph = "👼", .name = "baby angel", .keywords = "baby angel church face fairy fairytale fantasy tale person people body" }, + .{ .glyph = "🎅", .name = "Santa Claus", .keywords = "santa claus celebration christmas fairy fantasy father holiday merry tale xmas person people body" }, + .{ .glyph = "🤶", .name = "Mrs. Claus", .keywords = "mrs. claus celebration christmas fairy fantasy holiday merry mother mrs santa tale xmas person people body" }, + .{ .glyph = "🧑‍🎄", .name = "Mx Claus", .keywords = "mx claus celebration christmas fairy fantasy holiday merry santa tale xmas person people body" }, + .{ .glyph = "🦸", .name = "superhero", .keywords = "superhero good hero superpower person fantasy people body" }, + .{ .glyph = "🦸‍♂️", .name = "man superhero", .keywords = "man superhero good hero superpower person fantasy people body" }, + .{ .glyph = "🦸‍♀️", .name = "woman superhero", .keywords = "woman superhero good hero heroine superpower person fantasy people body" }, + .{ .glyph = "🦹", .name = "supervillain", .keywords = "supervillain bad criminal evil superpower villain person fantasy people body" }, + .{ .glyph = "🦹‍♂️", .name = "man supervillain", .keywords = "man supervillain bad criminal evil superpower villain person fantasy people body" }, + .{ .glyph = "🦹‍♀️", .name = "woman supervillain", .keywords = "woman supervillain bad criminal evil superpower villain person fantasy people body" }, + .{ .glyph = "🧙", .name = "mage", .keywords = "mage fantasy magic play sorcerer sorceress sorcery spell summon witch wizard person people body" }, + .{ .glyph = "🧙‍♂️", .name = "man mage", .keywords = "man mage fantasy magic play sorcerer sorceress sorcery spell summon witch wizard person people body" }, + .{ .glyph = "🧙‍♀️", .name = "woman mage", .keywords = "woman mage fantasy magic play sorcerer sorceress sorcery spell summon witch wizard person people body" }, + .{ .glyph = "🧚", .name = "fairy", .keywords = "fairy fairytale fantasy myth person pixie tale wings people body" }, + .{ .glyph = "🧚‍♂️", .name = "man fairy", .keywords = "man fairy fairytale fantasy myth oberon person pixie puck tale wings people body" }, + .{ .glyph = "🧚‍♀️", .name = "woman fairy", .keywords = "woman fairy fairytale fantasy myth person pixie tale titania wings people body" }, + .{ .glyph = "🧛", .name = "vampire", .keywords = "vampire blood dracula fangs halloween scary supernatural teeth undead person fantasy people body" }, + .{ .glyph = "🧛‍♂️", .name = "man vampire", .keywords = "man vampire blood fangs halloween scary supernatural teeth undead person fantasy people body" }, + .{ .glyph = "🧛‍♀️", .name = "woman vampire", .keywords = "woman vampire blood fangs halloween scary supernatural teeth undead person fantasy people body" }, + .{ .glyph = "🧜", .name = "merperson", .keywords = "merperson creature fairytale folklore ocean sea siren trident person fantasy people body" }, + .{ .glyph = "🧜‍♂️", .name = "merman", .keywords = "merman creature fairytale folklore neptune ocean poseidon sea siren trident triton person fantasy people body" }, + .{ .glyph = "🧜‍♀️", .name = "mermaid", .keywords = "mermaid creature fairytale folklore merwoman ocean sea siren trident person fantasy people body" }, + .{ .glyph = "🧝", .name = "elf", .keywords = "elf elves enchantment fantasy folklore magic magical myth person people body" }, + .{ .glyph = "🧝‍♂️", .name = "man elf", .keywords = "man elf elves enchantment fantasy folklore magic magical myth person people body" }, + .{ .glyph = "🧝‍♀️", .name = "woman elf", .keywords = "woman elf elves enchantment fantasy folklore magic magical myth person people body" }, + .{ .glyph = "🧞", .name = "genie", .keywords = "genie djinn fantasy jinn lamp myth rub wishes person people body" }, + .{ .glyph = "🧞‍♂️", .name = "man genie", .keywords = "man genie djinn fantasy jinn lamp myth rub wishes person people body" }, + .{ .glyph = "🧞‍♀️", .name = "woman genie", .keywords = "woman genie djinn fantasy jinn lamp myth rub wishes person people body" }, + .{ .glyph = "🧟", .name = "zombie", .keywords = "zombie apocalypse dead halloween horror scary undead walking person fantasy people body" }, + .{ .glyph = "🧟‍♂️", .name = "man zombie", .keywords = "man zombie apocalypse dead halloween horror scary undead walking person fantasy people body" }, + .{ .glyph = "🧟‍♀️", .name = "woman zombie", .keywords = "woman zombie apocalypse dead halloween horror scary undead walking person fantasy people body" }, + .{ .glyph = "🧌", .name = "troll", .keywords = "troll fairy fantasy monster tale trolling person people body" }, + .{ .glyph = "💆", .name = "person getting massage", .keywords = "person getting massage face headache relax relaxing salon soothe spa tension therapy treatment activity people body" }, + .{ .glyph = "💆‍♂️", .name = "man getting massage", .keywords = "man getting massage face headache relax relaxing salon soothe spa tension therapy treatment person activity people body" }, + .{ .glyph = "💆‍♀️", .name = "woman getting massage", .keywords = "woman getting massage face headache relax relaxing salon soothe spa tension therapy treatment person activity people body" }, + .{ .glyph = "💇", .name = "person getting haircut", .keywords = "person getting haircut barber beauty chop cosmetology cut groom hair parlor shears style activity people body" }, + .{ .glyph = "💇‍♂️", .name = "man getting haircut", .keywords = "man getting haircut barber beauty chop cosmetology cut groom hair parlor person shears style activity people body" }, + .{ .glyph = "💇‍♀️", .name = "woman getting haircut", .keywords = "woman getting haircut barber beauty chop cosmetology cut groom hair parlor person shears style activity people body" }, + .{ .glyph = "🚶", .name = "person walking", .keywords = "person walking amble gait hike man pace pedestrian stride stroll walk activity people body" }, + .{ .glyph = "🚶‍♂️", .name = "man walking", .keywords = "man walking amble gait hike pace pedestrian stride stroll walk person activity people body" }, + .{ .glyph = "🚶‍♀️", .name = "woman walking", .keywords = "woman walking amble gait hike man pace pedestrian stride stroll walk person activity people body" }, + .{ .glyph = "🚶‍➡️", .name = "person walking: facing right", .keywords = "person walking facing right amble gait hike man pace pedestrian stride stroll walk activity people body" }, + .{ .glyph = "🚶‍♀️‍➡️", .name = "woman walking: facing right", .keywords = "woman walking facing right amble gait hike man pace pedestrian stride stroll walk person activity people body" }, + .{ .glyph = "🚶‍♂️‍➡️", .name = "man walking: facing right", .keywords = "man walking facing right amble gait hike pace pedestrian stride stroll walk person activity people body" }, + .{ .glyph = "🧍", .name = "person standing", .keywords = "person standing stand activity people body" }, + .{ .glyph = "🧍‍♂️", .name = "man standing", .keywords = "man standing stand person activity people body" }, + .{ .glyph = "🧍‍♀️", .name = "woman standing", .keywords = "woman standing stand person activity people body" }, + .{ .glyph = "🧎", .name = "person kneeling", .keywords = "person kneeling kneel knees activity people body" }, + .{ .glyph = "🧎‍♂️", .name = "man kneeling", .keywords = "man kneeling kneel knees person activity people body" }, + .{ .glyph = "🧎‍♀️", .name = "woman kneeling", .keywords = "woman kneeling kneel knees person activity people body" }, + .{ .glyph = "🧎‍➡️", .name = "person kneeling: facing right", .keywords = "person kneeling facing right kneel knees activity people body" }, + .{ .glyph = "🧎‍♀️‍➡️", .name = "woman kneeling: facing right", .keywords = "woman kneeling facing right kneel knees person activity people body" }, + .{ .glyph = "🧎‍♂️‍➡️", .name = "man kneeling: facing right", .keywords = "man kneeling facing right kneel knees person activity people body" }, + .{ .glyph = "🧑‍🦯", .name = "person with white cane", .keywords = "person with white cane accessibility blind probing activity people body" }, + .{ .glyph = "🧑‍🦯‍➡️", .name = "person with white cane: facing right", .keywords = "person with white cane facing right accessibility blind probing activity people body" }, + .{ .glyph = "👨‍🦯", .name = "man with white cane", .keywords = "man with white cane accessibility blind probing person activity people body" }, + .{ .glyph = "👨‍🦯‍➡️", .name = "man with white cane: facing right", .keywords = "man with white cane facing right accessibility blind probing person activity people body" }, + .{ .glyph = "👩‍🦯", .name = "woman with white cane", .keywords = "woman with white cane accessibility blind probing person activity people body" }, + .{ .glyph = "👩‍🦯‍➡️", .name = "woman with white cane: facing right", .keywords = "woman with white cane facing right accessibility blind probing person activity people body" }, + .{ .glyph = "🧑‍🦼", .name = "person in motorized wheelchair", .keywords = "person in motorized wheelchair accessibility activity people body" }, + .{ .glyph = "🧑‍🦼‍➡️", .name = "person in motorized wheelchair: facing right", .keywords = "person in motorized wheelchair facing right accessibility activity people body" }, + .{ .glyph = "👨‍🦼", .name = "man in motorized wheelchair", .keywords = "man in motorized wheelchair accessibility person activity people body" }, + .{ .glyph = "👨‍🦼‍➡️", .name = "man in motorized wheelchair: facing right", .keywords = "man in motorized wheelchair facing right accessibility person activity people body" }, + .{ .glyph = "👩‍🦼", .name = "woman in motorized wheelchair", .keywords = "woman in motorized wheelchair accessibility person activity people body" }, + .{ .glyph = "👩‍🦼‍➡️", .name = "woman in motorized wheelchair: facing right", .keywords = "woman in motorized wheelchair facing right accessibility person activity people body" }, + .{ .glyph = "🧑‍🦽", .name = "person in manual wheelchair", .keywords = "person in manual wheelchair accessibility activity people body" }, + .{ .glyph = "🧑‍🦽‍➡️", .name = "person in manual wheelchair: facing right", .keywords = "person in manual wheelchair facing right accessibility activity people body" }, + .{ .glyph = "👨‍🦽", .name = "man in manual wheelchair", .keywords = "man in manual wheelchair accessibility person activity people body" }, + .{ .glyph = "👨‍🦽‍➡️", .name = "man in manual wheelchair: facing right", .keywords = "man in manual wheelchair facing right accessibility person activity people body" }, + .{ .glyph = "👩‍🦽", .name = "woman in manual wheelchair", .keywords = "woman in manual wheelchair accessibility person activity people body" }, + .{ .glyph = "👩‍🦽‍➡️", .name = "woman in manual wheelchair: facing right", .keywords = "woman in manual wheelchair facing right accessibility person activity people body" }, + .{ .glyph = "🏃", .name = "person running", .keywords = "person running fast hurry marathon move quick race racing run rush speed activity people body" }, + .{ .glyph = "🏃‍♂️", .name = "man running", .keywords = "man running fast hurry marathon move quick race racing run rush speed person activity people body" }, + .{ .glyph = "🏃‍♀️", .name = "woman running", .keywords = "woman running fast hurry marathon move quick race racing run rush speed person activity people body" }, + .{ .glyph = "🏃‍➡️", .name = "person running: facing right", .keywords = "person running facing right fast hurry marathon move quick race racing run rush speed activity people body" }, + .{ .glyph = "🏃‍♀️‍➡️", .name = "woman running: facing right", .keywords = "woman running facing right fast hurry marathon move quick race racing run rush speed person activity people body" }, + .{ .glyph = "🏃‍♂️‍➡️", .name = "man running: facing right", .keywords = "man running facing right fast hurry marathon move quick race racing run rush speed person activity people body" }, + .{ .glyph = "💃", .name = "woman dancing", .keywords = "woman dancing dance dancer elegant festive flair flamenco groove let’s salsa tango person activity people body" }, + .{ .glyph = "🕺", .name = "man dancing", .keywords = "man dancing dance dancer elegant festive flair flamenco groove let’s salsa tango person activity people body" }, + .{ .glyph = "🕴️", .name = "person in suit levitating", .keywords = "person in suit levitating business activity people body" }, + .{ .glyph = "👯", .name = "people with bunny ears", .keywords = "people with bunny ears bestie bff counterpart dancer double ear identical pair party partying soulmate twin twinsies person activity body" }, + .{ .glyph = "👯‍♂️", .name = "men with bunny ears", .keywords = "men with bunny ears bestie bff counterpart dancer double ear identical pair party partying people soulmate twin twinsies person activity body" }, + .{ .glyph = "👯‍♀️", .name = "women with bunny ears", .keywords = "women with bunny ears bestie bff counterpart dancer double ear identical pair party partying people soulmate twin twinsies person activity body" }, + .{ .glyph = "🧖", .name = "person in steamy room", .keywords = "person in steamy room day luxurious pamper relax sauna spa steam steambath unwind activity people body" }, + .{ .glyph = "🧖‍♂️", .name = "man in steamy room", .keywords = "man in steamy room day luxurious pamper relax sauna spa steam steambath unwind person activity people body" }, + .{ .glyph = "🧖‍♀️", .name = "woman in steamy room", .keywords = "woman in steamy room day luxurious pamper relax sauna spa steam steambath unwind person activity people body" }, + .{ .glyph = "🧗", .name = "person climbing", .keywords = "person climbing climb climber mountain rock scale up activity people body" }, + .{ .glyph = "🧗‍♂️", .name = "man climbing", .keywords = "man climbing climb climber mountain rock scale up person activity people body" }, + .{ .glyph = "🧗‍♀️", .name = "woman climbing", .keywords = "woman climbing climb climber mountain rock scale up person activity people body" }, + .{ .glyph = "🤺", .name = "person fencing", .keywords = "person fencing fencer sword sport people body" }, + .{ .glyph = "🏇", .name = "horse racing", .keywords = "horse racing jockey racehorse riding sport person people body" }, + .{ .glyph = "⛷️", .name = "skier", .keywords = "skier ski snow person sport people body" }, + .{ .glyph = "🏂", .name = "snowboarder", .keywords = "snowboarder ski snow snowboard sport person people body" }, + .{ .glyph = "🏌️", .name = "person golfing", .keywords = "person golfing ball birdie caddy driving golf green pga putt range tee sport people body" }, + .{ .glyph = "🏌️‍♂️", .name = "man golfing", .keywords = "man golfing ball birdie caddy driving golf green pga putt range tee person sport people body" }, + .{ .glyph = "🏌️‍♀️", .name = "woman golfing", .keywords = "woman golfing ball birdie caddy driving golf green pga putt range tee person sport people body" }, + .{ .glyph = "🏄", .name = "person surfing", .keywords = "person surfing beach ocean sport surf surfer swell waves people body" }, + .{ .glyph = "🏄‍♂️", .name = "man surfing", .keywords = "man surfing beach ocean sport surf surfer swell waves person people body" }, + .{ .glyph = "🏄‍♀️", .name = "woman surfing", .keywords = "woman surfing beach ocean person sport surf surfer swell waves people body" }, + .{ .glyph = "🚣", .name = "person rowing boat", .keywords = "person rowing boat canoe cruise fishing lake oar paddle raft river row rowboat sport people body" }, + .{ .glyph = "🚣‍♂️", .name = "man rowing boat", .keywords = "man rowing boat canoe cruise fishing lake oar paddle raft river row rowboat person sport people body" }, + .{ .glyph = "🚣‍♀️", .name = "woman rowing boat", .keywords = "woman rowing boat canoe cruise fishing lake oar paddle raft river row rowboat person sport people body" }, + .{ .glyph = "🏊", .name = "person swimming", .keywords = "person swimming freestyle sport swim swimmer triathlon people body" }, + .{ .glyph = "🏊‍♂️", .name = "man swimming", .keywords = "man swimming freestyle sport swim swimmer triathlon person people body" }, + .{ .glyph = "🏊‍♀️", .name = "woman swimming", .keywords = "woman swimming freestyle man sport swim swimmer triathlon person people body" }, + .{ .glyph = "⛹️", .name = "person bouncing ball", .keywords = "person bouncing ball athletic basketball championship dribble net player throw sport people body" }, + .{ .glyph = "⛹️‍♂️", .name = "man bouncing ball", .keywords = "man bouncing ball athletic basketball championship dribble net player throw person sport people body" }, + .{ .glyph = "⛹️‍♀️", .name = "woman bouncing ball", .keywords = "woman bouncing ball athletic basketball championship dribble net player throw person sport people body" }, + .{ .glyph = "🏋️", .name = "person lifting weights", .keywords = "person lifting weights barbell bodybuilder deadlift lifter powerlifting weight weightlifter workout sport people body" }, + .{ .glyph = "🏋️‍♂️", .name = "man lifting weights", .keywords = "man lifting weights barbell bodybuilder deadlift lifter powerlifting weight weightlifter workout person sport people body" }, + .{ .glyph = "🏋️‍♀️", .name = "woman lifting weights", .keywords = "woman lifting weights barbell bodybuilder deadlift lifter powerlifting weight weightlifter workout person sport people body" }, + .{ .glyph = "🚴", .name = "person biking", .keywords = "person biking bicycle bicyclist bike cycle cyclist riding sport people body" }, + .{ .glyph = "🚴‍♂️", .name = "man biking", .keywords = "man biking bicycle bicyclist bike cycle cyclist riding sport person people body" }, + .{ .glyph = "🚴‍♀️", .name = "woman biking", .keywords = "woman biking bicycle bicyclist bike cycle cyclist riding sport person people body" }, + .{ .glyph = "🚵", .name = "person mountain biking", .keywords = "person mountain biking bicycle bicyclist bike cycle cyclist riding sport people body" }, + .{ .glyph = "🚵‍♂️", .name = "man mountain biking", .keywords = "man mountain biking bicycle bicyclist bike cycle cyclist riding sport person people body" }, + .{ .glyph = "🚵‍♀️", .name = "woman mountain biking", .keywords = "woman mountain biking bicycle bicyclist bike cycle cyclist riding sport person people body" }, + .{ .glyph = "🤸", .name = "person cartwheeling", .keywords = "person cartwheeling active cartwheel excited flip gymnastics happy somersault sport people body" }, + .{ .glyph = "🤸‍♂️", .name = "man cartwheeling", .keywords = "man cartwheeling active cartwheel excited flip gymnastics happy somersault person sport people body" }, + .{ .glyph = "🤸‍♀️", .name = "woman cartwheeling", .keywords = "woman cartwheeling active cartwheel excited flip gymnastics happy somersault person sport people body" }, + .{ .glyph = "🤼", .name = "people wrestling", .keywords = "people wrestling combat duel grapple ring tournament wrestle person sport body" }, + .{ .glyph = "🤼‍♂️", .name = "men wrestling", .keywords = "men wrestling combat duel grapple ring tournament wrestle person sport people body" }, + .{ .glyph = "🤼‍♀️", .name = "women wrestling", .keywords = "women wrestling combat duel grapple ring tournament wrestle person sport people body" }, + .{ .glyph = "🤽", .name = "person playing water polo", .keywords = "person playing water polo sport swimming waterpolo people body" }, + .{ .glyph = "🤽‍♂️", .name = "man playing water polo", .keywords = "man playing water polo sport swimming waterpolo person people body" }, + .{ .glyph = "🤽‍♀️", .name = "woman playing water polo", .keywords = "woman playing water polo sport swimming waterpolo person people body" }, + .{ .glyph = "🤾", .name = "person playing handball", .keywords = "person playing handball athletics ball catch chuck hurl lob pitch sport throw toss people body" }, + .{ .glyph = "🤾‍♂️", .name = "man playing handball", .keywords = "man playing handball athletics ball catch chuck hurl lob pitch sport throw toss person people body" }, + .{ .glyph = "🤾‍♀️", .name = "woman playing handball", .keywords = "woman playing handball athletics ball catch chuck hurl lob pitch sport throw toss person people body" }, + .{ .glyph = "🤹", .name = "person juggling", .keywords = "person juggling act balance balancing handle juggle manage multitask skill sport people body" }, + .{ .glyph = "🤹‍♂️", .name = "man juggling", .keywords = "man juggling act balance balancing handle juggle manage multitask skill person sport people body" }, + .{ .glyph = "🤹‍♀️", .name = "woman juggling", .keywords = "woman juggling act balance balancing handle juggle manage multitask skill person sport people body" }, + .{ .glyph = "🧘", .name = "person in lotus position", .keywords = "person in lotus position cross legged legs meditation peace relax serenity yoga yogi zen resting people body" }, + .{ .glyph = "🧘‍♂️", .name = "man in lotus position", .keywords = "man in lotus position cross legged legs meditation peace relax serenity yoga yogi zen person resting people body" }, + .{ .glyph = "🧘‍♀️", .name = "woman in lotus position", .keywords = "woman in lotus position cross legged legs meditation peace relax serenity yoga yogi zen person resting people body" }, + .{ .glyph = "🛀", .name = "person taking bath", .keywords = "person taking bath bathtub tub resting people body" }, + .{ .glyph = "🛌", .name = "person in bed", .keywords = "person in bed bedtime good goodnight hotel nap night sleep tired zzz resting people body" }, + .{ .glyph = "🧑‍🤝‍🧑", .name = "people holding hands", .keywords = "people holding hands bae bestie bff couple dating flirt friends hand hold twins family body" }, + .{ .glyph = "👭", .name = "women holding hands", .keywords = "women holding hands bae bestie bff couple dating flirt friends girls hand hold sisters twins family people body" }, + .{ .glyph = "👫", .name = "woman and man holding hands", .keywords = "woman and man holding hands bae bestie bff couple dating flirt friends hand hold twins family people body" }, + .{ .glyph = "👬", .name = "men holding hands", .keywords = "men holding hands bae bestie bff boys brothers couple dating flirt friends hand hold twins family people body" }, + .{ .glyph = "💏", .name = "kiss", .keywords = "kiss anniversary babe bae couple date dating heart love mwah person romance together xoxo family people body" }, + .{ .glyph = "👩‍❤️‍💋‍👨", .name = "kiss: woman, man", .keywords = "kiss woman man anniversary babe bae couple date dating heart love mwah person romance together xoxo family people body" }, + .{ .glyph = "👨‍❤️‍💋‍👨", .name = "kiss: man, man", .keywords = "kiss man anniversary babe bae couple date dating heart love mwah person romance together xoxo family people body" }, + .{ .glyph = "👩‍❤️‍💋‍👩", .name = "kiss: woman, woman", .keywords = "kiss woman anniversary babe bae couple date dating heart love mwah person romance together xoxo family people body" }, + .{ .glyph = "💑", .name = "couple with heart", .keywords = "couple with heart anniversary babe bae dating kiss love person relationship romance together you family people body" }, + .{ .glyph = "👩‍❤️‍👨", .name = "couple with heart: woman, man", .keywords = "couple with heart woman man anniversary babe bae dating kiss love person relationship romance together you family people body" }, + .{ .glyph = "👨‍❤️‍👨", .name = "couple with heart: man, man", .keywords = "couple with heart man anniversary babe bae dating kiss love person relationship romance together you family people body" }, + .{ .glyph = "👩‍❤️‍👩", .name = "couple with heart: woman, woman", .keywords = "couple with heart woman anniversary babe bae dating kiss love person relationship romance together you family people body" }, + .{ .glyph = "👨‍👩‍👦", .name = "family: man, woman, boy", .keywords = "family man woman boy child people body" }, + .{ .glyph = "👨‍👩‍👧", .name = "family: man, woman, girl", .keywords = "family man woman girl child people body" }, + .{ .glyph = "👨‍👩‍👧‍👦", .name = "family: man, woman, girl, boy", .keywords = "family man woman girl boy child people body" }, + .{ .glyph = "👨‍👩‍👦‍👦", .name = "family: man, woman, boy, boy", .keywords = "family man woman boy child people body" }, + .{ .glyph = "👨‍👩‍👧‍👧", .name = "family: man, woman, girl, girl", .keywords = "family man woman girl child people body" }, + .{ .glyph = "👨‍👨‍👦", .name = "family: man, man, boy", .keywords = "family man boy child people body" }, + .{ .glyph = "👨‍👨‍👧", .name = "family: man, man, girl", .keywords = "family man girl child people body" }, + .{ .glyph = "👨‍👨‍👧‍👦", .name = "family: man, man, girl, boy", .keywords = "family man girl boy child people body" }, + .{ .glyph = "👨‍👨‍👦‍👦", .name = "family: man, man, boy, boy", .keywords = "family man boy child people body" }, + .{ .glyph = "👨‍👨‍👧‍👧", .name = "family: man, man, girl, girl", .keywords = "family man girl child people body" }, + .{ .glyph = "👩‍👩‍👦", .name = "family: woman, woman, boy", .keywords = "family woman boy child people body" }, + .{ .glyph = "👩‍👩‍👧", .name = "family: woman, woman, girl", .keywords = "family woman girl child people body" }, + .{ .glyph = "👩‍👩‍👧‍👦", .name = "family: woman, woman, girl, boy", .keywords = "family woman girl boy child people body" }, + .{ .glyph = "👩‍👩‍👦‍👦", .name = "family: woman, woman, boy, boy", .keywords = "family woman boy child people body" }, + .{ .glyph = "👩‍👩‍👧‍👧", .name = "family: woman, woman, girl, girl", .keywords = "family woman girl child people body" }, + .{ .glyph = "👨‍👦", .name = "family: man, boy", .keywords = "family man boy child people body" }, + .{ .glyph = "👨‍👦‍👦", .name = "family: man, boy, boy", .keywords = "family man boy child people body" }, + .{ .glyph = "👨‍👧", .name = "family: man, girl", .keywords = "family man girl child people body" }, + .{ .glyph = "👨‍👧‍👦", .name = "family: man, girl, boy", .keywords = "family man girl boy child people body" }, + .{ .glyph = "👨‍👧‍👧", .name = "family: man, girl, girl", .keywords = "family man girl child people body" }, + .{ .glyph = "👩‍👦", .name = "family: woman, boy", .keywords = "family woman boy child people body" }, + .{ .glyph = "👩‍👦‍👦", .name = "family: woman, boy, boy", .keywords = "family woman boy child people body" }, + .{ .glyph = "👩‍👧", .name = "family: woman, girl", .keywords = "family woman girl child people body" }, + .{ .glyph = "👩‍👧‍👦", .name = "family: woman, girl, boy", .keywords = "family woman girl boy child people body" }, + .{ .glyph = "👩‍👧‍👧", .name = "family: woman, girl, girl", .keywords = "family woman girl child people body" }, + .{ .glyph = "🗣️", .name = "speaking head", .keywords = "speaking head face silhouette speak person symbol people body" }, + .{ .glyph = "👤", .name = "bust in silhouette", .keywords = "bust in silhouette mysterious shadow person symbol people body" }, + .{ .glyph = "👥", .name = "busts in silhouette", .keywords = "busts in silhouette bff bust everyone friend friends people person symbol body" }, + .{ .glyph = "🫂", .name = "people hugging", .keywords = "people hugging comfort embrace farewell friendship goodbye hello hug love thanks person symbol body" }, + .{ .glyph = "👪", .name = "family", .keywords = "family child person symbol people body" }, + .{ .glyph = "🧑‍🧑‍🧒", .name = "family: adult, adult, child", .keywords = "family adult child person symbol people body" }, + .{ .glyph = "🧑‍🧑‍🧒‍🧒", .name = "family: adult, adult, child, child", .keywords = "family adult child person symbol people body" }, + .{ .glyph = "🧑‍🧒", .name = "family: adult, child", .keywords = "family adult child person symbol people body" }, + .{ .glyph = "🧑‍🧒‍🧒", .name = "family: adult, child, child", .keywords = "family adult child person symbol people body" }, + .{ .glyph = "👣", .name = "footprints", .keywords = "footprints barefoot clothing footprint omw print walk person symbol people body" }, + .{ .glyph = "🫆", .name = "fingerprint", .keywords = "fingerprint clue crime detective forensics identity mystery print safety trace person symbol people body" }, + + // ---- Animals & Nature -------------------------------------------- + .{ .glyph = "🐵", .name = "monkey face", .keywords = "monkey face animal banana mammal animals nature" }, + .{ .glyph = "🐒", .name = "monkey", .keywords = "monkey animal banana mammal animals nature" }, + .{ .glyph = "🦍", .name = "gorilla", .keywords = "gorilla animal mammal animals nature" }, + .{ .glyph = "🦧", .name = "orangutan", .keywords = "orangutan animal ape monkey mammal animals nature" }, + .{ .glyph = "🐶", .name = "dog face", .keywords = "dog face adorbs animal pet puppies puppy mammal animals nature" }, + .{ .glyph = "🐕", .name = "dog", .keywords = "dog animal animals dogs pet mammal nature" }, + .{ .glyph = "🦮", .name = "guide dog", .keywords = "guide dog accessibility animal blind mammal animals nature" }, + .{ .glyph = "🐕‍🦺", .name = "service dog", .keywords = "service dog accessibility animal assistance mammal animals nature" }, + .{ .glyph = "🐩", .name = "poodle", .keywords = "poodle animal dog fluffy mammal animals nature" }, + .{ .glyph = "🐺", .name = "wolf", .keywords = "wolf animal face mammal animals nature" }, + .{ .glyph = "🦊", .name = "fox", .keywords = "fox animal face mammal animals nature" }, + .{ .glyph = "🦝", .name = "raccoon", .keywords = "raccoon animal curious sly mammal animals nature" }, + .{ .glyph = "🐱", .name = "cat face", .keywords = "cat face animal kitten kitty pet mammal animals nature" }, + .{ .glyph = "🐈", .name = "cat", .keywords = "cat animal animals cats kitten pet mammal nature" }, + .{ .glyph = "🐈‍⬛", .name = "black cat", .keywords = "black cat animal feline halloween meow unlucky mammal animals nature" }, + .{ .glyph = "🦁", .name = "lion", .keywords = "lion alpha animal face leo mane order rawr roar safari strong zodiac mammal animals nature" }, + .{ .glyph = "🐯", .name = "tiger face", .keywords = "tiger face animal big cat predator mammal animals nature" }, + .{ .glyph = "🐅", .name = "tiger", .keywords = "tiger animal big cat predator zoo mammal animals nature" }, + .{ .glyph = "🐆", .name = "leopard", .keywords = "leopard animal big cat predator zoo mammal animals nature" }, + .{ .glyph = "🐴", .name = "horse face", .keywords = "horse face animal dressage equine farm horses mammal animals nature" }, + .{ .glyph = "🫎", .name = "moose", .keywords = "moose alces animal antlers elk mammal animals nature" }, + .{ .glyph = "🫏", .name = "donkey", .keywords = "donkey animal ass burro hinny mammal mule stubborn animals nature" }, + .{ .glyph = "🐎", .name = "horse", .keywords = "horse animal equestrian farm racehorse racing mammal animals nature" }, + .{ .glyph = "🦄", .name = "unicorn", .keywords = "unicorn face animal mammal animals nature" }, + .{ .glyph = "🦓", .name = "zebra", .keywords = "zebra animal stripe mammal animals nature" }, + .{ .glyph = "🦌", .name = "deer", .keywords = "deer animal mammal animals nature" }, + .{ .glyph = "🦬", .name = "bison", .keywords = "bison animal buffalo herd wisent mammal animals nature" }, + .{ .glyph = "🐮", .name = "cow face", .keywords = "cow face animal farm milk moo mammal animals nature" }, + .{ .glyph = "🐂", .name = "ox", .keywords = "ox animal animals bull farm taurus zodiac mammal nature" }, + .{ .glyph = "🐃", .name = "water buffalo", .keywords = "water buffalo animal zoo mammal animals nature" }, + .{ .glyph = "🐄", .name = "cow", .keywords = "cow animal animals farm milk moo mammal nature" }, + .{ .glyph = "🐷", .name = "pig face", .keywords = "pig face animal bacon farm pork mammal animals nature" }, + .{ .glyph = "🐖", .name = "pig", .keywords = "pig animal bacon farm pork sow mammal animals nature" }, + .{ .glyph = "🐗", .name = "boar", .keywords = "boar animal pig mammal animals nature" }, + .{ .glyph = "🐽", .name = "pig nose", .keywords = "pig nose animal face farm smell snout mammal animals nature" }, + .{ .glyph = "🐏", .name = "ram", .keywords = "ram animal aries horns male sheep zodiac zoo mammal animals nature" }, + .{ .glyph = "🐑", .name = "ewe", .keywords = "ewe animal baa farm female fluffy lamb sheep wool mammal animals nature" }, + .{ .glyph = "🐐", .name = "goat", .keywords = "goat animal capricorn farm milk zodiac mammal animals nature" }, + .{ .glyph = "🐪", .name = "camel", .keywords = "camel animal desert dromedary hump one mammal animals nature" }, + .{ .glyph = "🐫", .name = "two-hump camel", .keywords = "two hump camel animal bactrian desert mammal animals nature perl" }, + .{ .glyph = "🦙", .name = "llama", .keywords = "llama alpaca animal guanaco vicuña wool mammal animals nature" }, + .{ .glyph = "🦒", .name = "giraffe", .keywords = "giraffe animal spots mammal animals nature" }, + .{ .glyph = "🐘", .name = "elephant", .keywords = "elephant animal mammal animals nature postgres php memory" }, + .{ .glyph = "🦣", .name = "mammoth", .keywords = "mammoth animal extinction large tusk wooly mammal animals nature" }, + .{ .glyph = "🦏", .name = "rhinoceros", .keywords = "rhinoceros animal mammal animals nature" }, + .{ .glyph = "🦛", .name = "hippopotamus", .keywords = "hippopotamus animal hippo mammal animals nature" }, + .{ .glyph = "🐭", .name = "mouse face", .keywords = "mouse face animal mammal animals nature" }, + .{ .glyph = "🐁", .name = "mouse", .keywords = "mouse animal animals mammal nature" }, + .{ .glyph = "🐀", .name = "rat", .keywords = "rat animal mammal animals nature" }, + .{ .glyph = "🐹", .name = "hamster", .keywords = "hamster animal face pet mammal animals nature" }, + .{ .glyph = "🐰", .name = "rabbit face", .keywords = "rabbit face animal bunny pet mammal animals nature" }, + .{ .glyph = "🐇", .name = "rabbit", .keywords = "rabbit animal bunny pet mammal animals nature" }, + .{ .glyph = "🐿️", .name = "chipmunk", .keywords = "chipmunk animal squirrel mammal animals nature" }, + .{ .glyph = "🦫", .name = "beaver", .keywords = "beaver animal dam teeth mammal animals nature" }, + .{ .glyph = "🦔", .name = "hedgehog", .keywords = "hedgehog animal spiny mammal animals nature" }, + .{ .glyph = "🦇", .name = "bat", .keywords = "bat animal vampire mammal animals nature" }, + .{ .glyph = "🐻", .name = "bear", .keywords = "bear animal face grizzly growl honey mammal animals nature" }, + .{ .glyph = "🐻‍❄️", .name = "polar bear", .keywords = "polar bear animal arctic white mammal animals nature" }, + .{ .glyph = "🐨", .name = "koala", .keywords = "koala animal australia bear down face marsupial under mammal animals nature" }, + .{ .glyph = "🐼", .name = "panda", .keywords = "panda animal bamboo face mammal animals nature" }, + .{ .glyph = "🦥", .name = "sloth", .keywords = "sloth lazy slow animal mammal animals nature" }, + .{ .glyph = "🦦", .name = "otter", .keywords = "otter animal fishing playful mammal animals nature" }, + .{ .glyph = "🦨", .name = "skunk", .keywords = "skunk animal stink mammal animals nature" }, + .{ .glyph = "🦘", .name = "kangaroo", .keywords = "kangaroo animal joey jump marsupial mammal animals nature" }, + .{ .glyph = "🦡", .name = "badger", .keywords = "badger animal honey pester mammal animals nature" }, + .{ .glyph = "🐾", .name = "paw prints", .keywords = "paw prints feet paws print animal mammal animals nature" }, + .{ .glyph = "🦃", .name = "turkey", .keywords = "turkey bird gobble thanksgiving animal animals nature" }, + .{ .glyph = "🐔", .name = "chicken", .keywords = "chicken animal bird ornithology animals nature" }, + .{ .glyph = "🐓", .name = "rooster", .keywords = "rooster animal bird ornithology animals nature" }, + .{ .glyph = "🐣", .name = "hatching chick", .keywords = "hatching chick animal baby bird egg animals nature" }, + .{ .glyph = "🐤", .name = "baby chick", .keywords = "baby chick animal bird ornithology animals nature" }, + .{ .glyph = "🐥", .name = "front-facing baby chick", .keywords = "front facing baby chick animal bird newborn ornithology animals nature" }, + .{ .glyph = "🐦", .name = "bird", .keywords = "bird animal ornithology animals nature" }, + .{ .glyph = "🐧", .name = "penguin", .keywords = "penguin animal antarctica bird ornithology animals nature linux tux" }, + .{ .glyph = "🕊️", .name = "dove", .keywords = "dove bird fly ornithology peace animal animals nature" }, + .{ .glyph = "🦅", .name = "eagle", .keywords = "eagle animal bird ornithology animals nature" }, + .{ .glyph = "🦆", .name = "duck", .keywords = "duck animal bird ornithology animals nature" }, + .{ .glyph = "🦢", .name = "swan", .keywords = "swan animal bird cygnet duckling ornithology ugly animals nature" }, + .{ .glyph = "🦉", .name = "owl", .keywords = "owl animal bird ornithology wise animals nature" }, + .{ .glyph = "🦤", .name = "dodo", .keywords = "dodo animal bird extinction large ornithology animals nature" }, + .{ .glyph = "🪶", .name = "feather", .keywords = "feather bird flight light plumage animal animals nature" }, + .{ .glyph = "🦩", .name = "flamingo", .keywords = "flamingo animal bird flamboyant ornithology tropical animals nature" }, + .{ .glyph = "🦚", .name = "peacock", .keywords = "peacock animal bird colorful ornithology ostentatious peahen pretty proud animals nature" }, + .{ .glyph = "🦜", .name = "parrot", .keywords = "parrot animal bird ornithology pirate talk animals nature" }, + .{ .glyph = "🪽", .name = "wing", .keywords = "wing angelic ascend aviation bird fly flying heavenly mythology soar animal animals nature" }, + .{ .glyph = "🐦‍⬛", .name = "black bird", .keywords = "black bird animal beak caw corvid crow ornithology raven rook animals nature" }, + .{ .glyph = "🪿", .name = "goose", .keywords = "goose animal bird duck flock fowl gaggle gander geese honk ornithology silly animals nature" }, + .{ .glyph = "🐦‍🔥", .name = "phoenix", .keywords = "phoenix ascend ascension emerge fantasy firebird glory immortal rebirth reincarnation reinvent renewal revival revive rise transform animal bird animals nature" }, + .{ .glyph = "🐸", .name = "frog", .keywords = "frog animal face amphibian animals nature" }, + .{ .glyph = "🐊", .name = "crocodile", .keywords = "crocodile animal zoo reptile animals nature" }, + .{ .glyph = "🐢", .name = "turtle", .keywords = "turtle animal terrapin tortoise reptile animals nature" }, + .{ .glyph = "🦎", .name = "lizard", .keywords = "lizard animal reptile animals nature" }, + .{ .glyph = "🐍", .name = "snake", .keywords = "snake animal bearer ophiuchus serpent zodiac reptile animals nature python" }, + .{ .glyph = "🐲", .name = "dragon face", .keywords = "dragon face animal fairy fairytale tale reptile animals nature" }, + .{ .glyph = "🐉", .name = "dragon", .keywords = "dragon animal fairy fairytale knights tale reptile animals nature" }, + .{ .glyph = "🦕", .name = "sauropod", .keywords = "sauropod brachiosaurus brontosaurus dinosaur diplodocus animal reptile animals nature" }, + .{ .glyph = "🦖", .name = "T-Rex", .keywords = "t rex dinosaur tyrannosaurus animal reptile animals nature legacy ancient" }, + .{ .glyph = "🐳", .name = "spouting whale", .keywords = "spouting whale animal beach face ocean marine animals nature docker container" }, + .{ .glyph = "🐋", .name = "whale", .keywords = "whale animal beach ocean marine animals nature" }, + .{ .glyph = "🐬", .name = "dolphin", .keywords = "dolphin animal beach flipper ocean marine animals nature" }, + .{ .glyph = "🦭", .name = "seal", .keywords = "seal animal lion ocean sea marine animals nature" }, + .{ .glyph = "🐟", .name = "fish", .keywords = "fish animal dinner fishes fishing pisces zodiac marine animals nature" }, + .{ .glyph = "🐠", .name = "tropical fish", .keywords = "tropical fish animal fishes marine animals nature" }, + .{ .glyph = "🐡", .name = "blowfish", .keywords = "blowfish animal fish marine animals nature" }, + .{ .glyph = "🦈", .name = "shark", .keywords = "shark animal fish marine animals nature" }, + .{ .glyph = "🐙", .name = "octopus", .keywords = "octopus animal creature ocean marine animals nature" }, + .{ .glyph = "🐚", .name = "spiral shell", .keywords = "spiral shell animal beach conch sea marine animals nature" }, + .{ .glyph = "🪸", .name = "coral", .keywords = "coral change climate ocean reef sea animal marine animals nature" }, + .{ .glyph = "🪼", .name = "jellyfish", .keywords = "jellyfish animal aquarium burn invertebrate jelly life marine ocean ouch plankton sea sting stinger tentacles animals nature" }, + .{ .glyph = "🦀", .name = "crab", .keywords = "crab cancer zodiac animal marine animals nature rust cargo" }, + .{ .glyph = "🦞", .name = "lobster", .keywords = "lobster animal bisque claws seafood marine animals nature" }, + .{ .glyph = "🦐", .name = "shrimp", .keywords = "shrimp food shellfish small animal marine animals nature" }, + .{ .glyph = "🦑", .name = "squid", .keywords = "squid animal food mollusk marine animals nature" }, + .{ .glyph = "🦪", .name = "oyster", .keywords = "oyster diving pearl animal marine animals nature" }, + .{ .glyph = "🐌", .name = "snail", .keywords = "snail animal escargot garden nature slug bug animals" }, + .{ .glyph = "🦋", .name = "butterfly", .keywords = "butterfly insect pretty animal bug animals nature" }, + .{ .glyph = "🐛", .name = "bug", .keywords = "bug animal garden insect animals nature issue defect regression" }, + .{ .glyph = "🐜", .name = "ant", .keywords = "ant animal garden insect bug animals nature" }, + .{ .glyph = "🐝", .name = "honeybee", .keywords = "honeybee animal bee bumblebee honey insect nature spring bug animals" }, + .{ .glyph = "🪲", .name = "beetle", .keywords = "beetle animal bug insect animals nature" }, + .{ .glyph = "🐞", .name = "lady beetle", .keywords = "lady beetle animal garden insect ladybird ladybug nature bug animals" }, + .{ .glyph = "🦗", .name = "cricket", .keywords = "cricket animal bug grasshopper insect orthoptera animals nature" }, + .{ .glyph = "🪳", .name = "cockroach", .keywords = "cockroach animal insect pest roach bug animals nature" }, + .{ .glyph = "🕷️", .name = "spider", .keywords = "spider animal insect bug animals nature" }, + .{ .glyph = "🕸️", .name = "spider web", .keywords = "spider web animal bug animals nature stale abandoned cobweb" }, + .{ .glyph = "🦂", .name = "scorpion", .keywords = "scorpion scorpio scorpius zodiac animal bug animals nature" }, + .{ .glyph = "🦟", .name = "mosquito", .keywords = "mosquito bite disease fever insect malaria pest virus animal bug animals nature" }, + .{ .glyph = "🪰", .name = "fly", .keywords = "fly animal disease insect maggot pest rotting bug animals nature" }, + .{ .glyph = "🪱", .name = "worm", .keywords = "worm animal annelid earthworm parasite bug animals nature" }, + .{ .glyph = "🦠", .name = "microbe", .keywords = "microbe amoeba bacteria science virus animal bug animals nature" }, + .{ .glyph = "💐", .name = "bouquet", .keywords = "bouquet anniversary birthday date flower love plant romance animals nature" }, + .{ .glyph = "🌸", .name = "cherry blossom", .keywords = "cherry blossom flower plant spring springtime animals nature" }, + .{ .glyph = "💮", .name = "white flower", .keywords = "white flower plant animals nature" }, + .{ .glyph = "🪷", .name = "lotus", .keywords = "lotus beauty buddhism calm flower hinduism peace purity serenity plant animals nature" }, + .{ .glyph = "🏵️", .name = "rosette", .keywords = "rosette plant flower animals nature" }, + .{ .glyph = "🌹", .name = "rose", .keywords = "rose beauty elegant flower love plant red valentine animals nature" }, + .{ .glyph = "🥀", .name = "wilted flower", .keywords = "wilted flower dying plant animals nature" }, + .{ .glyph = "🌺", .name = "hibiscus", .keywords = "hibiscus flower plant animals nature" }, + .{ .glyph = "🌻", .name = "sunflower", .keywords = "sunflower flower outdoors plant sun animals nature" }, + .{ .glyph = "🌼", .name = "blossom", .keywords = "blossom buttercup dandelion flower plant animals nature" }, + .{ .glyph = "🌷", .name = "tulip", .keywords = "tulip blossom flower growth plant animals nature" }, + .{ .glyph = "🪻", .name = "hyacinth", .keywords = "hyacinth bloom bluebonnet flower indigo lavender lilac lupine plant purple shrub snapdragon spring violet animals nature" }, + .{ .glyph = "🌱", .name = "seedling", .keywords = "seedling plant sapling sprout young other animals nature" }, + .{ .glyph = "🪴", .name = "potted plant", .keywords = "potted plant decor grow house nurturing pot other animals nature" }, + .{ .glyph = "🌲", .name = "evergreen tree", .keywords = "evergreen tree christmas forest pine plant other animals nature" }, + .{ .glyph = "🌳", .name = "deciduous tree", .keywords = "deciduous tree forest green habitat shedding plant other animals nature" }, + .{ .glyph = "🌴", .name = "palm tree", .keywords = "palm tree beach plant tropical other animals nature" }, + .{ .glyph = "🌵", .name = "cactus", .keywords = "cactus desert drought nature plant other animals" }, + .{ .glyph = "🌾", .name = "sheaf of rice", .keywords = "sheaf of rice ear grain grains plant other animals nature" }, + .{ .glyph = "🌿", .name = "herb", .keywords = "herb leaf plant other animals nature" }, + .{ .glyph = "☘️", .name = "shamrock", .keywords = "shamrock irish plant other animals nature" }, + .{ .glyph = "🍀", .name = "four leaf clover", .keywords = "four leaf clover 4 irish lucky plant other animals nature" }, + .{ .glyph = "🍁", .name = "maple leaf", .keywords = "maple leaf falling plant other animals nature" }, + .{ .glyph = "🍂", .name = "fallen leaf", .keywords = "fallen leaf autumn fall falling plant other animals nature" }, + .{ .glyph = "🍃", .name = "leaf fluttering in wind", .keywords = "leaf fluttering in wind blow flutter plant other animals nature" }, + .{ .glyph = "🪹", .name = "empty nest", .keywords = "empty nest branch home nesting plant other animals nature" }, + .{ .glyph = "🪺", .name = "nest with eggs", .keywords = "nest with eggs bird branch egg nesting plant other animals nature" }, + .{ .glyph = "🍄", .name = "mushroom", .keywords = "mushroom fungus toadstool plant other animals nature" }, + .{ .glyph = "🪾", .name = "leafless tree", .keywords = "leafless tree bare barren branches dead drought trunk winter wood plant other animals nature" }, + + // ---- Food & Drink ------------------------------------------------ + .{ .glyph = "🍇", .name = "grapes", .keywords = "grapes dionysus fruit grape food drink" }, + .{ .glyph = "🍈", .name = "melon", .keywords = "melon cantaloupe fruit food drink" }, + .{ .glyph = "🍉", .name = "watermelon", .keywords = "watermelon fruit food drink" }, + .{ .glyph = "🍊", .name = "tangerine", .keywords = "tangerine c citrus fruit nectarine orange vitamin food drink" }, + .{ .glyph = "🍋", .name = "lemon", .keywords = "lemon citrus fruit sour food drink" }, + .{ .glyph = "🍋‍🟩", .name = "lime", .keywords = "lime acidity citrus cocktail fruit garnish key margarita mojito refreshing salsa sour tangy tequila tropical zest food drink" }, + .{ .glyph = "🍌", .name = "banana", .keywords = "banana fruit potassium food drink" }, + .{ .glyph = "🍍", .name = "pineapple", .keywords = "pineapple colada fruit pina tropical food drink" }, + .{ .glyph = "🥭", .name = "mango", .keywords = "mango food fruit tropical drink" }, + .{ .glyph = "🍎", .name = "red apple", .keywords = "red apple diet food fruit health ripe drink mac macos" }, + .{ .glyph = "🍏", .name = "green apple", .keywords = "green apple fruit food drink" }, + .{ .glyph = "🍐", .name = "pear", .keywords = "pear fruit food drink" }, + .{ .glyph = "🍑", .name = "peach", .keywords = "peach fruit food drink" }, + .{ .glyph = "🍒", .name = "cherries", .keywords = "cherries berries cherry fruit red food drink" }, + .{ .glyph = "🍓", .name = "strawberry", .keywords = "strawberry berry fruit food drink" }, + .{ .glyph = "🫐", .name = "blueberries", .keywords = "blueberries berries berry bilberry blue blueberry food fruit drink" }, + .{ .glyph = "🥝", .name = "kiwi fruit", .keywords = "kiwi fruit food drink" }, + .{ .glyph = "🍅", .name = "tomato", .keywords = "tomato food fruit vegetable drink" }, + .{ .glyph = "🫒", .name = "olive", .keywords = "olive food fruit drink" }, + .{ .glyph = "🥥", .name = "coconut", .keywords = "coconut colada palm piña food fruit drink" }, + .{ .glyph = "🥑", .name = "avocado", .keywords = "avocado food fruit vegetable drink" }, + .{ .glyph = "🍆", .name = "eggplant", .keywords = "eggplant aubergine vegetable food drink" }, + .{ .glyph = "🥔", .name = "potato", .keywords = "potato food vegetable drink" }, + .{ .glyph = "🥕", .name = "carrot", .keywords = "carrot food vegetable drink" }, + .{ .glyph = "🌽", .name = "ear of corn", .keywords = "ear of corn crops farm maize maze food vegetable drink" }, + .{ .glyph = "🌶️", .name = "hot pepper", .keywords = "hot pepper food vegetable drink" }, + .{ .glyph = "🫑", .name = "bell pepper", .keywords = "bell pepper capsicum food vegetable drink" }, + .{ .glyph = "🥒", .name = "cucumber", .keywords = "cucumber food pickle vegetable drink" }, + .{ .glyph = "🥬", .name = "leafy green", .keywords = "leafy green bok burgers cabbage choy kale lettuce salad food vegetable drink" }, + .{ .glyph = "🥦", .name = "broccoli", .keywords = "broccoli cabbage wild food vegetable drink" }, + .{ .glyph = "🧄", .name = "garlic", .keywords = "garlic flavoring food vegetable drink" }, + .{ .glyph = "🧅", .name = "onion", .keywords = "onion flavoring food vegetable drink" }, + .{ .glyph = "🥜", .name = "peanuts", .keywords = "peanuts food nut peanut vegetable drink" }, + .{ .glyph = "🫘", .name = "beans", .keywords = "beans food kidney legume small vegetable drink" }, + .{ .glyph = "🌰", .name = "chestnut", .keywords = "chestnut almond plant food vegetable drink" }, + .{ .glyph = "🫚", .name = "ginger root", .keywords = "ginger root beer health herb natural spice food vegetable drink" }, + .{ .glyph = "🫛", .name = "pea pod", .keywords = "pea pod beans beanstalk edamame legume soybean vegetable veggie food drink" }, + .{ .glyph = "🍄‍🟫", .name = "brown mushroom", .keywords = "brown mushroom food fungi fungus nature pizza portobello shiitake shroom spore sprout toppings truffle vegetable vegetarian veggie drink" }, + .{ .glyph = "🫜", .name = "root vegetable", .keywords = "root vegetable beet food garden radish salad turnip vegetarian drink" }, + .{ .glyph = "🍞", .name = "bread", .keywords = "bread carbs food grain loaf restaurant toast wheat prepared drink" }, + .{ .glyph = "🥐", .name = "croissant", .keywords = "croissant bread breakfast crescent food french roll prepared drink" }, + .{ .glyph = "🥖", .name = "baguette bread", .keywords = "baguette bread food french prepared drink" }, + .{ .glyph = "🫓", .name = "flatbread", .keywords = "flatbread arepa bread food gordita lavash naan pita prepared drink" }, + .{ .glyph = "🥨", .name = "pretzel", .keywords = "pretzel convoluted twisted food prepared drink" }, + .{ .glyph = "🥯", .name = "bagel", .keywords = "bagel bakery bread breakfast schmear food prepared drink" }, + .{ .glyph = "🥞", .name = "pancakes", .keywords = "pancakes breakfast crêpe food hotcake pancake prepared drink" }, + .{ .glyph = "🧇", .name = "waffle", .keywords = "waffle breakfast indecisive iron food prepared drink" }, + .{ .glyph = "🧀", .name = "cheese wedge", .keywords = "cheese wedge food prepared drink" }, + .{ .glyph = "🍖", .name = "meat on bone", .keywords = "meat on bone food prepared drink" }, + .{ .glyph = "🍗", .name = "poultry leg", .keywords = "poultry leg bone chicken drumstick hungry turkey food prepared drink" }, + .{ .glyph = "🥩", .name = "cut of meat", .keywords = "cut of meat chop lambchop porkchop red steak food prepared drink" }, + .{ .glyph = "🥓", .name = "bacon", .keywords = "bacon breakfast food meat prepared drink" }, + .{ .glyph = "🍔", .name = "hamburger", .keywords = "hamburger burger eat fast food hungry prepared drink" }, + .{ .glyph = "🍟", .name = "french fries", .keywords = "french fries fast food prepared drink" }, + .{ .glyph = "🍕", .name = "pizza", .keywords = "pizza cheese food hungry pepperoni slice prepared drink" }, + .{ .glyph = "🌭", .name = "hot dog", .keywords = "hot dog frankfurter hotdog sausage food prepared drink" }, + .{ .glyph = "🥪", .name = "sandwich", .keywords = "sandwich bread food prepared drink" }, + .{ .glyph = "🌮", .name = "taco", .keywords = "taco mexican food prepared drink" }, + .{ .glyph = "🌯", .name = "burrito", .keywords = "burrito mexican wrap food prepared drink" }, + .{ .glyph = "🫔", .name = "tamale", .keywords = "tamale food mexican pamonha wrapped prepared drink" }, + .{ .glyph = "🥙", .name = "stuffed flatbread", .keywords = "stuffed flatbread falafel food gyro kebab prepared drink" }, + .{ .glyph = "🧆", .name = "falafel", .keywords = "falafel chickpea meatball food prepared drink" }, + .{ .glyph = "🥚", .name = "egg", .keywords = "egg breakfast food prepared drink" }, + .{ .glyph = "🍳", .name = "cooking", .keywords = "cooking breakfast easy egg fry frying over pan restaurant side sunny up food prepared drink" }, + .{ .glyph = "🥘", .name = "shallow pan of food", .keywords = "shallow pan of food casserole paella prepared drink" }, + .{ .glyph = "🍲", .name = "pot of food", .keywords = "pot of food soup stew prepared drink" }, + .{ .glyph = "🫕", .name = "fondue", .keywords = "fondue cheese chocolate food melted pot ski prepared drink" }, + .{ .glyph = "🥣", .name = "bowl with spoon", .keywords = "bowl with spoon breakfast cereal congee oatmeal porridge food prepared drink" }, + .{ .glyph = "🥗", .name = "green salad", .keywords = "green salad food prepared drink" }, + .{ .glyph = "🍿", .name = "popcorn", .keywords = "popcorn corn movie pop food prepared drink" }, + .{ .glyph = "🧈", .name = "butter", .keywords = "butter dairy food prepared drink" }, + .{ .glyph = "🧂", .name = "salt", .keywords = "salt condiment flavor mad salty shaker taste upset food prepared drink" }, + .{ .glyph = "🥫", .name = "canned food", .keywords = "canned food can prepared drink" }, + .{ .glyph = "🍱", .name = "bento box", .keywords = "bento box food asian drink" }, + .{ .glyph = "🍘", .name = "rice cracker", .keywords = "rice cracker food asian drink" }, + .{ .glyph = "🍙", .name = "rice ball", .keywords = "rice ball food japanese asian drink" }, + .{ .glyph = "🍚", .name = "cooked rice", .keywords = "cooked rice food asian drink" }, + .{ .glyph = "🍛", .name = "curry rice", .keywords = "curry rice food asian drink" }, + .{ .glyph = "🍜", .name = "steaming bowl", .keywords = "steaming bowl chopsticks food noodle pho ramen soup asian drink" }, + .{ .glyph = "🍝", .name = "spaghetti", .keywords = "spaghetti food meatballs pasta restaurant asian drink" }, + .{ .glyph = "🍠", .name = "roasted sweet potato", .keywords = "roasted sweet potato food asian drink" }, + .{ .glyph = "🍢", .name = "oden", .keywords = "oden food kebab restaurant seafood skewer stick asian drink" }, + .{ .glyph = "🍣", .name = "sushi", .keywords = "sushi food asian drink" }, + .{ .glyph = "🍤", .name = "fried shrimp", .keywords = "fried shrimp prawn tempura food asian drink" }, + .{ .glyph = "🍥", .name = "fish cake with swirl", .keywords = "fish cake with swirl food pastry restaurant asian drink" }, + .{ .glyph = "🥮", .name = "moon cake", .keywords = "moon cake autumn festival yuèbǐng food asian drink" }, + .{ .glyph = "🍡", .name = "dango", .keywords = "dango dessert japanese skewer stick sweet food asian drink" }, + .{ .glyph = "🥟", .name = "dumpling", .keywords = "dumpling empanada gyōza jiaozi pierogi potsticker food asian drink" }, + .{ .glyph = "🥠", .name = "fortune cookie", .keywords = "fortune cookie prophecy food asian drink" }, + .{ .glyph = "🥡", .name = "takeout box", .keywords = "takeout box chopsticks delivery food oyster pail asian drink" }, + .{ .glyph = "🍦", .name = "soft ice cream", .keywords = "soft ice cream dessert food icecream restaurant serve sweet drink" }, + .{ .glyph = "🍧", .name = "shaved ice", .keywords = "shaved ice dessert restaurant sweet food drink" }, + .{ .glyph = "🍨", .name = "ice cream", .keywords = "ice cream dessert food restaurant sweet drink" }, + .{ .glyph = "🍩", .name = "doughnut", .keywords = "doughnut breakfast dessert donut food sweet drink" }, + .{ .glyph = "🍪", .name = "cookie", .keywords = "cookie chip chocolate dessert sweet food drink" }, + .{ .glyph = "🎂", .name = "birthday cake", .keywords = "birthday cake bday celebration dessert happy pastry sweet food drink" }, + .{ .glyph = "🍰", .name = "shortcake", .keywords = "shortcake cake dessert pastry slice sweet food drink" }, + .{ .glyph = "🧁", .name = "cupcake", .keywords = "cupcake bakery dessert sprinkles sugar sweet treat food drink" }, + .{ .glyph = "🥧", .name = "pie", .keywords = "pie apple filling fruit meat pastry pumpkin slice food sweet drink" }, + .{ .glyph = "🍫", .name = "chocolate bar", .keywords = "chocolate bar candy dessert halloween sweet tooth food drink" }, + .{ .glyph = "🍬", .name = "candy", .keywords = "candy cavities dessert halloween restaurant sweet tooth wrapper food drink" }, + .{ .glyph = "🍭", .name = "lollipop", .keywords = "lollipop candy dessert food restaurant sweet drink" }, + .{ .glyph = "🍮", .name = "custard", .keywords = "custard dessert pudding sweet food drink" }, + .{ .glyph = "🍯", .name = "honey pot", .keywords = "honey pot barrel bear food honeypot jar sweet drink" }, + .{ .glyph = "🍼", .name = "baby bottle", .keywords = "baby bottle babies birth born drink infant milk newborn food" }, + .{ .glyph = "🥛", .name = "glass of milk", .keywords = "glass of milk drink food" }, + .{ .glyph = "☕", .name = "hot beverage", .keywords = "hot beverage cafe caffeine chai coffee drink morning steaming tea food java jvm" }, + .{ .glyph = "🫖", .name = "teapot", .keywords = "teapot brew drink food pot tea" }, + .{ .glyph = "🍵", .name = "teacup without handle", .keywords = "teacup without handle beverage cup drink oolong tea food" }, + .{ .glyph = "🍶", .name = "sake", .keywords = "sake bar beverage bottle cup drink restaurant food" }, + .{ .glyph = "🍾", .name = "bottle with popping cork", .keywords = "bottle with popping cork bar drink food" }, + .{ .glyph = "🍷", .name = "wine glass", .keywords = "wine glass alcohol bar beverage booze club drink drinking drinks restaurant food" }, + .{ .glyph = "🍸", .name = "cocktail glass", .keywords = "cocktail glass alcohol bar booze club drink drinking drinks mad martini men food" }, + .{ .glyph = "🍹", .name = "tropical drink", .keywords = "tropical drink alcohol bar booze club cocktail drinking drinks drunk mai party tai tropics food" }, + .{ .glyph = "🍺", .name = "beer mug", .keywords = "beer mug alcohol ale bar booze drink drinking drinks octoberfest oktoberfest pint stein summer food" }, + .{ .glyph = "🍻", .name = "clinking beer mugs", .keywords = "clinking beer mugs alcohol bar booze bottoms cheers clink drinking drinks drink food" }, + .{ .glyph = "🥂", .name = "clinking glasses", .keywords = "clinking glasses celebrate clink drink glass food" }, + .{ .glyph = "🥃", .name = "tumbler glass", .keywords = "tumbler glass liquor scotch shot whiskey whisky drink food" }, + .{ .glyph = "🫗", .name = "pouring liquid", .keywords = "pouring liquid accident drink empty glass oops pour spill water food" }, + .{ .glyph = "🥤", .name = "cup with straw", .keywords = "cup with straw drink juice malt soda soft water food" }, + .{ .glyph = "🧋", .name = "bubble tea", .keywords = "bubble tea boba food milk pearl drink" }, + .{ .glyph = "🧃", .name = "beverage box", .keywords = "beverage box juice straw sweet drink food" }, + .{ .glyph = "🧉", .name = "mate", .keywords = "mate drink food" }, + .{ .glyph = "🧊", .name = "ice", .keywords = "ice cold cube iceberg drink food freeze frozen pinned" }, + .{ .glyph = "🥢", .name = "chopsticks", .keywords = "chopsticks hashi jeotgarak kuaizi dishware food drink" }, + .{ .glyph = "🍽️", .name = "fork and knife with plate", .keywords = "fork and knife with plate cooking dinner eat dishware food drink" }, + .{ .glyph = "🍴", .name = "fork and knife", .keywords = "fork and knife breakfast breaky cooking cutlery delicious dinner eat feed food hungry lunch restaurant yum yummy dishware drink" }, + .{ .glyph = "🥄", .name = "spoon", .keywords = "spoon eat tableware dishware food drink" }, + .{ .glyph = "🔪", .name = "kitchen knife", .keywords = "kitchen knife chef cooking hocho tool weapon dishware food drink" }, + .{ .glyph = "🫙", .name = "jar", .keywords = "jar condiment container empty nothing sauce store dishware food drink" }, + .{ .glyph = "🏺", .name = "amphora", .keywords = "amphora aquarius cooking drink jug tool weapon zodiac dishware food" }, + + // ---- Travel & Places --------------------------------------------- + .{ .glyph = "🌍", .name = "globe showing Europe-Africa", .keywords = "globe showing europe africa earth world place map travel places" }, + .{ .glyph = "🌎", .name = "globe showing Americas", .keywords = "globe showing americas earth world place map travel places" }, + .{ .glyph = "🌏", .name = "globe showing Asia-Australia", .keywords = "globe showing asia australia earth world place map travel places" }, + .{ .glyph = "🌐", .name = "globe with meridians", .keywords = "globe with meridians earth internet web world worldwide place map travel places" }, + .{ .glyph = "🗺️", .name = "world map", .keywords = "world map place travel places" }, + .{ .glyph = "🗾", .name = "map of Japan", .keywords = "map of japan place travel places" }, + .{ .glyph = "🧭", .name = "compass", .keywords = "compass direction magnetic navigation orienteering place map travel places navigate bearings" }, + .{ .glyph = "🏔️", .name = "snow-capped mountain", .keywords = "snow capped mountain cold place geographic travel places" }, + .{ .glyph = "⛰️", .name = "mountain", .keywords = "mountain place geographic travel places" }, + .{ .glyph = "🌋", .name = "volcano", .keywords = "volcano eruption mountain nature place geographic travel places" }, + .{ .glyph = "🗻", .name = "mount fuji", .keywords = "mount fuji mountain nature place geographic travel places" }, + .{ .glyph = "🏕️", .name = "camping", .keywords = "camping place geographic travel places" }, + .{ .glyph = "🏖️", .name = "beach with umbrella", .keywords = "beach with umbrella place geographic travel places" }, + .{ .glyph = "🏜️", .name = "desert", .keywords = "desert place geographic travel places" }, + .{ .glyph = "🏝️", .name = "desert island", .keywords = "desert island place geographic travel places" }, + .{ .glyph = "🏞️", .name = "national park", .keywords = "national park place geographic travel places" }, + .{ .glyph = "🏟️", .name = "stadium", .keywords = "stadium place building travel places" }, + .{ .glyph = "🏛️", .name = "classical building", .keywords = "classical building place travel places" }, + .{ .glyph = "🏗️", .name = "building construction", .keywords = "building construction crane place travel places wip scaffolding" }, + .{ .glyph = "🧱", .name = "brick", .keywords = "brick bricks clay mortar wall place building travel places" }, + .{ .glyph = "🪨", .name = "rock", .keywords = "rock boulder heavy solid stone tough place building travel places" }, + .{ .glyph = "🪵", .name = "wood", .keywords = "wood log lumber timber place building travel places" }, + .{ .glyph = "🛖", .name = "hut", .keywords = "hut home house roundhouse shelter yurt place building travel places" }, + .{ .glyph = "🏘️", .name = "houses", .keywords = "houses house place building travel places" }, + .{ .glyph = "🏚️", .name = "derelict house", .keywords = "derelict house home place building travel places" }, + .{ .glyph = "🏠", .name = "house", .keywords = "house building country heart home ranch settle simple suburban suburbia where place travel places" }, + .{ .glyph = "🏡", .name = "house with garden", .keywords = "house with garden building country heart home ranch settle simple suburban suburbia where place travel places" }, + .{ .glyph = "🏢", .name = "office building", .keywords = "office building city cubical job place travel places" }, + .{ .glyph = "🏣", .name = "Japanese post office", .keywords = "japanese post office building place travel places" }, + .{ .glyph = "🏤", .name = "post office", .keywords = "post office building european place travel places" }, + .{ .glyph = "🏥", .name = "hospital", .keywords = "hospital building doctor medicine place travel places" }, + .{ .glyph = "🏦", .name = "bank", .keywords = "bank building place travel places" }, + .{ .glyph = "🏨", .name = "hotel", .keywords = "hotel building place travel places" }, + .{ .glyph = "🏩", .name = "love hotel", .keywords = "love hotel building place travel places" }, + .{ .glyph = "🏪", .name = "convenience store", .keywords = "convenience store 24 building hours place travel places" }, + .{ .glyph = "🏫", .name = "school", .keywords = "school building place travel places" }, + .{ .glyph = "🏬", .name = "department store", .keywords = "department store building place travel places" }, + .{ .glyph = "🏭", .name = "factory", .keywords = "factory building place travel places" }, + .{ .glyph = "🏯", .name = "Japanese castle", .keywords = "japanese castle building place travel places" }, + .{ .glyph = "🏰", .name = "castle", .keywords = "castle building european place travel places" }, + .{ .glyph = "💒", .name = "wedding", .keywords = "wedding chapel hitched nuptials romance place building travel places" }, + .{ .glyph = "🗼", .name = "Tokyo tower", .keywords = "tokyo tower place building travel places" }, + .{ .glyph = "🗽", .name = "Statue of Liberty", .keywords = "statue of liberty new ny nyc york place building travel places" }, + .{ .glyph = "⛪", .name = "church", .keywords = "church bless chapel christian cross religion place religious travel places" }, + .{ .glyph = "🕌", .name = "mosque", .keywords = "mosque islam masjid muslim religion place religious travel places" }, + .{ .glyph = "🛕", .name = "hindu temple", .keywords = "hindu temple place religious travel places" }, + .{ .glyph = "🕍", .name = "synagogue", .keywords = "synagogue jew jewish judaism religion temple place religious travel places" }, + .{ .glyph = "⛩️", .name = "shinto shrine", .keywords = "shinto shrine religion place religious travel places" }, + .{ .glyph = "🕋", .name = "kaaba", .keywords = "kaaba hajj islam muslim religion umrah place religious travel places" }, + .{ .glyph = "⛲", .name = "fountain", .keywords = "fountain place other travel places" }, + .{ .glyph = "⛺", .name = "tent", .keywords = "tent camping place other travel places" }, + .{ .glyph = "🌁", .name = "foggy", .keywords = "foggy fog place other travel places" }, + .{ .glyph = "🌃", .name = "night with stars", .keywords = "night with stars star place other travel places" }, + .{ .glyph = "🏙️", .name = "cityscape", .keywords = "cityscape city place other travel places" }, + .{ .glyph = "🌄", .name = "sunrise over mountains", .keywords = "sunrise over mountains morning sun place other travel places" }, + .{ .glyph = "🌅", .name = "sunrise", .keywords = "sunrise morning nature sun place other travel places" }, + .{ .glyph = "🌆", .name = "cityscape at dusk", .keywords = "cityscape at dusk building city evening landscape sun sunset place other travel places" }, + .{ .glyph = "🌇", .name = "sunset", .keywords = "sunset building dusk sun place other travel places" }, + .{ .glyph = "🌉", .name = "bridge at night", .keywords = "bridge at night place other travel places" }, + .{ .glyph = "♨️", .name = "hot springs", .keywords = "hot springs hotsprings steaming place other travel places" }, + .{ .glyph = "🎠", .name = "carousel horse", .keywords = "carousel horse entertainment place other travel places" }, + .{ .glyph = "🛝", .name = "playground slide", .keywords = "playground slide amusement park play playing sliding theme place other travel places" }, + .{ .glyph = "🎡", .name = "ferris wheel", .keywords = "ferris wheel amusement park theme place other travel places" }, + .{ .glyph = "🎢", .name = "roller coaster", .keywords = "roller coaster amusement park theme place other travel places" }, + .{ .glyph = "💈", .name = "barber pole", .keywords = "barber pole cut fresh haircut shave place other travel places" }, + .{ .glyph = "🎪", .name = "circus tent", .keywords = "circus tent place other travel places" }, + .{ .glyph = "🚂", .name = "locomotive", .keywords = "locomotive caboose engine railway steam train trains travel transport ground places" }, + .{ .glyph = "🚃", .name = "railway car", .keywords = "railway car electric train tram travel trolleybus transport ground places" }, + .{ .glyph = "🚄", .name = "high-speed train", .keywords = "high speed train railway shinkansen transport ground travel places" }, + .{ .glyph = "🚅", .name = "bullet train", .keywords = "bullet train high speed nose railway shinkansen travel transport ground places" }, + .{ .glyph = "🚆", .name = "train", .keywords = "train arrived choo railway transport ground travel places" }, + .{ .glyph = "🚇", .name = "metro", .keywords = "metro subway travel transport ground places" }, + .{ .glyph = "🚈", .name = "light rail", .keywords = "light rail arrived monorail railway transport ground travel places" }, + .{ .glyph = "🚉", .name = "station", .keywords = "station railway train transport ground travel places" }, + .{ .glyph = "🚊", .name = "tram", .keywords = "tram trolleybus transport ground travel places" }, + .{ .glyph = "🚝", .name = "monorail", .keywords = "monorail vehicle transport ground travel places" }, + .{ .glyph = "🚞", .name = "mountain railway", .keywords = "mountain railway car trip transport ground travel places" }, + .{ .glyph = "🚋", .name = "tram car", .keywords = "tram car bus trolley trolleybus transport ground travel places" }, + .{ .glyph = "🚌", .name = "bus", .keywords = "bus school vehicle transport ground travel places" }, + .{ .glyph = "🚍", .name = "oncoming bus", .keywords = "oncoming bus cars transport ground travel places" }, + .{ .glyph = "🚎", .name = "trolleybus", .keywords = "trolleybus bus tram trolley transport ground travel places" }, + .{ .glyph = "🚐", .name = "minibus", .keywords = "minibus bus drive van vehicle transport ground travel places" }, + .{ .glyph = "🚑", .name = "ambulance", .keywords = "ambulance emergency vehicle transport ground travel places" }, + .{ .glyph = "🚒", .name = "fire engine", .keywords = "fire engine truck transport ground travel places" }, + .{ .glyph = "🚓", .name = "police car", .keywords = "police car 5–0 cops patrol transport ground travel places" }, + .{ .glyph = "🚔", .name = "oncoming police car", .keywords = "oncoming police car transport ground travel places" }, + .{ .glyph = "🚕", .name = "taxi", .keywords = "taxi cab cabbie car drive vehicle yellow transport ground travel places" }, + .{ .glyph = "🚖", .name = "oncoming taxi", .keywords = "oncoming taxi cab cabbie cars drove hail yellow transport ground travel places" }, + .{ .glyph = "🚗", .name = "automobile", .keywords = "automobile car driving vehicle transport ground travel places" }, + .{ .glyph = "🚘", .name = "oncoming automobile", .keywords = "oncoming automobile car cars drove vehicle transport ground travel places" }, + .{ .glyph = "🚙", .name = "sport utility vehicle", .keywords = "sport utility vehicle car drive recreational sportutility transport ground travel places" }, + .{ .glyph = "🛻", .name = "pickup truck", .keywords = "pickup truck automobile car flatbed pick up transportation transport ground travel places" }, + .{ .glyph = "🚚", .name = "delivery truck", .keywords = "delivery truck car drive vehicle transport ground travel places" }, + .{ .glyph = "🚛", .name = "articulated lorry", .keywords = "articulated lorry car drive move semi truck vehicle transport ground travel places" }, + .{ .glyph = "🚜", .name = "tractor", .keywords = "tractor vehicle transport ground travel places" }, + .{ .glyph = "🏎️", .name = "racing car", .keywords = "racing car zoom transport ground travel places" }, + .{ .glyph = "🏍️", .name = "motorcycle", .keywords = "motorcycle racing transport ground travel places" }, + .{ .glyph = "🛵", .name = "motor scooter", .keywords = "motor scooter transport ground travel places" }, + .{ .glyph = "🦽", .name = "manual wheelchair", .keywords = "manual wheelchair accessibility transport ground travel places" }, + .{ .glyph = "🦼", .name = "motorized wheelchair", .keywords = "motorized wheelchair accessibility transport ground travel places" }, + .{ .glyph = "🛺", .name = "auto rickshaw", .keywords = "auto rickshaw tuk transport ground travel places" }, + .{ .glyph = "🚲", .name = "bicycle", .keywords = "bicycle bike class cycle cycling cyclist gang ride spin spinning transport ground travel places" }, + .{ .glyph = "🛴", .name = "kick scooter", .keywords = "kick scooter transport ground travel places" }, + .{ .glyph = "🛹", .name = "skateboard", .keywords = "skateboard board skate skater wheels transport ground travel places" }, + .{ .glyph = "🛼", .name = "roller skate", .keywords = "roller skate blades skates sport transport ground travel places" }, + .{ .glyph = "🚏", .name = "bus stop", .keywords = "bus stop busstop transport ground travel places" }, + .{ .glyph = "🛣️", .name = "motorway", .keywords = "motorway highway road transport ground travel places" }, + .{ .glyph = "🛤️", .name = "railway track", .keywords = "railway track train transport ground travel places" }, + .{ .glyph = "🛢️", .name = "oil drum", .keywords = "oil drum transport ground travel places" }, + .{ .glyph = "⛽", .name = "fuel pump", .keywords = "fuel pump diesel fuelpump gas gasoline station transport ground travel places" }, + .{ .glyph = "🛞", .name = "wheel", .keywords = "wheel car circle tire turn vehicle transport ground travel places" }, + .{ .glyph = "🚨", .name = "police car light", .keywords = "police car light alarm alert beacon emergency revolving siren transport ground travel places" }, + .{ .glyph = "🚥", .name = "horizontal traffic light", .keywords = "horizontal traffic light intersection signal stop stoplight transport ground travel places" }, + .{ .glyph = "🚦", .name = "vertical traffic light", .keywords = "vertical traffic light drove intersection signal stop stoplight transport ground travel places ci status pipeline" }, + .{ .glyph = "🛑", .name = "stop sign", .keywords = "stop sign octagonal transport ground travel places" }, + .{ .glyph = "🚧", .name = "construction", .keywords = "construction barrier transport ground travel places wip work in progress unfinished" }, + .{ .glyph = "⚓", .name = "anchor", .keywords = "anchor ship tool transport water travel places" }, + .{ .glyph = "🛟", .name = "ring buoy", .keywords = "ring buoy float life lifesaver preserver rescue safety save saver swim transport water travel places" }, + .{ .glyph = "⛵", .name = "sailboat", .keywords = "sailboat boat resort sailing sea yacht transport water travel places" }, + .{ .glyph = "🛶", .name = "canoe", .keywords = "canoe boat transport water travel places" }, + .{ .glyph = "🚤", .name = "speedboat", .keywords = "speedboat billionaire boat lake luxury millionaire summer travel transport water places" }, + .{ .glyph = "🛳️", .name = "passenger ship", .keywords = "passenger ship transport water travel places" }, + .{ .glyph = "⛴️", .name = "ferry", .keywords = "ferry boat passenger transport water travel places" }, + .{ .glyph = "🛥️", .name = "motor boat", .keywords = "motor boat motorboat transport water travel places" }, + .{ .glyph = "🚢", .name = "ship", .keywords = "ship boat passenger travel transport water places" }, + .{ .glyph = "✈️", .name = "airplane", .keywords = "airplane aeroplane fly flying jet plane travel transport air places" }, + .{ .glyph = "🛩️", .name = "small airplane", .keywords = "small airplane aeroplane plane transport air travel places" }, + .{ .glyph = "🛫", .name = "airplane departure", .keywords = "airplane departure aeroplane check in departures plane transport air travel places" }, + .{ .glyph = "🛬", .name = "airplane arrival", .keywords = "airplane arrival aeroplane arrivals arriving landing plane transport air travel places" }, + .{ .glyph = "🪂", .name = "parachute", .keywords = "parachute hang glide parasail skydive transport air travel places" }, + .{ .glyph = "💺", .name = "seat", .keywords = "seat chair transport air travel places" }, + .{ .glyph = "🚁", .name = "helicopter", .keywords = "helicopter copter roflcopter travel vehicle transport air places" }, + .{ .glyph = "🚟", .name = "suspension railway", .keywords = "suspension railway transport air travel places" }, + .{ .glyph = "🚠", .name = "mountain cableway", .keywords = "mountain cableway cable gondola lift ski transport air travel places" }, + .{ .glyph = "🚡", .name = "aerial tramway", .keywords = "aerial tramway cable car gondola ropeway transport air travel places" }, + .{ .glyph = "🛰️", .name = "satellite", .keywords = "satellite space transport air travel places" }, + .{ .glyph = "🚀", .name = "rocket", .keywords = "rocket launch rockets space travel transport air places deploy ship release" }, + .{ .glyph = "🛸", .name = "flying saucer", .keywords = "flying saucer aliens extra terrestrial ufo transport air travel places" }, + .{ .glyph = "🛎️", .name = "bellhop bell", .keywords = "bellhop bell hotel travel places" }, + .{ .glyph = "🧳", .name = "luggage", .keywords = "luggage bag packing roller suitcase travel hotel places" }, + .{ .glyph = "⌛", .name = "hourglass done", .keywords = "hourglass done sand time timer travel places" }, + .{ .glyph = "⏳", .name = "hourglass not done", .keywords = "hourglass not done flowing hours sand timer waiting yolo time travel places" }, + .{ .glyph = "⌚", .name = "watch", .keywords = "watch clock time travel places" }, + .{ .glyph = "⏰", .name = "alarm clock", .keywords = "alarm clock hours hrs late time waiting travel places" }, + .{ .glyph = "⏱️", .name = "stopwatch", .keywords = "stopwatch clock time travel places benchmark perf timing latency" }, + .{ .glyph = "⏲️", .name = "timer clock", .keywords = "timer clock time travel places" }, + .{ .glyph = "🕰️", .name = "mantelpiece clock", .keywords = "mantelpiece clock time travel places" }, + .{ .glyph = "🕛", .name = "twelve o’clock", .keywords = "twelve o’clock 12 00 clock time travel places" }, + .{ .glyph = "🕧", .name = "twelve-thirty", .keywords = "twelve thirty 12 30 clock time travel places" }, + .{ .glyph = "🕐", .name = "one o’clock", .keywords = "one o’clock 1 00 clock time travel places" }, + .{ .glyph = "🕜", .name = "one-thirty", .keywords = "one thirty 1 30 clock time travel places" }, + .{ .glyph = "🕑", .name = "two o’clock", .keywords = "two o’clock 2 00 clock time travel places" }, + .{ .glyph = "🕝", .name = "two-thirty", .keywords = "two thirty 2 30 clock time travel places" }, + .{ .glyph = "🕒", .name = "three o’clock", .keywords = "three o’clock 3 00 clock time travel places" }, + .{ .glyph = "🕞", .name = "three-thirty", .keywords = "three thirty 3 30 clock time travel places" }, + .{ .glyph = "🕓", .name = "four o’clock", .keywords = "four o’clock 4 00 clock time travel places" }, + .{ .glyph = "🕟", .name = "four-thirty", .keywords = "four thirty 30 4 clock time travel places" }, + .{ .glyph = "🕔", .name = "five o’clock", .keywords = "five o’clock 5 00 clock time travel places" }, + .{ .glyph = "🕠", .name = "five-thirty", .keywords = "five thirty 30 5 clock time travel places" }, + .{ .glyph = "🕕", .name = "six o’clock", .keywords = "six o’clock 6 00 clock time travel places" }, + .{ .glyph = "🕡", .name = "six-thirty", .keywords = "six thirty 30 6 clock time travel places" }, + .{ .glyph = "🕖", .name = "seven o’clock", .keywords = "seven o’clock 0 7 00 clock time travel places" }, + .{ .glyph = "🕢", .name = "seven-thirty", .keywords = "seven thirty 30 7 clock time travel places" }, + .{ .glyph = "🕗", .name = "eight o’clock", .keywords = "eight o’clock 8 00 clock time travel places" }, + .{ .glyph = "🕣", .name = "eight-thirty", .keywords = "eight thirty 30 8 clock time travel places" }, + .{ .glyph = "🕘", .name = "nine o’clock", .keywords = "nine o’clock 9 00 clock time travel places" }, + .{ .glyph = "🕤", .name = "nine-thirty", .keywords = "nine thirty 30 9 clock time travel places" }, + .{ .glyph = "🕙", .name = "ten o’clock", .keywords = "ten o’clock 0 10 00 clock time travel places" }, + .{ .glyph = "🕥", .name = "ten-thirty", .keywords = "ten thirty 10 30 clock time travel places" }, + .{ .glyph = "🕚", .name = "eleven o’clock", .keywords = "eleven o’clock 11 00 clock time travel places" }, + .{ .glyph = "🕦", .name = "eleven-thirty", .keywords = "eleven thirty 11 30 clock time travel places" }, + .{ .glyph = "🌑", .name = "new moon", .keywords = "new moon dark space sky weather travel places" }, + .{ .glyph = "🌒", .name = "waxing crescent moon", .keywords = "waxing crescent moon dreams space sky weather travel places" }, + .{ .glyph = "🌓", .name = "first quarter moon", .keywords = "first quarter moon space sky weather travel places" }, + .{ .glyph = "🌔", .name = "waxing gibbous moon", .keywords = "waxing gibbous moon space sky weather travel places" }, + .{ .glyph = "🌕", .name = "full moon", .keywords = "full moon space sky weather travel places" }, + .{ .glyph = "🌖", .name = "waning gibbous moon", .keywords = "waning gibbous moon space sky weather travel places" }, + .{ .glyph = "🌗", .name = "last quarter moon", .keywords = "last quarter moon space sky weather travel places" }, + .{ .glyph = "🌘", .name = "waning crescent moon", .keywords = "waning crescent moon space sky weather travel places" }, + .{ .glyph = "🌙", .name = "crescent moon", .keywords = "crescent moon ramadan space sky weather travel places" }, + .{ .glyph = "🌚", .name = "new moon face", .keywords = "new moon face space sky weather travel places" }, + .{ .glyph = "🌛", .name = "first quarter moon face", .keywords = "first quarter moon face space sky weather travel places" }, + .{ .glyph = "🌜", .name = "last quarter moon face", .keywords = "last quarter moon face dreams sky weather travel places" }, + .{ .glyph = "🌡️", .name = "thermometer", .keywords = "thermometer weather sky travel places" }, + .{ .glyph = "☀️", .name = "sun", .keywords = "sun bright rays space sunny weather sky travel places" }, + .{ .glyph = "🌝", .name = "full moon face", .keywords = "full moon face bright sky weather travel places" }, + .{ .glyph = "🌞", .name = "sun with face", .keywords = "sun with face beach bright day heat shine sunny sunshine weather sky travel places" }, + .{ .glyph = "🪐", .name = "ringed planet", .keywords = "ringed planet saturn saturnine sky weather travel places" }, + .{ .glyph = "⭐", .name = "star", .keywords = "star astronomy medium stars white sky weather travel places" }, + .{ .glyph = "🌟", .name = "glowing star", .keywords = "glowing star glittery glow night shining sparkle win sky weather travel places" }, + .{ .glyph = "🌠", .name = "shooting star", .keywords = "shooting star falling night space sky weather travel places" }, + .{ .glyph = "🌌", .name = "milky way", .keywords = "milky way space sky weather travel places" }, + .{ .glyph = "☁️", .name = "cloud", .keywords = "cloud weather sky travel places" }, + .{ .glyph = "⛅", .name = "sun behind cloud", .keywords = "sun behind cloud cloudy weather sky travel places" }, + .{ .glyph = "⛈️", .name = "cloud with lightning and rain", .keywords = "cloud with lightning and rain thunder thunderstorm sky weather travel places" }, + .{ .glyph = "🌤️", .name = "sun behind small cloud", .keywords = "sun behind small cloud weather sky travel places" }, + .{ .glyph = "🌥️", .name = "sun behind large cloud", .keywords = "sun behind large cloud weather sky travel places" }, + .{ .glyph = "🌦️", .name = "sun behind rain cloud", .keywords = "sun behind rain cloud weather sky travel places" }, + .{ .glyph = "🌧️", .name = "cloud with rain", .keywords = "cloud with rain weather sky travel places" }, + .{ .glyph = "🌨️", .name = "cloud with snow", .keywords = "cloud with snow cold weather sky travel places" }, + .{ .glyph = "🌩️", .name = "cloud with lightning", .keywords = "cloud with lightning weather sky travel places" }, + .{ .glyph = "🌪️", .name = "tornado", .keywords = "tornado cloud weather whirlwind sky travel places" }, + .{ .glyph = "🌫️", .name = "fog", .keywords = "fog cloud weather sky travel places" }, + .{ .glyph = "🌬️", .name = "wind face", .keywords = "wind face blow cloud sky weather travel places" }, + .{ .glyph = "🌀", .name = "cyclone", .keywords = "cyclone dizzy hurricane twister typhoon weather sky travel places" }, + .{ .glyph = "🌈", .name = "rainbow", .keywords = "rainbow gay genderqueer glbt glbtq lesbian lgbt lgbtq lgbtqia nature pride queer rain trans transgender weather sky travel places" }, + .{ .glyph = "🌂", .name = "closed umbrella", .keywords = "closed umbrella clothing rain sky weather travel places" }, + .{ .glyph = "☂️", .name = "umbrella", .keywords = "umbrella clothing rain sky weather travel places" }, + .{ .glyph = "☔", .name = "umbrella with rain drops", .keywords = "umbrella with rain drops clothing drop weather sky travel places" }, + .{ .glyph = "⛱️", .name = "umbrella on ground", .keywords = "umbrella on ground rain sun sky weather travel places" }, + .{ .glyph = "⚡", .name = "high voltage", .keywords = "high voltage danger electric electricity lightning nature thunder thunderbolt zap sky weather travel places fast perf quick" }, + .{ .glyph = "❄️", .name = "snowflake", .keywords = "snowflake cold snow weather sky travel places" }, + .{ .glyph = "☃️", .name = "snowman", .keywords = "snowman cold man snow sky weather travel places" }, + .{ .glyph = "⛄", .name = "snowman without snow", .keywords = "snowman without snow cold man sky weather travel places" }, + .{ .glyph = "☄️", .name = "comet", .keywords = "comet space sky weather travel places" }, + .{ .glyph = "🔥", .name = "fire", .keywords = "fire af burn flame hot lit litaf tool sky weather travel places onfire urgent" }, + .{ .glyph = "💧", .name = "droplet", .keywords = "droplet cold comic drop nature sad sweat tear water weather sky travel places" }, + .{ .glyph = "🌊", .name = "water wave", .keywords = "water wave nature ocean surf surfer surfing sky weather travel places" }, + + // ---- Activities -------------------------------------------------- + .{ .glyph = "🎃", .name = "jack-o-lantern", .keywords = "jack o lantern celebration halloween pumpkin event activities" }, + .{ .glyph = "🎄", .name = "Christmas tree", .keywords = "christmas tree celebration event activities" }, + .{ .glyph = "🎆", .name = "fireworks", .keywords = "fireworks boom celebration entertainment yolo event activities" }, + .{ .glyph = "🎇", .name = "sparkler", .keywords = "sparkler boom celebration fireworks sparkle event activities" }, + .{ .glyph = "🧨", .name = "firecracker", .keywords = "firecracker dynamite explosive fire fireworks light pop popping spark event activities" }, + .{ .glyph = "✨", .name = "sparkles", .keywords = "sparkles * magic sparkle star event activities" }, + .{ .glyph = "🎈", .name = "balloon", .keywords = "balloon birthday celebrate celebration event activities" }, + .{ .glyph = "🎉", .name = "party popper", .keywords = "party popper awesome birthday celebrate celebration excited hooray tada woohoo event activities ship shipped release" }, + .{ .glyph = "🎊", .name = "confetti ball", .keywords = "confetti ball celebrate celebration party woohoo event activities" }, + .{ .glyph = "🎋", .name = "tanabata tree", .keywords = "tanabata tree banner celebration japanese event activities" }, + .{ .glyph = "🎍", .name = "pine decoration", .keywords = "pine decoration bamboo celebration japanese plant event activities" }, + .{ .glyph = "🎎", .name = "Japanese dolls", .keywords = "japanese dolls celebration doll festival event activities" }, + .{ .glyph = "🎏", .name = "carp streamer", .keywords = "carp streamer celebration event activities" }, + .{ .glyph = "🎐", .name = "wind chime", .keywords = "wind chime bell celebration event activities" }, + .{ .glyph = "🎑", .name = "moon viewing ceremony", .keywords = "moon viewing ceremony celebration event activities" }, + .{ .glyph = "🧧", .name = "red envelope", .keywords = "red envelope gift good hóngbāo lai luck money see event activities" }, + .{ .glyph = "🎀", .name = "ribbon", .keywords = "ribbon celebration event activities" }, + .{ .glyph = "🎁", .name = "wrapped gift", .keywords = "wrapped gift birthday bow box celebration christmas present surprise event activities" }, + .{ .glyph = "🎗️", .name = "reminder ribbon", .keywords = "reminder ribbon celebration event activities" }, + .{ .glyph = "🎟️", .name = "admission tickets", .keywords = "admission tickets ticket event activities" }, + .{ .glyph = "🎫", .name = "ticket", .keywords = "ticket admission stub event activities" }, + .{ .glyph = "🎖️", .name = "military medal", .keywords = "military medal award celebration activities" }, + .{ .glyph = "🏆", .name = "trophy", .keywords = "trophy champion champs prize slay sport victory win winning award medal activities" }, + .{ .glyph = "🏅", .name = "sports medal", .keywords = "sports medal award gold winner activities" }, + .{ .glyph = "🥇", .name = "1st place medal", .keywords = "1st place medal first gold award activities" }, + .{ .glyph = "🥈", .name = "2nd place medal", .keywords = "2nd place medal second silver award activities" }, + .{ .glyph = "🥉", .name = "3rd place medal", .keywords = "3rd place medal bronze third award activities" }, + .{ .glyph = "⚽", .name = "soccer ball", .keywords = "soccer ball football futbol sport activities" }, + .{ .glyph = "⚾", .name = "baseball", .keywords = "baseball ball sport activities" }, + .{ .glyph = "🥎", .name = "softball", .keywords = "softball ball glove sports underarm sport activities" }, + .{ .glyph = "🏀", .name = "basketball", .keywords = "basketball ball hoop sport activities" }, + .{ .glyph = "🏐", .name = "volleyball", .keywords = "volleyball ball game sport activities" }, + .{ .glyph = "🏈", .name = "american football", .keywords = "american football ball bowl sport super activities" }, + .{ .glyph = "🏉", .name = "rugby football", .keywords = "rugby football ball sport activities" }, + .{ .glyph = "🎾", .name = "tennis", .keywords = "tennis ball racquet sport activities" }, + .{ .glyph = "🥏", .name = "flying disc", .keywords = "flying disc ultimate sport activities" }, + .{ .glyph = "🎳", .name = "bowling", .keywords = "bowling ball game sport strike activities" }, + .{ .glyph = "🏏", .name = "cricket game", .keywords = "cricket game ball bat sport activities" }, + .{ .glyph = "🏑", .name = "field hockey", .keywords = "field hockey ball game stick sport activities" }, + .{ .glyph = "🏒", .name = "ice hockey", .keywords = "ice hockey game puck stick sport activities" }, + .{ .glyph = "🥍", .name = "lacrosse", .keywords = "lacrosse ball goal sports stick sport activities" }, + .{ .glyph = "🏓", .name = "ping pong", .keywords = "ping pong ball bat game paddle pingpong table tennis sport activities" }, + .{ .glyph = "🏸", .name = "badminton", .keywords = "badminton birdie game racquet shuttlecock sport activities" }, + .{ .glyph = "🥊", .name = "boxing glove", .keywords = "boxing glove sport activities" }, + .{ .glyph = "🥋", .name = "martial arts uniform", .keywords = "martial arts uniform judo karate taekwondo sport activities" }, + .{ .glyph = "🥅", .name = "goal net", .keywords = "goal net sport activities" }, + .{ .glyph = "⛳", .name = "flag in hole", .keywords = "flag in hole golf sport activities" }, + .{ .glyph = "⛸️", .name = "ice skate", .keywords = "ice skate skating sport activities" }, + .{ .glyph = "🎣", .name = "fishing pole", .keywords = "fishing pole entertainment fish sport activities" }, + .{ .glyph = "🤿", .name = "diving mask", .keywords = "diving mask scuba snorkeling sport activities" }, + .{ .glyph = "🎽", .name = "running shirt", .keywords = "running shirt athletics sash sport activities" }, + .{ .glyph = "🎿", .name = "skis", .keywords = "skis ski snow sport activities" }, + .{ .glyph = "🛷", .name = "sled", .keywords = "sled luge sledge sleigh snow toboggan sport activities" }, + .{ .glyph = "🥌", .name = "curling stone", .keywords = "curling stone game rock sport activities" }, + .{ .glyph = "🎯", .name = "bullseye", .keywords = "bullseye bull dart direct entertainment game hit target activities goal focus" }, + .{ .glyph = "🪀", .name = "yo-yo", .keywords = "yo fluctuate toy game activities" }, + .{ .glyph = "🪁", .name = "kite", .keywords = "kite fly soar game activities" }, + .{ .glyph = "🔫", .name = "water pistol", .keywords = "water pistol gun handgun revolver tool weapon game activities" }, + .{ .glyph = "🎱", .name = "pool 8 ball", .keywords = "pool 8 ball 8ball billiard eight game activities" }, + .{ .glyph = "🔮", .name = "crystal ball", .keywords = "crystal ball fairy fairytale fantasy fortune future magic tale tool game activities" }, + .{ .glyph = "🪄", .name = "magic wand", .keywords = "magic wand magician witch wizard game activities" }, + .{ .glyph = "🎮", .name = "video game", .keywords = "video game controller entertainment activities" }, + .{ .glyph = "🕹️", .name = "joystick", .keywords = "joystick game video videogame activities" }, + .{ .glyph = "🎰", .name = "slot machine", .keywords = "slot machine casino gamble gambling game slots activities" }, + .{ .glyph = "🎲", .name = "game die", .keywords = "game die dice entertainment activities" }, + .{ .glyph = "🧩", .name = "puzzle piece", .keywords = "puzzle piece clue interlocking jigsaw game activities" }, + .{ .glyph = "🧸", .name = "teddy bear", .keywords = "teddy bear plaything plush stuffed toy game activities" }, + .{ .glyph = "🪅", .name = "piñata", .keywords = "piñata candy celebrate celebration cinco de festive mayo party pinada pinata game activities" }, + .{ .glyph = "🪩", .name = "mirror ball", .keywords = "mirror ball dance disco glitter party game activities" }, + .{ .glyph = "🪆", .name = "nesting dolls", .keywords = "nesting dolls babooshka baboushka babushka doll matryoshka russia game activities" }, + .{ .glyph = "♠️", .name = "spade suit", .keywords = "spade suit card game activities" }, + .{ .glyph = "♥️", .name = "heart suit", .keywords = "heart suit card emotion game hearts activities" }, + .{ .glyph = "♦️", .name = "diamond suit", .keywords = "diamond suit card game activities" }, + .{ .glyph = "♣️", .name = "club suit", .keywords = "club suit card clubs game activities" }, + .{ .glyph = "♟️", .name = "chess pawn", .keywords = "chess pawn dupe expendable game activities" }, + .{ .glyph = "🃏", .name = "joker", .keywords = "joker card game wildcard activities" }, + .{ .glyph = "🀄", .name = "mahjong red dragon", .keywords = "mahjong red dragon game activities" }, + .{ .glyph = "🎴", .name = "flower playing cards", .keywords = "flower playing cards card game japanese activities" }, + .{ .glyph = "🎭", .name = "performing arts", .keywords = "performing arts actor actress art entertainment mask theater theatre thespian crafts activities" }, + .{ .glyph = "🖼️", .name = "framed picture", .keywords = "framed picture art frame museum painting arts crafts activities" }, + .{ .glyph = "🎨", .name = "artist palette", .keywords = "artist palette art artsy arty colorful creative entertainment museum painter painting arts crafts activities" }, + .{ .glyph = "🧵", .name = "thread", .keywords = "thread needle sewing spool string arts crafts activities" }, + .{ .glyph = "🪡", .name = "sewing needle", .keywords = "sewing needle embroidery sew stitches sutures tailoring thread arts crafts activities" }, + .{ .glyph = "🧶", .name = "yarn", .keywords = "yarn ball crochet knit arts crafts activities" }, + .{ .glyph = "🪢", .name = "knot", .keywords = "knot cord rope tangled tie twine twist arts crafts activities" }, + + // ---- Objects ----------------------------------------------------- + .{ .glyph = "👓", .name = "glasses", .keywords = "glasses clothing eye eyeglasses eyewear objects" }, + .{ .glyph = "🕶️", .name = "sunglasses", .keywords = "sunglasses dark eye eyewear glasses clothing objects" }, + .{ .glyph = "🥽", .name = "goggles", .keywords = "goggles dive eye protection scuba swimming welding clothing objects" }, + .{ .glyph = "🥼", .name = "lab coat", .keywords = "lab coat clothes doctor dr experiment jacket scientist white clothing objects" }, + .{ .glyph = "🦺", .name = "safety vest", .keywords = "safety vest emergency clothing objects" }, + .{ .glyph = "👔", .name = "necktie", .keywords = "necktie clothing employed serious shirt tie objects" }, + .{ .glyph = "👕", .name = "t-shirt", .keywords = "t shirt blue casual clothes clothing collar dressed shopping tshirt weekend objects" }, + .{ .glyph = "👖", .name = "jeans", .keywords = "jeans blue casual clothes clothing denim dressed pants shopping trousers weekend objects" }, + .{ .glyph = "🧣", .name = "scarf", .keywords = "scarf bundle cold neck up clothing objects" }, + .{ .glyph = "🧤", .name = "gloves", .keywords = "gloves hand clothing objects" }, + .{ .glyph = "🧥", .name = "coat", .keywords = "coat brr bundle cold jacket up clothing objects" }, + .{ .glyph = "🧦", .name = "socks", .keywords = "socks stocking clothing objects" }, + .{ .glyph = "👗", .name = "dress", .keywords = "dress clothes clothing dressed fancy shopping objects" }, + .{ .glyph = "👘", .name = "kimono", .keywords = "kimono clothing comfortable objects" }, + .{ .glyph = "🥻", .name = "sari", .keywords = "sari clothing dress objects" }, + .{ .glyph = "🩱", .name = "one-piece swimsuit", .keywords = "one piece swimsuit bathing suit clothing objects" }, + .{ .glyph = "🩲", .name = "briefs", .keywords = "briefs bathing one piece suit swimsuit underwear clothing objects" }, + .{ .glyph = "🩳", .name = "shorts", .keywords = "shorts bathing pants suit swimsuit underwear clothing objects" }, + .{ .glyph = "👙", .name = "bikini", .keywords = "bikini bathing beach clothing pool suit swim objects" }, + .{ .glyph = "👚", .name = "woman’s clothes", .keywords = "woman’s clothes blouse clothing collar dress dressed lady shirt shopping woman objects" }, + .{ .glyph = "🪭", .name = "folding hand fan", .keywords = "folding hand fan clack clap cool cooling dance flirt flutter hot shy clothing objects" }, + .{ .glyph = "👛", .name = "purse", .keywords = "purse clothes clothing coin dress fancy handbag shopping objects" }, + .{ .glyph = "👜", .name = "handbag", .keywords = "handbag bag clothes clothing dress lady purse shopping objects" }, + .{ .glyph = "👝", .name = "clutch bag", .keywords = "clutch bag clothes clothing dress handbag pouch purse objects" }, + .{ .glyph = "🛍️", .name = "shopping bags", .keywords = "shopping bags bag hotel clothing objects" }, + .{ .glyph = "🎒", .name = "backpack", .keywords = "backpack backpacking bag bookbag education rucksack satchel school clothing objects" }, + .{ .glyph = "🩴", .name = "thong sandal", .keywords = "thong sandal beach flip flop sandals shoe thongs zōri clothing objects" }, + .{ .glyph = "👞", .name = "man’s shoe", .keywords = "man’s shoe brown clothes clothing feet foot kick man shoes shopping objects" }, + .{ .glyph = "👟", .name = "running shoe", .keywords = "running shoe athletic clothes clothing fast kick shoes shopping sneaker tennis objects" }, + .{ .glyph = "🥾", .name = "hiking boot", .keywords = "hiking boot backpacking brown camping outdoors shoe clothing objects" }, + .{ .glyph = "🥿", .name = "flat shoe", .keywords = "flat shoe ballet comfy flats slip on slipper clothing objects" }, + .{ .glyph = "👠", .name = "high-heeled shoe", .keywords = "high heeled shoe clothes clothing dress fashion heel heels shoes shopping stiletto woman objects" }, + .{ .glyph = "👡", .name = "woman’s sandal", .keywords = "woman’s sandal clothing shoe woman objects" }, + .{ .glyph = "🩰", .name = "ballet shoes", .keywords = "ballet shoes dance clothing objects" }, + .{ .glyph = "👢", .name = "woman’s boot", .keywords = "woman’s boot clothes clothing dress shoe shoes shopping woman objects" }, + .{ .glyph = "🪮", .name = "hair pick", .keywords = "hair pick afro comb groom clothing objects" }, + .{ .glyph = "👑", .name = "crown", .keywords = "crown clothing family king medieval queen royal royalty win objects" }, + .{ .glyph = "👒", .name = "woman’s hat", .keywords = "woman’s hat clothes clothing garden hats party woman objects" }, + .{ .glyph = "🎩", .name = "top hat", .keywords = "top hat clothes clothing fancy formal magic tophat objects" }, + .{ .glyph = "🎓", .name = "graduation cap", .keywords = "graduation cap celebration clothing education hat scholar objects" }, + .{ .glyph = "🧢", .name = "billed cap", .keywords = "billed cap baseball bent dad hat clothing objects" }, + .{ .glyph = "🪖", .name = "military helmet", .keywords = "military helmet army soldier war warrior clothing objects" }, + .{ .glyph = "⛑️", .name = "rescue worker’s helmet", .keywords = "rescue worker’s helmet aid cross face hat clothing objects" }, + .{ .glyph = "📿", .name = "prayer beads", .keywords = "prayer beads clothing necklace religion objects" }, + .{ .glyph = "💄", .name = "lipstick", .keywords = "lipstick cosmetics date makeup clothing objects" }, + .{ .glyph = "💍", .name = "ring", .keywords = "ring diamond engaged engagement married romance shiny sparkling wedding clothing objects" }, + .{ .glyph = "💎", .name = "gem stone", .keywords = "gem stone diamond engagement jewel money romance wedding clothing objects ruby" }, + .{ .glyph = "🔇", .name = "muted speaker", .keywords = "muted speaker mute quiet silent sound objects" }, + .{ .glyph = "🔈", .name = "speaker low volume", .keywords = "speaker low volume soft sound objects" }, + .{ .glyph = "🔉", .name = "speaker medium volume", .keywords = "speaker medium volume sound objects" }, + .{ .glyph = "🔊", .name = "speaker high volume", .keywords = "speaker high volume loud music sound objects" }, + .{ .glyph = "📢", .name = "loudspeaker", .keywords = "loudspeaker address communication loud public sound objects" }, + .{ .glyph = "📣", .name = "megaphone", .keywords = "megaphone cheering sound objects" }, + .{ .glyph = "📯", .name = "postal horn", .keywords = "postal horn post sound objects" }, + .{ .glyph = "🔔", .name = "bell", .keywords = "bell break church sound objects alert notification ping" }, + .{ .glyph = "🔕", .name = "bell with slash", .keywords = "bell with slash forbidden mute no not prohibited quiet silent sound objects silence snooze" }, + .{ .glyph = "🎼", .name = "musical score", .keywords = "musical score music note objects" }, + .{ .glyph = "🎵", .name = "musical note", .keywords = "musical note music sound objects" }, + .{ .glyph = "🎶", .name = "musical notes", .keywords = "musical notes music note sound objects" }, + .{ .glyph = "🎙️", .name = "studio microphone", .keywords = "studio microphone mic music objects" }, + .{ .glyph = "🎚️", .name = "level slider", .keywords = "level slider music objects" }, + .{ .glyph = "🎛️", .name = "control knobs", .keywords = "control knobs music objects" }, + .{ .glyph = "🎤", .name = "microphone", .keywords = "microphone karaoke mic music sing sound objects" }, + .{ .glyph = "🎧", .name = "headphone", .keywords = "headphone earbud sound music objects" }, + .{ .glyph = "📻", .name = "radio", .keywords = "radio entertainment tbt video music objects" }, + .{ .glyph = "🎷", .name = "saxophone", .keywords = "saxophone instrument music sax musical objects" }, + .{ .glyph = "🎺", .name = "trumpet", .keywords = "trumpet instrument music musical objects" }, + .{ .glyph = "🪗", .name = "accordion", .keywords = "accordion box concertina instrument music squeeze squeezebox musical objects" }, + .{ .glyph = "🎸", .name = "guitar", .keywords = "guitar instrument music strat musical objects" }, + .{ .glyph = "🎹", .name = "musical keyboard", .keywords = "musical keyboard instrument music piano objects" }, + .{ .glyph = "🎻", .name = "violin", .keywords = "violin instrument music musical objects" }, + .{ .glyph = "🪕", .name = "banjo", .keywords = "banjo music stringed musical instrument objects" }, + .{ .glyph = "🥁", .name = "drum", .keywords = "drum drumsticks music musical instrument objects" }, + .{ .glyph = "🪘", .name = "long drum", .keywords = "long drum beat conga instrument rhythm musical objects" }, + .{ .glyph = "🪇", .name = "maracas", .keywords = "maracas cha dance instrument music party percussion rattle shake shaker musical objects" }, + .{ .glyph = "🪈", .name = "flute", .keywords = "flute band fife flautist instrument marching music orchestra piccolo pipe recorder woodwind musical objects" }, + .{ .glyph = "🪉", .name = "harp", .keywords = "harp cupid instrument love music orchestra musical objects" }, + .{ .glyph = "📱", .name = "mobile phone", .keywords = "mobile phone cell communication telephone objects" }, + .{ .glyph = "📲", .name = "mobile phone with arrow", .keywords = "mobile phone with arrow build call cell communication receive telephone objects" }, + .{ .glyph = "☎️", .name = "telephone", .keywords = "telephone phone objects" }, + .{ .glyph = "📞", .name = "telephone receiver", .keywords = "telephone receiver communication phone voip objects" }, + .{ .glyph = "📟", .name = "pager", .keywords = "pager communication phone objects" }, + .{ .glyph = "📠", .name = "fax machine", .keywords = "fax machine communication phone objects" }, + .{ .glyph = "🔋", .name = "battery", .keywords = "battery computer objects" }, + .{ .glyph = "🪫", .name = "low battery", .keywords = "low battery drained electronic energy power computer objects" }, + .{ .glyph = "🔌", .name = "electric plug", .keywords = "electric plug electricity computer objects" }, + .{ .glyph = "💻", .name = "laptop", .keywords = "laptop computer office pc personal objects dev code local" }, + .{ .glyph = "🖥️", .name = "desktop computer", .keywords = "desktop computer monitor objects server box host" }, + .{ .glyph = "🖨️", .name = "printer", .keywords = "printer computer objects" }, + .{ .glyph = "⌨️", .name = "keyboard", .keywords = "keyboard computer objects" }, + .{ .glyph = "🖱️", .name = "computer mouse", .keywords = "computer mouse objects" }, + .{ .glyph = "🖲️", .name = "trackball", .keywords = "trackball computer objects" }, + .{ .glyph = "💽", .name = "computer disk", .keywords = "computer disk minidisk optical objects" }, + .{ .glyph = "💾", .name = "floppy disk", .keywords = "floppy disk computer objects" }, + .{ .glyph = "💿", .name = "optical disk", .keywords = "optical disk blu ray cd computer dvd objects" }, + .{ .glyph = "📀", .name = "dvd", .keywords = "dvd blu ray cd computer disk optical objects" }, + .{ .glyph = "🧮", .name = "abacus", .keywords = "abacus calculation calculator computer objects" }, + .{ .glyph = "🎥", .name = "movie camera", .keywords = "movie camera bollywood cinema film hollywood record light video objects" }, + .{ .glyph = "🎞️", .name = "film frames", .keywords = "film frames cinema movie light video objects" }, + .{ .glyph = "📽️", .name = "film projector", .keywords = "film projector cinema movie video light objects" }, + .{ .glyph = "🎬", .name = "clapper board", .keywords = "clapper board action movie light video objects" }, + .{ .glyph = "📺", .name = "television", .keywords = "television tv video light objects" }, + .{ .glyph = "📷", .name = "camera", .keywords = "camera photo selfie snap tbt trip video light objects" }, + .{ .glyph = "📸", .name = "camera with flash", .keywords = "camera with flash video light objects" }, + .{ .glyph = "📹", .name = "video camera", .keywords = "video camera camcorder tbt light objects" }, + .{ .glyph = "📼", .name = "videocassette", .keywords = "videocassette old school tape vcr vhs video light objects" }, + .{ .glyph = "🔍", .name = "magnifying glass tilted left", .keywords = "magnifying glass tilted left lab pointing science search tool light video objects find grep lookup" }, + .{ .glyph = "🔎", .name = "magnifying glass tilted right", .keywords = "magnifying glass tilted right contact lab pointing science search tool light video objects" }, + .{ .glyph = "🕯️", .name = "candle", .keywords = "candle light video objects" }, + .{ .glyph = "💡", .name = "light bulb", .keywords = "light bulb comic electric idea video objects" }, + .{ .glyph = "🔦", .name = "flashlight", .keywords = "flashlight electric light tool torch video objects" }, + .{ .glyph = "🏮", .name = "red paper lantern", .keywords = "red paper lantern bar light restaurant video objects" }, + .{ .glyph = "🪔", .name = "diya lamp", .keywords = "diya lamp light oil video objects" }, + .{ .glyph = "📔", .name = "notebook with decorative cover", .keywords = "notebook with decorative cover book decorated education school writing paper objects" }, + .{ .glyph = "📕", .name = "closed book", .keywords = "closed book education paper objects" }, + .{ .glyph = "📖", .name = "open book", .keywords = "open book education fantasy knowledge library novels reading paper objects" }, + .{ .glyph = "📗", .name = "green book", .keywords = "green book education fantasy library reading paper objects" }, + .{ .glyph = "📘", .name = "blue book", .keywords = "blue book education fantasy library reading paper objects" }, + .{ .glyph = "📙", .name = "orange book", .keywords = "orange book education fantasy library reading paper objects" }, + .{ .glyph = "📚", .name = "books", .keywords = "books book education fantasy knowledge library novels reading school study paper objects" }, + .{ .glyph = "📓", .name = "notebook", .keywords = "notebook book paper objects" }, + .{ .glyph = "📒", .name = "ledger", .keywords = "ledger notebook book paper objects" }, + .{ .glyph = "📃", .name = "page with curl", .keywords = "page with curl document paper book objects" }, + .{ .glyph = "📜", .name = "scroll", .keywords = "scroll paper book objects" }, + .{ .glyph = "📄", .name = "page facing up", .keywords = "page facing up document paper book objects" }, + .{ .glyph = "📰", .name = "newspaper", .keywords = "newspaper communication news paper book objects" }, + .{ .glyph = "🗞️", .name = "rolled-up newspaper", .keywords = "rolled up newspaper news paper book objects" }, + .{ .glyph = "📑", .name = "bookmark tabs", .keywords = "bookmark tabs mark marker book paper objects" }, + .{ .glyph = "🔖", .name = "bookmark", .keywords = "bookmark mark book paper objects" }, + .{ .glyph = "🏷️", .name = "label", .keywords = "label tag book paper objects version release" }, + .{ .glyph = "🪙", .name = "coin", .keywords = "coin dollar euro gold metal money rich silver treasure objects" }, + .{ .glyph = "💰", .name = "money bag", .keywords = "money bag bank bet billion cash cost dollar gold million moneybag paid paying pot rich win objects" }, + .{ .glyph = "💴", .name = "yen banknote", .keywords = "yen banknote bank bill currency money note objects" }, + .{ .glyph = "💵", .name = "dollar banknote", .keywords = "dollar banknote bank bill currency money note objects" }, + .{ .glyph = "💶", .name = "euro banknote", .keywords = "euro banknote 100 bank bill currency money note rich objects" }, + .{ .glyph = "💷", .name = "pound banknote", .keywords = "pound banknote bank bill billion cash currency money note pounds objects" }, + .{ .glyph = "💸", .name = "money with wings", .keywords = "money with wings bank banknote bill billion cash dollar fly million note pay objects" }, + .{ .glyph = "💳", .name = "credit card", .keywords = "credit card bank cash charge money pay objects" }, + .{ .glyph = "🧾", .name = "receipt", .keywords = "receipt accounting bookkeeping evidence invoice proof money objects" }, + .{ .glyph = "💹", .name = "chart increasing with yen", .keywords = "chart increasing with yen bank currency graph growth market money rise trend upward objects" }, + .{ .glyph = "✉️", .name = "envelope", .keywords = "envelope e mail email letter objects" }, + .{ .glyph = "📧", .name = "e-mail", .keywords = "e mail email letter objects" }, + .{ .glyph = "📨", .name = "incoming envelope", .keywords = "incoming envelope delivering e mail email letter receive sent objects" }, + .{ .glyph = "📩", .name = "envelope with arrow", .keywords = "envelope with arrow communication down e mail email letter outgoing send sent objects" }, + .{ .glyph = "📤", .name = "outbox tray", .keywords = "outbox tray box email letter mail sent objects" }, + .{ .glyph = "📥", .name = "inbox tray", .keywords = "inbox tray box email letter mail receive zero objects" }, + .{ .glyph = "📦", .name = "package", .keywords = "package box communication delivery parcel shipping mail objects release bundle ship artifact" }, + .{ .glyph = "📫", .name = "closed mailbox with raised flag", .keywords = "closed mailbox with raised flag communication mail postbox objects" }, + .{ .glyph = "📪", .name = "closed mailbox with lowered flag", .keywords = "closed mailbox with lowered flag mail postbox objects" }, + .{ .glyph = "📬", .name = "open mailbox with raised flag", .keywords = "open mailbox with raised flag mail postbox objects" }, + .{ .glyph = "📭", .name = "open mailbox with lowered flag", .keywords = "open mailbox with lowered flag mail postbox objects" }, + .{ .glyph = "📮", .name = "postbox", .keywords = "postbox mail mailbox objects" }, + .{ .glyph = "🗳️", .name = "ballot box with ballot", .keywords = "ballot box with mail objects" }, + .{ .glyph = "✏️", .name = "pencil", .keywords = "pencil writing objects" }, + .{ .glyph = "✒️", .name = "black nib", .keywords = "black nib pen writing objects" }, + .{ .glyph = "🖋️", .name = "fountain pen", .keywords = "fountain pen writing objects" }, + .{ .glyph = "🖊️", .name = "pen", .keywords = "pen ballpoint writing objects" }, + .{ .glyph = "🖌️", .name = "paintbrush", .keywords = "paintbrush painting writing objects" }, + .{ .glyph = "🖍️", .name = "crayon", .keywords = "crayon writing objects" }, + .{ .glyph = "📝", .name = "memo", .keywords = "memo communication media notes pencil writing objects todo note scratch" }, + .{ .glyph = "💼", .name = "briefcase", .keywords = "briefcase office objects" }, + .{ .glyph = "📁", .name = "file folder", .keywords = "file folder office objects" }, + .{ .glyph = "📂", .name = "open file folder", .keywords = "open file folder office objects" }, + .{ .glyph = "🗂️", .name = "card index dividers", .keywords = "card index dividers office objects" }, + .{ .glyph = "📅", .name = "calendar", .keywords = "calendar date office objects" }, + .{ .glyph = "📆", .name = "tear-off calendar", .keywords = "tear off calendar office objects" }, + .{ .glyph = "🗒️", .name = "spiral notepad", .keywords = "spiral notepad note pad office objects" }, + .{ .glyph = "🗓️", .name = "spiral calendar", .keywords = "spiral calendar pad office objects" }, + .{ .glyph = "📇", .name = "card index", .keywords = "card index old rolodex school office objects" }, + .{ .glyph = "📈", .name = "chart increasing", .keywords = "chart increasing data graph growth right trend up upward office objects metrics analytics" }, + .{ .glyph = "📉", .name = "chart decreasing", .keywords = "chart decreasing data down downward graph negative trend office objects metrics regression analytics" }, + .{ .glyph = "📊", .name = "bar chart", .keywords = "bar chart data graph office objects metrics analytics stats dashboard" }, + .{ .glyph = "📋", .name = "clipboard", .keywords = "clipboard do list notes office objects" }, + .{ .glyph = "📌", .name = "pushpin", .keywords = "pushpin collage pin office objects" }, + .{ .glyph = "📍", .name = "round pushpin", .keywords = "round pushpin location map pin office objects" }, + .{ .glyph = "📎", .name = "paperclip", .keywords = "paperclip office objects" }, + .{ .glyph = "🖇️", .name = "linked paperclips", .keywords = "linked paperclips link paperclip office objects" }, + .{ .glyph = "📏", .name = "straight ruler", .keywords = "straight ruler angle edge math straightedge office objects" }, + .{ .glyph = "📐", .name = "triangular ruler", .keywords = "triangular ruler angle math rule set slide triangle office objects" }, + .{ .glyph = "✂️", .name = "scissors", .keywords = "scissors cut cutting paper tool office objects" }, + .{ .glyph = "🗃️", .name = "card file box", .keywords = "card file box office objects" }, + .{ .glyph = "🗄️", .name = "file cabinet", .keywords = "file cabinet filing paper office objects database storage archive" }, + .{ .glyph = "🗑️", .name = "wastebasket", .keywords = "wastebasket can garbage trash waste office objects delete remove drop" }, + .{ .glyph = "🔒", .name = "locked", .keywords = "locked closed lock private objects secure" }, + .{ .glyph = "🔓", .name = "unlocked", .keywords = "unlocked cracked lock open unlock objects public" }, + .{ .glyph = "🔏", .name = "locked with pen", .keywords = "locked with pen ink lock nib privacy objects" }, + .{ .glyph = "🔐", .name = "locked with key", .keywords = "locked with key bike closed lock secure objects" }, + .{ .glyph = "🔑", .name = "key", .keywords = "key keys lock major password unlock objects auth access token secret" }, + .{ .glyph = "🗝️", .name = "old key", .keywords = "old key clue lock objects" }, + .{ .glyph = "🔨", .name = "hammer", .keywords = "hammer home improvement repairs tool objects" }, + .{ .glyph = "🪓", .name = "axe", .keywords = "axe ax chop hatchet split wood tool objects" }, + .{ .glyph = "⛏️", .name = "pick", .keywords = "pick hammer mining tool objects" }, + .{ .glyph = "⚒️", .name = "hammer and pick", .keywords = "hammer and pick tool objects" }, + .{ .glyph = "🛠️", .name = "hammer and wrench", .keywords = "hammer and wrench spanner tool objects" }, + .{ .glyph = "🗡️", .name = "dagger", .keywords = "dagger knife weapon tool objects" }, + .{ .glyph = "⚔️", .name = "crossed swords", .keywords = "crossed swords weapon tool objects" }, + .{ .glyph = "💣", .name = "bomb", .keywords = "bomb boom comic dangerous explosion hot tool objects" }, + .{ .glyph = "🪃", .name = "boomerang", .keywords = "boomerang rebound repercussion weapon tool objects" }, + .{ .glyph = "🏹", .name = "bow and arrow", .keywords = "bow and arrow archer archery sagittarius tool weapon zodiac objects" }, + .{ .glyph = "🛡️", .name = "shield", .keywords = "shield weapon tool objects security hardening defense" }, + .{ .glyph = "🪚", .name = "carpentry saw", .keywords = "carpentry saw carpenter cut lumber tool trim objects" }, + .{ .glyph = "🔧", .name = "wrench", .keywords = "wrench home improvement spanner tool objects" }, + .{ .glyph = "🪛", .name = "screwdriver", .keywords = "screwdriver flathead handy screw tool objects" }, + .{ .glyph = "🔩", .name = "nut and bolt", .keywords = "nut and bolt home improvement tool objects" }, + .{ .glyph = "⚙️", .name = "gear", .keywords = "gear cog cogwheel tool objects settings config options" }, + .{ .glyph = "🗜️", .name = "clamp", .keywords = "clamp compress tool vice objects" }, + .{ .glyph = "⚖️", .name = "balance scale", .keywords = "balance scale justice libra scales tool weight zodiac objects" }, + .{ .glyph = "🦯", .name = "white cane", .keywords = "white cane accessibility blind probing tool objects" }, + .{ .glyph = "🔗", .name = "link", .keywords = "link links tool objects" }, + .{ .glyph = "⛓️‍💥", .name = "broken chain", .keywords = "broken chain break breaking cuffs freedom tool objects" }, + .{ .glyph = "⛓️", .name = "chains", .keywords = "chains chain tool objects" }, + .{ .glyph = "🪝", .name = "hook", .keywords = "hook catch crook curve ensnare point selling tool objects" }, + .{ .glyph = "🧰", .name = "toolbox", .keywords = "toolbox box chest mechanic red tool objects" }, + .{ .glyph = "🧲", .name = "magnet", .keywords = "magnet attraction horseshoe magnetic negative positive shape u tool objects" }, + .{ .glyph = "🪜", .name = "ladder", .keywords = "ladder climb rung step tool objects" }, + .{ .glyph = "🪏", .name = "shovel", .keywords = "shovel bury dig garden hole plant scoop snow spade tool objects" }, + .{ .glyph = "⚗️", .name = "alembic", .keywords = "alembic chemistry tool science objects" }, + .{ .glyph = "🧪", .name = "test tube", .keywords = "test tube chemist chemistry experiment lab science objects trial" }, + .{ .glyph = "🧫", .name = "petri dish", .keywords = "petri dish bacteria biologist biology culture lab science objects test" }, + .{ .glyph = "🧬", .name = "dna", .keywords = "dna biologist evolution gene genetics life science objects" }, + .{ .glyph = "🔬", .name = "microscope", .keywords = "microscope experiment lab science tool objects inspect investigate research" }, + .{ .glyph = "🔭", .name = "telescope", .keywords = "telescope contact extraterrestrial science tool objects" }, + .{ .glyph = "📡", .name = "satellite antenna", .keywords = "satellite antenna aliens contact dish science objects" }, + .{ .glyph = "💉", .name = "syringe", .keywords = "syringe doctor flu medicine needle shot sick tool vaccination medical objects" }, + .{ .glyph = "🩸", .name = "drop of blood", .keywords = "drop of blood bleed donation injury medicine menstruation medical objects" }, + .{ .glyph = "💊", .name = "pill", .keywords = "pill doctor drugs medicated medicine pills sick vitamin medical objects" }, + .{ .glyph = "🩹", .name = "adhesive bandage", .keywords = "adhesive bandage medical objects hotfix patch bandaid" }, + .{ .glyph = "🩼", .name = "crutch", .keywords = "crutch aid cane disability help hurt injured mobility stick medical objects" }, + .{ .glyph = "🩺", .name = "stethoscope", .keywords = "stethoscope doctor heart medicine medical objects" }, + .{ .glyph = "🩻", .name = "x-ray", .keywords = "x ray bones doctor medical skeleton skull xray objects" }, + .{ .glyph = "🚪", .name = "door", .keywords = "door back closet front household objects" }, + .{ .glyph = "🛗", .name = "elevator", .keywords = "elevator accessibility hoist lift household objects" }, + .{ .glyph = "🪞", .name = "mirror", .keywords = "mirror makeup reflection reflector speculum household objects" }, + .{ .glyph = "🪟", .name = "window", .keywords = "window air frame fresh opening transparent view household objects windows" }, + .{ .glyph = "🛏️", .name = "bed", .keywords = "bed hotel sleep household objects" }, + .{ .glyph = "🛋️", .name = "couch and lamp", .keywords = "couch and lamp hotel household objects" }, + .{ .glyph = "🪑", .name = "chair", .keywords = "chair seat sit household objects" }, + .{ .glyph = "🚽", .name = "toilet", .keywords = "toilet bathroom household objects" }, + .{ .glyph = "🪠", .name = "plunger", .keywords = "plunger cup force plumber poop suction toilet household objects" }, + .{ .glyph = "🚿", .name = "shower", .keywords = "shower water household objects" }, + .{ .glyph = "🛁", .name = "bathtub", .keywords = "bathtub bath household objects" }, + .{ .glyph = "🪤", .name = "mouse trap", .keywords = "mouse trap bait cheese lure mousetrap snare household objects" }, + .{ .glyph = "🪒", .name = "razor", .keywords = "razor sharp shave household objects" }, + .{ .glyph = "🧴", .name = "lotion bottle", .keywords = "lotion bottle moisturizer shampoo sunscreen household objects" }, + .{ .glyph = "🧷", .name = "safety pin", .keywords = "safety pin diaper punk rock household objects" }, + .{ .glyph = "🧹", .name = "broom", .keywords = "broom cleaning sweeping witch household objects cleanup refactor tidy sweep" }, + .{ .glyph = "🧺", .name = "basket", .keywords = "basket farming laundry picnic household objects" }, + .{ .glyph = "🧻", .name = "roll of paper", .keywords = "roll of paper toilet towels household objects" }, + .{ .glyph = "🪣", .name = "bucket", .keywords = "bucket cask pail vat household objects" }, + .{ .glyph = "🧼", .name = "soap", .keywords = "soap bar bathing clean cleaning lather soapdish household objects" }, + .{ .glyph = "🫧", .name = "bubbles", .keywords = "bubbles bubble burp clean floating pearl soap underwater household objects" }, + .{ .glyph = "🪥", .name = "toothbrush", .keywords = "toothbrush bathroom brush clean dental hygiene teeth toiletry household objects" }, + .{ .glyph = "🧽", .name = "sponge", .keywords = "sponge absorbing cleaning porous soak household objects" }, + .{ .glyph = "🧯", .name = "fire extinguisher", .keywords = "fire extinguisher extinguish quench household objects" }, + .{ .glyph = "🛒", .name = "shopping cart", .keywords = "shopping cart trolley household objects" }, + .{ .glyph = "🚬", .name = "cigarette", .keywords = "cigarette smoking other object objects" }, + .{ .glyph = "⚰️", .name = "coffin", .keywords = "coffin dead death vampire other object objects" }, + .{ .glyph = "🪦", .name = "headstone", .keywords = "headstone cemetery dead grave graveyard memorial rip tomb tombstone other object objects" }, + .{ .glyph = "⚱️", .name = "funeral urn", .keywords = "funeral urn ashes death other object objects" }, + .{ .glyph = "🧿", .name = "nazar amulet", .keywords = "nazar amulet bead blue charm evil eye talisman other object objects" }, + .{ .glyph = "🪬", .name = "hamsa", .keywords = "hamsa amulet fatima fortune guide hand mary miriam palm protect protection other object objects" }, + .{ .glyph = "🗿", .name = "moai", .keywords = "moai face moyai statue stoneface travel other object objects" }, + .{ .glyph = "🪧", .name = "placard", .keywords = "placard card demonstration notice picket plaque protest sign other object objects" }, + .{ .glyph = "🪪", .name = "identification card", .keywords = "identification card credentials document id license security other object objects" }, + + // ---- Symbols ----------------------------------------------------- + .{ .glyph = "🏧", .name = "ATM sign", .keywords = "atm sign automated bank cash money teller transport symbols" }, + .{ .glyph = "🚮", .name = "litter in bin sign", .keywords = "litter in bin sign litterbin transport symbols" }, + .{ .glyph = "🚰", .name = "potable water", .keywords = "potable water drinking transport sign symbols" }, + .{ .glyph = "♿", .name = "wheelchair symbol", .keywords = "wheelchair symbol access handicap transport sign symbols" }, + .{ .glyph = "🚹", .name = "men’s room", .keywords = "men’s room bathroom lavatory man restroom toilet wc transport sign symbols" }, + .{ .glyph = "🚺", .name = "women’s room", .keywords = "women’s room bathroom lavatory restroom toilet wc woman transport sign symbols" }, + .{ .glyph = "🚻", .name = "restroom", .keywords = "restroom bathroom lavatory toilet wc transport sign symbols" }, + .{ .glyph = "🚼", .name = "baby symbol", .keywords = "baby symbol changing transport sign symbols" }, + .{ .glyph = "🚾", .name = "water closet", .keywords = "water closet bathroom lavatory restroom toilet wc transport sign symbols" }, + .{ .glyph = "🛂", .name = "passport control", .keywords = "passport control transport sign symbols" }, + .{ .glyph = "🛃", .name = "customs", .keywords = "customs packing transport sign symbols" }, + .{ .glyph = "🛄", .name = "baggage claim", .keywords = "baggage claim arrived bags case checked journey packing plane ready travel trip transport sign symbols" }, + .{ .glyph = "🛅", .name = "left luggage", .keywords = "left luggage baggage case locker transport sign symbols" }, + .{ .glyph = "⚠️", .name = "warning", .keywords = "warning caution symbols warn" }, + .{ .glyph = "🚸", .name = "children crossing", .keywords = "children crossing child pedestrian traffic warning symbols" }, + .{ .glyph = "⛔", .name = "no entry", .keywords = "no entry do fail forbidden not pass prohibited traffic warning symbols" }, + .{ .glyph = "🚫", .name = "prohibited", .keywords = "prohibited entry forbidden no not smoke warning symbols" }, + .{ .glyph = "🚳", .name = "no bicycles", .keywords = "no bicycles bicycle bike forbidden not prohibited warning symbols" }, + .{ .glyph = "🚭", .name = "no smoking", .keywords = "no smoking forbidden not prohibited smoke warning symbols" }, + .{ .glyph = "🚯", .name = "no littering", .keywords = "no littering forbidden litter not prohibited warning symbols" }, + .{ .glyph = "🚱", .name = "non-potable water", .keywords = "non potable water dry drinking prohibited warning symbols" }, + .{ .glyph = "🚷", .name = "no pedestrians", .keywords = "no pedestrians forbidden not pedestrian prohibited warning symbols" }, + .{ .glyph = "📵", .name = "no mobile phones", .keywords = "no mobile phones cell forbidden not phone prohibited telephone warning symbols" }, + .{ .glyph = "🔞", .name = "no one under eighteen", .keywords = "no one under eighteen 18 age forbidden not prohibited restriction underage warning symbols" }, + .{ .glyph = "☢️", .name = "radioactive", .keywords = "radioactive sign warning symbols" }, + .{ .glyph = "☣️", .name = "biohazard", .keywords = "biohazard sign warning symbols" }, + .{ .glyph = "⬆️", .name = "up arrow", .keywords = "up arrow cardinal direction north symbols" }, + .{ .glyph = "↗️", .name = "up-right arrow", .keywords = "up right arrow direction intercardinal northeast symbols" }, + .{ .glyph = "➡️", .name = "right arrow", .keywords = "right arrow cardinal direction east symbols" }, + .{ .glyph = "↘️", .name = "down-right arrow", .keywords = "down right arrow direction intercardinal southeast symbols" }, + .{ .glyph = "⬇️", .name = "down arrow", .keywords = "down arrow cardinal direction south symbols" }, + .{ .glyph = "↙️", .name = "down-left arrow", .keywords = "down left arrow direction intercardinal southwest symbols" }, + .{ .glyph = "⬅️", .name = "left arrow", .keywords = "left arrow cardinal direction west symbols" }, + .{ .glyph = "↖️", .name = "up-left arrow", .keywords = "up left arrow direction intercardinal northwest symbols" }, + .{ .glyph = "↕️", .name = "up-down arrow", .keywords = "up down arrow symbols" }, + .{ .glyph = "↔️", .name = "left-right arrow", .keywords = "left right arrow symbols" }, + .{ .glyph = "↩️", .name = "right arrow curving left", .keywords = "right arrow curving left symbols" }, + .{ .glyph = "↪️", .name = "left arrow curving right", .keywords = "left arrow curving right symbols" }, + .{ .glyph = "⤴️", .name = "right arrow curving up", .keywords = "right arrow curving up symbols" }, + .{ .glyph = "⤵️", .name = "right arrow curving down", .keywords = "right arrow curving down symbols" }, + .{ .glyph = "🔃", .name = "clockwise vertical arrows", .keywords = "clockwise vertical arrows arrow refresh reload symbols" }, + .{ .glyph = "🔄", .name = "counterclockwise arrows button", .keywords = "counterclockwise arrows button again anticlockwise arrow deja refresh rewindershins vu symbols sync retry reload" }, + .{ .glyph = "🔙", .name = "BACK arrow", .keywords = "back arrow symbols" }, + .{ .glyph = "🔚", .name = "END arrow", .keywords = "end arrow symbols" }, + .{ .glyph = "🔛", .name = "ON! arrow", .keywords = "on arrow mark symbols" }, + .{ .glyph = "🔜", .name = "SOON arrow", .keywords = "soon arrow brb omw symbols" }, + .{ .glyph = "🔝", .name = "TOP arrow", .keywords = "top arrow homie up symbols" }, + .{ .glyph = "🛐", .name = "place of worship", .keywords = "place of worship pray religion symbols" }, + .{ .glyph = "⚛️", .name = "atom symbol", .keywords = "atom symbol atheist religion symbols" }, + .{ .glyph = "🕉️", .name = "om", .keywords = "om hindu religion symbols" }, + .{ .glyph = "✡️", .name = "star of David", .keywords = "star of david jew jewish judaism religion symbols" }, + .{ .glyph = "☸️", .name = "wheel of dharma", .keywords = "wheel of dharma buddhist religion symbols" }, + .{ .glyph = "☯️", .name = "yin yang", .keywords = "yin yang difficult lives religion tao taoist total yinyang symbols" }, + .{ .glyph = "✝️", .name = "latin cross", .keywords = "latin cross christ christian religion symbols" }, + .{ .glyph = "☦️", .name = "orthodox cross", .keywords = "orthodox cross christian religion symbols" }, + .{ .glyph = "☪️", .name = "star and crescent", .keywords = "star and crescent islam muslim ramadan religion symbols" }, + .{ .glyph = "☮️", .name = "peace symbol", .keywords = "peace symbol healing peaceful religion symbols" }, + .{ .glyph = "🕎", .name = "menorah", .keywords = "menorah candelabrum candlestick hanukkah jewish judaism religion symbols" }, + .{ .glyph = "🔯", .name = "dotted six-pointed star", .keywords = "dotted six pointed star fortune jewish judaism religion symbols" }, + .{ .glyph = "🪯", .name = "khanda", .keywords = "khanda deg fateh khalsa religion sikh sikhism tegh symbols" }, + .{ .glyph = "♈", .name = "Aries", .keywords = "aries horoscope ram zodiac symbols" }, + .{ .glyph = "♉", .name = "Taurus", .keywords = "taurus bull horoscope ox zodiac symbols" }, + .{ .glyph = "♊", .name = "Gemini", .keywords = "gemini horoscope twins zodiac symbols" }, + .{ .glyph = "♋", .name = "Cancer", .keywords = "cancer crab horoscope zodiac symbols" }, + .{ .glyph = "♌", .name = "Leo", .keywords = "leo horoscope lion zodiac symbols" }, + .{ .glyph = "♍", .name = "Virgo", .keywords = "virgo horoscope zodiac symbols" }, + .{ .glyph = "♎", .name = "Libra", .keywords = "libra balance horoscope justice scales zodiac symbols" }, + .{ .glyph = "♏", .name = "Scorpio", .keywords = "scorpio horoscope scorpion scorpius zodiac symbols" }, + .{ .glyph = "♐", .name = "Sagittarius", .keywords = "sagittarius archer horoscope zodiac symbols" }, + .{ .glyph = "♑", .name = "Capricorn", .keywords = "capricorn goat horoscope zodiac symbols" }, + .{ .glyph = "♒", .name = "Aquarius", .keywords = "aquarius bearer horoscope water zodiac symbols" }, + .{ .glyph = "♓", .name = "Pisces", .keywords = "pisces fish horoscope zodiac symbols" }, + .{ .glyph = "⛎", .name = "Ophiuchus", .keywords = "ophiuchus bearer serpent snake zodiac symbols" }, + .{ .glyph = "🔀", .name = "shuffle tracks button", .keywords = "shuffle tracks button arrow crossed av symbol symbols random merge" }, + .{ .glyph = "🔁", .name = "repeat button", .keywords = "repeat button arrow clockwise av symbol symbols" }, + .{ .glyph = "🔂", .name = "repeat single button", .keywords = "repeat single button arrow clockwise once av symbol symbols" }, + .{ .glyph = "▶️", .name = "play button", .keywords = "play button arrow right triangle av symbol symbols" }, + .{ .glyph = "⏩", .name = "fast-forward button", .keywords = "fast forward button arrow double av symbol symbols" }, + .{ .glyph = "⏭️", .name = "next track button", .keywords = "next track button arrow scene triangle av symbol symbols" }, + .{ .glyph = "⏯️", .name = "play or pause button", .keywords = "play or pause button arrow right triangle av symbol symbols" }, + .{ .glyph = "◀️", .name = "reverse button", .keywords = "reverse button arrow left triangle av symbol symbols" }, + .{ .glyph = "⏪", .name = "fast reverse button", .keywords = "fast reverse button arrow double rewind av symbol symbols" }, + .{ .glyph = "⏮️", .name = "last track button", .keywords = "last track button arrow previous scene triangle av symbol symbols" }, + .{ .glyph = "🔼", .name = "upwards button", .keywords = "upwards button arrow red up av symbol symbols" }, + .{ .glyph = "⏫", .name = "fast up button", .keywords = "fast up button arrow double av symbol symbols" }, + .{ .glyph = "🔽", .name = "downwards button", .keywords = "downwards button arrow down red av symbol symbols" }, + .{ .glyph = "⏬", .name = "fast down button", .keywords = "fast down button arrow double av symbol symbols" }, + .{ .glyph = "⏸️", .name = "pause button", .keywords = "pause button bar double vertical av symbol symbols" }, + .{ .glyph = "⏹️", .name = "stop button", .keywords = "stop button square av symbol symbols" }, + .{ .glyph = "⏺️", .name = "record button", .keywords = "record button circle av symbol symbols" }, + .{ .glyph = "⏏️", .name = "eject button", .keywords = "eject button av symbol symbols" }, + .{ .glyph = "🎦", .name = "cinema", .keywords = "cinema camera film movie av symbol symbols" }, + .{ .glyph = "🔅", .name = "dim button", .keywords = "dim button brightness low av symbol symbols" }, + .{ .glyph = "🔆", .name = "bright button", .keywords = "bright button brightness light av symbol symbols" }, + .{ .glyph = "📶", .name = "antenna bars", .keywords = "antenna bars bar cell communication mobile phone signal telephone av symbol symbols" }, + .{ .glyph = "🛜", .name = "wireless", .keywords = "wireless broadband computer connectivity hotspot internet network router smartphone wi fi wifi wlan av symbol symbols" }, + .{ .glyph = "📳", .name = "vibration mode", .keywords = "vibration mode cell communication mobile phone telephone av symbol symbols" }, + .{ .glyph = "📴", .name = "mobile phone off", .keywords = "mobile phone off cell telephone av symbol symbols" }, + .{ .glyph = "♀️", .name = "female sign", .keywords = "female sign woman gender symbols" }, + .{ .glyph = "♂️", .name = "male sign", .keywords = "male sign man gender symbols" }, + .{ .glyph = "⚧️", .name = "transgender symbol", .keywords = "transgender symbol gender symbols" }, + .{ .glyph = "✖️", .name = "multiply", .keywords = "multiply × cancel multiplication sign x math symbols" }, + .{ .glyph = "➕", .name = "plus", .keywords = "plus + math symbols" }, + .{ .glyph = "➖", .name = "minus", .keywords = "minus − heavy math sign symbols" }, + .{ .glyph = "➗", .name = "divide", .keywords = "divide ÷ division heavy math sign symbols" }, + .{ .glyph = "🟰", .name = "heavy equals sign", .keywords = "heavy equals sign answer equal equality math symbols" }, + .{ .glyph = "♾️", .name = "infinity", .keywords = "infinity forever unbounded universal math symbols" }, + .{ .glyph = "‼️", .name = "double exclamation mark", .keywords = "double exclamation mark bangbang punctuation symbols" }, + .{ .glyph = "⁉️", .name = "exclamation question mark", .keywords = "exclamation question mark interrobang punctuation symbols" }, + .{ .glyph = "❓", .name = "red question mark", .keywords = "red question mark punctuation symbols" }, + .{ .glyph = "❔", .name = "white question mark", .keywords = "white question mark outlined punctuation symbols" }, + .{ .glyph = "❕", .name = "white exclamation mark", .keywords = "white exclamation mark bang outlined punctuation symbols" }, + .{ .glyph = "❗", .name = "red exclamation mark", .keywords = "red exclamation mark bang punctuation symbols" }, + .{ .glyph = "〰️", .name = "wavy dash", .keywords = "wavy dash punctuation symbols" }, + .{ .glyph = "💱", .name = "currency exchange", .keywords = "currency exchange bank money symbols" }, + .{ .glyph = "💲", .name = "heavy dollar sign", .keywords = "heavy dollar sign billion cash charge currency million money pay symbols" }, + .{ .glyph = "⚕️", .name = "medical symbol", .keywords = "medical symbol aesculapius medicine staff other symbols" }, + .{ .glyph = "♻️", .name = "recycling symbol", .keywords = "recycling symbol recycle other symbols refactor reuse" }, + .{ .glyph = "⚜️", .name = "fleur-de-lis", .keywords = "fleur de lis knights other symbol symbols" }, + .{ .glyph = "🔱", .name = "trident emblem", .keywords = "trident emblem anchor poseidon ship tool other symbol symbols" }, + .{ .glyph = "📛", .name = "name badge", .keywords = "name badge other symbol symbols" }, + .{ .glyph = "🔰", .name = "Japanese symbol for beginner", .keywords = "japanese symbol for beginner chevron green leaf tool yellow other symbols" }, + .{ .glyph = "⭕", .name = "hollow red circle", .keywords = "hollow red circle heavy large o other symbol symbols" }, + .{ .glyph = "✅", .name = "check mark button", .keywords = "check mark button ✓ checked checkmark complete completed done fixed tick other symbol symbols pass passing green ok" }, + .{ .glyph = "☑️", .name = "check box with check", .keywords = "check box with ✓ ballot checked done off tick other symbol symbols" }, + .{ .glyph = "✔️", .name = "check mark", .keywords = "check mark ✓ checked checkmark done heavy tick other symbol symbols" }, + .{ .glyph = "❌", .name = "cross mark", .keywords = "cross mark × cancel multiplication multiply x other symbol symbols fail failing red broken" }, + .{ .glyph = "❎", .name = "cross mark button", .keywords = "cross mark button × multiplication multiply square x other symbol symbols" }, + .{ .glyph = "➰", .name = "curly loop", .keywords = "curly loop curl other symbol symbols" }, + .{ .glyph = "➿", .name = "double curly loop", .keywords = "double curly loop curl other symbol symbols" }, + .{ .glyph = "〽️", .name = "part alternation mark", .keywords = "part alternation mark other symbol symbols" }, + .{ .glyph = "✳️", .name = "eight-spoked asterisk", .keywords = "eight spoked asterisk * other symbol symbols" }, + .{ .glyph = "✴️", .name = "eight-pointed star", .keywords = "eight pointed star * other symbol symbols" }, + .{ .glyph = "❇️", .name = "sparkle", .keywords = "sparkle * other symbol symbols" }, + .{ .glyph = "©️", .name = "copyright", .keywords = "copyright c other symbol symbols" }, + .{ .glyph = "®️", .name = "registered", .keywords = "registered r other symbol symbols" }, + .{ .glyph = "™️", .name = "trade mark", .keywords = "trade mark tm trademark other symbol symbols" }, + .{ .glyph = "🫟", .name = "splatter", .keywords = "splatter drip holi ink liquid mess paint spill stain other symbol symbols" }, + .{ .glyph = "#️⃣", .name = "keycap: #", .keywords = "keycap # symbols" }, + .{ .glyph = "*️⃣", .name = "keycap: *", .keywords = "keycap * symbols" }, + .{ .glyph = "0️⃣", .name = "keycap: 0", .keywords = "keycap 0 zero symbols" }, + .{ .glyph = "1️⃣", .name = "keycap: 1", .keywords = "keycap 1 one symbols" }, + .{ .glyph = "2️⃣", .name = "keycap: 2", .keywords = "keycap 2 two symbols" }, + .{ .glyph = "3️⃣", .name = "keycap: 3", .keywords = "keycap 3 three symbols" }, + .{ .glyph = "4️⃣", .name = "keycap: 4", .keywords = "keycap 4 four symbols" }, + .{ .glyph = "5️⃣", .name = "keycap: 5", .keywords = "keycap 5 five symbols" }, + .{ .glyph = "6️⃣", .name = "keycap: 6", .keywords = "keycap 6 six symbols" }, + .{ .glyph = "7️⃣", .name = "keycap: 7", .keywords = "keycap 7 seven symbols" }, + .{ .glyph = "8️⃣", .name = "keycap: 8", .keywords = "keycap 8 eight symbols" }, + .{ .glyph = "9️⃣", .name = "keycap: 9", .keywords = "keycap 9 nine symbols" }, + .{ .glyph = "🔟", .name = "keycap: 10", .keywords = "keycap 10 symbols" }, + .{ .glyph = "🔠", .name = "input latin uppercase", .keywords = "input latin uppercase abcd letters alphanum symbols" }, + .{ .glyph = "🔡", .name = "input latin lowercase", .keywords = "input latin lowercase abcd letters alphanum symbols" }, + .{ .glyph = "🔢", .name = "input numbers", .keywords = "input numbers 1234 alphanum symbols" }, + .{ .glyph = "🔣", .name = "input symbols", .keywords = "input symbols % ♪ 〒 alphanum" }, + .{ .glyph = "🔤", .name = "input latin letters", .keywords = "input latin letters abc alphabet alphanum symbols" }, + .{ .glyph = "🅰️", .name = "A button (blood type)", .keywords = "a button blood type alphanum symbols" }, + .{ .glyph = "🆎", .name = "AB button (blood type)", .keywords = "ab button blood type alphanum symbols" }, + .{ .glyph = "🅱️", .name = "B button (blood type)", .keywords = "b button blood type alphanum symbols" }, + .{ .glyph = "🆑", .name = "CL button", .keywords = "cl button alphanum symbols" }, + .{ .glyph = "🆒", .name = "COOL button", .keywords = "cool button alphanum symbols" }, + .{ .glyph = "🆓", .name = "FREE button", .keywords = "free button alphanum symbols" }, + .{ .glyph = "ℹ️", .name = "information", .keywords = "information i alphanum symbols" }, + .{ .glyph = "🆔", .name = "ID button", .keywords = "id button identity alphanum symbols" }, + .{ .glyph = "Ⓜ️", .name = "circled M", .keywords = "circled m circle alphanum symbols" }, + .{ .glyph = "🆕", .name = "NEW button", .keywords = "new button alphanum symbols" }, + .{ .glyph = "🆖", .name = "NG button", .keywords = "ng button alphanum symbols" }, + .{ .glyph = "🅾️", .name = "O button (blood type)", .keywords = "o button blood type alphanum symbols" }, + .{ .glyph = "🆗", .name = "OK button", .keywords = "ok button okay alphanum symbols" }, + .{ .glyph = "🅿️", .name = "P button", .keywords = "p button parking alphanum symbols" }, + .{ .glyph = "🆘", .name = "SOS button", .keywords = "sos button help alphanum symbols" }, + .{ .glyph = "🆙", .name = "UP! button", .keywords = "up button mark alphanum symbols" }, + .{ .glyph = "🆚", .name = "VS button", .keywords = "vs button versus alphanum symbols" }, + .{ .glyph = "🈁", .name = "Japanese “here” button", .keywords = "japanese here button katakana alphanum symbols" }, + .{ .glyph = "🈂️", .name = "Japanese “service charge” button", .keywords = "japanese service charge button katakana alphanum symbols" }, + .{ .glyph = "🈷️", .name = "Japanese “monthly amount” button", .keywords = "japanese monthly amount button ideograph alphanum symbols" }, + .{ .glyph = "🈶", .name = "Japanese “not free of charge” button", .keywords = "japanese not free of charge button ideograph alphanum symbols" }, + .{ .glyph = "🈯", .name = "Japanese “reserved” button", .keywords = "japanese reserved button ideograph alphanum symbols" }, + .{ .glyph = "🉐", .name = "Japanese “bargain” button", .keywords = "japanese bargain button ideograph alphanum symbols" }, + .{ .glyph = "🈹", .name = "Japanese “discount” button", .keywords = "japanese discount button ideograph alphanum symbols" }, + .{ .glyph = "🈚", .name = "Japanese “free of charge” button", .keywords = "japanese free of charge button ideograph alphanum symbols" }, + .{ .glyph = "🈲", .name = "Japanese “prohibited” button", .keywords = "japanese prohibited button ideograph alphanum symbols" }, + .{ .glyph = "🉑", .name = "Japanese “acceptable” button", .keywords = "japanese acceptable button ideograph alphanum symbols" }, + .{ .glyph = "🈸", .name = "Japanese “application” button", .keywords = "japanese application button ideograph alphanum symbols" }, + .{ .glyph = "🈴", .name = "Japanese “passing grade” button", .keywords = "japanese passing grade button ideograph alphanum symbols" }, + .{ .glyph = "🈳", .name = "Japanese “vacancy” button", .keywords = "japanese vacancy button ideograph alphanum symbols" }, + .{ .glyph = "㊗️", .name = "Japanese “congratulations” button", .keywords = "japanese congratulations button ideograph alphanum symbols" }, + .{ .glyph = "㊙️", .name = "Japanese “secret” button", .keywords = "japanese secret button ideograph alphanum symbols" }, + .{ .glyph = "🈺", .name = "Japanese “open for business” button", .keywords = "japanese open for business button ideograph alphanum symbols" }, + .{ .glyph = "🈵", .name = "Japanese “no vacancy” button", .keywords = "japanese no vacancy button ideograph alphanum symbols" }, + .{ .glyph = "🔴", .name = "red circle", .keywords = "red circle geometric symbols" }, + .{ .glyph = "🟠", .name = "orange circle", .keywords = "orange circle geometric symbols" }, + .{ .glyph = "🟡", .name = "yellow circle", .keywords = "yellow circle geometric symbols" }, + .{ .glyph = "🟢", .name = "green circle", .keywords = "green circle geometric symbols" }, + .{ .glyph = "🔵", .name = "blue circle", .keywords = "blue circle geometric symbols" }, + .{ .glyph = "🟣", .name = "purple circle", .keywords = "purple circle geometric symbols" }, + .{ .glyph = "🟤", .name = "brown circle", .keywords = "brown circle geometric symbols" }, + .{ .glyph = "⚫", .name = "black circle", .keywords = "black circle geometric symbols" }, + .{ .glyph = "⚪", .name = "white circle", .keywords = "white circle geometric symbols" }, + .{ .glyph = "🟥", .name = "red square", .keywords = "red square card penalty geometric symbols" }, + .{ .glyph = "🟧", .name = "orange square", .keywords = "orange square geometric symbols" }, + .{ .glyph = "🟨", .name = "yellow square", .keywords = "yellow square card penalty geometric symbols" }, + .{ .glyph = "🟩", .name = "green square", .keywords = "green square geometric symbols" }, + .{ .glyph = "🟦", .name = "blue square", .keywords = "blue square geometric symbols" }, + .{ .glyph = "🟪", .name = "purple square", .keywords = "purple square geometric symbols" }, + .{ .glyph = "🟫", .name = "brown square", .keywords = "brown square geometric symbols" }, + .{ .glyph = "⬛", .name = "black large square", .keywords = "black large square geometric symbols" }, + .{ .glyph = "⬜", .name = "white large square", .keywords = "white large square geometric symbols" }, + .{ .glyph = "◼️", .name = "black medium square", .keywords = "black medium square geometric symbols" }, + .{ .glyph = "◻️", .name = "white medium square", .keywords = "white medium square geometric symbols" }, + .{ .glyph = "◾", .name = "black medium-small square", .keywords = "black medium small square geometric symbols" }, + .{ .glyph = "◽", .name = "white medium-small square", .keywords = "white medium small square geometric symbols" }, + .{ .glyph = "▪️", .name = "black small square", .keywords = "black small square geometric symbols" }, + .{ .glyph = "▫️", .name = "white small square", .keywords = "white small square geometric symbols" }, + .{ .glyph = "🔶", .name = "large orange diamond", .keywords = "large orange diamond geometric symbols" }, + .{ .glyph = "🔷", .name = "large blue diamond", .keywords = "large blue diamond geometric symbols" }, + .{ .glyph = "🔸", .name = "small orange diamond", .keywords = "small orange diamond geometric symbols" }, + .{ .glyph = "🔹", .name = "small blue diamond", .keywords = "small blue diamond geometric symbols" }, + .{ .glyph = "🔺", .name = "red triangle pointed up", .keywords = "red triangle pointed up geometric symbols" }, + .{ .glyph = "🔻", .name = "red triangle pointed down", .keywords = "red triangle pointed down geometric symbols" }, + .{ .glyph = "💠", .name = "diamond with a dot", .keywords = "diamond with a dot comic geometric symbols" }, + .{ .glyph = "🔘", .name = "radio button", .keywords = "radio button geometric symbols" }, + .{ .glyph = "🔳", .name = "white square button", .keywords = "white square button geometric outlined symbols" }, + .{ .glyph = "🔲", .name = "black square button", .keywords = "black square button geometric symbols" }, + + // ---- Flags ------------------------------------------------------- + .{ .glyph = "🏁", .name = "chequered flag", .keywords = "chequered flag checkered finish flags game race racing sport win done finished" }, + .{ .glyph = "🚩", .name = "triangular flag", .keywords = "triangular flag construction golf post flags" }, + .{ .glyph = "🎌", .name = "crossed flags", .keywords = "crossed flags celebration cross japanese flag" }, + .{ .glyph = "🏴", .name = "black flag", .keywords = "black flag waving flags" }, + .{ .glyph = "🏳️", .name = "white flag", .keywords = "white flag waving flags" }, + .{ .glyph = "🏳️‍🌈", .name = "rainbow flag", .keywords = "rainbow flag bisexual gay genderqueer glbt glbtq lesbian lgbt lgbtq lgbtqia pride queer trans transgender flags" }, + .{ .glyph = "🏳️‍⚧️", .name = "transgender flag", .keywords = "transgender flag blue light pink white flags" }, + .{ .glyph = "🏴‍☠️", .name = "pirate flag", .keywords = "pirate flag jolly plunder roger treasure flags" }, + .{ .glyph = "🇦🇨", .name = "flag: Ascension Island", .keywords = "flag ascension island country flags" }, + .{ .glyph = "🇦🇩", .name = "flag: Andorra", .keywords = "flag andorra country flags" }, + .{ .glyph = "🇦🇪", .name = "flag: United Arab Emirates", .keywords = "flag united arab emirates country flags" }, + .{ .glyph = "🇦🇫", .name = "flag: Afghanistan", .keywords = "flag afghanistan country flags" }, + .{ .glyph = "🇦🇬", .name = "flag: Antigua & Barbuda", .keywords = "flag antigua barbuda country flags" }, + .{ .glyph = "🇦🇮", .name = "flag: Anguilla", .keywords = "flag anguilla country flags" }, + .{ .glyph = "🇦🇱", .name = "flag: Albania", .keywords = "flag albania country flags" }, + .{ .glyph = "🇦🇲", .name = "flag: Armenia", .keywords = "flag armenia country flags" }, + .{ .glyph = "🇦🇴", .name = "flag: Angola", .keywords = "flag angola country flags" }, + .{ .glyph = "🇦🇶", .name = "flag: Antarctica", .keywords = "flag antarctica country flags" }, + .{ .glyph = "🇦🇷", .name = "flag: Argentina", .keywords = "flag argentina country flags" }, + .{ .glyph = "🇦🇸", .name = "flag: American Samoa", .keywords = "flag american samoa country flags" }, + .{ .glyph = "🇦🇹", .name = "flag: Austria", .keywords = "flag austria country flags" }, + .{ .glyph = "🇦🇺", .name = "flag: Australia", .keywords = "flag australia country flags" }, + .{ .glyph = "🇦🇼", .name = "flag: Aruba", .keywords = "flag aruba country flags" }, + .{ .glyph = "🇦🇽", .name = "flag: Åland Islands", .keywords = "flag åland islands country flags" }, + .{ .glyph = "🇦🇿", .name = "flag: Azerbaijan", .keywords = "flag azerbaijan country flags" }, + .{ .glyph = "🇧🇦", .name = "flag: Bosnia & Herzegovina", .keywords = "flag bosnia herzegovina country flags" }, + .{ .glyph = "🇧🇧", .name = "flag: Barbados", .keywords = "flag barbados country flags" }, + .{ .glyph = "🇧🇩", .name = "flag: Bangladesh", .keywords = "flag bangladesh country flags" }, + .{ .glyph = "🇧🇪", .name = "flag: Belgium", .keywords = "flag belgium country flags" }, + .{ .glyph = "🇧🇫", .name = "flag: Burkina Faso", .keywords = "flag burkina faso country flags" }, + .{ .glyph = "🇧🇬", .name = "flag: Bulgaria", .keywords = "flag bulgaria country flags" }, + .{ .glyph = "🇧🇭", .name = "flag: Bahrain", .keywords = "flag bahrain country flags" }, + .{ .glyph = "🇧🇮", .name = "flag: Burundi", .keywords = "flag burundi country flags" }, + .{ .glyph = "🇧🇯", .name = "flag: Benin", .keywords = "flag benin country flags" }, + .{ .glyph = "🇧🇱", .name = "flag: St. Barthélemy", .keywords = "flag st. barthélemy country flags" }, + .{ .glyph = "🇧🇲", .name = "flag: Bermuda", .keywords = "flag bermuda country flags" }, + .{ .glyph = "🇧🇳", .name = "flag: Brunei", .keywords = "flag brunei country flags" }, + .{ .glyph = "🇧🇴", .name = "flag: Bolivia", .keywords = "flag bolivia country flags" }, + .{ .glyph = "🇧🇶", .name = "flag: Caribbean Netherlands", .keywords = "flag caribbean netherlands country flags" }, + .{ .glyph = "🇧🇷", .name = "flag: Brazil", .keywords = "flag brazil country flags" }, + .{ .glyph = "🇧🇸", .name = "flag: Bahamas", .keywords = "flag bahamas country flags" }, + .{ .glyph = "🇧🇹", .name = "flag: Bhutan", .keywords = "flag bhutan country flags" }, + .{ .glyph = "🇧🇻", .name = "flag: Bouvet Island", .keywords = "flag bouvet island country flags" }, + .{ .glyph = "🇧🇼", .name = "flag: Botswana", .keywords = "flag botswana country flags" }, + .{ .glyph = "🇧🇾", .name = "flag: Belarus", .keywords = "flag belarus country flags" }, + .{ .glyph = "🇧🇿", .name = "flag: Belize", .keywords = "flag belize country flags" }, + .{ .glyph = "🇨🇦", .name = "flag: Canada", .keywords = "flag canada country flags" }, + .{ .glyph = "🇨🇨", .name = "flag: Cocos (Keeling) Islands", .keywords = "flag cocos keeling islands country flags" }, + .{ .glyph = "🇨🇩", .name = "flag: Congo - Kinshasa", .keywords = "flag congo kinshasa country flags" }, + .{ .glyph = "🇨🇫", .name = "flag: Central African Republic", .keywords = "flag central african republic country flags" }, + .{ .glyph = "🇨🇬", .name = "flag: Congo - Brazzaville", .keywords = "flag congo brazzaville country flags" }, + .{ .glyph = "🇨🇭", .name = "flag: Switzerland", .keywords = "flag switzerland country flags" }, + .{ .glyph = "🇨🇮", .name = "flag: Côte d’Ivoire", .keywords = "flag côte d’ivoire country flags" }, + .{ .glyph = "🇨🇰", .name = "flag: Cook Islands", .keywords = "flag cook islands country flags" }, + .{ .glyph = "🇨🇱", .name = "flag: Chile", .keywords = "flag chile country flags" }, + .{ .glyph = "🇨🇲", .name = "flag: Cameroon", .keywords = "flag cameroon country flags" }, + .{ .glyph = "🇨🇳", .name = "flag: China", .keywords = "flag china country flags" }, + .{ .glyph = "🇨🇴", .name = "flag: Colombia", .keywords = "flag colombia country flags" }, + .{ .glyph = "🇨🇵", .name = "flag: Clipperton Island", .keywords = "flag clipperton island country flags" }, + .{ .glyph = "🇨🇶", .name = "flag: Sark", .keywords = "flag sark country flags" }, + .{ .glyph = "🇨🇷", .name = "flag: Costa Rica", .keywords = "flag costa rica country flags" }, + .{ .glyph = "🇨🇺", .name = "flag: Cuba", .keywords = "flag cuba country flags" }, + .{ .glyph = "🇨🇻", .name = "flag: Cape Verde", .keywords = "flag cape verde country flags" }, + .{ .glyph = "🇨🇼", .name = "flag: Curaçao", .keywords = "flag curaçao country flags" }, + .{ .glyph = "🇨🇽", .name = "flag: Christmas Island", .keywords = "flag christmas island country flags" }, + .{ .glyph = "🇨🇾", .name = "flag: Cyprus", .keywords = "flag cyprus country flags" }, + .{ .glyph = "🇨🇿", .name = "flag: Czechia", .keywords = "flag czechia country flags" }, + .{ .glyph = "🇩🇪", .name = "flag: Germany", .keywords = "flag germany country flags" }, + .{ .glyph = "🇩🇬", .name = "flag: Diego Garcia", .keywords = "flag diego garcia country flags" }, + .{ .glyph = "🇩🇯", .name = "flag: Djibouti", .keywords = "flag djibouti country flags" }, + .{ .glyph = "🇩🇰", .name = "flag: Denmark", .keywords = "flag denmark country flags" }, + .{ .glyph = "🇩🇲", .name = "flag: Dominica", .keywords = "flag dominica country flags" }, + .{ .glyph = "🇩🇴", .name = "flag: Dominican Republic", .keywords = "flag dominican republic country flags" }, + .{ .glyph = "🇩🇿", .name = "flag: Algeria", .keywords = "flag algeria country flags" }, + .{ .glyph = "🇪🇦", .name = "flag: Ceuta & Melilla", .keywords = "flag ceuta melilla country flags" }, + .{ .glyph = "🇪🇨", .name = "flag: Ecuador", .keywords = "flag ecuador country flags" }, + .{ .glyph = "🇪🇪", .name = "flag: Estonia", .keywords = "flag estonia country flags" }, + .{ .glyph = "🇪🇬", .name = "flag: Egypt", .keywords = "flag egypt country flags" }, + .{ .glyph = "🇪🇭", .name = "flag: Western Sahara", .keywords = "flag western sahara country flags" }, + .{ .glyph = "🇪🇷", .name = "flag: Eritrea", .keywords = "flag eritrea country flags" }, + .{ .glyph = "🇪🇸", .name = "flag: Spain", .keywords = "flag spain country flags" }, + .{ .glyph = "🇪🇹", .name = "flag: Ethiopia", .keywords = "flag ethiopia country flags" }, + .{ .glyph = "🇪🇺", .name = "flag: European Union", .keywords = "flag european union country flags" }, + .{ .glyph = "🇫🇮", .name = "flag: Finland", .keywords = "flag finland country flags" }, + .{ .glyph = "🇫🇯", .name = "flag: Fiji", .keywords = "flag fiji country flags" }, + .{ .glyph = "🇫🇰", .name = "flag: Falkland Islands", .keywords = "flag falkland islands country flags" }, + .{ .glyph = "🇫🇲", .name = "flag: Micronesia", .keywords = "flag micronesia country flags" }, + .{ .glyph = "🇫🇴", .name = "flag: Faroe Islands", .keywords = "flag faroe islands country flags" }, + .{ .glyph = "🇫🇷", .name = "flag: France", .keywords = "flag france country flags" }, + .{ .glyph = "🇬🇦", .name = "flag: Gabon", .keywords = "flag gabon country flags" }, + .{ .glyph = "🇬🇧", .name = "flag: United Kingdom", .keywords = "flag united kingdom country flags" }, + .{ .glyph = "🇬🇩", .name = "flag: Grenada", .keywords = "flag grenada country flags" }, + .{ .glyph = "🇬🇪", .name = "flag: Georgia", .keywords = "flag georgia country flags" }, + .{ .glyph = "🇬🇫", .name = "flag: French Guiana", .keywords = "flag french guiana country flags" }, + .{ .glyph = "🇬🇬", .name = "flag: Guernsey", .keywords = "flag guernsey country flags" }, + .{ .glyph = "🇬🇭", .name = "flag: Ghana", .keywords = "flag ghana country flags" }, + .{ .glyph = "🇬🇮", .name = "flag: Gibraltar", .keywords = "flag gibraltar country flags" }, + .{ .glyph = "🇬🇱", .name = "flag: Greenland", .keywords = "flag greenland country flags" }, + .{ .glyph = "🇬🇲", .name = "flag: Gambia", .keywords = "flag gambia country flags" }, + .{ .glyph = "🇬🇳", .name = "flag: Guinea", .keywords = "flag guinea country flags" }, + .{ .glyph = "🇬🇵", .name = "flag: Guadeloupe", .keywords = "flag guadeloupe country flags" }, + .{ .glyph = "🇬🇶", .name = "flag: Equatorial Guinea", .keywords = "flag equatorial guinea country flags" }, + .{ .glyph = "🇬🇷", .name = "flag: Greece", .keywords = "flag greece country flags" }, + .{ .glyph = "🇬🇸", .name = "flag: South Georgia & South Sandwich Islands", .keywords = "flag south georgia sandwich islands country flags" }, + .{ .glyph = "🇬🇹", .name = "flag: Guatemala", .keywords = "flag guatemala country flags" }, + .{ .glyph = "🇬🇺", .name = "flag: Guam", .keywords = "flag guam country flags" }, + .{ .glyph = "🇬🇼", .name = "flag: Guinea-Bissau", .keywords = "flag guinea bissau country flags" }, + .{ .glyph = "🇬🇾", .name = "flag: Guyana", .keywords = "flag guyana country flags" }, + .{ .glyph = "🇭🇰", .name = "flag: Hong Kong SAR China", .keywords = "flag hong kong sar china country flags" }, + .{ .glyph = "🇭🇲", .name = "flag: Heard Island & McDonald Islands", .keywords = "flag heard island mcdonald islands country flags" }, + .{ .glyph = "🇭🇳", .name = "flag: Honduras", .keywords = "flag honduras country flags" }, + .{ .glyph = "🇭🇷", .name = "flag: Croatia", .keywords = "flag croatia country flags" }, + .{ .glyph = "🇭🇹", .name = "flag: Haiti", .keywords = "flag haiti country flags" }, + .{ .glyph = "🇭🇺", .name = "flag: Hungary", .keywords = "flag hungary country flags" }, + .{ .glyph = "🇮🇨", .name = "flag: Canary Islands", .keywords = "flag canary islands country flags" }, + .{ .glyph = "🇮🇩", .name = "flag: Indonesia", .keywords = "flag indonesia country flags" }, + .{ .glyph = "🇮🇪", .name = "flag: Ireland", .keywords = "flag ireland country flags" }, + .{ .glyph = "🇮🇱", .name = "flag: Israel", .keywords = "flag israel country flags" }, + .{ .glyph = "🇮🇲", .name = "flag: Isle of Man", .keywords = "flag isle of man country flags" }, + .{ .glyph = "🇮🇳", .name = "flag: India", .keywords = "flag india country flags" }, + .{ .glyph = "🇮🇴", .name = "flag: British Indian Ocean Territory", .keywords = "flag british indian ocean territory country flags" }, + .{ .glyph = "🇮🇶", .name = "flag: Iraq", .keywords = "flag iraq country flags" }, + .{ .glyph = "🇮🇷", .name = "flag: Iran", .keywords = "flag iran country flags" }, + .{ .glyph = "🇮🇸", .name = "flag: Iceland", .keywords = "flag iceland country flags" }, + .{ .glyph = "🇮🇹", .name = "flag: Italy", .keywords = "flag italy country flags" }, + .{ .glyph = "🇯🇪", .name = "flag: Jersey", .keywords = "flag jersey country flags" }, + .{ .glyph = "🇯🇲", .name = "flag: Jamaica", .keywords = "flag jamaica country flags" }, + .{ .glyph = "🇯🇴", .name = "flag: Jordan", .keywords = "flag jordan country flags" }, + .{ .glyph = "🇯🇵", .name = "flag: Japan", .keywords = "flag japan country flags" }, + .{ .glyph = "🇰🇪", .name = "flag: Kenya", .keywords = "flag kenya country flags" }, + .{ .glyph = "🇰🇬", .name = "flag: Kyrgyzstan", .keywords = "flag kyrgyzstan country flags" }, + .{ .glyph = "🇰🇭", .name = "flag: Cambodia", .keywords = "flag cambodia country flags" }, + .{ .glyph = "🇰🇮", .name = "flag: Kiribati", .keywords = "flag kiribati country flags" }, + .{ .glyph = "🇰🇲", .name = "flag: Comoros", .keywords = "flag comoros country flags" }, + .{ .glyph = "🇰🇳", .name = "flag: St. Kitts & Nevis", .keywords = "flag st. kitts nevis country flags" }, + .{ .glyph = "🇰🇵", .name = "flag: North Korea", .keywords = "flag north korea country flags" }, + .{ .glyph = "🇰🇷", .name = "flag: South Korea", .keywords = "flag south korea country flags" }, + .{ .glyph = "🇰🇼", .name = "flag: Kuwait", .keywords = "flag kuwait country flags" }, + .{ .glyph = "🇰🇾", .name = "flag: Cayman Islands", .keywords = "flag cayman islands country flags" }, + .{ .glyph = "🇰🇿", .name = "flag: Kazakhstan", .keywords = "flag kazakhstan country flags" }, + .{ .glyph = "🇱🇦", .name = "flag: Laos", .keywords = "flag laos country flags" }, + .{ .glyph = "🇱🇧", .name = "flag: Lebanon", .keywords = "flag lebanon country flags" }, + .{ .glyph = "🇱🇨", .name = "flag: St. Lucia", .keywords = "flag st. lucia country flags" }, + .{ .glyph = "🇱🇮", .name = "flag: Liechtenstein", .keywords = "flag liechtenstein country flags" }, + .{ .glyph = "🇱🇰", .name = "flag: Sri Lanka", .keywords = "flag sri lanka country flags" }, + .{ .glyph = "🇱🇷", .name = "flag: Liberia", .keywords = "flag liberia country flags" }, + .{ .glyph = "🇱🇸", .name = "flag: Lesotho", .keywords = "flag lesotho country flags" }, + .{ .glyph = "🇱🇹", .name = "flag: Lithuania", .keywords = "flag lithuania country flags" }, + .{ .glyph = "🇱🇺", .name = "flag: Luxembourg", .keywords = "flag luxembourg country flags" }, + .{ .glyph = "🇱🇻", .name = "flag: Latvia", .keywords = "flag latvia country flags" }, + .{ .glyph = "🇱🇾", .name = "flag: Libya", .keywords = "flag libya country flags" }, + .{ .glyph = "🇲🇦", .name = "flag: Morocco", .keywords = "flag morocco country flags" }, + .{ .glyph = "🇲🇨", .name = "flag: Monaco", .keywords = "flag monaco country flags" }, + .{ .glyph = "🇲🇩", .name = "flag: Moldova", .keywords = "flag moldova country flags" }, + .{ .glyph = "🇲🇪", .name = "flag: Montenegro", .keywords = "flag montenegro country flags" }, + .{ .glyph = "🇲🇫", .name = "flag: St. Martin", .keywords = "flag st. martin country flags" }, + .{ .glyph = "🇲🇬", .name = "flag: Madagascar", .keywords = "flag madagascar country flags" }, + .{ .glyph = "🇲🇭", .name = "flag: Marshall Islands", .keywords = "flag marshall islands country flags" }, + .{ .glyph = "🇲🇰", .name = "flag: North Macedonia", .keywords = "flag north macedonia country flags" }, + .{ .glyph = "🇲🇱", .name = "flag: Mali", .keywords = "flag mali country flags" }, + .{ .glyph = "🇲🇲", .name = "flag: Myanmar (Burma)", .keywords = "flag myanmar burma country flags" }, + .{ .glyph = "🇲🇳", .name = "flag: Mongolia", .keywords = "flag mongolia country flags" }, + .{ .glyph = "🇲🇴", .name = "flag: Macao SAR China", .keywords = "flag macao sar china country flags" }, + .{ .glyph = "🇲🇵", .name = "flag: Northern Mariana Islands", .keywords = "flag northern mariana islands country flags" }, + .{ .glyph = "🇲🇶", .name = "flag: Martinique", .keywords = "flag martinique country flags" }, + .{ .glyph = "🇲🇷", .name = "flag: Mauritania", .keywords = "flag mauritania country flags" }, + .{ .glyph = "🇲🇸", .name = "flag: Montserrat", .keywords = "flag montserrat country flags" }, + .{ .glyph = "🇲🇹", .name = "flag: Malta", .keywords = "flag malta country flags" }, + .{ .glyph = "🇲🇺", .name = "flag: Mauritius", .keywords = "flag mauritius country flags" }, + .{ .glyph = "🇲🇻", .name = "flag: Maldives", .keywords = "flag maldives country flags" }, + .{ .glyph = "🇲🇼", .name = "flag: Malawi", .keywords = "flag malawi country flags" }, + .{ .glyph = "🇲🇽", .name = "flag: Mexico", .keywords = "flag mexico country flags" }, + .{ .glyph = "🇲🇾", .name = "flag: Malaysia", .keywords = "flag malaysia country flags" }, + .{ .glyph = "🇲🇿", .name = "flag: Mozambique", .keywords = "flag mozambique country flags" }, + .{ .glyph = "🇳🇦", .name = "flag: Namibia", .keywords = "flag namibia country flags" }, + .{ .glyph = "🇳🇨", .name = "flag: New Caledonia", .keywords = "flag new caledonia country flags" }, + .{ .glyph = "🇳🇪", .name = "flag: Niger", .keywords = "flag niger country flags" }, + .{ .glyph = "🇳🇫", .name = "flag: Norfolk Island", .keywords = "flag norfolk island country flags" }, + .{ .glyph = "🇳🇬", .name = "flag: Nigeria", .keywords = "flag nigeria country flags" }, + .{ .glyph = "🇳🇮", .name = "flag: Nicaragua", .keywords = "flag nicaragua country flags" }, + .{ .glyph = "🇳🇱", .name = "flag: Netherlands", .keywords = "flag netherlands country flags" }, + .{ .glyph = "🇳🇴", .name = "flag: Norway", .keywords = "flag norway country flags" }, + .{ .glyph = "🇳🇵", .name = "flag: Nepal", .keywords = "flag nepal country flags" }, + .{ .glyph = "🇳🇷", .name = "flag: Nauru", .keywords = "flag nauru country flags" }, + .{ .glyph = "🇳🇺", .name = "flag: Niue", .keywords = "flag niue country flags" }, + .{ .glyph = "🇳🇿", .name = "flag: New Zealand", .keywords = "flag new zealand country flags" }, + .{ .glyph = "🇴🇲", .name = "flag: Oman", .keywords = "flag oman country flags" }, + .{ .glyph = "🇵🇦", .name = "flag: Panama", .keywords = "flag panama country flags" }, + .{ .glyph = "🇵🇪", .name = "flag: Peru", .keywords = "flag peru country flags" }, + .{ .glyph = "🇵🇫", .name = "flag: French Polynesia", .keywords = "flag french polynesia country flags" }, + .{ .glyph = "🇵🇬", .name = "flag: Papua New Guinea", .keywords = "flag papua new guinea country flags" }, + .{ .glyph = "🇵🇭", .name = "flag: Philippines", .keywords = "flag philippines country flags" }, + .{ .glyph = "🇵🇰", .name = "flag: Pakistan", .keywords = "flag pakistan country flags" }, + .{ .glyph = "🇵🇱", .name = "flag: Poland", .keywords = "flag poland country flags" }, + .{ .glyph = "🇵🇲", .name = "flag: St. Pierre & Miquelon", .keywords = "flag st. pierre miquelon country flags" }, + .{ .glyph = "🇵🇳", .name = "flag: Pitcairn Islands", .keywords = "flag pitcairn islands country flags" }, + .{ .glyph = "🇵🇷", .name = "flag: Puerto Rico", .keywords = "flag puerto rico country flags" }, + .{ .glyph = "🇵🇸", .name = "flag: Palestinian Territories", .keywords = "flag palestinian territories country flags" }, + .{ .glyph = "🇵🇹", .name = "flag: Portugal", .keywords = "flag portugal country flags" }, + .{ .glyph = "🇵🇼", .name = "flag: Palau", .keywords = "flag palau country flags" }, + .{ .glyph = "🇵🇾", .name = "flag: Paraguay", .keywords = "flag paraguay country flags" }, + .{ .glyph = "🇶🇦", .name = "flag: Qatar", .keywords = "flag qatar country flags" }, + .{ .glyph = "🇷🇪", .name = "flag: Réunion", .keywords = "flag réunion country flags" }, + .{ .glyph = "🇷🇴", .name = "flag: Romania", .keywords = "flag romania country flags" }, + .{ .glyph = "🇷🇸", .name = "flag: Serbia", .keywords = "flag serbia country flags" }, + .{ .glyph = "🇷🇺", .name = "flag: Russia", .keywords = "flag russia country flags" }, + .{ .glyph = "🇷🇼", .name = "flag: Rwanda", .keywords = "flag rwanda country flags" }, + .{ .glyph = "🇸🇦", .name = "flag: Saudi Arabia", .keywords = "flag saudi arabia country flags" }, + .{ .glyph = "🇸🇧", .name = "flag: Solomon Islands", .keywords = "flag solomon islands country flags" }, + .{ .glyph = "🇸🇨", .name = "flag: Seychelles", .keywords = "flag seychelles country flags" }, + .{ .glyph = "🇸🇩", .name = "flag: Sudan", .keywords = "flag sudan country flags" }, + .{ .glyph = "🇸🇪", .name = "flag: Sweden", .keywords = "flag sweden country flags" }, + .{ .glyph = "🇸🇬", .name = "flag: Singapore", .keywords = "flag singapore country flags" }, + .{ .glyph = "🇸🇭", .name = "flag: St. Helena, Ascension & Tristan da Cunha", .keywords = "flag st. helena ascension tristan da cunha country flags" }, + .{ .glyph = "🇸🇮", .name = "flag: Slovenia", .keywords = "flag slovenia country flags" }, + .{ .glyph = "🇸🇯", .name = "flag: Svalbard & Jan Mayen", .keywords = "flag svalbard jan mayen country flags" }, + .{ .glyph = "🇸🇰", .name = "flag: Slovakia", .keywords = "flag slovakia country flags" }, + .{ .glyph = "🇸🇱", .name = "flag: Sierra Leone", .keywords = "flag sierra leone country flags" }, + .{ .glyph = "🇸🇲", .name = "flag: San Marino", .keywords = "flag san marino country flags" }, + .{ .glyph = "🇸🇳", .name = "flag: Senegal", .keywords = "flag senegal country flags" }, + .{ .glyph = "🇸🇴", .name = "flag: Somalia", .keywords = "flag somalia country flags" }, + .{ .glyph = "🇸🇷", .name = "flag: Suriname", .keywords = "flag suriname country flags" }, + .{ .glyph = "🇸🇸", .name = "flag: South Sudan", .keywords = "flag south sudan country flags" }, + .{ .glyph = "🇸🇹", .name = "flag: São Tomé & Príncipe", .keywords = "flag são tomé príncipe country flags" }, + .{ .glyph = "🇸🇻", .name = "flag: El Salvador", .keywords = "flag el salvador country flags" }, + .{ .glyph = "🇸🇽", .name = "flag: Sint Maarten", .keywords = "flag sint maarten country flags" }, + .{ .glyph = "🇸🇾", .name = "flag: Syria", .keywords = "flag syria country flags" }, + .{ .glyph = "🇸🇿", .name = "flag: Eswatini", .keywords = "flag eswatini country flags" }, + .{ .glyph = "🇹🇦", .name = "flag: Tristan da Cunha", .keywords = "flag tristan da cunha country flags" }, + .{ .glyph = "🇹🇨", .name = "flag: Turks & Caicos Islands", .keywords = "flag turks caicos islands country flags" }, + .{ .glyph = "🇹🇩", .name = "flag: Chad", .keywords = "flag chad country flags" }, + .{ .glyph = "🇹🇫", .name = "flag: French Southern and Antarctic Lands", .keywords = "flag french southern and antarctic lands country flags" }, + .{ .glyph = "🇹🇬", .name = "flag: Togo", .keywords = "flag togo country flags" }, + .{ .glyph = "🇹🇭", .name = "flag: Thailand", .keywords = "flag thailand country flags" }, + .{ .glyph = "🇹🇯", .name = "flag: Tajikistan", .keywords = "flag tajikistan country flags" }, + .{ .glyph = "🇹🇰", .name = "flag: Tokelau", .keywords = "flag tokelau country flags" }, + .{ .glyph = "🇹🇱", .name = "flag: Timor-Leste", .keywords = "flag timor leste country flags" }, + .{ .glyph = "🇹🇲", .name = "flag: Turkmenistan", .keywords = "flag turkmenistan country flags" }, + .{ .glyph = "🇹🇳", .name = "flag: Tunisia", .keywords = "flag tunisia country flags" }, + .{ .glyph = "🇹🇴", .name = "flag: Tonga", .keywords = "flag tonga country flags" }, + .{ .glyph = "🇹🇷", .name = "flag: Türkiye", .keywords = "flag türkiye country flags" }, + .{ .glyph = "🇹🇹", .name = "flag: Trinidad & Tobago", .keywords = "flag trinidad tobago country flags" }, + .{ .glyph = "🇹🇻", .name = "flag: Tuvalu", .keywords = "flag tuvalu country flags" }, + .{ .glyph = "🇹🇼", .name = "flag: Taiwan", .keywords = "flag taiwan country flags" }, + .{ .glyph = "🇹🇿", .name = "flag: Tanzania", .keywords = "flag tanzania country flags" }, + .{ .glyph = "🇺🇦", .name = "flag: Ukraine", .keywords = "flag ukraine country flags" }, + .{ .glyph = "🇺🇬", .name = "flag: Uganda", .keywords = "flag uganda country flags" }, + .{ .glyph = "🇺🇲", .name = "flag: U.S. Outlying Islands", .keywords = "flag u.s. outlying islands country flags" }, + .{ .glyph = "🇺🇳", .name = "flag: United Nations", .keywords = "flag united nations country flags" }, + .{ .glyph = "🇺🇸", .name = "flag: United States", .keywords = "flag united states country flags" }, + .{ .glyph = "🇺🇾", .name = "flag: Uruguay", .keywords = "flag uruguay country flags" }, + .{ .glyph = "🇺🇿", .name = "flag: Uzbekistan", .keywords = "flag uzbekistan country flags" }, + .{ .glyph = "🇻🇦", .name = "flag: Vatican City", .keywords = "flag vatican city country flags" }, + .{ .glyph = "🇻🇨", .name = "flag: St. Vincent & Grenadines", .keywords = "flag st. vincent grenadines country flags" }, + .{ .glyph = "🇻🇪", .name = "flag: Venezuela", .keywords = "flag venezuela country flags" }, + .{ .glyph = "🇻🇬", .name = "flag: British Virgin Islands", .keywords = "flag british virgin islands country flags" }, + .{ .glyph = "🇻🇮", .name = "flag: U.S. Virgin Islands", .keywords = "flag u.s. virgin islands country flags" }, + .{ .glyph = "🇻🇳", .name = "flag: Vietnam", .keywords = "flag vietnam country flags" }, + .{ .glyph = "🇻🇺", .name = "flag: Vanuatu", .keywords = "flag vanuatu country flags" }, + .{ .glyph = "🇼🇫", .name = "flag: Wallis & Futuna", .keywords = "flag wallis futuna country flags" }, + .{ .glyph = "🇼🇸", .name = "flag: Samoa", .keywords = "flag samoa country flags" }, + .{ .glyph = "🇽🇰", .name = "flag: Kosovo", .keywords = "flag kosovo country flags" }, + .{ .glyph = "🇾🇪", .name = "flag: Yemen", .keywords = "flag yemen country flags" }, + .{ .glyph = "🇾🇹", .name = "flag: Mayotte", .keywords = "flag mayotte country flags" }, + .{ .glyph = "🇿🇦", .name = "flag: South Africa", .keywords = "flag south africa country flags" }, + .{ .glyph = "🇿🇲", .name = "flag: Zambia", .keywords = "flag zambia country flags" }, + .{ .glyph = "🇿🇼", .name = "flag: Zimbabwe", .keywords = "flag zimbabwe country flags" }, + .{ .glyph = "🏴󠁧󠁢󠁥󠁮󠁧󠁿", .name = "flag: England", .keywords = "flag england subdivision flags" }, + .{ .glyph = "🏴󠁧󠁢󠁳󠁣󠁴󠁿", .name = "flag: Scotland", .keywords = "flag scotland subdivision flags" }, + .{ .glyph = "🏴󠁧󠁢󠁷󠁬󠁳󠁿", .name = "flag: Wales", .keywords = "flag wales subdivision flags" }, +}; + +// ------------------------------------------------------------------------- +// Tests +// +// The generator is what keeps the table right; these are the properties the +// picker depends on it having. They run against whatever is checked in, so a +// bad regeneration fails here rather than in the dialog. + +test "every entry is usable" { + for (table) |entry| { + try std.testing.expect(entry.glyph.len > 0); + try std.testing.expect(std.unicode.utf8ValidateSlice(entry.glyph)); + + // Long enough for the longest RGI sequence, short enough that nothing + // here is quietly a whole word. + try std.testing.expect(entry.glyph.len <= 40); + + try std.testing.expect(entry.name.len > 0); + try std.testing.expect(std.unicode.utf8ValidateSlice(entry.name)); + + try std.testing.expect(entry.keywords.len > 0); + for (entry.keywords) |c| try std.testing.expect(!std.ascii.isUpper(c)); + } +} + +test "glyphs are distinct" { + // A child's position in the picker's grid is how the dialog names the entry + // it shows, and `indexOf` maps the other way by comparing glyphs. Both stop + // being true if a glyph appears twice. + for (table, 0..) |entry, i| { + for (table[i + 1 ..]) |other| { + try std.testing.expect(!std.mem.eql(u8, entry.glyph, other.glyph)); + } + } +} + +test "the whole set is here" { + // Unicode 17 has 1914 RGI emoji once skin-tone variants are folded away. + // A table that has drifted far from that has lost a group. + try std.testing.expect(table.len > 1800); +} + +/// The one entry a search test leans on, looked up rather than indexed so that +/// regenerating the table doesn't rewrite the tests. +fn find(glyph: []const u8) Emoji { + for (table) |entry| { + if (std.mem.eql(u8, entry.glyph, glyph)) return entry; + } + unreachable; +} + +test "an empty query matches everything" { + for (table) |entry| { + try std.testing.expect(matches(entry, "")); + try std.testing.expect(matches(entry, " ")); + } +} + +test "a term matches part of a keyword, in any case" { + const rocket = find("\u{1F680}"); + try std.testing.expect(matches(rocket, "rocket")); + try std.testing.expect(matches(rocket, "ROCKET")); + try std.testing.expect(matches(rocket, "Rock")); + try std.testing.expect(!matches(rocket, "banana")); +} + +test "every term has to match, in any order" { + const green = find("\u{1F7E2}"); + try std.testing.expect(matches(green, "green circle")); + try std.testing.expect(matches(green, "circle green")); + try std.testing.expect(matches(green, " green circle ")); + + // The second term is what rules the other circles out. + const red = find("\u{1F534}"); + try std.testing.expect(matches(red, "circle")); + try std.testing.expect(!matches(red, "green circle")); + + // And a term matching nothing rules out a glyph the rest of the query hit. + try std.testing.expect(!matches(green, "green circle sideways")); +} + +test "names are the phrase, not the keyword list" { + // What separates the two fields: the tooltip stays short enough to read. + for (table) |entry| try std.testing.expect(entry.name.len <= 64); + + try std.testing.expectEqualStrings("red apple", find("\u{1F34E}").name); + try std.testing.expectEqualStrings("rocket", find("\u{1F680}").name); +} + +test "CLDR keywords reach a glyph its name would not" { + try std.testing.expect(matches(find("\u{1F600}"), "grin")); + try std.testing.expect(matches(find("\u{1F60A}"), "blush")); + try std.testing.expect(matches(find("\u{1F4A9}"), "poop")); +} + +test "a group or subgroup brings back its whole shelf" { + try std.testing.expect(matches(find("\u{1F34E}"), "fruit")); + try std.testing.expect(matches(find("\u{1F1FA}\u{1F1F8}"), "flags")); + try std.testing.expect(matches(find("\u{2B06}\u{FE0F}"), "arrow")); +} + +test "synonyms reach the glyph the data would not" { + try std.testing.expect(matches(find("\u{1F680}"), "deploy")); + try std.testing.expect(matches(find("\u{1FA79}"), "hotfix")); + try std.testing.expect(matches(find("\u{1F433}"), "docker")); + try std.testing.expect(matches(find("\u{1F427}"), "linux")); + try std.testing.expect(matches(find("\u{1F980}"), "rust")); + try std.testing.expect(matches(find("\u{2705}"), "pass")); +} diff --git a/src/style.css b/src/style.css index db8a80a..4ccf7c6 100644 --- a/src/style.css +++ b/src/style.css @@ -119,6 +119,17 @@ button.playpen-header-button:hover, color: @pp_accent_strong; } +/* An emoji standing in for that icon. Sized to the width the icon occupies + rather than left to the glyph, so a sidebar mixing emoji rows with icon rows + still starts every label in the same column — emoji vary in advance width and + without this the labels beside them would step in and out by a pixel or two + per row. The font size is a little under the icon's 16px because a colour + glyph fills its box where a symbolic icon leaves air around itself. */ +.playpen-tab-emoji { + min-width: 16px; + font-size: 13px; +} + /* State on the row itself, not just on its dot. A bar down the leading edge and a wash behind the whole row, both in the @@ -307,6 +318,19 @@ button.playpen-header-button:hover, min-width: 220px; } +/* The row's right-click menu. Narrower than the rename popover and with tighter + padding: it holds two words per line, and a menu sized like a form reads as + though something failed to fill it. */ +.playpen-row-menu { + padding: 4px; + min-width: 150px; +} + +.playpen-row-menu > button { + padding: 5px 8px; + border-radius: 6px; +} + /* A web pane's navigation bar, below the pane header. Kept visually quieter than the header so the two rows don't compete. */ .playpen-nav { @@ -521,6 +545,70 @@ button.playpen-header-button:hover, border-color: @pp_accent_strong; } +/* ------------------------------------------------------------------------- + The emoji picker + + A tab's chosen glyph, then a search box over a grid of every glyph on offer. + The grid is a GtkFlowBox, so each cell is a `flowboxchild` wrapping a label + and the hover and selection states have to be drawn here — Adwaita styles a + flow box for lists of cards, which at this size leaves the cells looking like + nothing in particular. */ + +/* The current choice, big enough to check from across the dialog. Boxed to the + same square whether it holds a glyph or the word "None", so switching between + them doesn't shift the text beside it. */ +.playpen-emoji-preview { + min-width: 44px; + min-height: 44px; + font-size: 26px; + border: 1px solid @pp_border; + border-radius: 10px; + background-color: @pp_surface; +} + +.playpen-emoji-preview-none { + font-size: 0.85em; + color: @pp_text_faint; +} + +/* Sunk into the dialog rather than raised off it: the grid is a well you look + into, and the section card it sits in is already the raised surface. */ +.playpen-emoji-scroller { + border: 1px solid @pp_border; + border-radius: 10px; + background-color: @pp_surface; +} + +.playpen-emoji-grid { + padding: 6px; + background: none; +} + +.playpen-emoji-cell { + font-size: 19px; +} + +.playpen-emoji-grid > flowboxchild { + padding: 0; + border-radius: 8px; + background: none; + transition: background-color 100ms ease; +} + +.playpen-emoji-grid > flowboxchild:hover { + background-color: @pp_row_hover; +} + +/* The glyph in force. `background-image: none` for the same reason as the theme + buttons above: Adwaita paints selection with a gradient over the colour, and + without this the accent comes out washed. */ +.playpen-emoji-grid > flowboxchild:selected, +.playpen-emoji-grid > flowboxchild:selected:backdrop { + background-color: @pp_accent_muted; + background-image: none; + box-shadow: inset 0 0 0 1px @pp_accent; +} + /* Divider between panes. Wide enough to grab without hunting for it. */ .playpen-view paned > separator { background-color: @pp_bg; diff --git a/tools/gen-emoji.py b/tools/gen-emoji.py new file mode 100755 index 0000000..03afd91 --- /dev/null +++ b/tools/gen-emoji.py @@ -0,0 +1,509 @@ +#!/usr/bin/env python3 +"""Regenerate src/emoji.zig from Unicode and CLDR data. + + tools/gen-emoji.py # fetch the data, write src/emoji.zig + tools/gen-emoji.py --check # fail if the checked-in file is stale + tools/gen-emoji.py --emoji-test PATH --annotations PATH --derived PATH + +The table it writes is committed, so this runs by hand rather than as part of +the build: a build that needs the network to compile is a build that fails on a +train. Re-run it when a new Unicode version lands, or when you want to add a +synonym to SYNONYMS below. + +Three inputs, all canonical: + + emoji-test.txt Unicode's own ordering, grouped and subgrouped, with + the fully-qualified form of every RGI emoji. This is + what every emoji keyboard is laid out from. + annotations/en.xml CLDR's English keywords per emoji — the synonyms that + make search work ("grin" finding the grinning face). + annotationsDerived/en.xml + The same for sequences CLDR derives rather than names + outright, which is most of the ZWJ ones. + +Skin-tone variants are left out. Unicode lists 3944 fully-qualified emoji and +just over half of those are the same gesture five more times; a grid of them is +harder to look through, not more complete. Every base glyph is present, which +is the same choice GTK's own emoji chooser, iOS and Slack all make. + +So is anything newer than MAX_VERSION. Colour emoji fonts trail Unicode by a +year or two, and a glyph the font has never heard of draws as a hex-digit box — +which in a picker reads as a bug rather than as a font that needs updating. At +the time of writing, Noto Color Emoji could draw all but 7 of the E17.0 +additions and everything older. Raise MAX_VERSION when fonts have caught up; +`--max-version 99` turns the cutoff off entirely. +""" + +import argparse +import collections +import os +import re +import sys +import urllib.request + +# "latest" rather than a pinned version: the per-version directories under +# /Public/emoji/ stop being published once a version ships, so a pinned URL is +# one that 404s later. What version "latest" turned out to be is recorded in the +# generated file's header, and MAX_VERSION below is what actually decides the +# contents. +EMOJI_TEST = "https://unicode.org/Public/emoji/latest/emoji-test.txt" +ANNOTATIONS = "https://raw.githubusercontent.com/unicode-org/cldr/main/common/annotations/en.xml" +DERIVED = "https://raw.githubusercontent.com/unicode-org/cldr/main/common/annotationsDerived/en.xml" + +# Terms no data file will ever give you: what a glyph means to someone labelling +# a terminal tab. CLDR knows a rocket is a "space ship"; it does not know it is +# what you reach for when the tab is a deploy. +SYNONYMS = { + "🚀": "deploy ship launch release", + "📦": "release bundle package ship artifact", + "🏷️": "version tag release", + "🎉": "ship shipped release celebrate tada", + "🐛": "bug issue defect regression", + "🩹": "hotfix patch bandaid", + "🔥": "hot lit onfire urgent", + "💥": "crash boom broke", + "💀": "dead deprecated killed", + "🦖": "legacy ancient", + "⚡": "zap fast perf quick", + "⏱️": "benchmark perf timing latency", + "🧪": "test experiment trial", + "🧫": "test lab", + "🔬": "inspect investigate research", + "🔍": "search find grep lookup", + "👀": "review look watch eyes", + "✅": "pass passing green done ok", + "❌": "fail failing red broken", + "⚠️": "warn warning caution", + "🚧": "wip work in progress unfinished", + "🏗️": "wip building scaffolding", + "🧹": "cleanup refactor tidy sweep", + "♻️": "refactor reuse recycle", + "🔄": "sync retry refresh reload", + "🔀": "shuffle random merge", + "⚙️": "settings config gear options", + "🔒": "secure private locked", + "🔓": "public unlocked open", + "🔑": "auth key password access token secret", + "🛡️": "security hardening defense", + "📈": "metrics growth up analytics", + "📉": "metrics down regression analytics", + "📊": "metrics analytics stats dashboard", + "🔔": "alert notification ping", + "🔕": "mute silence snooze", + "💻": "dev code local laptop", + "🖥️": "server desktop box host", + "🗄️": "database storage archive", + "🐳": "docker container whale", + "🐧": "linux tux", + "🦀": "rust cargo", + "🐍": "python", + "🐫": "perl camel", + "☕": "java coffee jvm", + "💎": "ruby gem", + "🐘": "postgres php elephant memory", + "🍎": "apple mac macos", + "🪟": "windows", + "🤖": "bot agent ai automation claude", + "🧑‍💻": "dev developer engineer coding", + "📝": "todo note notes scratch", + "🗑️": "delete trash remove drop", + "🌈": "pride rainbow", + "🎯": "goal target focus", + "🧭": "navigate direction bearings", + "🚦": "ci status pipeline signal", + "🏁": "done finished race", + "🧊": "freeze frozen cold pinned", + "🕸️": "stale abandoned cobweb", + "🧠": "think smart reasoning", +} + +# Nothing in a keyword list should be a word you cannot type. Everything else is +# kept, including the non-ASCII names of places, because a term only has to +# match to be worth carrying. +STRIP = re.compile(r"[\"\\|,:;()\[\]{}!?“”]+") + +SKIN_TONES = range(0x1F3FB, 0x1F400) + +# Newest emoji version to include. See the note at the top of this file. +MAX_VERSION = "16.0" + + +def version_tuple(text): + """"E16.0" or "16" as something comparable. Unknown sorts newest.""" + try: + return tuple(int(p) for p in text.lstrip("Ee").split(".")) + except ValueError: + return (999,) + + +def read(source): + """Contents of a URL or a path, whichever `source` looks like.""" + if source.startswith(("http://", "https://")): + with urllib.request.urlopen(source, timeout=60) as response: + return response.read().decode("utf-8") + with open(source, encoding="utf-8") as handle: + return handle.read() + + +def parse_emoji_test(text, max_version): + """Unicode's list, in Unicode's order: (glyph, group, subgroup, name).""" + out = [] + skipped = [] + group = subgroup = "" + version = "unknown" + + for line in text.splitlines(): + if line.startswith("# Version:"): + version = line.split(":", 1)[1].strip() + continue + if line.startswith("# group:"): + group = line.split(":", 1)[1].strip() + continue + if line.startswith("# subgroup:"): + subgroup = line.split(":", 1)[1].strip() + continue + if not line.strip() or line.startswith("#"): + continue + + codepoints, rest = line.split(";", 1) + status, _, comment = rest.partition("#") + if status.strip() != "fully-qualified": + continue + + points = [int(c, 16) for c in codepoints.split()] + if any(p in SKIN_TONES for p in points): + continue + + # The comment is " E ": the version each sequence + # was introduced in, which is what the font-coverage cutoff reads. + parts = comment.strip().split(" ", 2) + introduced = parts[1] if len(parts) > 1 else "E0" + name = parts[2] if len(parts) > 2 else "" + + if version_tuple(introduced) > version_tuple(max_version): + skipped.append(introduced) + continue + + out.append(("".join(chr(p) for p in points), group, subgroup, name)) + + return version, out, collections.Counter(skipped) + + +def parse_annotations(text): + """CLDR's keywords and short name per emoji, merged into one dict.""" + keywords = {} + names = {} + + for match in re.finditer( + r' type="tts")?>(.*?)', + text, + re.DOTALL, + ): + cp, tts, body = match.group(1), match.group("tts"), match.group(3) + body = ( + body.replace("&", "&") + .replace("<", "<") + .replace(">", ">") + .replace(""", '"') + ) + if tts: + names[cp] = body.strip() + else: + keywords.setdefault(cp, []).extend(p.strip() for p in body.split("|")) + + return keywords, names + + +def escape(text): + """`text` as a Zig string literal body. + + Only the display name needs this. Keywords go through `tokenize`, which + drops every character that would have to be escaped in the first place. + """ + return text.replace("\\", "\\\\").replace('"', '\\"') + + +def tokenize(*phrases): + """Lowercase words from `phrases`, deduplicated, in first-seen order.""" + seen = [] + for phrase in phrases: + if not phrase: + continue + cleaned = STRIP.sub(" ", phrase.replace("-", " ").replace("_", " ")) + for word in cleaned.lower().split(): + # A bare "&" survives group names like "Smileys & Emotion". + if word == "&": + continue + if word not in seen: + seen.append(word) + return seen + + +def build(emoji_test, annotations, derived, max_version): + version, entries, skipped = parse_emoji_test(emoji_test, max_version) + + keywords, names = parse_annotations(annotations) + derived_keywords, derived_names = parse_annotations(derived) + for source, into in ((derived_keywords, keywords), (derived_names, names)): + for cp, value in source.items(): + if cp not in into: + into[cp] = value + + rows = [] + for glyph, group, subgroup, name in entries: + # CLDR keys on the emoji without its presentation selector as often as + # with it, so try both before giving up and using Unicode's own name. + bare = glyph.replace("\ufe0f", "") + short = names.get(glyph) or names.get(bare) or name + words = tokenize( + short, + " ".join(keywords.get(glyph, keywords.get(bare, []))), + # The group and subgroup make whole shelves reachable by name: + # "flags", "fruit", "arrow", "zodiac". + subgroup, + group, + SYNONYMS.get(glyph, ""), + ) + rows.append((glyph, group, escape(short), " ".join(words))) + + return version, rows, skipped + + +def render(version, rows, max_version): + out = [] + out.append( + HEADER + % {"version": version, "count": len(rows), "max_version": max_version} + ) + + group = None + for glyph, row_group, short, words in rows: + if row_group != group: + group = row_group + if out[-1].endswith("},\n"): + out.append("\n") + out.append(" // ---- %s %s\n" % (group, "-" * max(3, 60 - len(group)))) + out.append( + ' .{ .glyph = "%s", .name = "%s", .keywords = "%s" },\n' + % (glyph, short, words) + ) + + out.append("};\n") + out.append(TESTS) + return "".join(out) + + +HEADER = '''//! Every emoji a tab can wear in place of its icon, and the search that finds +//! them. +//! +//! Generated — run `tools/gen-emoji.py` rather than editing this file. It reads +//! Unicode's `emoji-test.txt` (currently version %(version)s) for the set and its +//! ordering, and CLDR's English annotations for the keywords, so the picker is +//! laid out and searchable the same way every other emoji keyboard is. +//! +//! %(count)d entries: the RGI set up to emoji %(max_version)s, minus skin-tone variants. +//! Unicode lists nearly twice this many fully-qualified sequences and the +//! difference is almost entirely the same gesture in five tones, which makes a +//! grid longer to look through without making it more complete. The version +//! cutoff is there because colour emoji fonts trail Unicode, and a glyph the +//! font has never heard of draws as a hex-digit box; the generator's header +//! explains how to raise it. +//! +//! Keywords are CLDR's, plus the group and subgroup a glyph belongs to — so +//! "fruit", "arrow" and "flags" each bring back a whole shelf — plus a table of +//! synonyms in the generator for the words a terminal user would actually type: +//! a rocket answers to "deploy", a bandage to "hotfix", a whale to "docker". + +const std = @import("std"); + +pub const Emoji = struct { + /// The glyph itself, NUL-terminated so it can go straight into a label. + glyph: [:0]const u8, + + /// CLDR's short name — "red apple", "flag: Kenya" — as the picker shows it + /// in a tooltip. NUL-terminated for the same reason as the glyph, and kept + /// apart from `keywords` because a name is one phrase and a keyword list is + /// twenty words: readable in a tooltip, and unreadable in one. + name: [:0]const u8, + + /// Space-separated search terms, lowercase, the name's own words among them. + keywords: []const u8, +}; + +/// Whether `emoji` should show for `query`. +/// +/// Every whitespace-separated term has to match somewhere, which is what makes +/// "red circle" and "circle red" both land on the same glyph while "red" alone +/// still brings back the whole family. An empty query matches everything, so +/// the unfiltered grid falls out of the same path as a filtered one. +pub fn matches(emoji: Emoji, query: []const u8) bool { + var terms = std.mem.tokenizeAny(u8, query, " \\t"); + while (terms.next()) |term| { + if (std.ascii.indexOfIgnoreCase(emoji.keywords, term) == null) return false; + } + return true; +} + +/// Every emoji the picker offers, in Unicode's order. +pub const table = [_]Emoji{ +''' + +TESTS = ''' +// ------------------------------------------------------------------------- +// Tests +// +// The generator is what keeps the table right; these are the properties the +// picker depends on it having. They run against whatever is checked in, so a +// bad regeneration fails here rather than in the dialog. + +test "every entry is usable" { + for (table) |entry| { + try std.testing.expect(entry.glyph.len > 0); + try std.testing.expect(std.unicode.utf8ValidateSlice(entry.glyph)); + + // Long enough for the longest RGI sequence, short enough that nothing + // here is quietly a whole word. + try std.testing.expect(entry.glyph.len <= 40); + + try std.testing.expect(entry.name.len > 0); + try std.testing.expect(std.unicode.utf8ValidateSlice(entry.name)); + + try std.testing.expect(entry.keywords.len > 0); + for (entry.keywords) |c| try std.testing.expect(!std.ascii.isUpper(c)); + } +} + +test "glyphs are distinct" { + // A child's position in the picker's grid is how the dialog names the entry + // it shows, and `indexOf` maps the other way by comparing glyphs. Both stop + // being true if a glyph appears twice. + for (table, 0..) |entry, i| { + for (table[i + 1 ..]) |other| { + try std.testing.expect(!std.mem.eql(u8, entry.glyph, other.glyph)); + } + } +} + +test "the whole set is here" { + // Unicode 17 has 1914 RGI emoji once skin-tone variants are folded away. + // A table that has drifted far from that has lost a group. + try std.testing.expect(table.len > 1800); +} + +/// The one entry a search test leans on, looked up rather than indexed so that +/// regenerating the table doesn't rewrite the tests. +fn find(glyph: []const u8) Emoji { + for (table) |entry| { + if (std.mem.eql(u8, entry.glyph, glyph)) return entry; + } + unreachable; +} + +test "an empty query matches everything" { + for (table) |entry| { + try std.testing.expect(matches(entry, "")); + try std.testing.expect(matches(entry, " ")); + } +} + +test "a term matches part of a keyword, in any case" { + const rocket = find("\\u{1F680}"); + try std.testing.expect(matches(rocket, "rocket")); + try std.testing.expect(matches(rocket, "ROCKET")); + try std.testing.expect(matches(rocket, "Rock")); + try std.testing.expect(!matches(rocket, "banana")); +} + +test "every term has to match, in any order" { + const green = find("\\u{1F7E2}"); + try std.testing.expect(matches(green, "green circle")); + try std.testing.expect(matches(green, "circle green")); + try std.testing.expect(matches(green, " green circle ")); + + // The second term is what rules the other circles out. + const red = find("\\u{1F534}"); + try std.testing.expect(matches(red, "circle")); + try std.testing.expect(!matches(red, "green circle")); + + // And a term matching nothing rules out a glyph the rest of the query hit. + try std.testing.expect(!matches(green, "green circle sideways")); +} + +test "names are the phrase, not the keyword list" { + // What separates the two fields: the tooltip stays short enough to read. + for (table) |entry| try std.testing.expect(entry.name.len <= 64); + + try std.testing.expectEqualStrings("red apple", find("\\u{1F34E}").name); + try std.testing.expectEqualStrings("rocket", find("\\u{1F680}").name); +} + +test "CLDR keywords reach a glyph its name would not" { + try std.testing.expect(matches(find("\\u{1F600}"), "grin")); + try std.testing.expect(matches(find("\\u{1F60A}"), "blush")); + try std.testing.expect(matches(find("\\u{1F4A9}"), "poop")); +} + +test "a group or subgroup brings back its whole shelf" { + try std.testing.expect(matches(find("\\u{1F34E}"), "fruit")); + try std.testing.expect(matches(find("\\u{1F1FA}\\u{1F1F8}"), "flags")); + try std.testing.expect(matches(find("\\u{2B06}\\u{FE0F}"), "arrow")); +} + +test "synonyms reach the glyph the data would not" { + try std.testing.expect(matches(find("\\u{1F680}"), "deploy")); + try std.testing.expect(matches(find("\\u{1FA79}"), "hotfix")); + try std.testing.expect(matches(find("\\u{1F433}"), "docker")); + try std.testing.expect(matches(find("\\u{1F427}"), "linux")); + try std.testing.expect(matches(find("\\u{1F980}"), "rust")); + try std.testing.expect(matches(find("\\u{2705}"), "pass")); +} +''' + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--emoji-test", default=EMOJI_TEST) + parser.add_argument("--annotations", default=ANNOTATIONS) + parser.add_argument("--derived", default=DERIVED) + parser.add_argument("--out", default=None) + parser.add_argument( + "--max-version", + default=MAX_VERSION, + help="newest emoji version to include (default %s)" % MAX_VERSION, + ) + parser.add_argument( + "--check", + action="store_true", + help="exit non-zero if the file on disk is not what we would write", + ) + args = parser.parse_args() + + root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + out = args.out or os.path.join(root, "src", "emoji.zig") + + version, rows, skipped = build( + read(args.emoji_test), + read(args.annotations), + read(args.derived), + args.max_version, + ) + text = render(version, rows, args.max_version) + + if args.check: + current = open(out, encoding="utf-8").read() if os.path.exists(out) else "" + if current != text: + print("%s is stale; re-run tools/gen-emoji.py" % out, file=sys.stderr) + return 1 + print("%s is up to date (%d emoji)" % (out, len(rows))) + return 0 + + with open(out, "w", encoding="utf-8") as handle: + handle.write(text) + print("wrote %s: %d emoji from Unicode %s" % (out, len(rows), version)) + for introduced, count in sorted(skipped.items()): + print(" held back %d from %s (newer than %s)" % (count, introduced, args.max_version)) + return 0 + + +if __name__ == "__main__": + sys.exit(main())