diff --git a/bootstrap/ssr/assets/ArtworkShareModal-DEVyX6r2.js b/bootstrap/ssr/assets/ArtworkShareModal-DEVyX6r2.js
new file mode 100644
index 00000000..3663af63
--- /dev/null
+++ b/bootstrap/ssr/assets/ArtworkShareModal-DEVyX6r2.js
@@ -0,0 +1,301 @@
+import { r as reactExports, a as reactDomExports, R as React } from "./vendor-tiptap-DSw66HfW.js";
+import { S as ShareToast } from "../ssr.js";
+import "util";
+import "stream";
+import "path";
+import "http";
+import "https";
+import "url";
+import "fs";
+import "crypto";
+import "http2";
+import "assert";
+import "tty";
+import "os";
+import "zlib";
+import "events";
+import "node:process";
+import "node:path";
+import "node:url";
+import "./vendor-tooltip-CIQaDNlG.js";
+import "./vendor-realtime-cgmg5qQY.js";
+import "buffer";
+import "child_process";
+import "net";
+import "tls";
+import "./vendor-motion-yDK3iGlC.js";
+import "process";
+import "async_hooks";
+const FeedShareArtworkModal = reactExports.lazy(() => import("../ssr.js").then((n) => n.a));
+function facebookUrl(url) {
+ return `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url)}`;
+}
+function twitterUrl(url, title) {
+ return `https://twitter.com/intent/tweet?url=${encodeURIComponent(url)}&text=${encodeURIComponent(title)}`;
+}
+function pinterestUrl(url, imageUrl, title) {
+ return `https://pinterest.com/pin/create/button/?url=${encodeURIComponent(url)}&media=${encodeURIComponent(imageUrl)}&description=${encodeURIComponent(title)}`;
+}
+function emailUrl(url, title) {
+ return `mailto:?subject=${encodeURIComponent(title)}&body=${encodeURIComponent(url)}`;
+}
+function CopyIcon() {
+ return /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: 1.5, stroke: "currentColor", className: "h-5 w-5" }, /* @__PURE__ */ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 0 1-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 0 1 1.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 0 0-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 0 1-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 0 0-3.375-3.375h-1.5a1.125 1.125 0 0 1-1.125-1.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H9.75" }));
+}
+function CheckIcon() {
+ return /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 20 20", fill: "currentColor", className: "h-5 w-5 text-emerald-400" }, /* @__PURE__ */ React.createElement("path", { fillRule: "evenodd", d: "M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z", clipRule: "evenodd" }));
+}
+function FacebookIcon() {
+ return /* @__PURE__ */ React.createElement("svg", { viewBox: "0 0 24 24", fill: "currentColor", className: "h-5 w-5" }, /* @__PURE__ */ React.createElement("path", { d: "M22 12c0-5.523-4.477-10-10-10S2 6.477 2 12c0 4.991 3.657 9.128 8.438 9.878v-6.987h-2.54V12h2.54V9.797c0-2.506 1.492-3.89 3.777-3.89 1.094 0 2.238.195 2.238.195v2.46h-1.26c-1.243 0-1.63.771-1.63 1.562V12h2.773l-.443 2.89h-2.33v6.988C18.343 21.128 22 16.991 22 12Z" }));
+}
+function XTwitterIcon() {
+ return /* @__PURE__ */ React.createElement("svg", { viewBox: "0 0 24 24", fill: "currentColor", className: "h-5 w-5" }, /* @__PURE__ */ React.createElement("path", { d: "M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231 5.45-6.231Zm-1.161 17.52h1.833L7.084 4.126H5.117L17.083 19.77Z" }));
+}
+function PinterestIcon() {
+ return /* @__PURE__ */ React.createElement("svg", { viewBox: "0 0 24 24", fill: "currentColor", className: "h-5 w-5" }, /* @__PURE__ */ React.createElement("path", { d: "M12 2C6.477 2 2 6.477 2 12c0 4.236 2.636 7.855 6.356 9.312-.088-.791-.167-2.005.035-2.868.181-.78 1.172-4.97 1.172-4.97s-.299-.598-.299-1.482c0-1.388.806-2.425 1.808-2.425.853 0 1.265.64 1.265 1.408 0 .858-.546 2.14-.828 3.33-.236.995.5 1.807 1.482 1.807 1.778 0 3.144-1.874 3.144-4.58 0-2.393-1.72-4.068-4.177-4.068-2.845 0-4.515 2.135-4.515 4.34 0 .859.331 1.781.745 2.282a.3.3 0 0 1 .069.288l-.278 1.133c-.044.183-.145.222-.335.134-1.249-.581-2.03-2.407-2.03-3.874 0-3.154 2.292-6.052 6.608-6.052 3.469 0 6.165 2.472 6.165 5.776 0 3.447-2.173 6.22-5.19 6.22-1.013 0-1.965-.527-2.291-1.148l-.623 2.378c-.226.869-.835 1.958-1.244 2.621.937.29 1.931.446 2.962.446 5.523 0 10-4.477 10-10S17.523 2 12 2Z" }));
+}
+function EmailIcon() {
+ return /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: 1.5, stroke: "currentColor", className: "h-5 w-5" }, /* @__PURE__ */ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21.75 6.75v10.5a2.25 2.25 0 0 1-2.25 2.25h-15a2.25 2.25 0 0 1-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0 0 19.5 4.5h-15a2.25 2.25 0 0 0-2.25 2.25m19.5 0v.243a2.25 2.25 0 0 1-1.07 1.916l-7.5 4.615a2.25 2.25 0 0 1-2.36 0L3.32 8.91a2.25 2.25 0 0 1-1.07-1.916V6.75" }));
+}
+function EmbedIcon() {
+ return /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: 1.5, stroke: "currentColor", className: "h-5 w-5" }, /* @__PURE__ */ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M17.25 6.75 22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3-4.5 16.5" }));
+}
+function CloseIcon() {
+ return /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: 2, stroke: "currentColor", className: "h-5 w-5" }, /* @__PURE__ */ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18 18 6M6 6l12 12" }));
+}
+function openShareWindow(url) {
+ window.open(url, "_blank", "noopener,noreferrer,width=600,height=500");
+}
+function trackShare(artworkId, platform) {
+ const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");
+ fetch(`/api/artworks/${artworkId}/share`, {
+ method: "POST",
+ headers: { "Content-Type": "application/json", "X-CSRF-TOKEN": csrfToken || "" },
+ credentials: "same-origin",
+ body: JSON.stringify({ platform })
+ }).catch(() => {
+ });
+}
+function ArtworkShareModal({ open, onClose, artwork, shareUrl, isLoggedIn = false }) {
+ const backdropRef = reactExports.useRef(null);
+ const [linkCopied, setLinkCopied] = reactExports.useState(false);
+ const [embedCopied, setEmbedCopied] = reactExports.useState(false);
+ const [showEmbed, setShowEmbed] = reactExports.useState(false);
+ const [toastVisible, setToastVisible] = reactExports.useState(false);
+ const [toastMessage, setToastMessage] = reactExports.useState("");
+ const [profileShareOpen, setProfileShareOpen] = reactExports.useState(false);
+ const url = shareUrl || artwork?.canonical_url || (typeof window !== "undefined" ? window.location.href : "#");
+ const title = artwork?.title || "Artwork";
+ const imageUrl = artwork?.thumbs?.xl?.url || artwork?.thumbs?.lg?.url || artwork?.thumbs?.md?.url || "";
+ const thumbMdUrl = artwork?.thumbs?.md?.url || imageUrl;
+ const embedCode = `
+
+`;
+ reactExports.useEffect(() => {
+ if (open) {
+ document.body.style.overflow = "hidden";
+ return () => {
+ document.body.style.overflow = "";
+ };
+ }
+ }, [open]);
+ reactExports.useEffect(() => {
+ if (!open) return;
+ const handler = (e) => {
+ if (e.key === "Escape") onClose();
+ };
+ window.addEventListener("keydown", handler);
+ return () => window.removeEventListener("keydown", handler);
+ }, [open, onClose]);
+ reactExports.useEffect(() => {
+ if (open) {
+ setLinkCopied(false);
+ setEmbedCopied(false);
+ setShowEmbed(false);
+ }
+ }, [open]);
+ const showToast = reactExports.useCallback((msg) => {
+ setToastMessage(msg);
+ setToastVisible(true);
+ }, []);
+ const handleCopyLink = async () => {
+ try {
+ await navigator.clipboard.writeText(url);
+ setLinkCopied(true);
+ showToast("Link copied!");
+ trackShare(artwork?.id, "copy");
+ setTimeout(() => setLinkCopied(false), 2500);
+ } catch {
+ }
+ };
+ const handleCopyEmbed = async () => {
+ try {
+ await navigator.clipboard.writeText(embedCode);
+ setEmbedCopied(true);
+ showToast("Embed code copied!");
+ trackShare(artwork?.id, "embed");
+ setTimeout(() => setEmbedCopied(false), 2500);
+ } catch {
+ }
+ };
+ const handlePlatformShare = (platform, shareLink) => {
+ openShareWindow(shareLink);
+ trackShare(artwork?.id, platform);
+ onClose();
+ };
+ if (!open) return null;
+ const SHARE_OPTIONS = [
+ {
+ label: linkCopied ? "Copied!" : "Copy Link",
+ icon: linkCopied ? /* @__PURE__ */ React.createElement(CheckIcon, null) : /* @__PURE__ */ React.createElement(CopyIcon, null),
+ onClick: handleCopyLink,
+ className: linkCopied ? "border-emerald-500/40 bg-emerald-500/15 text-emerald-400" : "border-white/[0.08] bg-white/[0.04] text-white/70 hover:border-white/[0.15] hover:bg-white/[0.07] hover:text-white"
+ },
+ {
+ label: "Facebook",
+ icon: /* @__PURE__ */ React.createElement(FacebookIcon, null),
+ onClick: () => handlePlatformShare("facebook", facebookUrl(url)),
+ className: "border-white/[0.08] bg-white/[0.04] text-white/70 hover:border-[#1877F2]/40 hover:bg-[#1877F2]/15 hover:text-[#1877F2]"
+ },
+ {
+ label: "X (Twitter)",
+ icon: /* @__PURE__ */ React.createElement(XTwitterIcon, null),
+ onClick: () => handlePlatformShare("twitter", twitterUrl(url, title)),
+ className: "border-white/[0.08] bg-white/[0.04] text-white/70 hover:border-white/30 hover:bg-white/[0.10] hover:text-white"
+ },
+ {
+ label: "Pinterest",
+ icon: /* @__PURE__ */ React.createElement(PinterestIcon, null),
+ onClick: () => handlePlatformShare("pinterest", pinterestUrl(url, imageUrl, title)),
+ className: "border-white/[0.08] bg-white/[0.04] text-white/70 hover:border-[#E60023]/40 hover:bg-[#E60023]/15 hover:text-[#E60023]"
+ },
+ {
+ label: "Email",
+ icon: /* @__PURE__ */ React.createElement(EmailIcon, null),
+ onClick: () => {
+ window.location.href = emailUrl(url, title);
+ trackShare(artwork?.id, "email");
+ },
+ className: "border-white/[0.08] bg-white/[0.04] text-white/70 hover:border-white/[0.15] hover:bg-white/[0.07] hover:text-white"
+ },
+ ...isLoggedIn ? [{
+ label: "My Profile",
+ icon: /* @__PURE__ */ React.createElement("i", { className: "fa-solid fa-share-nodes h-5 w-5 text-[1.1rem]" }),
+ onClick: () => setProfileShareOpen(true),
+ className: "border-sky-500/30 bg-sky-500/10 text-sky-400 hover:border-sky-400/50 hover:bg-sky-500/20"
+ }] : []
+ ];
+ return reactDomExports.createPortal(
+ /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
+ "div",
+ {
+ ref: backdropRef,
+ onClick: (e) => {
+ if (e.target === backdropRef.current) onClose();
+ },
+ className: "fixed inset-0 z-[9999] flex items-center justify-center bg-black/60 backdrop-blur-sm p-4",
+ role: "dialog",
+ "aria-modal": "true",
+ "aria-label": "Share this artwork"
+ },
+ /* @__PURE__ */ React.createElement("div", { className: "w-full max-w-md rounded-2xl border border-nova-700/50 bg-nova-900/80 shadow-2xl backdrop-blur-xl" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between border-b border-white/[0.06] px-6 py-4" }, /* @__PURE__ */ React.createElement("h3", { className: "text-base font-semibold text-white" }, "Share this artwork"), /* @__PURE__ */ React.createElement(
+ "button",
+ {
+ type: "button",
+ onClick: onClose,
+ className: "rounded-lg p-1.5 text-white/40 transition hover:bg-white/[0.06] hover:text-white/70",
+ "aria-label": "Close share dialog"
+ },
+ /* @__PURE__ */ React.createElement(CloseIcon, null)
+ )), thumbMdUrl && /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3 border-b border-white/[0.06] px-6 py-3" }, /* @__PURE__ */ React.createElement(
+ "img",
+ {
+ src: thumbMdUrl,
+ alt: title,
+ className: "h-14 w-14 rounded-lg object-cover",
+ loading: "lazy"
+ }
+ ), /* @__PURE__ */ React.createElement("div", { className: "min-w-0 flex-1" }, /* @__PURE__ */ React.createElement("p", { className: "truncate text-sm font-medium text-white" }, title), artwork?.user?.username && /* @__PURE__ */ React.createElement("p", { className: "truncate text-xs text-white/50" }, "by ", artwork.user.username))), /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-3 gap-2.5 px-6 py-5 sm:grid-cols-5" }, SHARE_OPTIONS.map((opt) => /* @__PURE__ */ React.createElement(
+ "button",
+ {
+ key: opt.label,
+ type: "button",
+ onClick: opt.onClick,
+ className: [
+ "flex flex-col items-center gap-1.5 rounded-xl border px-2 py-3 text-xs font-medium transition-all duration-200",
+ opt.className
+ ].join(" ")
+ },
+ opt.icon,
+ /* @__PURE__ */ React.createElement("span", { className: "truncate" }, opt.label)
+ ))), /* @__PURE__ */ React.createElement("div", { className: "border-t border-white/[0.06] px-6 py-4" }, /* @__PURE__ */ React.createElement(
+ "button",
+ {
+ type: "button",
+ onClick: () => setShowEmbed(!showEmbed),
+ className: "flex items-center gap-2 text-sm font-medium text-white/60 transition hover:text-white/80"
+ },
+ /* @__PURE__ */ React.createElement(EmbedIcon, null),
+ showEmbed ? "Hide Embed Code" : "Embed Code",
+ /* @__PURE__ */ React.createElement(
+ "svg",
+ {
+ xmlns: "http://www.w3.org/2000/svg",
+ viewBox: "0 0 16 16",
+ fill: "currentColor",
+ className: `h-3.5 w-3.5 transition-transform duration-200 ${showEmbed ? "rotate-180" : ""}`
+ },
+ /* @__PURE__ */ React.createElement("path", { fillRule: "evenodd", d: "M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z", clipRule: "evenodd" })
+ )
+ ), showEmbed && /* @__PURE__ */ React.createElement("div", { className: "mt-3 space-y-2" }, /* @__PURE__ */ React.createElement(
+ "textarea",
+ {
+ readOnly: true,
+ value: embedCode,
+ rows: 3,
+ className: "w-full resize-none rounded-xl border border-white/[0.08] bg-white/[0.03] px-4 py-3 font-mono text-xs text-white/70 outline-none focus:border-white/[0.15]",
+ onClick: (e) => e.target.select()
+ }
+ ), /* @__PURE__ */ React.createElement(
+ "button",
+ {
+ type: "button",
+ onClick: handleCopyEmbed,
+ className: [
+ "inline-flex items-center gap-1.5 rounded-full border px-4 py-1.5 text-xs font-medium transition-all duration-200",
+ embedCopied ? "border-emerald-500/40 bg-emerald-500/15 text-emerald-400" : "border-white/[0.08] bg-white/[0.04] text-white/60 hover:border-white/[0.15] hover:text-white/80"
+ ].join(" ")
+ },
+ embedCopied ? /* @__PURE__ */ React.createElement(CheckIcon, null) : /* @__PURE__ */ React.createElement(CopyIcon, null),
+ embedCopied ? "Copied!" : "Copy Embed"
+ ))))
+ ), /* @__PURE__ */ React.createElement(
+ ShareToast,
+ {
+ message: toastMessage,
+ visible: toastVisible,
+ onHide: () => setToastVisible(false)
+ }
+ ), profileShareOpen && /* @__PURE__ */ React.createElement(reactExports.Suspense, { fallback: null }, /* @__PURE__ */ React.createElement(
+ FeedShareArtworkModal,
+ {
+ isOpen: profileShareOpen,
+ onClose: () => setProfileShareOpen(false),
+ preselectedArtwork: artwork?.id ? {
+ id: artwork.id,
+ title: artwork.title,
+ thumb_url: artwork.thumbs?.md?.url ?? artwork.thumbs?.lg?.url ?? null,
+ user: artwork.user ?? null
+ } : null,
+ onShared: () => {
+ setProfileShareOpen(false);
+ showToast("Shared to your profile!");
+ }
+ }
+ ))),
+ document.body
+ );
+}
+export {
+ ArtworkShareModal as default
+};
diff --git a/bootstrap/ssr/assets/emoji-data-4xGXbtDn.js b/bootstrap/ssr/assets/emoji-data-4xGXbtDn.js
new file mode 100644
index 00000000..e6705c33
--- /dev/null
+++ b/bootstrap/ssr/assets/emoji-data-4xGXbtDn.js
@@ -0,0 +1,17 @@
+const categories = /* @__PURE__ */ JSON.parse('[{"id":"people","emojis":["grinning","smiley","smile","grin","laughing","sweat_smile","rolling_on_the_floor_laughing","joy","slightly_smiling_face","upside_down_face","melting_face","wink","blush","innocent","smiling_face_with_3_hearts","heart_eyes","star-struck","kissing_heart","kissing","relaxed","kissing_closed_eyes","kissing_smiling_eyes","smiling_face_with_tear","yum","stuck_out_tongue","stuck_out_tongue_winking_eye","zany_face","stuck_out_tongue_closed_eyes","money_mouth_face","hugging_face","face_with_hand_over_mouth","face_with_open_eyes_and_hand_over_mouth","face_with_peeking_eye","shushing_face","thinking_face","saluting_face","zipper_mouth_face","face_with_raised_eyebrow","neutral_face","expressionless","no_mouth","dotted_line_face","face_in_clouds","smirk","unamused","face_with_rolling_eyes","grimacing","face_exhaling","lying_face","shaking_face","relieved","pensive","sleepy","drooling_face","sleeping","mask","face_with_thermometer","face_with_head_bandage","nauseated_face","face_vomiting","sneezing_face","hot_face","cold_face","woozy_face","dizzy_face","face_with_spiral_eyes","exploding_head","face_with_cowboy_hat","partying_face","disguised_face","sunglasses","nerd_face","face_with_monocle","confused","face_with_diagonal_mouth","worried","slightly_frowning_face","white_frowning_face","open_mouth","hushed","astonished","flushed","pleading_face","face_holding_back_tears","frowning","anguished","fearful","cold_sweat","disappointed_relieved","cry","sob","scream","confounded","persevere","disappointed","sweat","weary","tired_face","yawning_face","triumph","rage","angry","face_with_symbols_on_mouth","smiling_imp","imp","skull","skull_and_crossbones","hankey","clown_face","japanese_ogre","japanese_goblin","ghost","alien","space_invader","wave","raised_back_of_hand","raised_hand_with_fingers_splayed","hand","spock-hand","rightwards_hand","leftwards_hand","palm_down_hand","palm_up_hand","leftwards_pushing_hand","rightwards_pushing_hand","ok_hand","pinched_fingers","pinching_hand","v","crossed_fingers","hand_with_index_finger_and_thumb_crossed","i_love_you_hand_sign","the_horns","call_me_hand","point_left","point_right","point_up_2","middle_finger","point_down","point_up","index_pointing_at_the_viewer","+1","-1","fist","facepunch","left-facing_fist","right-facing_fist","clap","raised_hands","heart_hands","open_hands","palms_up_together","handshake","pray","writing_hand","nail_care","selfie","muscle","mechanical_arm","mechanical_leg","leg","foot","ear","ear_with_hearing_aid","nose","brain","anatomical_heart","lungs","tooth","bone","eyes","eye","tongue","lips","biting_lip","baby","child","boy","girl","adult","person_with_blond_hair","man","bearded_person","man_with_beard","woman_with_beard","red_haired_man","curly_haired_man","white_haired_man","bald_man","woman","red_haired_woman","red_haired_person","curly_haired_woman","curly_haired_person","white_haired_woman","white_haired_person","bald_woman","bald_person","blond-haired-woman","blond-haired-man","older_adult","older_man","older_woman","person_frowning","man-frowning","woman-frowning","person_with_pouting_face","man-pouting","woman-pouting","no_good","man-gesturing-no","woman-gesturing-no","ok_woman","man-gesturing-ok","woman-gesturing-ok","information_desk_person","man-tipping-hand","woman-tipping-hand","raising_hand","man-raising-hand","woman-raising-hand","deaf_person","deaf_man","deaf_woman","bow","man-bowing","woman-bowing","face_palm","man-facepalming","woman-facepalming","shrug","man-shrugging","woman-shrugging","health_worker","male-doctor","female-doctor","student","male-student","female-student","teacher","male-teacher","female-teacher","judge","male-judge","female-judge","farmer","male-farmer","female-farmer","cook","male-cook","female-cook","mechanic","male-mechanic","female-mechanic","factory_worker","male-factory-worker","female-factory-worker","office_worker","male-office-worker","female-office-worker","scientist","male-scientist","female-scientist","technologist","male-technologist","female-technologist","singer","male-singer","female-singer","artist","male-artist","female-artist","pilot","male-pilot","female-pilot","astronaut","male-astronaut","female-astronaut","firefighter","male-firefighter","female-firefighter","cop","male-police-officer","female-police-officer","sleuth_or_spy","male-detective","female-detective","guardsman","male-guard","female-guard","ninja","construction_worker","male-construction-worker","female-construction-worker","person_with_crown","prince","princess","man_with_turban","man-wearing-turban","woman-wearing-turban","man_with_gua_pi_mao","person_with_headscarf","person_in_tuxedo","man_in_tuxedo","woman_in_tuxedo","bride_with_veil","man_with_veil","woman_with_veil","pregnant_woman","pregnant_man","pregnant_person","breast-feeding","woman_feeding_baby","man_feeding_baby","person_feeding_baby","angel","santa","mrs_claus","mx_claus","superhero","male_superhero","female_superhero","supervillain","male_supervillain","female_supervillain","mage","male_mage","female_mage","fairy","male_fairy","female_fairy","vampire","male_vampire","female_vampire","merperson","merman","mermaid","elf","male_elf","female_elf","genie","male_genie","female_genie","zombie","male_zombie","female_zombie","troll","massage","man-getting-massage","woman-getting-massage","haircut","man-getting-haircut","woman-getting-haircut","walking","man-walking","woman-walking","standing_person","man_standing","woman_standing","kneeling_person","man_kneeling","woman_kneeling","person_with_probing_cane","man_with_probing_cane","woman_with_probing_cane","person_in_motorized_wheelchair","man_in_motorized_wheelchair","woman_in_motorized_wheelchair","person_in_manual_wheelchair","man_in_manual_wheelchair","woman_in_manual_wheelchair","runner","man-running","woman-running","dancer","man_dancing","man_in_business_suit_levitating","dancers","men-with-bunny-ears-partying","women-with-bunny-ears-partying","person_in_steamy_room","man_in_steamy_room","woman_in_steamy_room","person_climbing","man_climbing","woman_climbing","fencer","horse_racing","skier","snowboarder","golfer","man-golfing","woman-golfing","surfer","man-surfing","woman-surfing","rowboat","man-rowing-boat","woman-rowing-boat","swimmer","man-swimming","woman-swimming","person_with_ball","man-bouncing-ball","woman-bouncing-ball","weight_lifter","man-lifting-weights","woman-lifting-weights","bicyclist","man-biking","woman-biking","mountain_bicyclist","man-mountain-biking","woman-mountain-biking","person_doing_cartwheel","man-cartwheeling","woman-cartwheeling","wrestlers","man-wrestling","woman-wrestling","water_polo","man-playing-water-polo","woman-playing-water-polo","handball","man-playing-handball","woman-playing-handball","juggling","man-juggling","woman-juggling","person_in_lotus_position","man_in_lotus_position","woman_in_lotus_position","bath","sleeping_accommodation","people_holding_hands","two_women_holding_hands","man_and_woman_holding_hands","two_men_holding_hands","couplekiss","woman-kiss-man","man-kiss-man","woman-kiss-woman","couple_with_heart","woman-heart-man","man-heart-man","woman-heart-woman","family","man-woman-boy","man-woman-girl","man-woman-girl-boy","man-woman-boy-boy","man-woman-girl-girl","man-man-boy","man-man-girl","man-man-girl-boy","man-man-boy-boy","man-man-girl-girl","woman-woman-boy","woman-woman-girl","woman-woman-girl-boy","woman-woman-boy-boy","woman-woman-girl-girl","man-boy","man-boy-boy","man-girl","man-girl-boy","man-girl-girl","woman-boy","woman-boy-boy","woman-girl","woman-girl-boy","woman-girl-girl","speaking_head_in_silhouette","bust_in_silhouette","busts_in_silhouette","people_hugging","footprints","robot_face","smiley_cat","smile_cat","joy_cat","heart_eyes_cat","smirk_cat","kissing_cat","scream_cat","crying_cat_face","pouting_cat","see_no_evil","hear_no_evil","speak_no_evil","love_letter","cupid","gift_heart","sparkling_heart","heartpulse","heartbeat","revolving_hearts","two_hearts","heart_decoration","heavy_heart_exclamation_mark_ornament","broken_heart","heart_on_fire","mending_heart","heart","pink_heart","orange_heart","yellow_heart","green_heart","blue_heart","light_blue_heart","purple_heart","brown_heart","black_heart","grey_heart","white_heart","kiss","100","anger","boom","dizzy","sweat_drops","dash","hole","speech_balloon","eye-in-speech-bubble","left_speech_bubble","right_anger_bubble","thought_balloon","zzz"]},{"id":"nature","emojis":["monkey_face","monkey","gorilla","orangutan","dog","dog2","guide_dog","service_dog","poodle","wolf","fox_face","raccoon","cat","cat2","black_cat","lion_face","tiger","tiger2","leopard","horse","moose","donkey","racehorse","unicorn_face","zebra_face","deer","bison","cow","ox","water_buffalo","cow2","pig","pig2","boar","pig_nose","ram","sheep","goat","dromedary_camel","camel","llama","giraffe_face","elephant","mammoth","rhinoceros","hippopotamus","mouse","mouse2","rat","hamster","rabbit","rabbit2","chipmunk","beaver","hedgehog","bat","bear","polar_bear","koala","panda_face","sloth","otter","skunk","kangaroo","badger","feet","turkey","chicken","rooster","hatching_chick","baby_chick","hatched_chick","bird","penguin","dove_of_peace","eagle","duck","swan","owl","dodo","feather","flamingo","peacock","parrot","wing","black_bird","goose","frog","crocodile","turtle","lizard","snake","dragon_face","dragon","sauropod","t-rex","whale","whale2","dolphin","seal","fish","tropical_fish","blowfish","shark","octopus","shell","coral","jellyfish","snail","butterfly","bug","ant","bee","beetle","ladybug","cricket","cockroach","spider","spider_web","scorpion","mosquito","fly","worm","microbe","bouquet","cherry_blossom","white_flower","lotus","rosette","rose","wilted_flower","hibiscus","sunflower","blossom","tulip","hyacinth","seedling","potted_plant","evergreen_tree","deciduous_tree","palm_tree","cactus","ear_of_rice","herb","shamrock","four_leaf_clover","maple_leaf","fallen_leaf","leaves","empty_nest","nest_with_eggs","mushroom"]},{"id":"foods","emojis":["grapes","melon","watermelon","tangerine","lemon","banana","pineapple","mango","apple","green_apple","pear","peach","cherries","strawberry","blueberries","kiwifruit","tomato","olive","coconut","avocado","eggplant","potato","carrot","corn","hot_pepper","bell_pepper","cucumber","leafy_green","broccoli","garlic","onion","peanuts","beans","chestnut","ginger_root","pea_pod","bread","croissant","baguette_bread","flatbread","pretzel","bagel","pancakes","waffle","cheese_wedge","meat_on_bone","poultry_leg","cut_of_meat","bacon","hamburger","fries","pizza","hotdog","sandwich","taco","burrito","tamale","stuffed_flatbread","falafel","egg","fried_egg","shallow_pan_of_food","stew","fondue","bowl_with_spoon","green_salad","popcorn","butter","salt","canned_food","bento","rice_cracker","rice_ball","rice","curry","ramen","spaghetti","sweet_potato","oden","sushi","fried_shrimp","fish_cake","moon_cake","dango","dumpling","fortune_cookie","takeout_box","crab","lobster","shrimp","squid","oyster","icecream","shaved_ice","ice_cream","doughnut","cookie","birthday","cake","cupcake","pie","chocolate_bar","candy","lollipop","custard","honey_pot","baby_bottle","glass_of_milk","coffee","teapot","tea","sake","champagne","wine_glass","cocktail","tropical_drink","beer","beers","clinking_glasses","tumbler_glass","pouring_liquid","cup_with_straw","bubble_tea","beverage_box","mate_drink","ice_cube","chopsticks","knife_fork_plate","fork_and_knife","spoon","hocho","jar","amphora"]},{"id":"activity","emojis":["jack_o_lantern","christmas_tree","fireworks","sparkler","firecracker","sparkles","balloon","tada","confetti_ball","tanabata_tree","bamboo","dolls","flags","wind_chime","rice_scene","red_envelope","ribbon","gift","reminder_ribbon","admission_tickets","ticket","medal","trophy","sports_medal","first_place_medal","second_place_medal","third_place_medal","soccer","baseball","softball","basketball","volleyball","football","rugby_football","tennis","flying_disc","bowling","cricket_bat_and_ball","field_hockey_stick_and_ball","ice_hockey_stick_and_puck","lacrosse","table_tennis_paddle_and_ball","badminton_racquet_and_shuttlecock","boxing_glove","martial_arts_uniform","goal_net","golf","ice_skate","fishing_pole_and_fish","diving_mask","running_shirt_with_sash","ski","sled","curling_stone","dart","yo-yo","kite","gun","8ball","crystal_ball","magic_wand","video_game","joystick","slot_machine","game_die","jigsaw","teddy_bear","pinata","mirror_ball","nesting_dolls","spades","hearts","diamonds","clubs","chess_pawn","black_joker","mahjong","flower_playing_cards","performing_arts","frame_with_picture","art","thread","sewing_needle","yarn","knot"]},{"id":"places","emojis":["earth_africa","earth_americas","earth_asia","globe_with_meridians","world_map","japan","compass","snow_capped_mountain","mountain","volcano","mount_fuji","camping","beach_with_umbrella","desert","desert_island","national_park","stadium","classical_building","building_construction","bricks","rock","wood","hut","house_buildings","derelict_house_building","house","house_with_garden","office","post_office","european_post_office","hospital","bank","hotel","love_hotel","convenience_store","school","department_store","factory","japanese_castle","european_castle","wedding","tokyo_tower","statue_of_liberty","church","mosque","hindu_temple","synagogue","shinto_shrine","kaaba","fountain","tent","foggy","night_with_stars","cityscape","sunrise_over_mountains","sunrise","city_sunset","city_sunrise","bridge_at_night","hotsprings","carousel_horse","playground_slide","ferris_wheel","roller_coaster","barber","circus_tent","steam_locomotive","railway_car","bullettrain_side","bullettrain_front","train2","metro","light_rail","station","tram","monorail","mountain_railway","train","bus","oncoming_bus","trolleybus","minibus","ambulance","fire_engine","police_car","oncoming_police_car","taxi","oncoming_taxi","car","oncoming_automobile","blue_car","pickup_truck","truck","articulated_lorry","tractor","racing_car","racing_motorcycle","motor_scooter","manual_wheelchair","motorized_wheelchair","auto_rickshaw","bike","scooter","skateboard","roller_skate","busstop","motorway","railway_track","oil_drum","fuelpump","wheel","rotating_light","traffic_light","vertical_traffic_light","octagonal_sign","construction","anchor","ring_buoy","boat","canoe","speedboat","passenger_ship","ferry","motor_boat","ship","airplane","small_airplane","airplane_departure","airplane_arriving","parachute","seat","helicopter","suspension_railway","mountain_cableway","aerial_tramway","satellite","rocket","flying_saucer","bellhop_bell","luggage","hourglass","hourglass_flowing_sand","watch","alarm_clock","stopwatch","timer_clock","mantelpiece_clock","clock12","clock1230","clock1","clock130","clock2","clock230","clock3","clock330","clock4","clock430","clock5","clock530","clock6","clock630","clock7","clock730","clock8","clock830","clock9","clock930","clock10","clock1030","clock11","clock1130","new_moon","waxing_crescent_moon","first_quarter_moon","moon","full_moon","waning_gibbous_moon","last_quarter_moon","waning_crescent_moon","crescent_moon","new_moon_with_face","first_quarter_moon_with_face","last_quarter_moon_with_face","thermometer","sunny","full_moon_with_face","sun_with_face","ringed_planet","star","star2","stars","milky_way","cloud","partly_sunny","thunder_cloud_and_rain","mostly_sunny","barely_sunny","partly_sunny_rain","rain_cloud","snow_cloud","lightning","tornado","fog","wind_blowing_face","cyclone","rainbow","closed_umbrella","umbrella","umbrella_with_rain_drops","umbrella_on_ground","zap","snowflake","snowman","snowman_without_snow","comet","fire","droplet","ocean"]},{"id":"objects","emojis":["eyeglasses","dark_sunglasses","goggles","lab_coat","safety_vest","necktie","shirt","jeans","scarf","gloves","coat","socks","dress","kimono","sari","one-piece_swimsuit","briefs","shorts","bikini","womans_clothes","folding_hand_fan","purse","handbag","pouch","shopping_bags","school_satchel","thong_sandal","mans_shoe","athletic_shoe","hiking_boot","womans_flat_shoe","high_heel","sandal","ballet_shoes","boot","hair_pick","crown","womans_hat","tophat","mortar_board","billed_cap","military_helmet","helmet_with_white_cross","prayer_beads","lipstick","ring","gem","mute","speaker","sound","loud_sound","loudspeaker","mega","postal_horn","bell","no_bell","musical_score","musical_note","notes","studio_microphone","level_slider","control_knobs","microphone","headphones","radio","saxophone","accordion","guitar","musical_keyboard","trumpet","violin","banjo","drum_with_drumsticks","long_drum","maracas","flute","iphone","calling","phone","telephone_receiver","pager","fax","battery","low_battery","electric_plug","computer","desktop_computer","printer","keyboard","three_button_mouse","trackball","minidisc","floppy_disk","cd","dvd","abacus","movie_camera","film_frames","film_projector","clapper","tv","camera","camera_with_flash","video_camera","vhs","mag","mag_right","candle","bulb","flashlight","izakaya_lantern","diya_lamp","notebook_with_decorative_cover","closed_book","book","green_book","blue_book","orange_book","books","notebook","ledger","page_with_curl","scroll","page_facing_up","newspaper","rolled_up_newspaper","bookmark_tabs","bookmark","label","moneybag","coin","yen","dollar","euro","pound","money_with_wings","credit_card","receipt","chart","email","e-mail","incoming_envelope","envelope_with_arrow","outbox_tray","inbox_tray","package","mailbox","mailbox_closed","mailbox_with_mail","mailbox_with_no_mail","postbox","ballot_box_with_ballot","pencil2","black_nib","lower_left_fountain_pen","lower_left_ballpoint_pen","lower_left_paintbrush","lower_left_crayon","memo","briefcase","file_folder","open_file_folder","card_index_dividers","date","calendar","spiral_note_pad","spiral_calendar_pad","card_index","chart_with_upwards_trend","chart_with_downwards_trend","bar_chart","clipboard","pushpin","round_pushpin","paperclip","linked_paperclips","straight_ruler","triangular_ruler","scissors","card_file_box","file_cabinet","wastebasket","lock","unlock","lock_with_ink_pen","closed_lock_with_key","key","old_key","hammer","axe","pick","hammer_and_pick","hammer_and_wrench","dagger_knife","crossed_swords","bomb","boomerang","bow_and_arrow","shield","carpentry_saw","wrench","screwdriver","nut_and_bolt","gear","compression","scales","probing_cane","link","chains","hook","toolbox","magnet","ladder","alembic","test_tube","petri_dish","dna","microscope","telescope","satellite_antenna","syringe","drop_of_blood","pill","adhesive_bandage","crutch","stethoscope","x-ray","door","elevator","mirror","window","bed","couch_and_lamp","chair","toilet","plunger","shower","bathtub","mouse_trap","razor","lotion_bottle","safety_pin","broom","basket","roll_of_paper","bucket","soap","bubbles","toothbrush","sponge","fire_extinguisher","shopping_trolley","smoking","coffin","headstone","funeral_urn","nazar_amulet","hamsa","moyai","placard","identification_card"]},{"id":"symbols","emojis":["atm","put_litter_in_its_place","potable_water","wheelchair","mens","womens","restroom","baby_symbol","wc","passport_control","customs","baggage_claim","left_luggage","warning","children_crossing","no_entry","no_entry_sign","no_bicycles","no_smoking","do_not_litter","non-potable_water","no_pedestrians","no_mobile_phones","underage","radioactive_sign","biohazard_sign","arrow_up","arrow_upper_right","arrow_right","arrow_lower_right","arrow_down","arrow_lower_left","arrow_left","arrow_upper_left","arrow_up_down","left_right_arrow","leftwards_arrow_with_hook","arrow_right_hook","arrow_heading_up","arrow_heading_down","arrows_clockwise","arrows_counterclockwise","back","end","on","soon","top","place_of_worship","atom_symbol","om_symbol","star_of_david","wheel_of_dharma","yin_yang","latin_cross","orthodox_cross","star_and_crescent","peace_symbol","menorah_with_nine_branches","six_pointed_star","khanda","aries","taurus","gemini","cancer","leo","virgo","libra","scorpius","sagittarius","capricorn","aquarius","pisces","ophiuchus","twisted_rightwards_arrows","repeat","repeat_one","arrow_forward","fast_forward","black_right_pointing_double_triangle_with_vertical_bar","black_right_pointing_triangle_with_double_vertical_bar","arrow_backward","rewind","black_left_pointing_double_triangle_with_vertical_bar","arrow_up_small","arrow_double_up","arrow_down_small","arrow_double_down","double_vertical_bar","black_square_for_stop","black_circle_for_record","eject","cinema","low_brightness","high_brightness","signal_strength","wireless","vibration_mode","mobile_phone_off","female_sign","male_sign","transgender_symbol","heavy_multiplication_x","heavy_plus_sign","heavy_minus_sign","heavy_division_sign","heavy_equals_sign","infinity","bangbang","interrobang","question","grey_question","grey_exclamation","exclamation","wavy_dash","currency_exchange","heavy_dollar_sign","medical_symbol","recycle","fleur_de_lis","trident","name_badge","beginner","o","white_check_mark","ballot_box_with_check","heavy_check_mark","x","negative_squared_cross_mark","curly_loop","loop","part_alternation_mark","eight_spoked_asterisk","eight_pointed_black_star","sparkle","copyright","registered","tm","hash","keycap_star","zero","one","two","three","four","five","six","seven","eight","nine","keycap_ten","capital_abcd","abcd","1234","symbols","abc","a","ab","b","cl","cool","free","information_source","id","m","new","ng","o2","ok","parking","sos","up","vs","koko","sa","u6708","u6709","u6307","ideograph_advantage","u5272","u7121","u7981","accept","u7533","u5408","u7a7a","congratulations","secret","u55b6","u6e80","red_circle","large_orange_circle","large_yellow_circle","large_green_circle","large_blue_circle","large_purple_circle","large_brown_circle","black_circle","white_circle","large_red_square","large_orange_square","large_yellow_square","large_green_square","large_blue_square","large_purple_square","large_brown_square","black_large_square","white_large_square","black_medium_square","white_medium_square","black_medium_small_square","white_medium_small_square","black_small_square","white_small_square","large_orange_diamond","large_blue_diamond","small_orange_diamond","small_blue_diamond","small_red_triangle","small_red_triangle_down","diamond_shape_with_a_dot_inside","radio_button","white_square_button","black_square_button"]},{"id":"flags","emojis":["checkered_flag","cn","crossed_flags","de","es","flag-ac","flag-ad","flag-ae","flag-af","flag-ag","flag-ai","flag-al","flag-am","flag-ao","flag-aq","flag-ar","flag-as","flag-at","flag-au","flag-aw","flag-ax","flag-az","flag-ba","flag-bb","flag-bd","flag-be","flag-bf","flag-bg","flag-bh","flag-bi","flag-bj","flag-bl","flag-bm","flag-bn","flag-bo","flag-bq","flag-br","flag-bs","flag-bt","flag-bv","flag-bw","flag-by","flag-bz","flag-ca","flag-cc","flag-cd","flag-cf","flag-cg","flag-ch","flag-ci","flag-ck","flag-cl","flag-cm","flag-co","flag-cp","flag-cr","flag-cu","flag-cv","flag-cw","flag-cx","flag-cy","flag-cz","flag-dg","flag-dj","flag-dk","flag-dm","flag-do","flag-dz","flag-ea","flag-ec","flag-ee","flag-eg","flag-eh","flag-england","flag-er","flag-et","flag-eu","flag-fi","flag-fj","flag-fk","flag-fm","flag-fo","flag-ga","flag-gd","flag-ge","flag-gf","flag-gg","flag-gh","flag-gi","flag-gl","flag-gm","flag-gn","flag-gp","flag-gq","flag-gr","flag-gs","flag-gt","flag-gu","flag-gw","flag-gy","flag-hk","flag-hm","flag-hn","flag-hr","flag-ht","flag-hu","flag-ic","flag-id","flag-ie","flag-il","flag-im","flag-in","flag-io","flag-iq","flag-ir","flag-is","flag-je","flag-jm","flag-jo","flag-ke","flag-kg","flag-kh","flag-ki","flag-km","flag-kn","flag-kp","flag-kw","flag-ky","flag-kz","flag-la","flag-lb","flag-lc","flag-li","flag-lk","flag-lr","flag-ls","flag-lt","flag-lu","flag-lv","flag-ly","flag-ma","flag-mc","flag-md","flag-me","flag-mf","flag-mg","flag-mh","flag-mk","flag-ml","flag-mm","flag-mn","flag-mo","flag-mp","flag-mq","flag-mr","flag-ms","flag-mt","flag-mu","flag-mv","flag-mw","flag-mx","flag-my","flag-mz","flag-na","flag-nc","flag-ne","flag-nf","flag-ng","flag-ni","flag-nl","flag-no","flag-np","flag-nr","flag-nu","flag-nz","flag-om","flag-pa","flag-pe","flag-pf","flag-pg","flag-ph","flag-pk","flag-pl","flag-pm","flag-pn","flag-pr","flag-ps","flag-pt","flag-pw","flag-py","flag-qa","flag-re","flag-ro","flag-rs","flag-rw","flag-sa","flag-sb","flag-sc","flag-scotland","flag-sd","flag-se","flag-sg","flag-sh","flag-si","flag-sj","flag-sk","flag-sl","flag-sm","flag-sn","flag-so","flag-sr","flag-ss","flag-st","flag-sv","flag-sx","flag-sy","flag-sz","flag-ta","flag-tc","flag-td","flag-tf","flag-tg","flag-th","flag-tj","flag-tk","flag-tl","flag-tm","flag-tn","flag-to","flag-tr","flag-tt","flag-tv","flag-tw","flag-tz","flag-ua","flag-ug","flag-um","flag-un","flag-uy","flag-uz","flag-va","flag-vc","flag-ve","flag-vg","flag-vi","flag-vn","flag-vu","flag-wales","flag-wf","flag-ws","flag-xk","flag-ye","flag-yt","flag-za","flag-zm","flag-zw","fr","gb","it","jp","kr","pirate_flag","rainbow-flag","ru","transgender_flag","triangular_flag_on_post","us","waving_black_flag","waving_white_flag"]}]');
+const emojis = /* @__PURE__ */ JSON.parse(`{"100":{"id":"100","name":"Hundred Points","keywords":["100","score","perfect","numbers","century","exam","quiz","test","pass"],"skins":[{"unified":"1f4af","native":"💯"}],"version":1},"1234":{"id":"1234","name":"Input Numbers","keywords":["1234","blue","square","1","2","3","4"],"skins":[{"unified":"1f522","native":"🔢"}],"version":1},"grinning":{"id":"grinning","name":"Grinning Face","emoticons":[":D"],"keywords":["smile","happy","joy",":D","grin"],"skins":[{"unified":"1f600","native":"😀"}],"version":1},"smiley":{"id":"smiley","name":"Grinning Face with Big Eyes","emoticons":[":)","=)","=-)"],"keywords":["smiley","happy","joy","haha",":D",":)","smile","funny"],"skins":[{"unified":"1f603","native":"😃"}],"version":1},"smile":{"id":"smile","name":"Grinning Face with Smiling Eyes","emoticons":[":)","C:","c:",":D",":-D"],"keywords":["smile","happy","joy","funny","haha","laugh","like",":D",":)"],"skins":[{"unified":"1f604","native":"😄"}],"version":1},"grin":{"id":"grin","name":"Beaming Face with Smiling Eyes","keywords":["grin","happy","smile","joy","kawaii"],"skins":[{"unified":"1f601","native":"😁"}],"version":1},"laughing":{"id":"laughing","name":"Grinning Squinting Face","emoticons":[":>",":->"],"keywords":["laughing","satisfied","happy","joy","lol","haha","glad","XD","laugh"],"skins":[{"unified":"1f606","native":"😆"}],"version":1},"sweat_smile":{"id":"sweat_smile","name":"Grinning Face with Sweat","keywords":["smile","hot","happy","laugh","relief"],"skins":[{"unified":"1f605","native":"😅"}],"version":1},"rolling_on_the_floor_laughing":{"id":"rolling_on_the_floor_laughing","name":"Rolling on the Floor Laughing","keywords":["face","lol","haha","rofl"],"skins":[{"unified":"1f923","native":"🤣"}],"version":3},"joy":{"id":"joy","name":"Face with Tears of Joy","keywords":["cry","weep","happy","happytears","haha"],"skins":[{"unified":"1f602","native":"😂"}],"version":1},"slightly_smiling_face":{"id":"slightly_smiling_face","name":"Slightly Smiling Face","emoticons":[":)","(:",":-)"],"keywords":["smile"],"skins":[{"unified":"1f642","native":"🙂"}],"version":1},"upside_down_face":{"id":"upside_down_face","name":"Upside-Down Face","keywords":["upside","down","flipped","silly","smile"],"skins":[{"unified":"1f643","native":"🙃"}],"version":1},"melting_face":{"id":"melting_face","name":"Melting Face","keywords":["hot","heat"],"skins":[{"unified":"1fae0","native":"🫠"}],"version":14},"wink":{"id":"wink","name":"Winking Face","emoticons":[";)",";-)"],"keywords":["wink","happy","mischievous","secret",";)","smile","eye"],"skins":[{"unified":"1f609","native":"😉"}],"version":1},"blush":{"id":"blush","name":"Smiling Face with Smiling Eyes","emoticons":[":)"],"keywords":["blush","smile","happy","flushed","crush","embarrassed","shy","joy"],"skins":[{"unified":"1f60a","native":"😊"}],"version":1},"innocent":{"id":"innocent","name":"Smiling Face with Halo","keywords":["innocent","angel","heaven"],"skins":[{"unified":"1f607","native":"😇"}],"version":1},"smiling_face_with_3_hearts":{"id":"smiling_face_with_3_hearts","name":"Smiling Face with Hearts","keywords":["3","love","like","affection","valentines","infatuation","crush","adore"],"skins":[{"unified":"1f970","native":"🥰"}],"version":11},"heart_eyes":{"id":"heart_eyes","name":"Smiling Face with Heart-Eyes","keywords":["heart","eyes","love","like","affection","valentines","infatuation","crush"],"skins":[{"unified":"1f60d","native":"😍"}],"version":1},"star-struck":{"id":"star-struck","name":"Star-Struck","keywords":["star","struck","grinning","face","with","eyes","smile","starry"],"skins":[{"unified":"1f929","native":"🤩"}],"version":5},"kissing_heart":{"id":"kissing_heart","name":"Face Blowing a Kiss","emoticons":[":*",":-*"],"keywords":["kissing","heart","love","like","affection","valentines","infatuation"],"skins":[{"unified":"1f618","native":"😘"}],"version":1},"kissing":{"id":"kissing","name":"Kissing Face","keywords":["love","like","3","valentines","infatuation","kiss"],"skins":[{"unified":"1f617","native":"😗"}],"version":1},"relaxed":{"id":"relaxed","name":"Smiling Face","keywords":["relaxed","blush","massage","happiness"],"skins":[{"unified":"263a-fe0f","native":"☺️"}],"version":1},"kissing_closed_eyes":{"id":"kissing_closed_eyes","name":"Kissing Face with Closed Eyes","keywords":["love","like","affection","valentines","infatuation","kiss"],"skins":[{"unified":"1f61a","native":"😚"}],"version":1},"kissing_smiling_eyes":{"id":"kissing_smiling_eyes","name":"Kissing Face with Smiling Eyes","keywords":["affection","valentines","infatuation","kiss"],"skins":[{"unified":"1f619","native":"😙"}],"version":1},"smiling_face_with_tear":{"id":"smiling_face_with_tear","name":"Smiling Face with Tear","keywords":["sad","cry","pretend"],"skins":[{"unified":"1f972","native":"🥲"}],"version":13},"yum":{"id":"yum","name":"Face Savoring Food","keywords":["yum","happy","joy","tongue","smile","silly","yummy","nom","delicious","savouring"],"skins":[{"unified":"1f60b","native":"😋"}],"version":1},"stuck_out_tongue":{"id":"stuck_out_tongue","name":"Face with Tongue","emoticons":[":p",":-p",":P",":-P",":b",":-b"],"keywords":["stuck","out","prank","childish","playful","mischievous","smile"],"skins":[{"unified":"1f61b","native":"😛"}],"version":1},"stuck_out_tongue_winking_eye":{"id":"stuck_out_tongue_winking_eye","name":"Winking Face with Tongue","emoticons":[";p",";-p",";b",";-b",";P",";-P"],"keywords":["stuck","out","eye","prank","childish","playful","mischievous","smile","wink"],"skins":[{"unified":"1f61c","native":"😜"}],"version":1},"zany_face":{"id":"zany_face","name":"Zany Face","keywords":["grinning","with","one","large","and","small","eye","goofy","crazy"],"skins":[{"unified":"1f92a","native":"🤪"}],"version":5},"stuck_out_tongue_closed_eyes":{"id":"stuck_out_tongue_closed_eyes","name":"Squinting Face with Tongue","keywords":["stuck","out","closed","eyes","prank","playful","mischievous","smile"],"skins":[{"unified":"1f61d","native":"😝"}],"version":1},"money_mouth_face":{"id":"money_mouth_face","name":"Money-Mouth Face","keywords":["money","mouth","rich","dollar"],"skins":[{"unified":"1f911","native":"🤑"}],"version":1},"hugging_face":{"id":"hugging_face","name":"Hugging Face","keywords":["smile","hug"],"skins":[{"unified":"1f917","native":"🤗"}],"version":1},"face_with_hand_over_mouth":{"id":"face_with_hand_over_mouth","name":"Face with Hand over Mouth","keywords":["smiling","eyes","and","covering","whoops","shock","surprise"],"skins":[{"unified":"1f92d","native":"🤭"}],"version":5},"face_with_open_eyes_and_hand_over_mouth":{"id":"face_with_open_eyes_and_hand_over_mouth","name":"Face with Open Eyes and Hand over Mouth","keywords":["silence","secret","shock","surprise"],"skins":[{"unified":"1fae2","native":"🫢"}],"version":14},"face_with_peeking_eye":{"id":"face_with_peeking_eye","name":"Face with Peeking Eye","keywords":["scared","frightening","embarrassing","shy"],"skins":[{"unified":"1fae3","native":"🫣"}],"version":14},"shushing_face":{"id":"shushing_face","name":"Shushing Face","keywords":["with","finger","covering","closed","lips","quiet","shhh"],"skins":[{"unified":"1f92b","native":"🤫"}],"version":5},"thinking_face":{"id":"thinking_face","name":"Thinking Face","keywords":["hmmm","think","consider"],"skins":[{"unified":"1f914","native":"🤔"}],"version":1},"saluting_face":{"id":"saluting_face","name":"Saluting Face","keywords":["respect","salute"],"skins":[{"unified":"1fae1","native":"🫡"}],"version":14},"zipper_mouth_face":{"id":"zipper_mouth_face","name":"Zipper-Mouth Face","keywords":["zipper","mouth","sealed","secret"],"skins":[{"unified":"1f910","native":"🤐"}],"version":1},"face_with_raised_eyebrow":{"id":"face_with_raised_eyebrow","name":"Face with Raised Eyebrow","keywords":["one","distrust","scepticism","disapproval","disbelief","surprise"],"skins":[{"unified":"1f928","native":"🤨"}],"version":5},"neutral_face":{"id":"neutral_face","name":"Neutral Face","emoticons":[":|",":-|"],"keywords":["indifference","meh",":",""],"skins":[{"unified":"1f610","native":"😐"}],"version":1},"expressionless":{"id":"expressionless","name":"Expressionless Face","emoticons":["-_-"],"keywords":["indifferent","-","","meh","deadpan"],"skins":[{"unified":"1f611","native":"😑"}],"version":1},"no_mouth":{"id":"no_mouth","name":"Face Without Mouth","keywords":["no","hellokitty"],"skins":[{"unified":"1f636","native":"😶"}],"version":1},"dotted_line_face":{"id":"dotted_line_face","name":"Dotted Line Face","keywords":["invisible","lonely","isolation","depression"],"skins":[{"unified":"1fae5","native":"🫥"}],"version":14},"face_in_clouds":{"id":"face_in_clouds","name":"Face in Clouds","keywords":["shower","steam","dream"],"skins":[{"unified":"1f636-200d-1f32b-fe0f","native":"😶🌫️"}],"version":13.1},"smirk":{"id":"smirk","name":"Smirking Face","keywords":["smirk","smile","mean","prank","smug","sarcasm"],"skins":[{"unified":"1f60f","native":"😏"}],"version":1},"unamused":{"id":"unamused","name":"Unamused Face","emoticons":[":("],"keywords":["indifference","bored","straight","serious","sarcasm","unimpressed","skeptical","dubious","side","eye"],"skins":[{"unified":"1f612","native":"😒"}],"version":1},"face_with_rolling_eyes":{"id":"face_with_rolling_eyes","name":"Face with Rolling Eyes","keywords":["eyeroll","frustrated"],"skins":[{"unified":"1f644","native":"🙄"}],"version":1},"grimacing":{"id":"grimacing","name":"Grimacing Face","keywords":["grimace","teeth"],"skins":[{"unified":"1f62c","native":"😬"}],"version":1},"face_exhaling":{"id":"face_exhaling","name":"Face Exhaling","keywords":["relieve","relief","tired","sigh"],"skins":[{"unified":"1f62e-200d-1f4a8","native":"😮💨"}],"version":13.1},"lying_face":{"id":"lying_face","name":"Lying Face","keywords":["lie","pinocchio"],"skins":[{"unified":"1f925","native":"🤥"}],"version":3},"shaking_face":{"id":"shaking_face","name":"Shaking Face","keywords":["dizzy","shock","blurry","earthquake"],"skins":[{"unified":"1fae8","native":"🫨"}],"version":15},"relieved":{"id":"relieved","name":"Relieved Face","keywords":["relaxed","phew","massage","happiness"],"skins":[{"unified":"1f60c","native":"😌"}],"version":1},"pensive":{"id":"pensive","name":"Pensive Face","keywords":["sad","depressed","upset"],"skins":[{"unified":"1f614","native":"😔"}],"version":1},"sleepy":{"id":"sleepy","name":"Sleepy Face","keywords":["tired","rest","nap"],"skins":[{"unified":"1f62a","native":"😪"}],"version":1},"drooling_face":{"id":"drooling_face","name":"Drooling Face","keywords":[],"skins":[{"unified":"1f924","native":"🤤"}],"version":3},"sleeping":{"id":"sleeping","name":"Sleeping Face","keywords":["tired","sleepy","night","zzz"],"skins":[{"unified":"1f634","native":"😴"}],"version":1},"mask":{"id":"mask","name":"Face with Medical Mask","keywords":["sick","ill","disease","covid"],"skins":[{"unified":"1f637","native":"😷"}],"version":1},"face_with_thermometer":{"id":"face_with_thermometer","name":"Face with Thermometer","keywords":["sick","temperature","cold","fever","covid"],"skins":[{"unified":"1f912","native":"🤒"}],"version":1},"face_with_head_bandage":{"id":"face_with_head_bandage","name":"Face with Head-Bandage","keywords":["head","bandage","injured","clumsy","hurt"],"skins":[{"unified":"1f915","native":"🤕"}],"version":1},"nauseated_face":{"id":"nauseated_face","name":"Nauseated Face","keywords":["vomit","gross","green","sick","throw","up","ill"],"skins":[{"unified":"1f922","native":"🤢"}],"version":3},"face_vomiting":{"id":"face_vomiting","name":"Face Vomiting","keywords":["with","open","mouth","sick"],"skins":[{"unified":"1f92e","native":"🤮"}],"version":5},"sneezing_face":{"id":"sneezing_face","name":"Sneezing Face","keywords":["gesundheit","sneeze","sick","allergy"],"skins":[{"unified":"1f927","native":"🤧"}],"version":3},"hot_face":{"id":"hot_face","name":"Hot Face","keywords":["feverish","heat","red","sweating"],"skins":[{"unified":"1f975","native":"🥵"}],"version":11},"cold_face":{"id":"cold_face","name":"Cold Face","keywords":["blue","freezing","frozen","frostbite","icicles"],"skins":[{"unified":"1f976","native":"🥶"}],"version":11},"woozy_face":{"id":"woozy_face","name":"Woozy Face","keywords":["dizzy","intoxicated","tipsy","wavy"],"skins":[{"unified":"1f974","native":"🥴"}],"version":11},"dizzy_face":{"id":"dizzy_face","name":"Dizzy Face","keywords":["spent","unconscious","xox"],"skins":[{"unified":"1f635","native":"😵"}],"version":1},"face_with_spiral_eyes":{"id":"face_with_spiral_eyes","name":"Face with Spiral Eyes","keywords":["sick","ill","confused","nauseous","nausea"],"skins":[{"unified":"1f635-200d-1f4ab","native":"😵💫"}],"version":13.1},"exploding_head":{"id":"exploding_head","name":"Exploding Head","keywords":["shocked","face","with","mind","blown"],"skins":[{"unified":"1f92f","native":"🤯"}],"version":5},"face_with_cowboy_hat":{"id":"face_with_cowboy_hat","name":"Cowboy Hat Face","keywords":["with","cowgirl"],"skins":[{"unified":"1f920","native":"🤠"}],"version":3},"partying_face":{"id":"partying_face","name":"Partying Face","keywords":["celebration","woohoo"],"skins":[{"unified":"1f973","native":"🥳"}],"version":11},"disguised_face":{"id":"disguised_face","name":"Disguised Face","keywords":["pretent","brows","glasses","moustache"],"skins":[{"unified":"1f978","native":"🥸"}],"version":13},"sunglasses":{"id":"sunglasses","name":"Smiling Face with Sunglasses","emoticons":["8)"],"keywords":["cool","smile","summer","beach","sunglass"],"skins":[{"unified":"1f60e","native":"😎"}],"version":1},"nerd_face":{"id":"nerd_face","name":"Nerd Face","keywords":["nerdy","geek","dork"],"skins":[{"unified":"1f913","native":"🤓"}],"version":1},"face_with_monocle":{"id":"face_with_monocle","name":"Face with Monocle","keywords":["stuffy","wealthy"],"skins":[{"unified":"1f9d0","native":"🧐"}],"version":5},"confused":{"id":"confused","name":"Confused Face","emoticons":[":\\\\",":-\\\\",":/",":-/"],"keywords":["indifference","huh","weird","hmmm",":/"],"skins":[{"unified":"1f615","native":"😕"}],"version":1},"face_with_diagonal_mouth":{"id":"face_with_diagonal_mouth","name":"Face with Diagonal Mouth","keywords":["skeptic","confuse","frustrated","indifferent"],"skins":[{"unified":"1fae4","native":"🫤"}],"version":14},"worried":{"id":"worried","name":"Worried Face","keywords":["concern","nervous",":("],"skins":[{"unified":"1f61f","native":"😟"}],"version":1},"slightly_frowning_face":{"id":"slightly_frowning_face","name":"Slightly Frowning Face","keywords":["disappointed","sad","upset"],"skins":[{"unified":"1f641","native":"🙁"}],"version":1},"white_frowning_face":{"id":"white_frowning_face","name":"Frowning Face","keywords":["white","sad","upset","frown"],"skins":[{"unified":"2639-fe0f","native":"☹️"}],"version":1},"open_mouth":{"id":"open_mouth","name":"Face with Open Mouth","emoticons":[":o",":-o",":O",":-O"],"keywords":["surprise","impressed","wow","whoa",":O"],"skins":[{"unified":"1f62e","native":"😮"}],"version":1},"hushed":{"id":"hushed","name":"Hushed Face","keywords":["woo","shh"],"skins":[{"unified":"1f62f","native":"😯"}],"version":1},"astonished":{"id":"astonished","name":"Astonished Face","keywords":["xox","surprised","poisoned"],"skins":[{"unified":"1f632","native":"😲"}],"version":1},"flushed":{"id":"flushed","name":"Flushed Face","keywords":["blush","shy","flattered"],"skins":[{"unified":"1f633","native":"😳"}],"version":1},"pleading_face":{"id":"pleading_face","name":"Pleading Face","keywords":["begging","mercy","cry","tears","sad","grievance"],"skins":[{"unified":"1f97a","native":"🥺"}],"version":11},"face_holding_back_tears":{"id":"face_holding_back_tears","name":"Face Holding Back Tears","keywords":["touched","gratitude","cry"],"skins":[{"unified":"1f979","native":"🥹"}],"version":14},"frowning":{"id":"frowning","name":"Frowning Face with Open Mouth","keywords":["aw","what"],"skins":[{"unified":"1f626","native":"😦"}],"version":1},"anguished":{"id":"anguished","name":"Anguished Face","emoticons":["D:"],"keywords":["stunned","nervous"],"skins":[{"unified":"1f627","native":"😧"}],"version":1},"fearful":{"id":"fearful","name":"Fearful Face","keywords":["scared","terrified","nervous"],"skins":[{"unified":"1f628","native":"😨"}],"version":1},"cold_sweat":{"id":"cold_sweat","name":"Anxious Face with Sweat","keywords":["cold","nervous"],"skins":[{"unified":"1f630","native":"😰"}],"version":1},"disappointed_relieved":{"id":"disappointed_relieved","name":"Sad but Relieved Face","keywords":["disappointed","phew","sweat","nervous"],"skins":[{"unified":"1f625","native":"😥"}],"version":1},"cry":{"id":"cry","name":"Crying Face","emoticons":[":'("],"keywords":["cry","tears","sad","depressed","upset",":'("],"skins":[{"unified":"1f622","native":"😢"}],"version":1},"sob":{"id":"sob","name":"Loudly Crying Face","emoticons":[":'("],"keywords":["sob","cry","tears","sad","upset","depressed"],"skins":[{"unified":"1f62d","native":"😭"}],"version":1},"scream":{"id":"scream","name":"Face Screaming in Fear","keywords":["scream","munch","scared","omg"],"skins":[{"unified":"1f631","native":"😱"}],"version":1},"confounded":{"id":"confounded","name":"Confounded Face","keywords":["confused","sick","unwell","oops",":S"],"skins":[{"unified":"1f616","native":"😖"}],"version":1},"persevere":{"id":"persevere","name":"Persevering Face","keywords":["persevere","sick","no","upset","oops"],"skins":[{"unified":"1f623","native":"😣"}],"version":1},"disappointed":{"id":"disappointed","name":"Disappointed Face","emoticons":["):",":(",":-("],"keywords":["sad","upset","depressed",":("],"skins":[{"unified":"1f61e","native":"😞"}],"version":1},"sweat":{"id":"sweat","name":"Face with Cold Sweat","keywords":["downcast","hot","sad","tired","exercise"],"skins":[{"unified":"1f613","native":"😓"}],"version":1},"weary":{"id":"weary","name":"Weary Face","keywords":["tired","sleepy","sad","frustrated","upset"],"skins":[{"unified":"1f629","native":"😩"}],"version":1},"tired_face":{"id":"tired_face","name":"Tired Face","keywords":["sick","whine","upset","frustrated"],"skins":[{"unified":"1f62b","native":"😫"}],"version":1},"yawning_face":{"id":"yawning_face","name":"Yawning Face","keywords":["tired","sleepy"],"skins":[{"unified":"1f971","native":"🥱"}],"version":12},"triumph":{"id":"triumph","name":"Face with Look of Triumph","keywords":["steam","from","nose","gas","phew","proud","pride"],"skins":[{"unified":"1f624","native":"😤"}],"version":1},"rage":{"id":"rage","name":"Pouting Face","keywords":["rage","angry","mad","hate","despise"],"skins":[{"unified":"1f621","native":"😡"}],"version":1},"angry":{"id":"angry","name":"Angry Face","emoticons":[">:(",">:-("],"keywords":["mad","annoyed","frustrated"],"skins":[{"unified":"1f620","native":"😠"}],"version":1},"face_with_symbols_on_mouth":{"id":"face_with_symbols_on_mouth","name":"Face with Symbols on Mouth","keywords":["serious","covering","swearing","cursing","cussing","profanity","expletive"],"skins":[{"unified":"1f92c","native":"🤬"}],"version":5},"smiling_imp":{"id":"smiling_imp","name":"Smiling Face with Horns","keywords":["imp","devil"],"skins":[{"unified":"1f608","native":"😈"}],"version":1},"imp":{"id":"imp","name":"Imp","keywords":["angry","face","with","horns","devil"],"skins":[{"unified":"1f47f","native":"👿"}],"version":1},"skull":{"id":"skull","name":"Skull","keywords":["dead","skeleton","creepy","death"],"skins":[{"unified":"1f480","native":"💀"}],"version":1},"skull_and_crossbones":{"id":"skull_and_crossbones","name":"Skull and Crossbones","keywords":["poison","danger","deadly","scary","death","pirate","evil"],"skins":[{"unified":"2620-fe0f","native":"☠️"}],"version":1},"hankey":{"id":"hankey","name":"Pile of Poo","keywords":["hankey","poop","shit","shitface","fail","turd"],"skins":[{"unified":"1f4a9","native":"💩"}],"version":1},"clown_face":{"id":"clown_face","name":"Clown Face","keywords":[],"skins":[{"unified":"1f921","native":"🤡"}],"version":3},"japanese_ogre":{"id":"japanese_ogre","name":"Ogre","keywords":["japanese","monster","red","mask","halloween","scary","creepy","devil","demon"],"skins":[{"unified":"1f479","native":"👹"}],"version":1},"japanese_goblin":{"id":"japanese_goblin","name":"Goblin","keywords":["japanese","red","evil","mask","monster","scary","creepy"],"skins":[{"unified":"1f47a","native":"👺"}],"version":1},"ghost":{"id":"ghost","name":"Ghost","keywords":["halloween","spooky","scary"],"skins":[{"unified":"1f47b","native":"👻"}],"version":1},"alien":{"id":"alien","name":"Alien","keywords":["UFO","paul","weird","outer","space"],"skins":[{"unified":"1f47d","native":"👽"}],"version":1},"space_invader":{"id":"space_invader","name":"Alien Monster","keywords":["space","invader","game","arcade","play"],"skins":[{"unified":"1f47e","native":"👾"}],"version":1},"robot_face":{"id":"robot_face","name":"Robot","keywords":["face","computer","machine","bot"],"skins":[{"unified":"1f916","native":"🤖"}],"version":1},"smiley_cat":{"id":"smiley_cat","name":"Grinning Cat","keywords":["smiley","animal","cats","happy","smile"],"skins":[{"unified":"1f63a","native":"😺"}],"version":1},"smile_cat":{"id":"smile_cat","name":"Grinning Cat with Smiling Eyes","keywords":["smile","animal","cats"],"skins":[{"unified":"1f638","native":"😸"}],"version":1},"joy_cat":{"id":"joy_cat","name":"Cat with Tears of Joy","keywords":["animal","cats","haha","happy"],"skins":[{"unified":"1f639","native":"😹"}],"version":1},"heart_eyes_cat":{"id":"heart_eyes_cat","name":"Smiling Cat with Heart-Eyes","keywords":["heart","eyes","animal","love","like","affection","cats","valentines"],"skins":[{"unified":"1f63b","native":"😻"}],"version":1},"smirk_cat":{"id":"smirk_cat","name":"Cat with Wry Smile","keywords":["smirk","animal","cats"],"skins":[{"unified":"1f63c","native":"😼"}],"version":1},"kissing_cat":{"id":"kissing_cat","name":"Kissing Cat","keywords":["animal","cats","kiss"],"skins":[{"unified":"1f63d","native":"😽"}],"version":1},"scream_cat":{"id":"scream_cat","name":"Weary Cat","keywords":["scream","animal","cats","munch","scared"],"skins":[{"unified":"1f640","native":"🙀"}],"version":1},"crying_cat_face":{"id":"crying_cat_face","name":"Crying Cat","keywords":["face","animal","tears","weep","sad","cats","upset","cry"],"skins":[{"unified":"1f63f","native":"😿"}],"version":1},"pouting_cat":{"id":"pouting_cat","name":"Pouting Cat","keywords":["animal","cats"],"skins":[{"unified":"1f63e","native":"😾"}],"version":1},"see_no_evil":{"id":"see_no_evil","name":"See-No-Evil Monkey","keywords":["see","no","evil","animal","nature","haha"],"skins":[{"unified":"1f648","native":"🙈"}],"version":1},"hear_no_evil":{"id":"hear_no_evil","name":"Hear-No-Evil Monkey","keywords":["hear","no","evil","animal","nature"],"skins":[{"unified":"1f649","native":"🙉"}],"version":1},"speak_no_evil":{"id":"speak_no_evil","name":"Speak-No-Evil Monkey","keywords":["speak","no","evil","animal","nature","omg"],"skins":[{"unified":"1f64a","native":"🙊"}],"version":1},"love_letter":{"id":"love_letter","name":"Love Letter","keywords":["email","like","affection","envelope","valentines"],"skins":[{"unified":"1f48c","native":"💌"}],"version":1},"cupid":{"id":"cupid","name":"Heart with Arrow","keywords":["cupid","love","like","affection","valentines"],"skins":[{"unified":"1f498","native":"💘"}],"version":1},"gift_heart":{"id":"gift_heart","name":"Heart with Ribbon","keywords":["gift","love","valentines"],"skins":[{"unified":"1f49d","native":"💝"}],"version":1},"sparkling_heart":{"id":"sparkling_heart","name":"Sparkling Heart","keywords":["love","like","affection","valentines"],"skins":[{"unified":"1f496","native":"💖"}],"version":1},"heartpulse":{"id":"heartpulse","name":"Growing Heart","keywords":["heartpulse","like","love","affection","valentines","pink"],"skins":[{"unified":"1f497","native":"💗"}],"version":1},"heartbeat":{"id":"heartbeat","name":"Beating Heart","keywords":["heartbeat","love","like","affection","valentines","pink"],"skins":[{"unified":"1f493","native":"💓"}],"version":1},"revolving_hearts":{"id":"revolving_hearts","name":"Revolving Hearts","keywords":["love","like","affection","valentines"],"skins":[{"unified":"1f49e","native":"💞"}],"version":1},"two_hearts":{"id":"two_hearts","name":"Two Hearts","keywords":["love","like","affection","valentines","heart"],"skins":[{"unified":"1f495","native":"💕"}],"version":1},"heart_decoration":{"id":"heart_decoration","name":"Heart Decoration","keywords":["purple","square","love","like"],"skins":[{"unified":"1f49f","native":"💟"}],"version":1},"heavy_heart_exclamation_mark_ornament":{"id":"heavy_heart_exclamation_mark_ornament","name":"Heart Exclamation","keywords":["heavy","mark","ornament","decoration","love"],"skins":[{"unified":"2763-fe0f","native":"❣️"}],"version":1},"broken_heart":{"id":"broken_heart","name":"Broken Heart","emoticons":["3"],"keywords":["sad","sorry","break","heartbreak"],"skins":[{"unified":"1f494","native":"💔"}],"version":1},"heart_on_fire":{"id":"heart_on_fire","name":"Heart on Fire","keywords":["passionate","enthusiastic"],"skins":[{"unified":"2764-fe0f-200d-1f525","native":"❤️🔥"}],"version":13.1},"mending_heart":{"id":"mending_heart","name":"Mending Heart","keywords":["broken","bandage","wounded"],"skins":[{"unified":"2764-fe0f-200d-1fa79","native":"❤️🩹"}],"version":13.1},"heart":{"id":"heart","name":"Red Heart","emoticons":["<3"],"keywords":["love","like","valentines"],"skins":[{"unified":"2764-fe0f","native":"❤️"}],"version":1},"pink_heart":{"id":"pink_heart","name":"Pink Heart","keywords":["valentines"],"skins":[{"unified":"1fa77","native":"🩷"}],"version":15},"orange_heart":{"id":"orange_heart","name":"Orange Heart","keywords":["love","like","affection","valentines"],"skins":[{"unified":"1f9e1","native":"🧡"}],"version":5},"yellow_heart":{"id":"yellow_heart","name":"Yellow Heart","emoticons":["<3"],"keywords":["love","like","affection","valentines"],"skins":[{"unified":"1f49b","native":"💛"}],"version":1},"green_heart":{"id":"green_heart","name":"Green Heart","emoticons":["<3"],"keywords":["love","like","affection","valentines"],"skins":[{"unified":"1f49a","native":"💚"}],"version":1},"blue_heart":{"id":"blue_heart","name":"Blue Heart","emoticons":["<3"],"keywords":["love","like","affection","valentines"],"skins":[{"unified":"1f499","native":"💙"}],"version":1},"light_blue_heart":{"id":"light_blue_heart","name":"Light Blue Heart","keywords":["ice","baby"],"skins":[{"unified":"1fa75","native":"🩵"}],"version":15},"purple_heart":{"id":"purple_heart","name":"Purple Heart","emoticons":["<3"],"keywords":["love","like","affection","valentines"],"skins":[{"unified":"1f49c","native":"💜"}],"version":1},"brown_heart":{"id":"brown_heart","name":"Brown Heart","keywords":["coffee"],"skins":[{"unified":"1f90e","native":"🤎"}],"version":12},"black_heart":{"id":"black_heart","name":"Black Heart","keywords":["evil"],"skins":[{"unified":"1f5a4","native":"🖤"}],"version":3},"grey_heart":{"id":"grey_heart","name":"Grey Heart","keywords":["silver","monochrome"],"skins":[{"unified":"1fa76","native":"🩶"}],"version":15},"white_heart":{"id":"white_heart","name":"White Heart","keywords":["pure"],"skins":[{"unified":"1f90d","native":"🤍"}],"version":12},"kiss":{"id":"kiss","name":"Kiss Mark","keywords":["face","lips","love","like","affection","valentines"],"skins":[{"unified":"1f48b","native":"💋"}],"version":1},"anger":{"id":"anger","name":"Anger Symbol","keywords":["angry","mad"],"skins":[{"unified":"1f4a2","native":"💢"}],"version":1},"boom":{"id":"boom","name":"Collision","keywords":["boom","bomb","explode","explosion","blown"],"skins":[{"unified":"1f4a5","native":"💥"}],"version":1},"dizzy":{"id":"dizzy","name":"Dizzy","keywords":["star","sparkle","shoot","magic"],"skins":[{"unified":"1f4ab","native":"💫"}],"version":1},"sweat_drops":{"id":"sweat_drops","name":"Sweat Droplets","keywords":["drops","water","drip","oops"],"skins":[{"unified":"1f4a6","native":"💦"}],"version":1},"dash":{"id":"dash","name":"Dash Symbol","keywords":["dashing","away","wind","air","fast","shoo","fart","smoke","puff"],"skins":[{"unified":"1f4a8","native":"💨"}],"version":1},"hole":{"id":"hole","name":"Hole","keywords":["embarrassing"],"skins":[{"unified":"1f573-fe0f","native":"🕳️"}],"version":1},"speech_balloon":{"id":"speech_balloon","name":"Speech Balloon","keywords":["bubble","words","message","talk","chatting"],"skins":[{"unified":"1f4ac","native":"💬"}],"version":1},"eye-in-speech-bubble":{"id":"eye-in-speech-bubble","name":"Eye in Speech Bubble","keywords":["in-speech-bubble","info"],"skins":[{"unified":"1f441-fe0f-200d-1f5e8-fe0f","native":"👁️🗨️"}],"version":2},"left_speech_bubble":{"id":"left_speech_bubble","name":"Left Speech Bubble","keywords":["words","message","talk","chatting"],"skins":[{"unified":"1f5e8-fe0f","native":"🗨️"}],"version":2},"right_anger_bubble":{"id":"right_anger_bubble","name":"Right Anger Bubble","keywords":["caption","speech","thinking","mad"],"skins":[{"unified":"1f5ef-fe0f","native":"🗯️"}],"version":1},"thought_balloon":{"id":"thought_balloon","name":"Thought Balloon","keywords":["bubble","cloud","speech","thinking","dream"],"skins":[{"unified":"1f4ad","native":"💭"}],"version":1},"zzz":{"id":"zzz","name":"Zzz","keywords":["sleepy","tired","dream"],"skins":[{"unified":"1f4a4","native":"💤"}],"version":1},"wave":{"id":"wave","name":"Waving Hand","keywords":["wave","hands","gesture","goodbye","solong","farewell","hello","hi","palm"],"skins":[{"unified":"1f44b","native":"👋"},{"unified":"1f44b-1f3fb","native":"👋🏻"},{"unified":"1f44b-1f3fc","native":"👋🏼"},{"unified":"1f44b-1f3fd","native":"👋🏽"},{"unified":"1f44b-1f3fe","native":"👋🏾"},{"unified":"1f44b-1f3ff","native":"👋🏿"}],"version":1},"raised_back_of_hand":{"id":"raised_back_of_hand","name":"Raised Back of Hand","keywords":["fingers","backhand"],"skins":[{"unified":"1f91a","native":"🤚"},{"unified":"1f91a-1f3fb","native":"🤚🏻"},{"unified":"1f91a-1f3fc","native":"🤚🏼"},{"unified":"1f91a-1f3fd","native":"🤚🏽"},{"unified":"1f91a-1f3fe","native":"🤚🏾"},{"unified":"1f91a-1f3ff","native":"🤚🏿"}],"version":3},"raised_hand_with_fingers_splayed":{"id":"raised_hand_with_fingers_splayed","name":"Hand with Fingers Splayed","keywords":["raised","palm"],"skins":[{"unified":"1f590-fe0f","native":"🖐️"},{"unified":"1f590-1f3fb","native":"🖐🏻"},{"unified":"1f590-1f3fc","native":"🖐🏼"},{"unified":"1f590-1f3fd","native":"🖐🏽"},{"unified":"1f590-1f3fe","native":"🖐🏾"},{"unified":"1f590-1f3ff","native":"🖐🏿"}],"version":1},"hand":{"id":"hand","name":"Raised Hand","keywords":["fingers","stop","highfive","high","five","palm","ban"],"skins":[{"unified":"270b","native":"✋"},{"unified":"270b-1f3fb","native":"✋🏻"},{"unified":"270b-1f3fc","native":"✋🏼"},{"unified":"270b-1f3fd","native":"✋🏽"},{"unified":"270b-1f3fe","native":"✋🏾"},{"unified":"270b-1f3ff","native":"✋🏿"}],"version":1},"spock-hand":{"id":"spock-hand","name":"Vulcan Salute","keywords":["spock","hand","fingers","star","trek"],"skins":[{"unified":"1f596","native":"🖖"},{"unified":"1f596-1f3fb","native":"🖖🏻"},{"unified":"1f596-1f3fc","native":"🖖🏼"},{"unified":"1f596-1f3fd","native":"🖖🏽"},{"unified":"1f596-1f3fe","native":"🖖🏾"},{"unified":"1f596-1f3ff","native":"🖖🏿"}],"version":1},"rightwards_hand":{"id":"rightwards_hand","name":"Rightwards Hand","keywords":["palm","offer"],"skins":[{"unified":"1faf1","native":"🫱"},{"unified":"1faf1-1f3fb","native":"🫱🏻"},{"unified":"1faf1-1f3fc","native":"🫱🏼"},{"unified":"1faf1-1f3fd","native":"🫱🏽"},{"unified":"1faf1-1f3fe","native":"🫱🏾"},{"unified":"1faf1-1f3ff","native":"🫱🏿"}],"version":14},"leftwards_hand":{"id":"leftwards_hand","name":"Leftwards Hand","keywords":["palm","offer"],"skins":[{"unified":"1faf2","native":"🫲"},{"unified":"1faf2-1f3fb","native":"🫲🏻"},{"unified":"1faf2-1f3fc","native":"🫲🏼"},{"unified":"1faf2-1f3fd","native":"🫲🏽"},{"unified":"1faf2-1f3fe","native":"🫲🏾"},{"unified":"1faf2-1f3ff","native":"🫲🏿"}],"version":14},"palm_down_hand":{"id":"palm_down_hand","name":"Palm Down Hand","keywords":["drop"],"skins":[{"unified":"1faf3","native":"🫳"},{"unified":"1faf3-1f3fb","native":"🫳🏻"},{"unified":"1faf3-1f3fc","native":"🫳🏼"},{"unified":"1faf3-1f3fd","native":"🫳🏽"},{"unified":"1faf3-1f3fe","native":"🫳🏾"},{"unified":"1faf3-1f3ff","native":"🫳🏿"}],"version":14},"palm_up_hand":{"id":"palm_up_hand","name":"Palm Up Hand","keywords":["lift","offer","demand"],"skins":[{"unified":"1faf4","native":"🫴"},{"unified":"1faf4-1f3fb","native":"🫴🏻"},{"unified":"1faf4-1f3fc","native":"🫴🏼"},{"unified":"1faf4-1f3fd","native":"🫴🏽"},{"unified":"1faf4-1f3fe","native":"🫴🏾"},{"unified":"1faf4-1f3ff","native":"🫴🏿"}],"version":14},"leftwards_pushing_hand":{"id":"leftwards_pushing_hand","name":"Leftwards Pushing Hand","keywords":["highfive","high","five","pressing","stop"],"skins":[{"unified":"1faf7","native":"🫷"},{"unified":"1faf7-1f3fb","native":"🫷🏻"},{"unified":"1faf7-1f3fc","native":"🫷🏼"},{"unified":"1faf7-1f3fd","native":"🫷🏽"},{"unified":"1faf7-1f3fe","native":"🫷🏾"},{"unified":"1faf7-1f3ff","native":"🫷🏿"}],"version":15},"rightwards_pushing_hand":{"id":"rightwards_pushing_hand","name":"Rightwards Pushing Hand","keywords":["highfive","high","five","pressing","stop"],"skins":[{"unified":"1faf8","native":"🫸"},{"unified":"1faf8-1f3fb","native":"🫸🏻"},{"unified":"1faf8-1f3fc","native":"🫸🏼"},{"unified":"1faf8-1f3fd","native":"🫸🏽"},{"unified":"1faf8-1f3fe","native":"🫸🏾"},{"unified":"1faf8-1f3ff","native":"🫸🏿"}],"version":15},"ok_hand":{"id":"ok_hand","name":"Ok Hand","keywords":["fingers","limbs","perfect","okay"],"skins":[{"unified":"1f44c","native":"👌"},{"unified":"1f44c-1f3fb","native":"👌🏻"},{"unified":"1f44c-1f3fc","native":"👌🏼"},{"unified":"1f44c-1f3fd","native":"👌🏽"},{"unified":"1f44c-1f3fe","native":"👌🏾"},{"unified":"1f44c-1f3ff","native":"👌🏿"}],"version":1},"pinched_fingers":{"id":"pinched_fingers","name":"Pinched Fingers","keywords":["size","tiny","small"],"skins":[{"unified":"1f90c","native":"🤌"},{"unified":"1f90c-1f3fb","native":"🤌🏻"},{"unified":"1f90c-1f3fc","native":"🤌🏼"},{"unified":"1f90c-1f3fd","native":"🤌🏽"},{"unified":"1f90c-1f3fe","native":"🤌🏾"},{"unified":"1f90c-1f3ff","native":"🤌🏿"}],"version":13},"pinching_hand":{"id":"pinching_hand","name":"Pinching Hand","keywords":["tiny","small","size"],"skins":[{"unified":"1f90f","native":"🤏"},{"unified":"1f90f-1f3fb","native":"🤏🏻"},{"unified":"1f90f-1f3fc","native":"🤏🏼"},{"unified":"1f90f-1f3fd","native":"🤏🏽"},{"unified":"1f90f-1f3fe","native":"🤏🏾"},{"unified":"1f90f-1f3ff","native":"🤏🏿"}],"version":12},"v":{"id":"v","name":"Victory Hand","keywords":["v","fingers","ohyeah","peace","two"],"skins":[{"unified":"270c-fe0f","native":"✌️"},{"unified":"270c-1f3fb","native":"✌🏻"},{"unified":"270c-1f3fc","native":"✌🏼"},{"unified":"270c-1f3fd","native":"✌🏽"},{"unified":"270c-1f3fe","native":"✌🏾"},{"unified":"270c-1f3ff","native":"✌🏿"}],"version":1},"crossed_fingers":{"id":"crossed_fingers","name":"Crossed Fingers","keywords":["hand","with","index","and","middle","good","lucky"],"skins":[{"unified":"1f91e","native":"🤞"},{"unified":"1f91e-1f3fb","native":"🤞🏻"},{"unified":"1f91e-1f3fc","native":"🤞🏼"},{"unified":"1f91e-1f3fd","native":"🤞🏽"},{"unified":"1f91e-1f3fe","native":"🤞🏾"},{"unified":"1f91e-1f3ff","native":"🤞🏿"}],"version":3},"hand_with_index_finger_and_thumb_crossed":{"id":"hand_with_index_finger_and_thumb_crossed","name":"Hand with Index Finger and Thumb Crossed","keywords":["heart","love","money","expensive"],"skins":[{"unified":"1faf0","native":"🫰"},{"unified":"1faf0-1f3fb","native":"🫰🏻"},{"unified":"1faf0-1f3fc","native":"🫰🏼"},{"unified":"1faf0-1f3fd","native":"🫰🏽"},{"unified":"1faf0-1f3fe","native":"🫰🏾"},{"unified":"1faf0-1f3ff","native":"🫰🏿"}],"version":14},"i_love_you_hand_sign":{"id":"i_love_you_hand_sign","name":"Love-You Gesture","keywords":["i","love","you","hand","sign","fingers"],"skins":[{"unified":"1f91f","native":"🤟"},{"unified":"1f91f-1f3fb","native":"🤟🏻"},{"unified":"1f91f-1f3fc","native":"🤟🏼"},{"unified":"1f91f-1f3fd","native":"🤟🏽"},{"unified":"1f91f-1f3fe","native":"🤟🏾"},{"unified":"1f91f-1f3ff","native":"🤟🏿"}],"version":5},"the_horns":{"id":"the_horns","name":"Sign of the Horns","keywords":["hand","fingers","evil","eye","rock","on"],"skins":[{"unified":"1f918","native":"🤘"},{"unified":"1f918-1f3fb","native":"🤘🏻"},{"unified":"1f918-1f3fc","native":"🤘🏼"},{"unified":"1f918-1f3fd","native":"🤘🏽"},{"unified":"1f918-1f3fe","native":"🤘🏾"},{"unified":"1f918-1f3ff","native":"🤘🏿"}],"version":1},"call_me_hand":{"id":"call_me_hand","name":"Call Me Hand","keywords":["hands","gesture","shaka"],"skins":[{"unified":"1f919","native":"🤙"},{"unified":"1f919-1f3fb","native":"🤙🏻"},{"unified":"1f919-1f3fc","native":"🤙🏼"},{"unified":"1f919-1f3fd","native":"🤙🏽"},{"unified":"1f919-1f3fe","native":"🤙🏾"},{"unified":"1f919-1f3ff","native":"🤙🏿"}],"version":3},"point_left":{"id":"point_left","name":"Backhand Index Pointing Left","keywords":["point","direction","fingers","hand"],"skins":[{"unified":"1f448","native":"👈"},{"unified":"1f448-1f3fb","native":"👈🏻"},{"unified":"1f448-1f3fc","native":"👈🏼"},{"unified":"1f448-1f3fd","native":"👈🏽"},{"unified":"1f448-1f3fe","native":"👈🏾"},{"unified":"1f448-1f3ff","native":"👈🏿"}],"version":1},"point_right":{"id":"point_right","name":"Backhand Index Pointing Right","keywords":["point","fingers","hand","direction"],"skins":[{"unified":"1f449","native":"👉"},{"unified":"1f449-1f3fb","native":"👉🏻"},{"unified":"1f449-1f3fc","native":"👉🏼"},{"unified":"1f449-1f3fd","native":"👉🏽"},{"unified":"1f449-1f3fe","native":"👉🏾"},{"unified":"1f449-1f3ff","native":"👉🏿"}],"version":1},"point_up_2":{"id":"point_up_2","name":"Backhand Index Pointing Up","keywords":["point","2","fingers","hand","direction"],"skins":[{"unified":"1f446","native":"👆"},{"unified":"1f446-1f3fb","native":"👆🏻"},{"unified":"1f446-1f3fc","native":"👆🏼"},{"unified":"1f446-1f3fd","native":"👆🏽"},{"unified":"1f446-1f3fe","native":"👆🏾"},{"unified":"1f446-1f3ff","native":"👆🏿"}],"version":1},"middle_finger":{"id":"middle_finger","name":"Middle Finger","keywords":["reversed","hand","with","extended","fingers","rude","flipping"],"skins":[{"unified":"1f595","native":"🖕"},{"unified":"1f595-1f3fb","native":"🖕🏻"},{"unified":"1f595-1f3fc","native":"🖕🏼"},{"unified":"1f595-1f3fd","native":"🖕🏽"},{"unified":"1f595-1f3fe","native":"🖕🏾"},{"unified":"1f595-1f3ff","native":"🖕🏿"}],"version":1},"point_down":{"id":"point_down","name":"Backhand Index Pointing Down","keywords":["point","fingers","hand","direction"],"skins":[{"unified":"1f447","native":"👇"},{"unified":"1f447-1f3fb","native":"👇🏻"},{"unified":"1f447-1f3fc","native":"👇🏼"},{"unified":"1f447-1f3fd","native":"👇🏽"},{"unified":"1f447-1f3fe","native":"👇🏾"},{"unified":"1f447-1f3ff","native":"👇🏿"}],"version":1},"point_up":{"id":"point_up","name":"Index Pointing Up","keywords":["point","hand","fingers","direction"],"skins":[{"unified":"261d-fe0f","native":"☝️"},{"unified":"261d-1f3fb","native":"☝🏻"},{"unified":"261d-1f3fc","native":"☝🏼"},{"unified":"261d-1f3fd","native":"☝🏽"},{"unified":"261d-1f3fe","native":"☝🏾"},{"unified":"261d-1f3ff","native":"☝🏿"}],"version":1},"index_pointing_at_the_viewer":{"id":"index_pointing_at_the_viewer","name":"Index Pointing at the Viewer","keywords":["you","recruit"],"skins":[{"unified":"1faf5","native":"🫵"},{"unified":"1faf5-1f3fb","native":"🫵🏻"},{"unified":"1faf5-1f3fc","native":"🫵🏼"},{"unified":"1faf5-1f3fd","native":"🫵🏽"},{"unified":"1faf5-1f3fe","native":"🫵🏾"},{"unified":"1faf5-1f3ff","native":"🫵🏿"}],"version":14},"+1":{"id":"+1","name":"Thumbs Up","keywords":["+1","thumbsup","yes","awesome","good","agree","accept","cool","hand","like"],"skins":[{"unified":"1f44d","native":"👍"},{"unified":"1f44d-1f3fb","native":"👍🏻"},{"unified":"1f44d-1f3fc","native":"👍🏼"},{"unified":"1f44d-1f3fd","native":"👍🏽"},{"unified":"1f44d-1f3fe","native":"👍🏾"},{"unified":"1f44d-1f3ff","native":"👍🏿"}],"version":1},"-1":{"id":"-1","name":"Thumbs Down","keywords":["-1","thumbsdown","no","dislike","hand"],"skins":[{"unified":"1f44e","native":"👎"},{"unified":"1f44e-1f3fb","native":"👎🏻"},{"unified":"1f44e-1f3fc","native":"👎🏼"},{"unified":"1f44e-1f3fd","native":"👎🏽"},{"unified":"1f44e-1f3fe","native":"👎🏾"},{"unified":"1f44e-1f3ff","native":"👎🏿"}],"version":1},"fist":{"id":"fist","name":"Raised Fist","keywords":["fingers","hand","grasp"],"skins":[{"unified":"270a","native":"✊"},{"unified":"270a-1f3fb","native":"✊🏻"},{"unified":"270a-1f3fc","native":"✊🏼"},{"unified":"270a-1f3fd","native":"✊🏽"},{"unified":"270a-1f3fe","native":"✊🏾"},{"unified":"270a-1f3ff","native":"✊🏿"}],"version":1},"facepunch":{"id":"facepunch","name":"Oncoming Fist","keywords":["facepunch","punch","angry","violence","hit","attack","hand"],"skins":[{"unified":"1f44a","native":"👊"},{"unified":"1f44a-1f3fb","native":"👊🏻"},{"unified":"1f44a-1f3fc","native":"👊🏼"},{"unified":"1f44a-1f3fd","native":"👊🏽"},{"unified":"1f44a-1f3fe","native":"👊🏾"},{"unified":"1f44a-1f3ff","native":"👊🏿"}],"version":1},"left-facing_fist":{"id":"left-facing_fist","name":"Left-Facing Fist","keywords":["left","facing","hand","fistbump"],"skins":[{"unified":"1f91b","native":"🤛"},{"unified":"1f91b-1f3fb","native":"🤛🏻"},{"unified":"1f91b-1f3fc","native":"🤛🏼"},{"unified":"1f91b-1f3fd","native":"🤛🏽"},{"unified":"1f91b-1f3fe","native":"🤛🏾"},{"unified":"1f91b-1f3ff","native":"🤛🏿"}],"version":3},"right-facing_fist":{"id":"right-facing_fist","name":"Right-Facing Fist","keywords":["right","facing","hand","fistbump"],"skins":[{"unified":"1f91c","native":"🤜"},{"unified":"1f91c-1f3fb","native":"🤜🏻"},{"unified":"1f91c-1f3fc","native":"🤜🏼"},{"unified":"1f91c-1f3fd","native":"🤜🏽"},{"unified":"1f91c-1f3fe","native":"🤜🏾"},{"unified":"1f91c-1f3ff","native":"🤜🏿"}],"version":3},"clap":{"id":"clap","name":"Clapping Hands","keywords":["clap","praise","applause","congrats","yay"],"skins":[{"unified":"1f44f","native":"👏"},{"unified":"1f44f-1f3fb","native":"👏🏻"},{"unified":"1f44f-1f3fc","native":"👏🏼"},{"unified":"1f44f-1f3fd","native":"👏🏽"},{"unified":"1f44f-1f3fe","native":"👏🏾"},{"unified":"1f44f-1f3ff","native":"👏🏿"}],"version":1},"raised_hands":{"id":"raised_hands","name":"Raising Hands","keywords":["raised","gesture","hooray","yea","celebration"],"skins":[{"unified":"1f64c","native":"🙌"},{"unified":"1f64c-1f3fb","native":"🙌🏻"},{"unified":"1f64c-1f3fc","native":"🙌🏼"},{"unified":"1f64c-1f3fd","native":"🙌🏽"},{"unified":"1f64c-1f3fe","native":"🙌🏾"},{"unified":"1f64c-1f3ff","native":"🙌🏿"}],"version":1},"heart_hands":{"id":"heart_hands","name":"Heart Hands","keywords":["love","appreciation","support"],"skins":[{"unified":"1faf6","native":"🫶"},{"unified":"1faf6-1f3fb","native":"🫶🏻"},{"unified":"1faf6-1f3fc","native":"🫶🏼"},{"unified":"1faf6-1f3fd","native":"🫶🏽"},{"unified":"1faf6-1f3fe","native":"🫶🏾"},{"unified":"1faf6-1f3ff","native":"🫶🏿"}],"version":14},"open_hands":{"id":"open_hands","name":"Open Hands","keywords":["fingers","butterfly"],"skins":[{"unified":"1f450","native":"👐"},{"unified":"1f450-1f3fb","native":"👐🏻"},{"unified":"1f450-1f3fc","native":"👐🏼"},{"unified":"1f450-1f3fd","native":"👐🏽"},{"unified":"1f450-1f3fe","native":"👐🏾"},{"unified":"1f450-1f3ff","native":"👐🏿"}],"version":1},"palms_up_together":{"id":"palms_up_together","name":"Palms Up Together","keywords":["hands","gesture","cupped","prayer"],"skins":[{"unified":"1f932","native":"🤲"},{"unified":"1f932-1f3fb","native":"🤲🏻"},{"unified":"1f932-1f3fc","native":"🤲🏼"},{"unified":"1f932-1f3fd","native":"🤲🏽"},{"unified":"1f932-1f3fe","native":"🤲🏾"},{"unified":"1f932-1f3ff","native":"🤲🏿"}],"version":5},"handshake":{"id":"handshake","name":"Handshake","keywords":["agreement","shake"],"skins":[{"unified":"1f91d","native":"🤝"},{"unified":"1f91d-1f3fb","native":"🤝🏻"},{"unified":"1f91d-1f3fc","native":"🤝🏼"},{"unified":"1f91d-1f3fd","native":"🤝🏽"},{"unified":"1f91d-1f3fe","native":"🤝🏾"},{"unified":"1f91d-1f3ff","native":"🤝🏿"}],"version":3},"pray":{"id":"pray","name":"Folded Hands","keywords":["pray","please","hope","wish","namaste","highfive","high","five","thank","you","thanks","appreciate"],"skins":[{"unified":"1f64f","native":"🙏"},{"unified":"1f64f-1f3fb","native":"🙏🏻"},{"unified":"1f64f-1f3fc","native":"🙏🏼"},{"unified":"1f64f-1f3fd","native":"🙏🏽"},{"unified":"1f64f-1f3fe","native":"🙏🏾"},{"unified":"1f64f-1f3ff","native":"🙏🏿"}],"version":1},"writing_hand":{"id":"writing_hand","name":"Writing Hand","keywords":["lower","left","ballpoint","pen","stationery","write","compose"],"skins":[{"unified":"270d-fe0f","native":"✍️"},{"unified":"270d-1f3fb","native":"✍🏻"},{"unified":"270d-1f3fc","native":"✍🏼"},{"unified":"270d-1f3fd","native":"✍🏽"},{"unified":"270d-1f3fe","native":"✍🏾"},{"unified":"270d-1f3ff","native":"✍🏿"}],"version":1},"nail_care":{"id":"nail_care","name":"Nail Polish","keywords":["care","beauty","manicure","finger","fashion"],"skins":[{"unified":"1f485","native":"💅"},{"unified":"1f485-1f3fb","native":"💅🏻"},{"unified":"1f485-1f3fc","native":"💅🏼"},{"unified":"1f485-1f3fd","native":"💅🏽"},{"unified":"1f485-1f3fe","native":"💅🏾"},{"unified":"1f485-1f3ff","native":"💅🏿"}],"version":1},"selfie":{"id":"selfie","name":"Selfie","keywords":["camera","phone"],"skins":[{"unified":"1f933","native":"🤳"},{"unified":"1f933-1f3fb","native":"🤳🏻"},{"unified":"1f933-1f3fc","native":"🤳🏼"},{"unified":"1f933-1f3fd","native":"🤳🏽"},{"unified":"1f933-1f3fe","native":"🤳🏾"},{"unified":"1f933-1f3ff","native":"🤳🏿"}],"version":3},"muscle":{"id":"muscle","name":"Flexed Biceps","keywords":["muscle","arm","flex","hand","summer","strong"],"skins":[{"unified":"1f4aa","native":"💪"},{"unified":"1f4aa-1f3fb","native":"💪🏻"},{"unified":"1f4aa-1f3fc","native":"💪🏼"},{"unified":"1f4aa-1f3fd","native":"💪🏽"},{"unified":"1f4aa-1f3fe","native":"💪🏾"},{"unified":"1f4aa-1f3ff","native":"💪🏿"}],"version":1},"mechanical_arm":{"id":"mechanical_arm","name":"Mechanical Arm","keywords":["accessibility"],"skins":[{"unified":"1f9be","native":"🦾"}],"version":12},"mechanical_leg":{"id":"mechanical_leg","name":"Mechanical Leg","keywords":["accessibility"],"skins":[{"unified":"1f9bf","native":"🦿"}],"version":12},"leg":{"id":"leg","name":"Leg","keywords":["kick","limb"],"skins":[{"unified":"1f9b5","native":"🦵"},{"unified":"1f9b5-1f3fb","native":"🦵🏻"},{"unified":"1f9b5-1f3fc","native":"🦵🏼"},{"unified":"1f9b5-1f3fd","native":"🦵🏽"},{"unified":"1f9b5-1f3fe","native":"🦵🏾"},{"unified":"1f9b5-1f3ff","native":"🦵🏿"}],"version":11},"foot":{"id":"foot","name":"Foot","keywords":["kick","stomp"],"skins":[{"unified":"1f9b6","native":"🦶"},{"unified":"1f9b6-1f3fb","native":"🦶🏻"},{"unified":"1f9b6-1f3fc","native":"🦶🏼"},{"unified":"1f9b6-1f3fd","native":"🦶🏽"},{"unified":"1f9b6-1f3fe","native":"🦶🏾"},{"unified":"1f9b6-1f3ff","native":"🦶🏿"}],"version":11},"ear":{"id":"ear","name":"Ear","keywords":["face","hear","sound","listen"],"skins":[{"unified":"1f442","native":"👂"},{"unified":"1f442-1f3fb","native":"👂🏻"},{"unified":"1f442-1f3fc","native":"👂🏼"},{"unified":"1f442-1f3fd","native":"👂🏽"},{"unified":"1f442-1f3fe","native":"👂🏾"},{"unified":"1f442-1f3ff","native":"👂🏿"}],"version":1},"ear_with_hearing_aid":{"id":"ear_with_hearing_aid","name":"Ear with Hearing Aid","keywords":["accessibility"],"skins":[{"unified":"1f9bb","native":"🦻"},{"unified":"1f9bb-1f3fb","native":"🦻🏻"},{"unified":"1f9bb-1f3fc","native":"🦻🏼"},{"unified":"1f9bb-1f3fd","native":"🦻🏽"},{"unified":"1f9bb-1f3fe","native":"🦻🏾"},{"unified":"1f9bb-1f3ff","native":"🦻🏿"}],"version":12},"nose":{"id":"nose","name":"Nose","keywords":["smell","sniff"],"skins":[{"unified":"1f443","native":"👃"},{"unified":"1f443-1f3fb","native":"👃🏻"},{"unified":"1f443-1f3fc","native":"👃🏼"},{"unified":"1f443-1f3fd","native":"👃🏽"},{"unified":"1f443-1f3fe","native":"👃🏾"},{"unified":"1f443-1f3ff","native":"👃🏿"}],"version":1},"brain":{"id":"brain","name":"Brain","keywords":["smart","intelligent"],"skins":[{"unified":"1f9e0","native":"🧠"}],"version":5},"anatomical_heart":{"id":"anatomical_heart","name":"Anatomical Heart","keywords":["health","heartbeat"],"skins":[{"unified":"1fac0","native":"🫀"}],"version":13},"lungs":{"id":"lungs","name":"Lungs","keywords":["breathe"],"skins":[{"unified":"1fac1","native":"🫁"}],"version":13},"tooth":{"id":"tooth","name":"Tooth","keywords":["teeth","dentist"],"skins":[{"unified":"1f9b7","native":"🦷"}],"version":11},"bone":{"id":"bone","name":"Bone","keywords":["skeleton"],"skins":[{"unified":"1f9b4","native":"🦴"}],"version":11},"eyes":{"id":"eyes","name":"Eyes","keywords":["look","watch","stalk","peek","see"],"skins":[{"unified":"1f440","native":"👀"}],"version":1},"eye":{"id":"eye","name":"Eye","keywords":["face","look","see","watch","stare"],"skins":[{"unified":"1f441-fe0f","native":"👁️"}],"version":1},"tongue":{"id":"tongue","name":"Tongue","keywords":["mouth","playful"],"skins":[{"unified":"1f445","native":"👅"}],"version":1},"lips":{"id":"lips","name":"Mouth","keywords":["lips","kiss"],"skins":[{"unified":"1f444","native":"👄"}],"version":1},"biting_lip":{"id":"biting_lip","name":"Biting Lip","keywords":["flirt","sexy","pain","worry"],"skins":[{"unified":"1fae6","native":"🫦"}],"version":14},"baby":{"id":"baby","name":"Baby","keywords":["child","boy","girl","toddler"],"skins":[{"unified":"1f476","native":"👶"},{"unified":"1f476-1f3fb","native":"👶🏻"},{"unified":"1f476-1f3fc","native":"👶🏼"},{"unified":"1f476-1f3fd","native":"👶🏽"},{"unified":"1f476-1f3fe","native":"👶🏾"},{"unified":"1f476-1f3ff","native":"👶🏿"}],"version":1},"child":{"id":"child","name":"Child","keywords":["gender","neutral","young"],"skins":[{"unified":"1f9d2","native":"🧒"},{"unified":"1f9d2-1f3fb","native":"🧒🏻"},{"unified":"1f9d2-1f3fc","native":"🧒🏼"},{"unified":"1f9d2-1f3fd","native":"🧒🏽"},{"unified":"1f9d2-1f3fe","native":"🧒🏾"},{"unified":"1f9d2-1f3ff","native":"🧒🏿"}],"version":5},"boy":{"id":"boy","name":"Boy","keywords":["man","male","guy","teenager"],"skins":[{"unified":"1f466","native":"👦"},{"unified":"1f466-1f3fb","native":"👦🏻"},{"unified":"1f466-1f3fc","native":"👦🏼"},{"unified":"1f466-1f3fd","native":"👦🏽"},{"unified":"1f466-1f3fe","native":"👦🏾"},{"unified":"1f466-1f3ff","native":"👦🏿"}],"version":1},"girl":{"id":"girl","name":"Girl","keywords":["female","woman","teenager"],"skins":[{"unified":"1f467","native":"👧"},{"unified":"1f467-1f3fb","native":"👧🏻"},{"unified":"1f467-1f3fc","native":"👧🏼"},{"unified":"1f467-1f3fd","native":"👧🏽"},{"unified":"1f467-1f3fe","native":"👧🏾"},{"unified":"1f467-1f3ff","native":"👧🏿"}],"version":1},"adult":{"id":"adult","name":"Adult","keywords":["person","gender","neutral"],"skins":[{"unified":"1f9d1","native":"🧑"},{"unified":"1f9d1-1f3fb","native":"🧑🏻"},{"unified":"1f9d1-1f3fc","native":"🧑🏼"},{"unified":"1f9d1-1f3fd","native":"🧑🏽"},{"unified":"1f9d1-1f3fe","native":"🧑🏾"},{"unified":"1f9d1-1f3ff","native":"🧑🏿"}],"version":5},"person_with_blond_hair":{"id":"person_with_blond_hair","name":"Person Blond Hair","keywords":["with","hairstyle"],"skins":[{"unified":"1f471","native":"👱"},{"unified":"1f471-1f3fb","native":"👱🏻"},{"unified":"1f471-1f3fc","native":"👱🏼"},{"unified":"1f471-1f3fd","native":"👱🏽"},{"unified":"1f471-1f3fe","native":"👱🏾"},{"unified":"1f471-1f3ff","native":"👱🏿"}],"version":1},"man":{"id":"man","name":"Man","keywords":["mustache","father","dad","guy","classy","sir","moustache"],"skins":[{"unified":"1f468","native":"👨"},{"unified":"1f468-1f3fb","native":"👨🏻"},{"unified":"1f468-1f3fc","native":"👨🏼"},{"unified":"1f468-1f3fd","native":"👨🏽"},{"unified":"1f468-1f3fe","native":"👨🏾"},{"unified":"1f468-1f3ff","native":"👨🏿"}],"version":1},"bearded_person":{"id":"bearded_person","name":"Person Beard","keywords":["bearded","man","bewhiskered"],"skins":[{"unified":"1f9d4","native":"🧔"},{"unified":"1f9d4-1f3fb","native":"🧔🏻"},{"unified":"1f9d4-1f3fc","native":"🧔🏼"},{"unified":"1f9d4-1f3fd","native":"🧔🏽"},{"unified":"1f9d4-1f3fe","native":"🧔🏾"},{"unified":"1f9d4-1f3ff","native":"🧔🏿"}],"version":5},"man_with_beard":{"id":"man_with_beard","name":"Man: Beard","keywords":["man","with","facial","hair"],"skins":[{"unified":"1f9d4-200d-2642-fe0f","native":"🧔♂️"},{"unified":"1f9d4-1f3fb-200d-2642-fe0f","native":"🧔🏻♂️"},{"unified":"1f9d4-1f3fc-200d-2642-fe0f","native":"🧔🏼♂️"},{"unified":"1f9d4-1f3fd-200d-2642-fe0f","native":"🧔🏽♂️"},{"unified":"1f9d4-1f3fe-200d-2642-fe0f","native":"🧔🏾♂️"},{"unified":"1f9d4-1f3ff-200d-2642-fe0f","native":"🧔🏿♂️"}],"version":13.1},"woman_with_beard":{"id":"woman_with_beard","name":"Woman: Beard","keywords":["woman","with","facial","hair"],"skins":[{"unified":"1f9d4-200d-2640-fe0f","native":"🧔♀️"},{"unified":"1f9d4-1f3fb-200d-2640-fe0f","native":"🧔🏻♀️"},{"unified":"1f9d4-1f3fc-200d-2640-fe0f","native":"🧔🏼♀️"},{"unified":"1f9d4-1f3fd-200d-2640-fe0f","native":"🧔🏽♀️"},{"unified":"1f9d4-1f3fe-200d-2640-fe0f","native":"🧔🏾♀️"},{"unified":"1f9d4-1f3ff-200d-2640-fe0f","native":"🧔🏿♀️"}],"version":13.1},"red_haired_man":{"id":"red_haired_man","name":"Man: Red Hair","keywords":["haired","man","hairstyle"],"skins":[{"unified":"1f468-200d-1f9b0","native":"👨🦰"},{"unified":"1f468-1f3fb-200d-1f9b0","native":"👨🏻🦰"},{"unified":"1f468-1f3fc-200d-1f9b0","native":"👨🏼🦰"},{"unified":"1f468-1f3fd-200d-1f9b0","native":"👨🏽🦰"},{"unified":"1f468-1f3fe-200d-1f9b0","native":"👨🏾🦰"},{"unified":"1f468-1f3ff-200d-1f9b0","native":"👨🏿🦰"}],"version":11},"curly_haired_man":{"id":"curly_haired_man","name":"Man: Curly Hair","keywords":["haired","man","hairstyle"],"skins":[{"unified":"1f468-200d-1f9b1","native":"👨🦱"},{"unified":"1f468-1f3fb-200d-1f9b1","native":"👨🏻🦱"},{"unified":"1f468-1f3fc-200d-1f9b1","native":"👨🏼🦱"},{"unified":"1f468-1f3fd-200d-1f9b1","native":"👨🏽🦱"},{"unified":"1f468-1f3fe-200d-1f9b1","native":"👨🏾🦱"},{"unified":"1f468-1f3ff-200d-1f9b1","native":"👨🏿🦱"}],"version":11},"white_haired_man":{"id":"white_haired_man","name":"Man: White Hair","keywords":["haired","man","old","elder"],"skins":[{"unified":"1f468-200d-1f9b3","native":"👨🦳"},{"unified":"1f468-1f3fb-200d-1f9b3","native":"👨🏻🦳"},{"unified":"1f468-1f3fc-200d-1f9b3","native":"👨🏼🦳"},{"unified":"1f468-1f3fd-200d-1f9b3","native":"👨🏽🦳"},{"unified":"1f468-1f3fe-200d-1f9b3","native":"👨🏾🦳"},{"unified":"1f468-1f3ff-200d-1f9b3","native":"👨🏿🦳"}],"version":11},"bald_man":{"id":"bald_man","name":"Man: Bald","keywords":["man","hairless"],"skins":[{"unified":"1f468-200d-1f9b2","native":"👨🦲"},{"unified":"1f468-1f3fb-200d-1f9b2","native":"👨🏻🦲"},{"unified":"1f468-1f3fc-200d-1f9b2","native":"👨🏼🦲"},{"unified":"1f468-1f3fd-200d-1f9b2","native":"👨🏽🦲"},{"unified":"1f468-1f3fe-200d-1f9b2","native":"👨🏾🦲"},{"unified":"1f468-1f3ff-200d-1f9b2","native":"👨🏿🦲"}],"version":11},"woman":{"id":"woman","name":"Woman","keywords":["female","girls","lady"],"skins":[{"unified":"1f469","native":"👩"},{"unified":"1f469-1f3fb","native":"👩🏻"},{"unified":"1f469-1f3fc","native":"👩🏼"},{"unified":"1f469-1f3fd","native":"👩🏽"},{"unified":"1f469-1f3fe","native":"👩🏾"},{"unified":"1f469-1f3ff","native":"👩🏿"}],"version":1},"red_haired_woman":{"id":"red_haired_woman","name":"Woman: Red Hair","keywords":["haired","woman","hairstyle"],"skins":[{"unified":"1f469-200d-1f9b0","native":"👩🦰"},{"unified":"1f469-1f3fb-200d-1f9b0","native":"👩🏻🦰"},{"unified":"1f469-1f3fc-200d-1f9b0","native":"👩🏼🦰"},{"unified":"1f469-1f3fd-200d-1f9b0","native":"👩🏽🦰"},{"unified":"1f469-1f3fe-200d-1f9b0","native":"👩🏾🦰"},{"unified":"1f469-1f3ff-200d-1f9b0","native":"👩🏿🦰"}],"version":11},"red_haired_person":{"id":"red_haired_person","name":"Person: Red Hair","keywords":["haired","person","hairstyle"],"skins":[{"unified":"1f9d1-200d-1f9b0","native":"🧑🦰"},{"unified":"1f9d1-1f3fb-200d-1f9b0","native":"🧑🏻🦰"},{"unified":"1f9d1-1f3fc-200d-1f9b0","native":"🧑🏼🦰"},{"unified":"1f9d1-1f3fd-200d-1f9b0","native":"🧑🏽🦰"},{"unified":"1f9d1-1f3fe-200d-1f9b0","native":"🧑🏾🦰"},{"unified":"1f9d1-1f3ff-200d-1f9b0","native":"🧑🏿🦰"}],"version":12.1},"curly_haired_woman":{"id":"curly_haired_woman","name":"Woman: Curly Hair","keywords":["haired","woman","hairstyle"],"skins":[{"unified":"1f469-200d-1f9b1","native":"👩🦱"},{"unified":"1f469-1f3fb-200d-1f9b1","native":"👩🏻🦱"},{"unified":"1f469-1f3fc-200d-1f9b1","native":"👩🏼🦱"},{"unified":"1f469-1f3fd-200d-1f9b1","native":"👩🏽🦱"},{"unified":"1f469-1f3fe-200d-1f9b1","native":"👩🏾🦱"},{"unified":"1f469-1f3ff-200d-1f9b1","native":"👩🏿🦱"}],"version":11},"curly_haired_person":{"id":"curly_haired_person","name":"Person: Curly Hair","keywords":["haired","person","hairstyle"],"skins":[{"unified":"1f9d1-200d-1f9b1","native":"🧑🦱"},{"unified":"1f9d1-1f3fb-200d-1f9b1","native":"🧑🏻🦱"},{"unified":"1f9d1-1f3fc-200d-1f9b1","native":"🧑🏼🦱"},{"unified":"1f9d1-1f3fd-200d-1f9b1","native":"🧑🏽🦱"},{"unified":"1f9d1-1f3fe-200d-1f9b1","native":"🧑🏾🦱"},{"unified":"1f9d1-1f3ff-200d-1f9b1","native":"🧑🏿🦱"}],"version":12.1},"white_haired_woman":{"id":"white_haired_woman","name":"Woman: White Hair","keywords":["haired","woman","old","elder"],"skins":[{"unified":"1f469-200d-1f9b3","native":"👩🦳"},{"unified":"1f469-1f3fb-200d-1f9b3","native":"👩🏻🦳"},{"unified":"1f469-1f3fc-200d-1f9b3","native":"👩🏼🦳"},{"unified":"1f469-1f3fd-200d-1f9b3","native":"👩🏽🦳"},{"unified":"1f469-1f3fe-200d-1f9b3","native":"👩🏾🦳"},{"unified":"1f469-1f3ff-200d-1f9b3","native":"👩🏿🦳"}],"version":11},"white_haired_person":{"id":"white_haired_person","name":"Person: White Hair","keywords":["haired","person","elder","old"],"skins":[{"unified":"1f9d1-200d-1f9b3","native":"🧑🦳"},{"unified":"1f9d1-1f3fb-200d-1f9b3","native":"🧑🏻🦳"},{"unified":"1f9d1-1f3fc-200d-1f9b3","native":"🧑🏼🦳"},{"unified":"1f9d1-1f3fd-200d-1f9b3","native":"🧑🏽🦳"},{"unified":"1f9d1-1f3fe-200d-1f9b3","native":"🧑🏾🦳"},{"unified":"1f9d1-1f3ff-200d-1f9b3","native":"🧑🏿🦳"}],"version":12.1},"bald_woman":{"id":"bald_woman","name":"Woman: Bald","keywords":["woman","hairless"],"skins":[{"unified":"1f469-200d-1f9b2","native":"👩🦲"},{"unified":"1f469-1f3fb-200d-1f9b2","native":"👩🏻🦲"},{"unified":"1f469-1f3fc-200d-1f9b2","native":"👩🏼🦲"},{"unified":"1f469-1f3fd-200d-1f9b2","native":"👩🏽🦲"},{"unified":"1f469-1f3fe-200d-1f9b2","native":"👩🏾🦲"},{"unified":"1f469-1f3ff-200d-1f9b2","native":"👩🏿🦲"}],"version":11},"bald_person":{"id":"bald_person","name":"Person: Bald","keywords":["person","hairless"],"skins":[{"unified":"1f9d1-200d-1f9b2","native":"🧑🦲"},{"unified":"1f9d1-1f3fb-200d-1f9b2","native":"🧑🏻🦲"},{"unified":"1f9d1-1f3fc-200d-1f9b2","native":"🧑🏼🦲"},{"unified":"1f9d1-1f3fd-200d-1f9b2","native":"🧑🏽🦲"},{"unified":"1f9d1-1f3fe-200d-1f9b2","native":"🧑🏾🦲"},{"unified":"1f9d1-1f3ff-200d-1f9b2","native":"🧑🏿🦲"}],"version":12.1},"blond-haired-woman":{"id":"blond-haired-woman","name":"Woman: Blond Hair","keywords":["haired-woman","woman","female","girl","blonde","person"],"skins":[{"unified":"1f471-200d-2640-fe0f","native":"👱♀️"},{"unified":"1f471-1f3fb-200d-2640-fe0f","native":"👱🏻♀️"},{"unified":"1f471-1f3fc-200d-2640-fe0f","native":"👱🏼♀️"},{"unified":"1f471-1f3fd-200d-2640-fe0f","native":"👱🏽♀️"},{"unified":"1f471-1f3fe-200d-2640-fe0f","native":"👱🏾♀️"},{"unified":"1f471-1f3ff-200d-2640-fe0f","native":"👱🏿♀️"}],"version":4},"blond-haired-man":{"id":"blond-haired-man","name":"Man: Blond Hair","keywords":["haired-man","man","male","boy","blonde","guy","person"],"skins":[{"unified":"1f471-200d-2642-fe0f","native":"👱♂️"},{"unified":"1f471-1f3fb-200d-2642-fe0f","native":"👱🏻♂️"},{"unified":"1f471-1f3fc-200d-2642-fe0f","native":"👱🏼♂️"},{"unified":"1f471-1f3fd-200d-2642-fe0f","native":"👱🏽♂️"},{"unified":"1f471-1f3fe-200d-2642-fe0f","native":"👱🏾♂️"},{"unified":"1f471-1f3ff-200d-2642-fe0f","native":"👱🏿♂️"}],"version":4},"older_adult":{"id":"older_adult","name":"Older Adult","keywords":["person","human","elder","senior","gender","neutral"],"skins":[{"unified":"1f9d3","native":"🧓"},{"unified":"1f9d3-1f3fb","native":"🧓🏻"},{"unified":"1f9d3-1f3fc","native":"🧓🏼"},{"unified":"1f9d3-1f3fd","native":"🧓🏽"},{"unified":"1f9d3-1f3fe","native":"🧓🏾"},{"unified":"1f9d3-1f3ff","native":"🧓🏿"}],"version":5},"older_man":{"id":"older_man","name":"Old Man","keywords":["older","human","male","men","elder","senior"],"skins":[{"unified":"1f474","native":"👴"},{"unified":"1f474-1f3fb","native":"👴🏻"},{"unified":"1f474-1f3fc","native":"👴🏼"},{"unified":"1f474-1f3fd","native":"👴🏽"},{"unified":"1f474-1f3fe","native":"👴🏾"},{"unified":"1f474-1f3ff","native":"👴🏿"}],"version":1},"older_woman":{"id":"older_woman","name":"Old Woman","keywords":["older","human","female","women","lady","elder","senior"],"skins":[{"unified":"1f475","native":"👵"},{"unified":"1f475-1f3fb","native":"👵🏻"},{"unified":"1f475-1f3fc","native":"👵🏼"},{"unified":"1f475-1f3fd","native":"👵🏽"},{"unified":"1f475-1f3fe","native":"👵🏾"},{"unified":"1f475-1f3ff","native":"👵🏿"}],"version":1},"person_frowning":{"id":"person_frowning","name":"Person Frowning","keywords":["worried"],"skins":[{"unified":"1f64d","native":"🙍"},{"unified":"1f64d-1f3fb","native":"🙍🏻"},{"unified":"1f64d-1f3fc","native":"🙍🏼"},{"unified":"1f64d-1f3fd","native":"🙍🏽"},{"unified":"1f64d-1f3fe","native":"🙍🏾"},{"unified":"1f64d-1f3ff","native":"🙍🏿"}],"version":1},"man-frowning":{"id":"man-frowning","name":"Man Frowning","keywords":["male","boy","sad","depressed","discouraged","unhappy"],"skins":[{"unified":"1f64d-200d-2642-fe0f","native":"🙍♂️"},{"unified":"1f64d-1f3fb-200d-2642-fe0f","native":"🙍🏻♂️"},{"unified":"1f64d-1f3fc-200d-2642-fe0f","native":"🙍🏼♂️"},{"unified":"1f64d-1f3fd-200d-2642-fe0f","native":"🙍🏽♂️"},{"unified":"1f64d-1f3fe-200d-2642-fe0f","native":"🙍🏾♂️"},{"unified":"1f64d-1f3ff-200d-2642-fe0f","native":"🙍🏿♂️"}],"version":4},"woman-frowning":{"id":"woman-frowning","name":"Woman Frowning","keywords":["female","girl","sad","depressed","discouraged","unhappy"],"skins":[{"unified":"1f64d-200d-2640-fe0f","native":"🙍♀️"},{"unified":"1f64d-1f3fb-200d-2640-fe0f","native":"🙍🏻♀️"},{"unified":"1f64d-1f3fc-200d-2640-fe0f","native":"🙍🏼♀️"},{"unified":"1f64d-1f3fd-200d-2640-fe0f","native":"🙍🏽♀️"},{"unified":"1f64d-1f3fe-200d-2640-fe0f","native":"🙍🏾♀️"},{"unified":"1f64d-1f3ff-200d-2640-fe0f","native":"🙍🏿♀️"}],"version":4},"person_with_pouting_face":{"id":"person_with_pouting_face","name":"Person Pouting","keywords":["with","face","upset"],"skins":[{"unified":"1f64e","native":"🙎"},{"unified":"1f64e-1f3fb","native":"🙎🏻"},{"unified":"1f64e-1f3fc","native":"🙎🏼"},{"unified":"1f64e-1f3fd","native":"🙎🏽"},{"unified":"1f64e-1f3fe","native":"🙎🏾"},{"unified":"1f64e-1f3ff","native":"🙎🏿"}],"version":1},"man-pouting":{"id":"man-pouting","name":"Man Pouting","keywords":["male","boy"],"skins":[{"unified":"1f64e-200d-2642-fe0f","native":"🙎♂️"},{"unified":"1f64e-1f3fb-200d-2642-fe0f","native":"🙎🏻♂️"},{"unified":"1f64e-1f3fc-200d-2642-fe0f","native":"🙎🏼♂️"},{"unified":"1f64e-1f3fd-200d-2642-fe0f","native":"🙎🏽♂️"},{"unified":"1f64e-1f3fe-200d-2642-fe0f","native":"🙎🏾♂️"},{"unified":"1f64e-1f3ff-200d-2642-fe0f","native":"🙎🏿♂️"}],"version":4},"woman-pouting":{"id":"woman-pouting","name":"Woman Pouting","keywords":["female","girl"],"skins":[{"unified":"1f64e-200d-2640-fe0f","native":"🙎♀️"},{"unified":"1f64e-1f3fb-200d-2640-fe0f","native":"🙎🏻♀️"},{"unified":"1f64e-1f3fc-200d-2640-fe0f","native":"🙎🏼♀️"},{"unified":"1f64e-1f3fd-200d-2640-fe0f","native":"🙎🏽♀️"},{"unified":"1f64e-1f3fe-200d-2640-fe0f","native":"🙎🏾♀️"},{"unified":"1f64e-1f3ff-200d-2640-fe0f","native":"🙎🏿♀️"}],"version":4},"no_good":{"id":"no_good","name":"Person Gesturing No","keywords":["good","decline"],"skins":[{"unified":"1f645","native":"🙅"},{"unified":"1f645-1f3fb","native":"🙅🏻"},{"unified":"1f645-1f3fc","native":"🙅🏼"},{"unified":"1f645-1f3fd","native":"🙅🏽"},{"unified":"1f645-1f3fe","native":"🙅🏾"},{"unified":"1f645-1f3ff","native":"🙅🏿"}],"version":1},"man-gesturing-no":{"id":"man-gesturing-no","name":"Man Gesturing No","keywords":["gesturing-no","male","boy","nope"],"skins":[{"unified":"1f645-200d-2642-fe0f","native":"🙅♂️"},{"unified":"1f645-1f3fb-200d-2642-fe0f","native":"🙅🏻♂️"},{"unified":"1f645-1f3fc-200d-2642-fe0f","native":"🙅🏼♂️"},{"unified":"1f645-1f3fd-200d-2642-fe0f","native":"🙅🏽♂️"},{"unified":"1f645-1f3fe-200d-2642-fe0f","native":"🙅🏾♂️"},{"unified":"1f645-1f3ff-200d-2642-fe0f","native":"🙅🏿♂️"}],"version":4},"woman-gesturing-no":{"id":"woman-gesturing-no","name":"Woman Gesturing No","keywords":["gesturing-no","female","girl","nope"],"skins":[{"unified":"1f645-200d-2640-fe0f","native":"🙅♀️"},{"unified":"1f645-1f3fb-200d-2640-fe0f","native":"🙅🏻♀️"},{"unified":"1f645-1f3fc-200d-2640-fe0f","native":"🙅🏼♀️"},{"unified":"1f645-1f3fd-200d-2640-fe0f","native":"🙅🏽♀️"},{"unified":"1f645-1f3fe-200d-2640-fe0f","native":"🙅🏾♀️"},{"unified":"1f645-1f3ff-200d-2640-fe0f","native":"🙅🏿♀️"}],"version":4},"ok_woman":{"id":"ok_woman","name":"Person Gesturing Ok","keywords":["woman","agree"],"skins":[{"unified":"1f646","native":"🙆"},{"unified":"1f646-1f3fb","native":"🙆🏻"},{"unified":"1f646-1f3fc","native":"🙆🏼"},{"unified":"1f646-1f3fd","native":"🙆🏽"},{"unified":"1f646-1f3fe","native":"🙆🏾"},{"unified":"1f646-1f3ff","native":"🙆🏿"}],"version":1},"man-gesturing-ok":{"id":"man-gesturing-ok","name":"Man Gesturing Ok","keywords":["gesturing-ok","men","boy","male","blue","human"],"skins":[{"unified":"1f646-200d-2642-fe0f","native":"🙆♂️"},{"unified":"1f646-1f3fb-200d-2642-fe0f","native":"🙆🏻♂️"},{"unified":"1f646-1f3fc-200d-2642-fe0f","native":"🙆🏼♂️"},{"unified":"1f646-1f3fd-200d-2642-fe0f","native":"🙆🏽♂️"},{"unified":"1f646-1f3fe-200d-2642-fe0f","native":"🙆🏾♂️"},{"unified":"1f646-1f3ff-200d-2642-fe0f","native":"🙆🏿♂️"}],"version":4},"woman-gesturing-ok":{"id":"woman-gesturing-ok","name":"Woman Gesturing Ok","keywords":["gesturing-ok","women","girl","female","pink","human"],"skins":[{"unified":"1f646-200d-2640-fe0f","native":"🙆♀️"},{"unified":"1f646-1f3fb-200d-2640-fe0f","native":"🙆🏻♀️"},{"unified":"1f646-1f3fc-200d-2640-fe0f","native":"🙆🏼♀️"},{"unified":"1f646-1f3fd-200d-2640-fe0f","native":"🙆🏽♀️"},{"unified":"1f646-1f3fe-200d-2640-fe0f","native":"🙆🏾♀️"},{"unified":"1f646-1f3ff-200d-2640-fe0f","native":"🙆🏿♀️"}],"version":4},"information_desk_person":{"id":"information_desk_person","name":"Person Tipping Hand","keywords":["information","desk"],"skins":[{"unified":"1f481","native":"💁"},{"unified":"1f481-1f3fb","native":"💁🏻"},{"unified":"1f481-1f3fc","native":"💁🏼"},{"unified":"1f481-1f3fd","native":"💁🏽"},{"unified":"1f481-1f3fe","native":"💁🏾"},{"unified":"1f481-1f3ff","native":"💁🏿"}],"version":1},"man-tipping-hand":{"id":"man-tipping-hand","name":"Man Tipping Hand","keywords":["tipping-hand","male","boy","human","information"],"skins":[{"unified":"1f481-200d-2642-fe0f","native":"💁♂️"},{"unified":"1f481-1f3fb-200d-2642-fe0f","native":"💁🏻♂️"},{"unified":"1f481-1f3fc-200d-2642-fe0f","native":"💁🏼♂️"},{"unified":"1f481-1f3fd-200d-2642-fe0f","native":"💁🏽♂️"},{"unified":"1f481-1f3fe-200d-2642-fe0f","native":"💁🏾♂️"},{"unified":"1f481-1f3ff-200d-2642-fe0f","native":"💁🏿♂️"}],"version":4},"woman-tipping-hand":{"id":"woman-tipping-hand","name":"Woman Tipping Hand","keywords":["tipping-hand","female","girl","human","information"],"skins":[{"unified":"1f481-200d-2640-fe0f","native":"💁♀️"},{"unified":"1f481-1f3fb-200d-2640-fe0f","native":"💁🏻♀️"},{"unified":"1f481-1f3fc-200d-2640-fe0f","native":"💁🏼♀️"},{"unified":"1f481-1f3fd-200d-2640-fe0f","native":"💁🏽♀️"},{"unified":"1f481-1f3fe-200d-2640-fe0f","native":"💁🏾♀️"},{"unified":"1f481-1f3ff-200d-2640-fe0f","native":"💁🏿♀️"}],"version":4},"raising_hand":{"id":"raising_hand","name":"Person Raising Hand","keywords":["question"],"skins":[{"unified":"1f64b","native":"🙋"},{"unified":"1f64b-1f3fb","native":"🙋🏻"},{"unified":"1f64b-1f3fc","native":"🙋🏼"},{"unified":"1f64b-1f3fd","native":"🙋🏽"},{"unified":"1f64b-1f3fe","native":"🙋🏾"},{"unified":"1f64b-1f3ff","native":"🙋🏿"}],"version":1},"man-raising-hand":{"id":"man-raising-hand","name":"Man Raising Hand","keywords":["raising-hand","male","boy"],"skins":[{"unified":"1f64b-200d-2642-fe0f","native":"🙋♂️"},{"unified":"1f64b-1f3fb-200d-2642-fe0f","native":"🙋🏻♂️"},{"unified":"1f64b-1f3fc-200d-2642-fe0f","native":"🙋🏼♂️"},{"unified":"1f64b-1f3fd-200d-2642-fe0f","native":"🙋🏽♂️"},{"unified":"1f64b-1f3fe-200d-2642-fe0f","native":"🙋🏾♂️"},{"unified":"1f64b-1f3ff-200d-2642-fe0f","native":"🙋🏿♂️"}],"version":4},"woman-raising-hand":{"id":"woman-raising-hand","name":"Woman Raising Hand","keywords":["raising-hand","female","girl"],"skins":[{"unified":"1f64b-200d-2640-fe0f","native":"🙋♀️"},{"unified":"1f64b-1f3fb-200d-2640-fe0f","native":"🙋🏻♀️"},{"unified":"1f64b-1f3fc-200d-2640-fe0f","native":"🙋🏼♀️"},{"unified":"1f64b-1f3fd-200d-2640-fe0f","native":"🙋🏽♀️"},{"unified":"1f64b-1f3fe-200d-2640-fe0f","native":"🙋🏾♀️"},{"unified":"1f64b-1f3ff-200d-2640-fe0f","native":"🙋🏿♀️"}],"version":4},"deaf_person":{"id":"deaf_person","name":"Deaf Person","keywords":["accessibility"],"skins":[{"unified":"1f9cf","native":"🧏"},{"unified":"1f9cf-1f3fb","native":"🧏🏻"},{"unified":"1f9cf-1f3fc","native":"🧏🏼"},{"unified":"1f9cf-1f3fd","native":"🧏🏽"},{"unified":"1f9cf-1f3fe","native":"🧏🏾"},{"unified":"1f9cf-1f3ff","native":"🧏🏿"}],"version":12},"deaf_man":{"id":"deaf_man","name":"Deaf Man","keywords":["accessibility"],"skins":[{"unified":"1f9cf-200d-2642-fe0f","native":"🧏♂️"},{"unified":"1f9cf-1f3fb-200d-2642-fe0f","native":"🧏🏻♂️"},{"unified":"1f9cf-1f3fc-200d-2642-fe0f","native":"🧏🏼♂️"},{"unified":"1f9cf-1f3fd-200d-2642-fe0f","native":"🧏🏽♂️"},{"unified":"1f9cf-1f3fe-200d-2642-fe0f","native":"🧏🏾♂️"},{"unified":"1f9cf-1f3ff-200d-2642-fe0f","native":"🧏🏿♂️"}],"version":12},"deaf_woman":{"id":"deaf_woman","name":"Deaf Woman","keywords":["accessibility"],"skins":[{"unified":"1f9cf-200d-2640-fe0f","native":"🧏♀️"},{"unified":"1f9cf-1f3fb-200d-2640-fe0f","native":"🧏🏻♀️"},{"unified":"1f9cf-1f3fc-200d-2640-fe0f","native":"🧏🏼♀️"},{"unified":"1f9cf-1f3fd-200d-2640-fe0f","native":"🧏🏽♀️"},{"unified":"1f9cf-1f3fe-200d-2640-fe0f","native":"🧏🏾♀️"},{"unified":"1f9cf-1f3ff-200d-2640-fe0f","native":"🧏🏿♀️"}],"version":12},"bow":{"id":"bow","name":"Person Bowing","keywords":["bow","respectiful"],"skins":[{"unified":"1f647","native":"🙇"},{"unified":"1f647-1f3fb","native":"🙇🏻"},{"unified":"1f647-1f3fc","native":"🙇🏼"},{"unified":"1f647-1f3fd","native":"🙇🏽"},{"unified":"1f647-1f3fe","native":"🙇🏾"},{"unified":"1f647-1f3ff","native":"🙇🏿"}],"version":1},"man-bowing":{"id":"man-bowing","name":"Man Bowing","keywords":["male","boy"],"skins":[{"unified":"1f647-200d-2642-fe0f","native":"🙇♂️"},{"unified":"1f647-1f3fb-200d-2642-fe0f","native":"🙇🏻♂️"},{"unified":"1f647-1f3fc-200d-2642-fe0f","native":"🙇🏼♂️"},{"unified":"1f647-1f3fd-200d-2642-fe0f","native":"🙇🏽♂️"},{"unified":"1f647-1f3fe-200d-2642-fe0f","native":"🙇🏾♂️"},{"unified":"1f647-1f3ff-200d-2642-fe0f","native":"🙇🏿♂️"}],"version":4},"woman-bowing":{"id":"woman-bowing","name":"Woman Bowing","keywords":["female","girl"],"skins":[{"unified":"1f647-200d-2640-fe0f","native":"🙇♀️"},{"unified":"1f647-1f3fb-200d-2640-fe0f","native":"🙇🏻♀️"},{"unified":"1f647-1f3fc-200d-2640-fe0f","native":"🙇🏼♀️"},{"unified":"1f647-1f3fd-200d-2640-fe0f","native":"🙇🏽♀️"},{"unified":"1f647-1f3fe-200d-2640-fe0f","native":"🙇🏾♀️"},{"unified":"1f647-1f3ff-200d-2640-fe0f","native":"🙇🏿♀️"}],"version":4},"face_palm":{"id":"face_palm","name":"Face Palm","keywords":["person","facepalming","disappointed"],"skins":[{"unified":"1f926","native":"🤦"},{"unified":"1f926-1f3fb","native":"🤦🏻"},{"unified":"1f926-1f3fc","native":"🤦🏼"},{"unified":"1f926-1f3fd","native":"🤦🏽"},{"unified":"1f926-1f3fe","native":"🤦🏾"},{"unified":"1f926-1f3ff","native":"🤦🏿"}],"version":3},"man-facepalming":{"id":"man-facepalming","name":"Man Facepalming","keywords":["male","boy","disbelief"],"skins":[{"unified":"1f926-200d-2642-fe0f","native":"🤦♂️"},{"unified":"1f926-1f3fb-200d-2642-fe0f","native":"🤦🏻♂️"},{"unified":"1f926-1f3fc-200d-2642-fe0f","native":"🤦🏼♂️"},{"unified":"1f926-1f3fd-200d-2642-fe0f","native":"🤦🏽♂️"},{"unified":"1f926-1f3fe-200d-2642-fe0f","native":"🤦🏾♂️"},{"unified":"1f926-1f3ff-200d-2642-fe0f","native":"🤦🏿♂️"}],"version":4},"woman-facepalming":{"id":"woman-facepalming","name":"Woman Facepalming","keywords":["female","girl","disbelief"],"skins":[{"unified":"1f926-200d-2640-fe0f","native":"🤦♀️"},{"unified":"1f926-1f3fb-200d-2640-fe0f","native":"🤦🏻♀️"},{"unified":"1f926-1f3fc-200d-2640-fe0f","native":"🤦🏼♀️"},{"unified":"1f926-1f3fd-200d-2640-fe0f","native":"🤦🏽♀️"},{"unified":"1f926-1f3fe-200d-2640-fe0f","native":"🤦🏾♀️"},{"unified":"1f926-1f3ff-200d-2640-fe0f","native":"🤦🏿♀️"}],"version":4},"shrug":{"id":"shrug","name":"Shrug","keywords":["person","shrugging","regardless"],"skins":[{"unified":"1f937","native":"🤷"},{"unified":"1f937-1f3fb","native":"🤷🏻"},{"unified":"1f937-1f3fc","native":"🤷🏼"},{"unified":"1f937-1f3fd","native":"🤷🏽"},{"unified":"1f937-1f3fe","native":"🤷🏾"},{"unified":"1f937-1f3ff","native":"🤷🏿"}],"version":3},"man-shrugging":{"id":"man-shrugging","name":"Man Shrugging","keywords":["male","boy","confused","indifferent","doubt"],"skins":[{"unified":"1f937-200d-2642-fe0f","native":"🤷♂️"},{"unified":"1f937-1f3fb-200d-2642-fe0f","native":"🤷🏻♂️"},{"unified":"1f937-1f3fc-200d-2642-fe0f","native":"🤷🏼♂️"},{"unified":"1f937-1f3fd-200d-2642-fe0f","native":"🤷🏽♂️"},{"unified":"1f937-1f3fe-200d-2642-fe0f","native":"🤷🏾♂️"},{"unified":"1f937-1f3ff-200d-2642-fe0f","native":"🤷🏿♂️"}],"version":4},"woman-shrugging":{"id":"woman-shrugging","name":"Woman Shrugging","keywords":["female","girl","confused","indifferent","doubt"],"skins":[{"unified":"1f937-200d-2640-fe0f","native":"🤷♀️"},{"unified":"1f937-1f3fb-200d-2640-fe0f","native":"🤷🏻♀️"},{"unified":"1f937-1f3fc-200d-2640-fe0f","native":"🤷🏼♀️"},{"unified":"1f937-1f3fd-200d-2640-fe0f","native":"🤷🏽♀️"},{"unified":"1f937-1f3fe-200d-2640-fe0f","native":"🤷🏾♀️"},{"unified":"1f937-1f3ff-200d-2640-fe0f","native":"🤷🏿♀️"}],"version":4},"health_worker":{"id":"health_worker","name":"Health Worker","keywords":["hospital"],"skins":[{"unified":"1f9d1-200d-2695-fe0f","native":"🧑⚕️"},{"unified":"1f9d1-1f3fb-200d-2695-fe0f","native":"🧑🏻⚕️"},{"unified":"1f9d1-1f3fc-200d-2695-fe0f","native":"🧑🏼⚕️"},{"unified":"1f9d1-1f3fd-200d-2695-fe0f","native":"🧑🏽⚕️"},{"unified":"1f9d1-1f3fe-200d-2695-fe0f","native":"🧑🏾⚕️"},{"unified":"1f9d1-1f3ff-200d-2695-fe0f","native":"🧑🏿⚕️"}],"version":12.1},"male-doctor":{"id":"male-doctor","name":"Man Health Worker","keywords":["male","doctor","nurse","therapist","healthcare","human"],"skins":[{"unified":"1f468-200d-2695-fe0f","native":"👨⚕️"},{"unified":"1f468-1f3fb-200d-2695-fe0f","native":"👨🏻⚕️"},{"unified":"1f468-1f3fc-200d-2695-fe0f","native":"👨🏼⚕️"},{"unified":"1f468-1f3fd-200d-2695-fe0f","native":"👨🏽⚕️"},{"unified":"1f468-1f3fe-200d-2695-fe0f","native":"👨🏾⚕️"},{"unified":"1f468-1f3ff-200d-2695-fe0f","native":"👨🏿⚕️"}],"version":4},"female-doctor":{"id":"female-doctor","name":"Woman Health Worker","keywords":["female","doctor","nurse","therapist","healthcare","human"],"skins":[{"unified":"1f469-200d-2695-fe0f","native":"👩⚕️"},{"unified":"1f469-1f3fb-200d-2695-fe0f","native":"👩🏻⚕️"},{"unified":"1f469-1f3fc-200d-2695-fe0f","native":"👩🏼⚕️"},{"unified":"1f469-1f3fd-200d-2695-fe0f","native":"👩🏽⚕️"},{"unified":"1f469-1f3fe-200d-2695-fe0f","native":"👩🏾⚕️"},{"unified":"1f469-1f3ff-200d-2695-fe0f","native":"👩🏿⚕️"}],"version":4},"student":{"id":"student","name":"Student","keywords":["learn"],"skins":[{"unified":"1f9d1-200d-1f393","native":"🧑🎓"},{"unified":"1f9d1-1f3fb-200d-1f393","native":"🧑🏻🎓"},{"unified":"1f9d1-1f3fc-200d-1f393","native":"🧑🏼🎓"},{"unified":"1f9d1-1f3fd-200d-1f393","native":"🧑🏽🎓"},{"unified":"1f9d1-1f3fe-200d-1f393","native":"🧑🏾🎓"},{"unified":"1f9d1-1f3ff-200d-1f393","native":"🧑🏿🎓"}],"version":12.1},"male-student":{"id":"male-student","name":"Man Student","keywords":["male","graduate","human"],"skins":[{"unified":"1f468-200d-1f393","native":"👨🎓"},{"unified":"1f468-1f3fb-200d-1f393","native":"👨🏻🎓"},{"unified":"1f468-1f3fc-200d-1f393","native":"👨🏼🎓"},{"unified":"1f468-1f3fd-200d-1f393","native":"👨🏽🎓"},{"unified":"1f468-1f3fe-200d-1f393","native":"👨🏾🎓"},{"unified":"1f468-1f3ff-200d-1f393","native":"👨🏿🎓"}],"version":4},"female-student":{"id":"female-student","name":"Woman Student","keywords":["female","graduate","human"],"skins":[{"unified":"1f469-200d-1f393","native":"👩🎓"},{"unified":"1f469-1f3fb-200d-1f393","native":"👩🏻🎓"},{"unified":"1f469-1f3fc-200d-1f393","native":"👩🏼🎓"},{"unified":"1f469-1f3fd-200d-1f393","native":"👩🏽🎓"},{"unified":"1f469-1f3fe-200d-1f393","native":"👩🏾🎓"},{"unified":"1f469-1f3ff-200d-1f393","native":"👩🏿🎓"}],"version":4},"teacher":{"id":"teacher","name":"Teacher","keywords":["professor"],"skins":[{"unified":"1f9d1-200d-1f3eb","native":"🧑🏫"},{"unified":"1f9d1-1f3fb-200d-1f3eb","native":"🧑🏻🏫"},{"unified":"1f9d1-1f3fc-200d-1f3eb","native":"🧑🏼🏫"},{"unified":"1f9d1-1f3fd-200d-1f3eb","native":"🧑🏽🏫"},{"unified":"1f9d1-1f3fe-200d-1f3eb","native":"🧑🏾🏫"},{"unified":"1f9d1-1f3ff-200d-1f3eb","native":"🧑🏿🏫"}],"version":12.1},"male-teacher":{"id":"male-teacher","name":"Man Teacher","keywords":["male","instructor","professor","human"],"skins":[{"unified":"1f468-200d-1f3eb","native":"👨🏫"},{"unified":"1f468-1f3fb-200d-1f3eb","native":"👨🏻🏫"},{"unified":"1f468-1f3fc-200d-1f3eb","native":"👨🏼🏫"},{"unified":"1f468-1f3fd-200d-1f3eb","native":"👨🏽🏫"},{"unified":"1f468-1f3fe-200d-1f3eb","native":"👨🏾🏫"},{"unified":"1f468-1f3ff-200d-1f3eb","native":"👨🏿🏫"}],"version":4},"female-teacher":{"id":"female-teacher","name":"Woman Teacher","keywords":["female","instructor","professor","human"],"skins":[{"unified":"1f469-200d-1f3eb","native":"👩🏫"},{"unified":"1f469-1f3fb-200d-1f3eb","native":"👩🏻🏫"},{"unified":"1f469-1f3fc-200d-1f3eb","native":"👩🏼🏫"},{"unified":"1f469-1f3fd-200d-1f3eb","native":"👩🏽🏫"},{"unified":"1f469-1f3fe-200d-1f3eb","native":"👩🏾🏫"},{"unified":"1f469-1f3ff-200d-1f3eb","native":"👩🏿🏫"}],"version":4},"judge":{"id":"judge","name":"Judge","keywords":["law"],"skins":[{"unified":"1f9d1-200d-2696-fe0f","native":"🧑⚖️"},{"unified":"1f9d1-1f3fb-200d-2696-fe0f","native":"🧑🏻⚖️"},{"unified":"1f9d1-1f3fc-200d-2696-fe0f","native":"🧑🏼⚖️"},{"unified":"1f9d1-1f3fd-200d-2696-fe0f","native":"🧑🏽⚖️"},{"unified":"1f9d1-1f3fe-200d-2696-fe0f","native":"🧑🏾⚖️"},{"unified":"1f9d1-1f3ff-200d-2696-fe0f","native":"🧑🏿⚖️"}],"version":12.1},"male-judge":{"id":"male-judge","name":"Man Judge","keywords":["male","justice","court","human"],"skins":[{"unified":"1f468-200d-2696-fe0f","native":"👨⚖️"},{"unified":"1f468-1f3fb-200d-2696-fe0f","native":"👨🏻⚖️"},{"unified":"1f468-1f3fc-200d-2696-fe0f","native":"👨🏼⚖️"},{"unified":"1f468-1f3fd-200d-2696-fe0f","native":"👨🏽⚖️"},{"unified":"1f468-1f3fe-200d-2696-fe0f","native":"👨🏾⚖️"},{"unified":"1f468-1f3ff-200d-2696-fe0f","native":"👨🏿⚖️"}],"version":4},"female-judge":{"id":"female-judge","name":"Woman Judge","keywords":["female","justice","court","human"],"skins":[{"unified":"1f469-200d-2696-fe0f","native":"👩⚖️"},{"unified":"1f469-1f3fb-200d-2696-fe0f","native":"👩🏻⚖️"},{"unified":"1f469-1f3fc-200d-2696-fe0f","native":"👩🏼⚖️"},{"unified":"1f469-1f3fd-200d-2696-fe0f","native":"👩🏽⚖️"},{"unified":"1f469-1f3fe-200d-2696-fe0f","native":"👩🏾⚖️"},{"unified":"1f469-1f3ff-200d-2696-fe0f","native":"👩🏿⚖️"}],"version":4},"farmer":{"id":"farmer","name":"Farmer","keywords":["crops"],"skins":[{"unified":"1f9d1-200d-1f33e","native":"🧑🌾"},{"unified":"1f9d1-1f3fb-200d-1f33e","native":"🧑🏻🌾"},{"unified":"1f9d1-1f3fc-200d-1f33e","native":"🧑🏼🌾"},{"unified":"1f9d1-1f3fd-200d-1f33e","native":"🧑🏽🌾"},{"unified":"1f9d1-1f3fe-200d-1f33e","native":"🧑🏾🌾"},{"unified":"1f9d1-1f3ff-200d-1f33e","native":"🧑🏿🌾"}],"version":12.1},"male-farmer":{"id":"male-farmer","name":"Man Farmer","keywords":["male","rancher","gardener","human"],"skins":[{"unified":"1f468-200d-1f33e","native":"👨🌾"},{"unified":"1f468-1f3fb-200d-1f33e","native":"👨🏻🌾"},{"unified":"1f468-1f3fc-200d-1f33e","native":"👨🏼🌾"},{"unified":"1f468-1f3fd-200d-1f33e","native":"👨🏽🌾"},{"unified":"1f468-1f3fe-200d-1f33e","native":"👨🏾🌾"},{"unified":"1f468-1f3ff-200d-1f33e","native":"👨🏿🌾"}],"version":4},"female-farmer":{"id":"female-farmer","name":"Woman Farmer","keywords":["female","rancher","gardener","human"],"skins":[{"unified":"1f469-200d-1f33e","native":"👩🌾"},{"unified":"1f469-1f3fb-200d-1f33e","native":"👩🏻🌾"},{"unified":"1f469-1f3fc-200d-1f33e","native":"👩🏼🌾"},{"unified":"1f469-1f3fd-200d-1f33e","native":"👩🏽🌾"},{"unified":"1f469-1f3fe-200d-1f33e","native":"👩🏾🌾"},{"unified":"1f469-1f3ff-200d-1f33e","native":"👩🏿🌾"}],"version":4},"cook":{"id":"cook","name":"Cook","keywords":["food","kitchen","culinary"],"skins":[{"unified":"1f9d1-200d-1f373","native":"🧑🍳"},{"unified":"1f9d1-1f3fb-200d-1f373","native":"🧑🏻🍳"},{"unified":"1f9d1-1f3fc-200d-1f373","native":"🧑🏼🍳"},{"unified":"1f9d1-1f3fd-200d-1f373","native":"🧑🏽🍳"},{"unified":"1f9d1-1f3fe-200d-1f373","native":"🧑🏾🍳"},{"unified":"1f9d1-1f3ff-200d-1f373","native":"🧑🏿🍳"}],"version":12.1},"male-cook":{"id":"male-cook","name":"Man Cook","keywords":["male","chef","human"],"skins":[{"unified":"1f468-200d-1f373","native":"👨🍳"},{"unified":"1f468-1f3fb-200d-1f373","native":"👨🏻🍳"},{"unified":"1f468-1f3fc-200d-1f373","native":"👨🏼🍳"},{"unified":"1f468-1f3fd-200d-1f373","native":"👨🏽🍳"},{"unified":"1f468-1f3fe-200d-1f373","native":"👨🏾🍳"},{"unified":"1f468-1f3ff-200d-1f373","native":"👨🏿🍳"}],"version":4},"female-cook":{"id":"female-cook","name":"Woman Cook","keywords":["female","chef","human"],"skins":[{"unified":"1f469-200d-1f373","native":"👩🍳"},{"unified":"1f469-1f3fb-200d-1f373","native":"👩🏻🍳"},{"unified":"1f469-1f3fc-200d-1f373","native":"👩🏼🍳"},{"unified":"1f469-1f3fd-200d-1f373","native":"👩🏽🍳"},{"unified":"1f469-1f3fe-200d-1f373","native":"👩🏾🍳"},{"unified":"1f469-1f3ff-200d-1f373","native":"👩🏿🍳"}],"version":4},"mechanic":{"id":"mechanic","name":"Mechanic","keywords":["worker","technician"],"skins":[{"unified":"1f9d1-200d-1f527","native":"🧑🔧"},{"unified":"1f9d1-1f3fb-200d-1f527","native":"🧑🏻🔧"},{"unified":"1f9d1-1f3fc-200d-1f527","native":"🧑🏼🔧"},{"unified":"1f9d1-1f3fd-200d-1f527","native":"🧑🏽🔧"},{"unified":"1f9d1-1f3fe-200d-1f527","native":"🧑🏾🔧"},{"unified":"1f9d1-1f3ff-200d-1f527","native":"🧑🏿🔧"}],"version":12.1},"male-mechanic":{"id":"male-mechanic","name":"Man Mechanic","keywords":["male","plumber","human","wrench"],"skins":[{"unified":"1f468-200d-1f527","native":"👨🔧"},{"unified":"1f468-1f3fb-200d-1f527","native":"👨🏻🔧"},{"unified":"1f468-1f3fc-200d-1f527","native":"👨🏼🔧"},{"unified":"1f468-1f3fd-200d-1f527","native":"👨🏽🔧"},{"unified":"1f468-1f3fe-200d-1f527","native":"👨🏾🔧"},{"unified":"1f468-1f3ff-200d-1f527","native":"👨🏿🔧"}],"version":4},"female-mechanic":{"id":"female-mechanic","name":"Woman Mechanic","keywords":["female","plumber","human","wrench"],"skins":[{"unified":"1f469-200d-1f527","native":"👩🔧"},{"unified":"1f469-1f3fb-200d-1f527","native":"👩🏻🔧"},{"unified":"1f469-1f3fc-200d-1f527","native":"👩🏼🔧"},{"unified":"1f469-1f3fd-200d-1f527","native":"👩🏽🔧"},{"unified":"1f469-1f3fe-200d-1f527","native":"👩🏾🔧"},{"unified":"1f469-1f3ff-200d-1f527","native":"👩🏿🔧"}],"version":4},"factory_worker":{"id":"factory_worker","name":"Factory Worker","keywords":["labor"],"skins":[{"unified":"1f9d1-200d-1f3ed","native":"🧑🏭"},{"unified":"1f9d1-1f3fb-200d-1f3ed","native":"🧑🏻🏭"},{"unified":"1f9d1-1f3fc-200d-1f3ed","native":"🧑🏼🏭"},{"unified":"1f9d1-1f3fd-200d-1f3ed","native":"🧑🏽🏭"},{"unified":"1f9d1-1f3fe-200d-1f3ed","native":"🧑🏾🏭"},{"unified":"1f9d1-1f3ff-200d-1f3ed","native":"🧑🏿🏭"}],"version":12.1},"male-factory-worker":{"id":"male-factory-worker","name":"Man Factory Worker","keywords":["male","factory-worker","assembly","industrial","human"],"skins":[{"unified":"1f468-200d-1f3ed","native":"👨🏭"},{"unified":"1f468-1f3fb-200d-1f3ed","native":"👨🏻🏭"},{"unified":"1f468-1f3fc-200d-1f3ed","native":"👨🏼🏭"},{"unified":"1f468-1f3fd-200d-1f3ed","native":"👨🏽🏭"},{"unified":"1f468-1f3fe-200d-1f3ed","native":"👨🏾🏭"},{"unified":"1f468-1f3ff-200d-1f3ed","native":"👨🏿🏭"}],"version":4},"female-factory-worker":{"id":"female-factory-worker","name":"Woman Factory Worker","keywords":["female","factory-worker","assembly","industrial","human"],"skins":[{"unified":"1f469-200d-1f3ed","native":"👩🏭"},{"unified":"1f469-1f3fb-200d-1f3ed","native":"👩🏻🏭"},{"unified":"1f469-1f3fc-200d-1f3ed","native":"👩🏼🏭"},{"unified":"1f469-1f3fd-200d-1f3ed","native":"👩🏽🏭"},{"unified":"1f469-1f3fe-200d-1f3ed","native":"👩🏾🏭"},{"unified":"1f469-1f3ff-200d-1f3ed","native":"👩🏿🏭"}],"version":4},"office_worker":{"id":"office_worker","name":"Office Worker","keywords":["business"],"skins":[{"unified":"1f9d1-200d-1f4bc","native":"🧑💼"},{"unified":"1f9d1-1f3fb-200d-1f4bc","native":"🧑🏻💼"},{"unified":"1f9d1-1f3fc-200d-1f4bc","native":"🧑🏼💼"},{"unified":"1f9d1-1f3fd-200d-1f4bc","native":"🧑🏽💼"},{"unified":"1f9d1-1f3fe-200d-1f4bc","native":"🧑🏾💼"},{"unified":"1f9d1-1f3ff-200d-1f4bc","native":"🧑🏿💼"}],"version":12.1},"male-office-worker":{"id":"male-office-worker","name":"Man Office Worker","keywords":["male","office-worker","business","manager","human"],"skins":[{"unified":"1f468-200d-1f4bc","native":"👨💼"},{"unified":"1f468-1f3fb-200d-1f4bc","native":"👨🏻💼"},{"unified":"1f468-1f3fc-200d-1f4bc","native":"👨🏼💼"},{"unified":"1f468-1f3fd-200d-1f4bc","native":"👨🏽💼"},{"unified":"1f468-1f3fe-200d-1f4bc","native":"👨🏾💼"},{"unified":"1f468-1f3ff-200d-1f4bc","native":"👨🏿💼"}],"version":4},"female-office-worker":{"id":"female-office-worker","name":"Woman Office Worker","keywords":["female","office-worker","business","manager","human"],"skins":[{"unified":"1f469-200d-1f4bc","native":"👩💼"},{"unified":"1f469-1f3fb-200d-1f4bc","native":"👩🏻💼"},{"unified":"1f469-1f3fc-200d-1f4bc","native":"👩🏼💼"},{"unified":"1f469-1f3fd-200d-1f4bc","native":"👩🏽💼"},{"unified":"1f469-1f3fe-200d-1f4bc","native":"👩🏾💼"},{"unified":"1f469-1f3ff-200d-1f4bc","native":"👩🏿💼"}],"version":4},"scientist":{"id":"scientist","name":"Scientist","keywords":["chemistry"],"skins":[{"unified":"1f9d1-200d-1f52c","native":"🧑🔬"},{"unified":"1f9d1-1f3fb-200d-1f52c","native":"🧑🏻🔬"},{"unified":"1f9d1-1f3fc-200d-1f52c","native":"🧑🏼🔬"},{"unified":"1f9d1-1f3fd-200d-1f52c","native":"🧑🏽🔬"},{"unified":"1f9d1-1f3fe-200d-1f52c","native":"🧑🏾🔬"},{"unified":"1f9d1-1f3ff-200d-1f52c","native":"🧑🏿🔬"}],"version":12.1},"male-scientist":{"id":"male-scientist","name":"Man Scientist","keywords":["male","biologist","chemist","engineer","physicist","human"],"skins":[{"unified":"1f468-200d-1f52c","native":"👨🔬"},{"unified":"1f468-1f3fb-200d-1f52c","native":"👨🏻🔬"},{"unified":"1f468-1f3fc-200d-1f52c","native":"👨🏼🔬"},{"unified":"1f468-1f3fd-200d-1f52c","native":"👨🏽🔬"},{"unified":"1f468-1f3fe-200d-1f52c","native":"👨🏾🔬"},{"unified":"1f468-1f3ff-200d-1f52c","native":"👨🏿🔬"}],"version":4},"female-scientist":{"id":"female-scientist","name":"Woman Scientist","keywords":["female","biologist","chemist","engineer","physicist","human"],"skins":[{"unified":"1f469-200d-1f52c","native":"👩🔬"},{"unified":"1f469-1f3fb-200d-1f52c","native":"👩🏻🔬"},{"unified":"1f469-1f3fc-200d-1f52c","native":"👩🏼🔬"},{"unified":"1f469-1f3fd-200d-1f52c","native":"👩🏽🔬"},{"unified":"1f469-1f3fe-200d-1f52c","native":"👩🏾🔬"},{"unified":"1f469-1f3ff-200d-1f52c","native":"👩🏿🔬"}],"version":4},"technologist":{"id":"technologist","name":"Technologist","keywords":["computer"],"skins":[{"unified":"1f9d1-200d-1f4bb","native":"🧑💻"},{"unified":"1f9d1-1f3fb-200d-1f4bb","native":"🧑🏻💻"},{"unified":"1f9d1-1f3fc-200d-1f4bb","native":"🧑🏼💻"},{"unified":"1f9d1-1f3fd-200d-1f4bb","native":"🧑🏽💻"},{"unified":"1f9d1-1f3fe-200d-1f4bb","native":"🧑🏾💻"},{"unified":"1f9d1-1f3ff-200d-1f4bb","native":"🧑🏿💻"}],"version":12.1},"male-technologist":{"id":"male-technologist","name":"Man Technologist","keywords":["male","coder","developer","engineer","programmer","software","human","laptop","computer"],"skins":[{"unified":"1f468-200d-1f4bb","native":"👨💻"},{"unified":"1f468-1f3fb-200d-1f4bb","native":"👨🏻💻"},{"unified":"1f468-1f3fc-200d-1f4bb","native":"👨🏼💻"},{"unified":"1f468-1f3fd-200d-1f4bb","native":"👨🏽💻"},{"unified":"1f468-1f3fe-200d-1f4bb","native":"👨🏾💻"},{"unified":"1f468-1f3ff-200d-1f4bb","native":"👨🏿💻"}],"version":4},"female-technologist":{"id":"female-technologist","name":"Woman Technologist","keywords":["female","coder","developer","engineer","programmer","software","human","laptop","computer"],"skins":[{"unified":"1f469-200d-1f4bb","native":"👩💻"},{"unified":"1f469-1f3fb-200d-1f4bb","native":"👩🏻💻"},{"unified":"1f469-1f3fc-200d-1f4bb","native":"👩🏼💻"},{"unified":"1f469-1f3fd-200d-1f4bb","native":"👩🏽💻"},{"unified":"1f469-1f3fe-200d-1f4bb","native":"👩🏾💻"},{"unified":"1f469-1f3ff-200d-1f4bb","native":"👩🏿💻"}],"version":4},"singer":{"id":"singer","name":"Singer","keywords":["song","artist","performer"],"skins":[{"unified":"1f9d1-200d-1f3a4","native":"🧑🎤"},{"unified":"1f9d1-1f3fb-200d-1f3a4","native":"🧑🏻🎤"},{"unified":"1f9d1-1f3fc-200d-1f3a4","native":"🧑🏼🎤"},{"unified":"1f9d1-1f3fd-200d-1f3a4","native":"🧑🏽🎤"},{"unified":"1f9d1-1f3fe-200d-1f3a4","native":"🧑🏾🎤"},{"unified":"1f9d1-1f3ff-200d-1f3a4","native":"🧑🏿🎤"}],"version":12.1},"male-singer":{"id":"male-singer","name":"Man Singer","keywords":["male","rockstar","entertainer","human"],"skins":[{"unified":"1f468-200d-1f3a4","native":"👨🎤"},{"unified":"1f468-1f3fb-200d-1f3a4","native":"👨🏻🎤"},{"unified":"1f468-1f3fc-200d-1f3a4","native":"👨🏼🎤"},{"unified":"1f468-1f3fd-200d-1f3a4","native":"👨🏽🎤"},{"unified":"1f468-1f3fe-200d-1f3a4","native":"👨🏾🎤"},{"unified":"1f468-1f3ff-200d-1f3a4","native":"👨🏿🎤"}],"version":4},"female-singer":{"id":"female-singer","name":"Woman Singer","keywords":["female","rockstar","entertainer","human"],"skins":[{"unified":"1f469-200d-1f3a4","native":"👩🎤"},{"unified":"1f469-1f3fb-200d-1f3a4","native":"👩🏻🎤"},{"unified":"1f469-1f3fc-200d-1f3a4","native":"👩🏼🎤"},{"unified":"1f469-1f3fd-200d-1f3a4","native":"👩🏽🎤"},{"unified":"1f469-1f3fe-200d-1f3a4","native":"👩🏾🎤"},{"unified":"1f469-1f3ff-200d-1f3a4","native":"👩🏿🎤"}],"version":4},"artist":{"id":"artist","name":"Artist","keywords":["painting","draw","creativity"],"skins":[{"unified":"1f9d1-200d-1f3a8","native":"🧑🎨"},{"unified":"1f9d1-1f3fb-200d-1f3a8","native":"🧑🏻🎨"},{"unified":"1f9d1-1f3fc-200d-1f3a8","native":"🧑🏼🎨"},{"unified":"1f9d1-1f3fd-200d-1f3a8","native":"🧑🏽🎨"},{"unified":"1f9d1-1f3fe-200d-1f3a8","native":"🧑🏾🎨"},{"unified":"1f9d1-1f3ff-200d-1f3a8","native":"🧑🏿🎨"}],"version":12.1},"male-artist":{"id":"male-artist","name":"Man Artist","keywords":["male","painter","human"],"skins":[{"unified":"1f468-200d-1f3a8","native":"👨🎨"},{"unified":"1f468-1f3fb-200d-1f3a8","native":"👨🏻🎨"},{"unified":"1f468-1f3fc-200d-1f3a8","native":"👨🏼🎨"},{"unified":"1f468-1f3fd-200d-1f3a8","native":"👨🏽🎨"},{"unified":"1f468-1f3fe-200d-1f3a8","native":"👨🏾🎨"},{"unified":"1f468-1f3ff-200d-1f3a8","native":"👨🏿🎨"}],"version":4},"female-artist":{"id":"female-artist","name":"Woman Artist","keywords":["female","painter","human"],"skins":[{"unified":"1f469-200d-1f3a8","native":"👩🎨"},{"unified":"1f469-1f3fb-200d-1f3a8","native":"👩🏻🎨"},{"unified":"1f469-1f3fc-200d-1f3a8","native":"👩🏼🎨"},{"unified":"1f469-1f3fd-200d-1f3a8","native":"👩🏽🎨"},{"unified":"1f469-1f3fe-200d-1f3a8","native":"👩🏾🎨"},{"unified":"1f469-1f3ff-200d-1f3a8","native":"👩🏿🎨"}],"version":4},"pilot":{"id":"pilot","name":"Pilot","keywords":["fly","plane","airplane"],"skins":[{"unified":"1f9d1-200d-2708-fe0f","native":"🧑✈️"},{"unified":"1f9d1-1f3fb-200d-2708-fe0f","native":"🧑🏻✈️"},{"unified":"1f9d1-1f3fc-200d-2708-fe0f","native":"🧑🏼✈️"},{"unified":"1f9d1-1f3fd-200d-2708-fe0f","native":"🧑🏽✈️"},{"unified":"1f9d1-1f3fe-200d-2708-fe0f","native":"🧑🏾✈️"},{"unified":"1f9d1-1f3ff-200d-2708-fe0f","native":"🧑🏿✈️"}],"version":12.1},"male-pilot":{"id":"male-pilot","name":"Man Pilot","keywords":["male","aviator","plane","human"],"skins":[{"unified":"1f468-200d-2708-fe0f","native":"👨✈️"},{"unified":"1f468-1f3fb-200d-2708-fe0f","native":"👨🏻✈️"},{"unified":"1f468-1f3fc-200d-2708-fe0f","native":"👨🏼✈️"},{"unified":"1f468-1f3fd-200d-2708-fe0f","native":"👨🏽✈️"},{"unified":"1f468-1f3fe-200d-2708-fe0f","native":"👨🏾✈️"},{"unified":"1f468-1f3ff-200d-2708-fe0f","native":"👨🏿✈️"}],"version":4},"female-pilot":{"id":"female-pilot","name":"Woman Pilot","keywords":["female","aviator","plane","human"],"skins":[{"unified":"1f469-200d-2708-fe0f","native":"👩✈️"},{"unified":"1f469-1f3fb-200d-2708-fe0f","native":"👩🏻✈️"},{"unified":"1f469-1f3fc-200d-2708-fe0f","native":"👩🏼✈️"},{"unified":"1f469-1f3fd-200d-2708-fe0f","native":"👩🏽✈️"},{"unified":"1f469-1f3fe-200d-2708-fe0f","native":"👩🏾✈️"},{"unified":"1f469-1f3ff-200d-2708-fe0f","native":"👩🏿✈️"}],"version":4},"astronaut":{"id":"astronaut","name":"Astronaut","keywords":["outerspace"],"skins":[{"unified":"1f9d1-200d-1f680","native":"🧑🚀"},{"unified":"1f9d1-1f3fb-200d-1f680","native":"🧑🏻🚀"},{"unified":"1f9d1-1f3fc-200d-1f680","native":"🧑🏼🚀"},{"unified":"1f9d1-1f3fd-200d-1f680","native":"🧑🏽🚀"},{"unified":"1f9d1-1f3fe-200d-1f680","native":"🧑🏾🚀"},{"unified":"1f9d1-1f3ff-200d-1f680","native":"🧑🏿🚀"}],"version":12.1},"male-astronaut":{"id":"male-astronaut","name":"Man Astronaut","keywords":["male","space","rocket","human"],"skins":[{"unified":"1f468-200d-1f680","native":"👨🚀"},{"unified":"1f468-1f3fb-200d-1f680","native":"👨🏻🚀"},{"unified":"1f468-1f3fc-200d-1f680","native":"👨🏼🚀"},{"unified":"1f468-1f3fd-200d-1f680","native":"👨🏽🚀"},{"unified":"1f468-1f3fe-200d-1f680","native":"👨🏾🚀"},{"unified":"1f468-1f3ff-200d-1f680","native":"👨🏿🚀"}],"version":4},"female-astronaut":{"id":"female-astronaut","name":"Woman Astronaut","keywords":["female","space","rocket","human"],"skins":[{"unified":"1f469-200d-1f680","native":"👩🚀"},{"unified":"1f469-1f3fb-200d-1f680","native":"👩🏻🚀"},{"unified":"1f469-1f3fc-200d-1f680","native":"👩🏼🚀"},{"unified":"1f469-1f3fd-200d-1f680","native":"👩🏽🚀"},{"unified":"1f469-1f3fe-200d-1f680","native":"👩🏾🚀"},{"unified":"1f469-1f3ff-200d-1f680","native":"👩🏿🚀"}],"version":4},"firefighter":{"id":"firefighter","name":"Firefighter","keywords":["fire"],"skins":[{"unified":"1f9d1-200d-1f692","native":"🧑🚒"},{"unified":"1f9d1-1f3fb-200d-1f692","native":"🧑🏻🚒"},{"unified":"1f9d1-1f3fc-200d-1f692","native":"🧑🏼🚒"},{"unified":"1f9d1-1f3fd-200d-1f692","native":"🧑🏽🚒"},{"unified":"1f9d1-1f3fe-200d-1f692","native":"🧑🏾🚒"},{"unified":"1f9d1-1f3ff-200d-1f692","native":"🧑🏿🚒"}],"version":12.1},"male-firefighter":{"id":"male-firefighter","name":"Man Firefighter","keywords":["male","fireman","human"],"skins":[{"unified":"1f468-200d-1f692","native":"👨🚒"},{"unified":"1f468-1f3fb-200d-1f692","native":"👨🏻🚒"},{"unified":"1f468-1f3fc-200d-1f692","native":"👨🏼🚒"},{"unified":"1f468-1f3fd-200d-1f692","native":"👨🏽🚒"},{"unified":"1f468-1f3fe-200d-1f692","native":"👨🏾🚒"},{"unified":"1f468-1f3ff-200d-1f692","native":"👨🏿🚒"}],"version":4},"female-firefighter":{"id":"female-firefighter","name":"Woman Firefighter","keywords":["female","fireman","human"],"skins":[{"unified":"1f469-200d-1f692","native":"👩🚒"},{"unified":"1f469-1f3fb-200d-1f692","native":"👩🏻🚒"},{"unified":"1f469-1f3fc-200d-1f692","native":"👩🏼🚒"},{"unified":"1f469-1f3fd-200d-1f692","native":"👩🏽🚒"},{"unified":"1f469-1f3fe-200d-1f692","native":"👩🏾🚒"},{"unified":"1f469-1f3ff-200d-1f692","native":"👩🏿🚒"}],"version":4},"cop":{"id":"cop","name":"Police Officer","keywords":["cop"],"skins":[{"unified":"1f46e","native":"👮"},{"unified":"1f46e-1f3fb","native":"👮🏻"},{"unified":"1f46e-1f3fc","native":"👮🏼"},{"unified":"1f46e-1f3fd","native":"👮🏽"},{"unified":"1f46e-1f3fe","native":"👮🏾"},{"unified":"1f46e-1f3ff","native":"👮🏿"}],"version":1},"male-police-officer":{"id":"male-police-officer","name":"Man Police Officer","keywords":["male","police-officer","law","legal","enforcement","arrest","911"],"skins":[{"unified":"1f46e-200d-2642-fe0f","native":"👮♂️"},{"unified":"1f46e-1f3fb-200d-2642-fe0f","native":"👮🏻♂️"},{"unified":"1f46e-1f3fc-200d-2642-fe0f","native":"👮🏼♂️"},{"unified":"1f46e-1f3fd-200d-2642-fe0f","native":"👮🏽♂️"},{"unified":"1f46e-1f3fe-200d-2642-fe0f","native":"👮🏾♂️"},{"unified":"1f46e-1f3ff-200d-2642-fe0f","native":"👮🏿♂️"}],"version":4},"female-police-officer":{"id":"female-police-officer","name":"Woman Police Officer","keywords":["female","police-officer","law","legal","enforcement","arrest","911"],"skins":[{"unified":"1f46e-200d-2640-fe0f","native":"👮♀️"},{"unified":"1f46e-1f3fb-200d-2640-fe0f","native":"👮🏻♀️"},{"unified":"1f46e-1f3fc-200d-2640-fe0f","native":"👮🏼♀️"},{"unified":"1f46e-1f3fd-200d-2640-fe0f","native":"👮🏽♀️"},{"unified":"1f46e-1f3fe-200d-2640-fe0f","native":"👮🏾♀️"},{"unified":"1f46e-1f3ff-200d-2640-fe0f","native":"👮🏿♀️"}],"version":4},"sleuth_or_spy":{"id":"sleuth_or_spy","name":"Detective","keywords":["sleuth","or","spy","human"],"skins":[{"unified":"1f575-fe0f","native":"🕵️"},{"unified":"1f575-1f3fb","native":"🕵🏻"},{"unified":"1f575-1f3fc","native":"🕵🏼"},{"unified":"1f575-1f3fd","native":"🕵🏽"},{"unified":"1f575-1f3fe","native":"🕵🏾"},{"unified":"1f575-1f3ff","native":"🕵🏿"}],"version":1},"male-detective":{"id":"male-detective","name":"Man Detective","keywords":["male","crime"],"skins":[{"unified":"1f575-fe0f-200d-2642-fe0f","native":"🕵️♂️"},{"unified":"1f575-1f3fb-200d-2642-fe0f","native":"🕵🏻♂️"},{"unified":"1f575-1f3fc-200d-2642-fe0f","native":"🕵🏼♂️"},{"unified":"1f575-1f3fd-200d-2642-fe0f","native":"🕵🏽♂️"},{"unified":"1f575-1f3fe-200d-2642-fe0f","native":"🕵🏾♂️"},{"unified":"1f575-1f3ff-200d-2642-fe0f","native":"🕵🏿♂️"}],"version":4},"female-detective":{"id":"female-detective","name":"Woman Detective","keywords":["female","human","spy"],"skins":[{"unified":"1f575-fe0f-200d-2640-fe0f","native":"🕵️♀️"},{"unified":"1f575-1f3fb-200d-2640-fe0f","native":"🕵🏻♀️"},{"unified":"1f575-1f3fc-200d-2640-fe0f","native":"🕵🏼♀️"},{"unified":"1f575-1f3fd-200d-2640-fe0f","native":"🕵🏽♀️"},{"unified":"1f575-1f3fe-200d-2640-fe0f","native":"🕵🏾♀️"},{"unified":"1f575-1f3ff-200d-2640-fe0f","native":"🕵🏿♀️"}],"version":4},"guardsman":{"id":"guardsman","name":"Guard","keywords":["guardsman","protect"],"skins":[{"unified":"1f482","native":"💂"},{"unified":"1f482-1f3fb","native":"💂🏻"},{"unified":"1f482-1f3fc","native":"💂🏼"},{"unified":"1f482-1f3fd","native":"💂🏽"},{"unified":"1f482-1f3fe","native":"💂🏾"},{"unified":"1f482-1f3ff","native":"💂🏿"}],"version":1},"male-guard":{"id":"male-guard","name":"Man Guard","keywords":["male","uk","gb","british","guy","royal"],"skins":[{"unified":"1f482-200d-2642-fe0f","native":"💂♂️"},{"unified":"1f482-1f3fb-200d-2642-fe0f","native":"💂🏻♂️"},{"unified":"1f482-1f3fc-200d-2642-fe0f","native":"💂🏼♂️"},{"unified":"1f482-1f3fd-200d-2642-fe0f","native":"💂🏽♂️"},{"unified":"1f482-1f3fe-200d-2642-fe0f","native":"💂🏾♂️"},{"unified":"1f482-1f3ff-200d-2642-fe0f","native":"💂🏿♂️"}],"version":4},"female-guard":{"id":"female-guard","name":"Woman Guard","keywords":["female","uk","gb","british","royal"],"skins":[{"unified":"1f482-200d-2640-fe0f","native":"💂♀️"},{"unified":"1f482-1f3fb-200d-2640-fe0f","native":"💂🏻♀️"},{"unified":"1f482-1f3fc-200d-2640-fe0f","native":"💂🏼♀️"},{"unified":"1f482-1f3fd-200d-2640-fe0f","native":"💂🏽♀️"},{"unified":"1f482-1f3fe-200d-2640-fe0f","native":"💂🏾♀️"},{"unified":"1f482-1f3ff-200d-2640-fe0f","native":"💂🏿♀️"}],"version":4},"ninja":{"id":"ninja","name":"Ninja","keywords":["ninjutsu","skills","japanese"],"skins":[{"unified":"1f977","native":"🥷"},{"unified":"1f977-1f3fb","native":"🥷🏻"},{"unified":"1f977-1f3fc","native":"🥷🏼"},{"unified":"1f977-1f3fd","native":"🥷🏽"},{"unified":"1f977-1f3fe","native":"🥷🏾"},{"unified":"1f977-1f3ff","native":"🥷🏿"}],"version":13},"construction_worker":{"id":"construction_worker","name":"Construction Worker","keywords":["labor","build"],"skins":[{"unified":"1f477","native":"👷"},{"unified":"1f477-1f3fb","native":"👷🏻"},{"unified":"1f477-1f3fc","native":"👷🏼"},{"unified":"1f477-1f3fd","native":"👷🏽"},{"unified":"1f477-1f3fe","native":"👷🏾"},{"unified":"1f477-1f3ff","native":"👷🏿"}],"version":1},"male-construction-worker":{"id":"male-construction-worker","name":"Man Construction Worker","keywords":["male","construction-worker","human","wip","guy","build","labor"],"skins":[{"unified":"1f477-200d-2642-fe0f","native":"👷♂️"},{"unified":"1f477-1f3fb-200d-2642-fe0f","native":"👷🏻♂️"},{"unified":"1f477-1f3fc-200d-2642-fe0f","native":"👷🏼♂️"},{"unified":"1f477-1f3fd-200d-2642-fe0f","native":"👷🏽♂️"},{"unified":"1f477-1f3fe-200d-2642-fe0f","native":"👷🏾♂️"},{"unified":"1f477-1f3ff-200d-2642-fe0f","native":"👷🏿♂️"}],"version":4},"female-construction-worker":{"id":"female-construction-worker","name":"Woman Construction Worker","keywords":["female","construction-worker","human","wip","build","labor"],"skins":[{"unified":"1f477-200d-2640-fe0f","native":"👷♀️"},{"unified":"1f477-1f3fb-200d-2640-fe0f","native":"👷🏻♀️"},{"unified":"1f477-1f3fc-200d-2640-fe0f","native":"👷🏼♀️"},{"unified":"1f477-1f3fd-200d-2640-fe0f","native":"👷🏽♀️"},{"unified":"1f477-1f3fe-200d-2640-fe0f","native":"👷🏾♀️"},{"unified":"1f477-1f3ff-200d-2640-fe0f","native":"👷🏿♀️"}],"version":4},"person_with_crown":{"id":"person_with_crown","name":"Person with Crown","keywords":["royalty","power"],"skins":[{"unified":"1fac5","native":"🫅"},{"unified":"1fac5-1f3fb","native":"🫅🏻"},{"unified":"1fac5-1f3fc","native":"🫅🏼"},{"unified":"1fac5-1f3fd","native":"🫅🏽"},{"unified":"1fac5-1f3fe","native":"🫅🏾"},{"unified":"1fac5-1f3ff","native":"🫅🏿"}],"version":14},"prince":{"id":"prince","name":"Prince","keywords":["boy","man","male","crown","royal","king"],"skins":[{"unified":"1f934","native":"🤴"},{"unified":"1f934-1f3fb","native":"🤴🏻"},{"unified":"1f934-1f3fc","native":"🤴🏼"},{"unified":"1f934-1f3fd","native":"🤴🏽"},{"unified":"1f934-1f3fe","native":"🤴🏾"},{"unified":"1f934-1f3ff","native":"🤴🏿"}],"version":3},"princess":{"id":"princess","name":"Princess","keywords":["girl","woman","female","blond","crown","royal","queen"],"skins":[{"unified":"1f478","native":"👸"},{"unified":"1f478-1f3fb","native":"👸🏻"},{"unified":"1f478-1f3fc","native":"👸🏼"},{"unified":"1f478-1f3fd","native":"👸🏽"},{"unified":"1f478-1f3fe","native":"👸🏾"},{"unified":"1f478-1f3ff","native":"👸🏿"}],"version":1},"man_with_turban":{"id":"man_with_turban","name":"Man with Turban","keywords":["person","wearing","headdress"],"skins":[{"unified":"1f473","native":"👳"},{"unified":"1f473-1f3fb","native":"👳🏻"},{"unified":"1f473-1f3fc","native":"👳🏼"},{"unified":"1f473-1f3fd","native":"👳🏽"},{"unified":"1f473-1f3fe","native":"👳🏾"},{"unified":"1f473-1f3ff","native":"👳🏿"}],"version":1},"man-wearing-turban":{"id":"man-wearing-turban","name":"Man Wearing Turban","keywords":["wearing-turban","male","indian","hinduism","arabs"],"skins":[{"unified":"1f473-200d-2642-fe0f","native":"👳♂️"},{"unified":"1f473-1f3fb-200d-2642-fe0f","native":"👳🏻♂️"},{"unified":"1f473-1f3fc-200d-2642-fe0f","native":"👳🏼♂️"},{"unified":"1f473-1f3fd-200d-2642-fe0f","native":"👳🏽♂️"},{"unified":"1f473-1f3fe-200d-2642-fe0f","native":"👳🏾♂️"},{"unified":"1f473-1f3ff-200d-2642-fe0f","native":"👳🏿♂️"}],"version":4},"woman-wearing-turban":{"id":"woman-wearing-turban","name":"Woman Wearing Turban","keywords":["wearing-turban","female","indian","hinduism","arabs"],"skins":[{"unified":"1f473-200d-2640-fe0f","native":"👳♀️"},{"unified":"1f473-1f3fb-200d-2640-fe0f","native":"👳🏻♀️"},{"unified":"1f473-1f3fc-200d-2640-fe0f","native":"👳🏼♀️"},{"unified":"1f473-1f3fd-200d-2640-fe0f","native":"👳🏽♀️"},{"unified":"1f473-1f3fe-200d-2640-fe0f","native":"👳🏾♀️"},{"unified":"1f473-1f3ff-200d-2640-fe0f","native":"👳🏿♀️"}],"version":4},"man_with_gua_pi_mao":{"id":"man_with_gua_pi_mao","name":"Man with Gua Pi Mao","keywords":["skullcap","male","boy","chinese"],"skins":[{"unified":"1f472","native":"👲"},{"unified":"1f472-1f3fb","native":"👲🏻"},{"unified":"1f472-1f3fc","native":"👲🏼"},{"unified":"1f472-1f3fd","native":"👲🏽"},{"unified":"1f472-1f3fe","native":"👲🏾"},{"unified":"1f472-1f3ff","native":"👲🏿"}],"version":1},"person_with_headscarf":{"id":"person_with_headscarf","name":"Woman with Headscarf","keywords":["person","female","hijab","mantilla","tichel"],"skins":[{"unified":"1f9d5","native":"🧕"},{"unified":"1f9d5-1f3fb","native":"🧕🏻"},{"unified":"1f9d5-1f3fc","native":"🧕🏼"},{"unified":"1f9d5-1f3fd","native":"🧕🏽"},{"unified":"1f9d5-1f3fe","native":"🧕🏾"},{"unified":"1f9d5-1f3ff","native":"🧕🏿"}],"version":5},"person_in_tuxedo":{"id":"person_in_tuxedo","name":"Man in Tuxedo","keywords":["person","couple","marriage","wedding","groom"],"skins":[{"unified":"1f935","native":"🤵"},{"unified":"1f935-1f3fb","native":"🤵🏻"},{"unified":"1f935-1f3fc","native":"🤵🏼"},{"unified":"1f935-1f3fd","native":"🤵🏽"},{"unified":"1f935-1f3fe","native":"🤵🏾"},{"unified":"1f935-1f3ff","native":"🤵🏿"}],"version":3},"man_in_tuxedo":{"id":"man_in_tuxedo","name":"Man in Tuxedo","keywords":["formal","fashion"],"skins":[{"unified":"1f935-200d-2642-fe0f","native":"🤵♂️"},{"unified":"1f935-1f3fb-200d-2642-fe0f","native":"🤵🏻♂️"},{"unified":"1f935-1f3fc-200d-2642-fe0f","native":"🤵🏼♂️"},{"unified":"1f935-1f3fd-200d-2642-fe0f","native":"🤵🏽♂️"},{"unified":"1f935-1f3fe-200d-2642-fe0f","native":"🤵🏾♂️"},{"unified":"1f935-1f3ff-200d-2642-fe0f","native":"🤵🏿♂️"}],"version":13},"woman_in_tuxedo":{"id":"woman_in_tuxedo","name":"Woman in Tuxedo","keywords":["formal","fashion"],"skins":[{"unified":"1f935-200d-2640-fe0f","native":"🤵♀️"},{"unified":"1f935-1f3fb-200d-2640-fe0f","native":"🤵🏻♀️"},{"unified":"1f935-1f3fc-200d-2640-fe0f","native":"🤵🏼♀️"},{"unified":"1f935-1f3fd-200d-2640-fe0f","native":"🤵🏽♀️"},{"unified":"1f935-1f3fe-200d-2640-fe0f","native":"🤵🏾♀️"},{"unified":"1f935-1f3ff-200d-2640-fe0f","native":"🤵🏿♀️"}],"version":13},"bride_with_veil":{"id":"bride_with_veil","name":"Bride with Veil","keywords":["couple","marriage","wedding","woman"],"skins":[{"unified":"1f470","native":"👰"},{"unified":"1f470-1f3fb","native":"👰🏻"},{"unified":"1f470-1f3fc","native":"👰🏼"},{"unified":"1f470-1f3fd","native":"👰🏽"},{"unified":"1f470-1f3fe","native":"👰🏾"},{"unified":"1f470-1f3ff","native":"👰🏿"}],"version":1},"man_with_veil":{"id":"man_with_veil","name":"Man with Veil","keywords":["wedding","marriage"],"skins":[{"unified":"1f470-200d-2642-fe0f","native":"👰♂️"},{"unified":"1f470-1f3fb-200d-2642-fe0f","native":"👰🏻♂️"},{"unified":"1f470-1f3fc-200d-2642-fe0f","native":"👰🏼♂️"},{"unified":"1f470-1f3fd-200d-2642-fe0f","native":"👰🏽♂️"},{"unified":"1f470-1f3fe-200d-2642-fe0f","native":"👰🏾♂️"},{"unified":"1f470-1f3ff-200d-2642-fe0f","native":"👰🏿♂️"}],"version":13},"woman_with_veil":{"id":"woman_with_veil","name":"Woman with Veil","keywords":["wedding","marriage"],"skins":[{"unified":"1f470-200d-2640-fe0f","native":"👰♀️"},{"unified":"1f470-1f3fb-200d-2640-fe0f","native":"👰🏻♀️"},{"unified":"1f470-1f3fc-200d-2640-fe0f","native":"👰🏼♀️"},{"unified":"1f470-1f3fd-200d-2640-fe0f","native":"👰🏽♀️"},{"unified":"1f470-1f3fe-200d-2640-fe0f","native":"👰🏾♀️"},{"unified":"1f470-1f3ff-200d-2640-fe0f","native":"👰🏿♀️"}],"version":13},"pregnant_woman":{"id":"pregnant_woman","name":"Pregnant Woman","keywords":["baby"],"skins":[{"unified":"1f930","native":"🤰"},{"unified":"1f930-1f3fb","native":"🤰🏻"},{"unified":"1f930-1f3fc","native":"🤰🏼"},{"unified":"1f930-1f3fd","native":"🤰🏽"},{"unified":"1f930-1f3fe","native":"🤰🏾"},{"unified":"1f930-1f3ff","native":"🤰🏿"}],"version":3},"pregnant_man":{"id":"pregnant_man","name":"Pregnant Man","keywords":["baby","belly"],"skins":[{"unified":"1fac3","native":"🫃"},{"unified":"1fac3-1f3fb","native":"🫃🏻"},{"unified":"1fac3-1f3fc","native":"🫃🏼"},{"unified":"1fac3-1f3fd","native":"🫃🏽"},{"unified":"1fac3-1f3fe","native":"🫃🏾"},{"unified":"1fac3-1f3ff","native":"🫃🏿"}],"version":14},"pregnant_person":{"id":"pregnant_person","name":"Pregnant Person","keywords":["baby","belly"],"skins":[{"unified":"1fac4","native":"🫄"},{"unified":"1fac4-1f3fb","native":"🫄🏻"},{"unified":"1fac4-1f3fc","native":"🫄🏼"},{"unified":"1fac4-1f3fd","native":"🫄🏽"},{"unified":"1fac4-1f3fe","native":"🫄🏾"},{"unified":"1fac4-1f3ff","native":"🫄🏿"}],"version":14},"breast-feeding":{"id":"breast-feeding","name":"Breast-Feeding","keywords":["breast","feeding","nursing","baby"],"skins":[{"unified":"1f931","native":"🤱"},{"unified":"1f931-1f3fb","native":"🤱🏻"},{"unified":"1f931-1f3fc","native":"🤱🏼"},{"unified":"1f931-1f3fd","native":"🤱🏽"},{"unified":"1f931-1f3fe","native":"🤱🏾"},{"unified":"1f931-1f3ff","native":"🤱🏿"}],"version":5},"woman_feeding_baby":{"id":"woman_feeding_baby","name":"Woman Feeding Baby","keywords":["birth","food"],"skins":[{"unified":"1f469-200d-1f37c","native":"👩🍼"},{"unified":"1f469-1f3fb-200d-1f37c","native":"👩🏻🍼"},{"unified":"1f469-1f3fc-200d-1f37c","native":"👩🏼🍼"},{"unified":"1f469-1f3fd-200d-1f37c","native":"👩🏽🍼"},{"unified":"1f469-1f3fe-200d-1f37c","native":"👩🏾🍼"},{"unified":"1f469-1f3ff-200d-1f37c","native":"👩🏿🍼"}],"version":13},"man_feeding_baby":{"id":"man_feeding_baby","name":"Man Feeding Baby","keywords":["birth","food"],"skins":[{"unified":"1f468-200d-1f37c","native":"👨🍼"},{"unified":"1f468-1f3fb-200d-1f37c","native":"👨🏻🍼"},{"unified":"1f468-1f3fc-200d-1f37c","native":"👨🏼🍼"},{"unified":"1f468-1f3fd-200d-1f37c","native":"👨🏽🍼"},{"unified":"1f468-1f3fe-200d-1f37c","native":"👨🏾🍼"},{"unified":"1f468-1f3ff-200d-1f37c","native":"👨🏿🍼"}],"version":13},"person_feeding_baby":{"id":"person_feeding_baby","name":"Person Feeding Baby","keywords":["birth","food"],"skins":[{"unified":"1f9d1-200d-1f37c","native":"🧑🍼"},{"unified":"1f9d1-1f3fb-200d-1f37c","native":"🧑🏻🍼"},{"unified":"1f9d1-1f3fc-200d-1f37c","native":"🧑🏼🍼"},{"unified":"1f9d1-1f3fd-200d-1f37c","native":"🧑🏽🍼"},{"unified":"1f9d1-1f3fe-200d-1f37c","native":"🧑🏾🍼"},{"unified":"1f9d1-1f3ff-200d-1f37c","native":"🧑🏿🍼"}],"version":13},"angel":{"id":"angel","name":"Baby Angel","keywords":["heaven","wings","halo"],"skins":[{"unified":"1f47c","native":"👼"},{"unified":"1f47c-1f3fb","native":"👼🏻"},{"unified":"1f47c-1f3fc","native":"👼🏼"},{"unified":"1f47c-1f3fd","native":"👼🏽"},{"unified":"1f47c-1f3fe","native":"👼🏾"},{"unified":"1f47c-1f3ff","native":"👼🏿"}],"version":1},"santa":{"id":"santa","name":"Santa Claus","keywords":["festival","man","male","xmas","father","christmas"],"skins":[{"unified":"1f385","native":"🎅"},{"unified":"1f385-1f3fb","native":"🎅🏻"},{"unified":"1f385-1f3fc","native":"🎅🏼"},{"unified":"1f385-1f3fd","native":"🎅🏽"},{"unified":"1f385-1f3fe","native":"🎅🏾"},{"unified":"1f385-1f3ff","native":"🎅🏿"}],"version":1},"mrs_claus":{"id":"mrs_claus","name":"Mrs. Claus","keywords":["mrs","mother","christmas","woman","female","xmas"],"skins":[{"unified":"1f936","native":"🤶"},{"unified":"1f936-1f3fb","native":"🤶🏻"},{"unified":"1f936-1f3fc","native":"🤶🏼"},{"unified":"1f936-1f3fd","native":"🤶🏽"},{"unified":"1f936-1f3fe","native":"🤶🏾"},{"unified":"1f936-1f3ff","native":"🤶🏿"}],"version":3},"mx_claus":{"id":"mx_claus","name":"Mx Claus","keywords":["christmas"],"skins":[{"unified":"1f9d1-200d-1f384","native":"🧑🎄"},{"unified":"1f9d1-1f3fb-200d-1f384","native":"🧑🏻🎄"},{"unified":"1f9d1-1f3fc-200d-1f384","native":"🧑🏼🎄"},{"unified":"1f9d1-1f3fd-200d-1f384","native":"🧑🏽🎄"},{"unified":"1f9d1-1f3fe-200d-1f384","native":"🧑🏾🎄"},{"unified":"1f9d1-1f3ff-200d-1f384","native":"🧑🏿🎄"}],"version":13},"superhero":{"id":"superhero","name":"Superhero","keywords":["marvel"],"skins":[{"unified":"1f9b8","native":"🦸"},{"unified":"1f9b8-1f3fb","native":"🦸🏻"},{"unified":"1f9b8-1f3fc","native":"🦸🏼"},{"unified":"1f9b8-1f3fd","native":"🦸🏽"},{"unified":"1f9b8-1f3fe","native":"🦸🏾"},{"unified":"1f9b8-1f3ff","native":"🦸🏿"}],"version":11},"male_superhero":{"id":"male_superhero","name":"Man Superhero","keywords":["male","good","hero","superpowers"],"skins":[{"unified":"1f9b8-200d-2642-fe0f","native":"🦸♂️"},{"unified":"1f9b8-1f3fb-200d-2642-fe0f","native":"🦸🏻♂️"},{"unified":"1f9b8-1f3fc-200d-2642-fe0f","native":"🦸🏼♂️"},{"unified":"1f9b8-1f3fd-200d-2642-fe0f","native":"🦸🏽♂️"},{"unified":"1f9b8-1f3fe-200d-2642-fe0f","native":"🦸🏾♂️"},{"unified":"1f9b8-1f3ff-200d-2642-fe0f","native":"🦸🏿♂️"}],"version":11},"female_superhero":{"id":"female_superhero","name":"Woman Superhero","keywords":["female","good","heroine","superpowers"],"skins":[{"unified":"1f9b8-200d-2640-fe0f","native":"🦸♀️"},{"unified":"1f9b8-1f3fb-200d-2640-fe0f","native":"🦸🏻♀️"},{"unified":"1f9b8-1f3fc-200d-2640-fe0f","native":"🦸🏼♀️"},{"unified":"1f9b8-1f3fd-200d-2640-fe0f","native":"🦸🏽♀️"},{"unified":"1f9b8-1f3fe-200d-2640-fe0f","native":"🦸🏾♀️"},{"unified":"1f9b8-1f3ff-200d-2640-fe0f","native":"🦸🏿♀️"}],"version":11},"supervillain":{"id":"supervillain","name":"Supervillain","keywords":["marvel"],"skins":[{"unified":"1f9b9","native":"🦹"},{"unified":"1f9b9-1f3fb","native":"🦹🏻"},{"unified":"1f9b9-1f3fc","native":"🦹🏼"},{"unified":"1f9b9-1f3fd","native":"🦹🏽"},{"unified":"1f9b9-1f3fe","native":"🦹🏾"},{"unified":"1f9b9-1f3ff","native":"🦹🏿"}],"version":11},"male_supervillain":{"id":"male_supervillain","name":"Man Supervillain","keywords":["male","evil","bad","criminal","hero","superpowers"],"skins":[{"unified":"1f9b9-200d-2642-fe0f","native":"🦹♂️"},{"unified":"1f9b9-1f3fb-200d-2642-fe0f","native":"🦹🏻♂️"},{"unified":"1f9b9-1f3fc-200d-2642-fe0f","native":"🦹🏼♂️"},{"unified":"1f9b9-1f3fd-200d-2642-fe0f","native":"🦹🏽♂️"},{"unified":"1f9b9-1f3fe-200d-2642-fe0f","native":"🦹🏾♂️"},{"unified":"1f9b9-1f3ff-200d-2642-fe0f","native":"🦹🏿♂️"}],"version":11},"female_supervillain":{"id":"female_supervillain","name":"Woman Supervillain","keywords":["female","evil","bad","criminal","heroine","superpowers"],"skins":[{"unified":"1f9b9-200d-2640-fe0f","native":"🦹♀️"},{"unified":"1f9b9-1f3fb-200d-2640-fe0f","native":"🦹🏻♀️"},{"unified":"1f9b9-1f3fc-200d-2640-fe0f","native":"🦹🏼♀️"},{"unified":"1f9b9-1f3fd-200d-2640-fe0f","native":"🦹🏽♀️"},{"unified":"1f9b9-1f3fe-200d-2640-fe0f","native":"🦹🏾♀️"},{"unified":"1f9b9-1f3ff-200d-2640-fe0f","native":"🦹🏿♀️"}],"version":11},"mage":{"id":"mage","name":"Mage","keywords":["magic"],"skins":[{"unified":"1f9d9","native":"🧙"},{"unified":"1f9d9-1f3fb","native":"🧙🏻"},{"unified":"1f9d9-1f3fc","native":"🧙🏼"},{"unified":"1f9d9-1f3fd","native":"🧙🏽"},{"unified":"1f9d9-1f3fe","native":"🧙🏾"},{"unified":"1f9d9-1f3ff","native":"🧙🏿"}],"version":5},"male_mage":{"id":"male_mage","name":"Man Mage","keywords":["male","sorcerer"],"skins":[{"unified":"1f9d9-200d-2642-fe0f","native":"🧙♂️"},{"unified":"1f9d9-1f3fb-200d-2642-fe0f","native":"🧙🏻♂️"},{"unified":"1f9d9-1f3fc-200d-2642-fe0f","native":"🧙🏼♂️"},{"unified":"1f9d9-1f3fd-200d-2642-fe0f","native":"🧙🏽♂️"},{"unified":"1f9d9-1f3fe-200d-2642-fe0f","native":"🧙🏾♂️"},{"unified":"1f9d9-1f3ff-200d-2642-fe0f","native":"🧙🏿♂️"}],"version":5},"female_mage":{"id":"female_mage","name":"Woman Mage","keywords":["female","witch"],"skins":[{"unified":"1f9d9-200d-2640-fe0f","native":"🧙♀️"},{"unified":"1f9d9-1f3fb-200d-2640-fe0f","native":"🧙🏻♀️"},{"unified":"1f9d9-1f3fc-200d-2640-fe0f","native":"🧙🏼♀️"},{"unified":"1f9d9-1f3fd-200d-2640-fe0f","native":"🧙🏽♀️"},{"unified":"1f9d9-1f3fe-200d-2640-fe0f","native":"🧙🏾♀️"},{"unified":"1f9d9-1f3ff-200d-2640-fe0f","native":"🧙🏿♀️"}],"version":5},"fairy":{"id":"fairy","name":"Fairy","keywords":["wings","magical"],"skins":[{"unified":"1f9da","native":"🧚"},{"unified":"1f9da-1f3fb","native":"🧚🏻"},{"unified":"1f9da-1f3fc","native":"🧚🏼"},{"unified":"1f9da-1f3fd","native":"🧚🏽"},{"unified":"1f9da-1f3fe","native":"🧚🏾"},{"unified":"1f9da-1f3ff","native":"🧚🏿"}],"version":5},"male_fairy":{"id":"male_fairy","name":"Man Fairy","keywords":["male"],"skins":[{"unified":"1f9da-200d-2642-fe0f","native":"🧚♂️"},{"unified":"1f9da-1f3fb-200d-2642-fe0f","native":"🧚🏻♂️"},{"unified":"1f9da-1f3fc-200d-2642-fe0f","native":"🧚🏼♂️"},{"unified":"1f9da-1f3fd-200d-2642-fe0f","native":"🧚🏽♂️"},{"unified":"1f9da-1f3fe-200d-2642-fe0f","native":"🧚🏾♂️"},{"unified":"1f9da-1f3ff-200d-2642-fe0f","native":"🧚🏿♂️"}],"version":5},"female_fairy":{"id":"female_fairy","name":"Woman Fairy","keywords":["female"],"skins":[{"unified":"1f9da-200d-2640-fe0f","native":"🧚♀️"},{"unified":"1f9da-1f3fb-200d-2640-fe0f","native":"🧚🏻♀️"},{"unified":"1f9da-1f3fc-200d-2640-fe0f","native":"🧚🏼♀️"},{"unified":"1f9da-1f3fd-200d-2640-fe0f","native":"🧚🏽♀️"},{"unified":"1f9da-1f3fe-200d-2640-fe0f","native":"🧚🏾♀️"},{"unified":"1f9da-1f3ff-200d-2640-fe0f","native":"🧚🏿♀️"}],"version":5},"vampire":{"id":"vampire","name":"Vampire","keywords":["blood","twilight"],"skins":[{"unified":"1f9db","native":"🧛"},{"unified":"1f9db-1f3fb","native":"🧛🏻"},{"unified":"1f9db-1f3fc","native":"🧛🏼"},{"unified":"1f9db-1f3fd","native":"🧛🏽"},{"unified":"1f9db-1f3fe","native":"🧛🏾"},{"unified":"1f9db-1f3ff","native":"🧛🏿"}],"version":5},"male_vampire":{"id":"male_vampire","name":"Man Vampire","keywords":["male","dracula"],"skins":[{"unified":"1f9db-200d-2642-fe0f","native":"🧛♂️"},{"unified":"1f9db-1f3fb-200d-2642-fe0f","native":"🧛🏻♂️"},{"unified":"1f9db-1f3fc-200d-2642-fe0f","native":"🧛🏼♂️"},{"unified":"1f9db-1f3fd-200d-2642-fe0f","native":"🧛🏽♂️"},{"unified":"1f9db-1f3fe-200d-2642-fe0f","native":"🧛🏾♂️"},{"unified":"1f9db-1f3ff-200d-2642-fe0f","native":"🧛🏿♂️"}],"version":5},"female_vampire":{"id":"female_vampire","name":"Woman Vampire","keywords":["female"],"skins":[{"unified":"1f9db-200d-2640-fe0f","native":"🧛♀️"},{"unified":"1f9db-1f3fb-200d-2640-fe0f","native":"🧛🏻♀️"},{"unified":"1f9db-1f3fc-200d-2640-fe0f","native":"🧛🏼♀️"},{"unified":"1f9db-1f3fd-200d-2640-fe0f","native":"🧛🏽♀️"},{"unified":"1f9db-1f3fe-200d-2640-fe0f","native":"🧛🏾♀️"},{"unified":"1f9db-1f3ff-200d-2640-fe0f","native":"🧛🏿♀️"}],"version":5},"merperson":{"id":"merperson","name":"Merperson","keywords":["sea"],"skins":[{"unified":"1f9dc","native":"🧜"},{"unified":"1f9dc-1f3fb","native":"🧜🏻"},{"unified":"1f9dc-1f3fc","native":"🧜🏼"},{"unified":"1f9dc-1f3fd","native":"🧜🏽"},{"unified":"1f9dc-1f3fe","native":"🧜🏾"},{"unified":"1f9dc-1f3ff","native":"🧜🏿"}],"version":5},"merman":{"id":"merman","name":"Merman","keywords":["man","male","triton"],"skins":[{"unified":"1f9dc-200d-2642-fe0f","native":"🧜♂️"},{"unified":"1f9dc-1f3fb-200d-2642-fe0f","native":"🧜🏻♂️"},{"unified":"1f9dc-1f3fc-200d-2642-fe0f","native":"🧜🏼♂️"},{"unified":"1f9dc-1f3fd-200d-2642-fe0f","native":"🧜🏽♂️"},{"unified":"1f9dc-1f3fe-200d-2642-fe0f","native":"🧜🏾♂️"},{"unified":"1f9dc-1f3ff-200d-2642-fe0f","native":"🧜🏿♂️"}],"version":5},"mermaid":{"id":"mermaid","name":"Mermaid","keywords":["woman","female","merwoman","ariel"],"skins":[{"unified":"1f9dc-200d-2640-fe0f","native":"🧜♀️"},{"unified":"1f9dc-1f3fb-200d-2640-fe0f","native":"🧜🏻♀️"},{"unified":"1f9dc-1f3fc-200d-2640-fe0f","native":"🧜🏼♀️"},{"unified":"1f9dc-1f3fd-200d-2640-fe0f","native":"🧜🏽♀️"},{"unified":"1f9dc-1f3fe-200d-2640-fe0f","native":"🧜🏾♀️"},{"unified":"1f9dc-1f3ff-200d-2640-fe0f","native":"🧜🏿♀️"}],"version":5},"elf":{"id":"elf","name":"Elf","keywords":["magical"],"skins":[{"unified":"1f9dd","native":"🧝"},{"unified":"1f9dd-1f3fb","native":"🧝🏻"},{"unified":"1f9dd-1f3fc","native":"🧝🏼"},{"unified":"1f9dd-1f3fd","native":"🧝🏽"},{"unified":"1f9dd-1f3fe","native":"🧝🏾"},{"unified":"1f9dd-1f3ff","native":"🧝🏿"}],"version":5},"male_elf":{"id":"male_elf","name":"Man Elf","keywords":["male"],"skins":[{"unified":"1f9dd-200d-2642-fe0f","native":"🧝♂️"},{"unified":"1f9dd-1f3fb-200d-2642-fe0f","native":"🧝🏻♂️"},{"unified":"1f9dd-1f3fc-200d-2642-fe0f","native":"🧝🏼♂️"},{"unified":"1f9dd-1f3fd-200d-2642-fe0f","native":"🧝🏽♂️"},{"unified":"1f9dd-1f3fe-200d-2642-fe0f","native":"🧝🏾♂️"},{"unified":"1f9dd-1f3ff-200d-2642-fe0f","native":"🧝🏿♂️"}],"version":5},"female_elf":{"id":"female_elf","name":"Woman Elf","keywords":["female"],"skins":[{"unified":"1f9dd-200d-2640-fe0f","native":"🧝♀️"},{"unified":"1f9dd-1f3fb-200d-2640-fe0f","native":"🧝🏻♀️"},{"unified":"1f9dd-1f3fc-200d-2640-fe0f","native":"🧝🏼♀️"},{"unified":"1f9dd-1f3fd-200d-2640-fe0f","native":"🧝🏽♀️"},{"unified":"1f9dd-1f3fe-200d-2640-fe0f","native":"🧝🏾♀️"},{"unified":"1f9dd-1f3ff-200d-2640-fe0f","native":"🧝🏿♀️"}],"version":5},"genie":{"id":"genie","name":"Genie","keywords":["magical","wishes"],"skins":[{"unified":"1f9de","native":"🧞"}],"version":5},"male_genie":{"id":"male_genie","name":"Man Genie","keywords":["male"],"skins":[{"unified":"1f9de-200d-2642-fe0f","native":"🧞♂️"}],"version":5},"female_genie":{"id":"female_genie","name":"Woman Genie","keywords":["female"],"skins":[{"unified":"1f9de-200d-2640-fe0f","native":"🧞♀️"}],"version":5},"zombie":{"id":"zombie","name":"Zombie","keywords":["dead"],"skins":[{"unified":"1f9df","native":"🧟"}],"version":5},"male_zombie":{"id":"male_zombie","name":"Man Zombie","keywords":["male","dracula","undead","walking","dead"],"skins":[{"unified":"1f9df-200d-2642-fe0f","native":"🧟♂️"}],"version":5},"female_zombie":{"id":"female_zombie","name":"Woman Zombie","keywords":["female","undead","walking","dead"],"skins":[{"unified":"1f9df-200d-2640-fe0f","native":"🧟♀️"}],"version":5},"troll":{"id":"troll","name":"Troll","keywords":["mystical","monster"],"skins":[{"unified":"1f9cc","native":"🧌"}],"version":14},"massage":{"id":"massage","name":"Face Massage","keywords":["person","getting","relax"],"skins":[{"unified":"1f486","native":"💆"},{"unified":"1f486-1f3fb","native":"💆🏻"},{"unified":"1f486-1f3fc","native":"💆🏼"},{"unified":"1f486-1f3fd","native":"💆🏽"},{"unified":"1f486-1f3fe","native":"💆🏾"},{"unified":"1f486-1f3ff","native":"💆🏿"}],"version":1},"man-getting-massage":{"id":"man-getting-massage","name":"Man Getting Massage","keywords":["getting-massage","male","boy","head"],"skins":[{"unified":"1f486-200d-2642-fe0f","native":"💆♂️"},{"unified":"1f486-1f3fb-200d-2642-fe0f","native":"💆🏻♂️"},{"unified":"1f486-1f3fc-200d-2642-fe0f","native":"💆🏼♂️"},{"unified":"1f486-1f3fd-200d-2642-fe0f","native":"💆🏽♂️"},{"unified":"1f486-1f3fe-200d-2642-fe0f","native":"💆🏾♂️"},{"unified":"1f486-1f3ff-200d-2642-fe0f","native":"💆🏿♂️"}],"version":4},"woman-getting-massage":{"id":"woman-getting-massage","name":"Woman Getting Massage","keywords":["getting-massage","female","girl","head"],"skins":[{"unified":"1f486-200d-2640-fe0f","native":"💆♀️"},{"unified":"1f486-1f3fb-200d-2640-fe0f","native":"💆🏻♀️"},{"unified":"1f486-1f3fc-200d-2640-fe0f","native":"💆🏼♀️"},{"unified":"1f486-1f3fd-200d-2640-fe0f","native":"💆🏽♀️"},{"unified":"1f486-1f3fe-200d-2640-fe0f","native":"💆🏾♀️"},{"unified":"1f486-1f3ff-200d-2640-fe0f","native":"💆🏿♀️"}],"version":4},"haircut":{"id":"haircut","name":"Haircut","keywords":["person","getting","hairstyle"],"skins":[{"unified":"1f487","native":"💇"},{"unified":"1f487-1f3fb","native":"💇🏻"},{"unified":"1f487-1f3fc","native":"💇🏼"},{"unified":"1f487-1f3fd","native":"💇🏽"},{"unified":"1f487-1f3fe","native":"💇🏾"},{"unified":"1f487-1f3ff","native":"💇🏿"}],"version":1},"man-getting-haircut":{"id":"man-getting-haircut","name":"Man Getting Haircut","keywords":["getting-haircut","male","boy"],"skins":[{"unified":"1f487-200d-2642-fe0f","native":"💇♂️"},{"unified":"1f487-1f3fb-200d-2642-fe0f","native":"💇🏻♂️"},{"unified":"1f487-1f3fc-200d-2642-fe0f","native":"💇🏼♂️"},{"unified":"1f487-1f3fd-200d-2642-fe0f","native":"💇🏽♂️"},{"unified":"1f487-1f3fe-200d-2642-fe0f","native":"💇🏾♂️"},{"unified":"1f487-1f3ff-200d-2642-fe0f","native":"💇🏿♂️"}],"version":4},"woman-getting-haircut":{"id":"woman-getting-haircut","name":"Woman Getting Haircut","keywords":["getting-haircut","female","girl"],"skins":[{"unified":"1f487-200d-2640-fe0f","native":"💇♀️"},{"unified":"1f487-1f3fb-200d-2640-fe0f","native":"💇🏻♀️"},{"unified":"1f487-1f3fc-200d-2640-fe0f","native":"💇🏼♀️"},{"unified":"1f487-1f3fd-200d-2640-fe0f","native":"💇🏽♀️"},{"unified":"1f487-1f3fe-200d-2640-fe0f","native":"💇🏾♀️"},{"unified":"1f487-1f3ff-200d-2640-fe0f","native":"💇🏿♀️"}],"version":4},"walking":{"id":"walking","name":"Pedestrian","keywords":["walking","person","move"],"skins":[{"unified":"1f6b6","native":"🚶"},{"unified":"1f6b6-1f3fb","native":"🚶🏻"},{"unified":"1f6b6-1f3fc","native":"🚶🏼"},{"unified":"1f6b6-1f3fd","native":"🚶🏽"},{"unified":"1f6b6-1f3fe","native":"🚶🏾"},{"unified":"1f6b6-1f3ff","native":"🚶🏿"}],"version":1},"man-walking":{"id":"man-walking","name":"Man Walking","keywords":["human","feet","steps"],"skins":[{"unified":"1f6b6-200d-2642-fe0f","native":"🚶♂️"},{"unified":"1f6b6-1f3fb-200d-2642-fe0f","native":"🚶🏻♂️"},{"unified":"1f6b6-1f3fc-200d-2642-fe0f","native":"🚶🏼♂️"},{"unified":"1f6b6-1f3fd-200d-2642-fe0f","native":"🚶🏽♂️"},{"unified":"1f6b6-1f3fe-200d-2642-fe0f","native":"🚶🏾♂️"},{"unified":"1f6b6-1f3ff-200d-2642-fe0f","native":"🚶🏿♂️"}],"version":4},"woman-walking":{"id":"woman-walking","name":"Woman Walking","keywords":["human","feet","steps","female"],"skins":[{"unified":"1f6b6-200d-2640-fe0f","native":"🚶♀️"},{"unified":"1f6b6-1f3fb-200d-2640-fe0f","native":"🚶🏻♀️"},{"unified":"1f6b6-1f3fc-200d-2640-fe0f","native":"🚶🏼♀️"},{"unified":"1f6b6-1f3fd-200d-2640-fe0f","native":"🚶🏽♀️"},{"unified":"1f6b6-1f3fe-200d-2640-fe0f","native":"🚶🏾♀️"},{"unified":"1f6b6-1f3ff-200d-2640-fe0f","native":"🚶🏿♀️"}],"version":4},"standing_person":{"id":"standing_person","name":"Standing Person","keywords":["still"],"skins":[{"unified":"1f9cd","native":"🧍"},{"unified":"1f9cd-1f3fb","native":"🧍🏻"},{"unified":"1f9cd-1f3fc","native":"🧍🏼"},{"unified":"1f9cd-1f3fd","native":"🧍🏽"},{"unified":"1f9cd-1f3fe","native":"🧍🏾"},{"unified":"1f9cd-1f3ff","native":"🧍🏿"}],"version":12},"man_standing":{"id":"man_standing","name":"Man Standing","keywords":["still"],"skins":[{"unified":"1f9cd-200d-2642-fe0f","native":"🧍♂️"},{"unified":"1f9cd-1f3fb-200d-2642-fe0f","native":"🧍🏻♂️"},{"unified":"1f9cd-1f3fc-200d-2642-fe0f","native":"🧍🏼♂️"},{"unified":"1f9cd-1f3fd-200d-2642-fe0f","native":"🧍🏽♂️"},{"unified":"1f9cd-1f3fe-200d-2642-fe0f","native":"🧍🏾♂️"},{"unified":"1f9cd-1f3ff-200d-2642-fe0f","native":"🧍🏿♂️"}],"version":12},"woman_standing":{"id":"woman_standing","name":"Woman Standing","keywords":["still"],"skins":[{"unified":"1f9cd-200d-2640-fe0f","native":"🧍♀️"},{"unified":"1f9cd-1f3fb-200d-2640-fe0f","native":"🧍🏻♀️"},{"unified":"1f9cd-1f3fc-200d-2640-fe0f","native":"🧍🏼♀️"},{"unified":"1f9cd-1f3fd-200d-2640-fe0f","native":"🧍🏽♀️"},{"unified":"1f9cd-1f3fe-200d-2640-fe0f","native":"🧍🏾♀️"},{"unified":"1f9cd-1f3ff-200d-2640-fe0f","native":"🧍🏿♀️"}],"version":12},"kneeling_person":{"id":"kneeling_person","name":"Kneeling Person","keywords":["pray","respectful"],"skins":[{"unified":"1f9ce","native":"🧎"},{"unified":"1f9ce-1f3fb","native":"🧎🏻"},{"unified":"1f9ce-1f3fc","native":"🧎🏼"},{"unified":"1f9ce-1f3fd","native":"🧎🏽"},{"unified":"1f9ce-1f3fe","native":"🧎🏾"},{"unified":"1f9ce-1f3ff","native":"🧎🏿"}],"version":12},"man_kneeling":{"id":"man_kneeling","name":"Man Kneeling","keywords":["pray","respectful"],"skins":[{"unified":"1f9ce-200d-2642-fe0f","native":"🧎♂️"},{"unified":"1f9ce-1f3fb-200d-2642-fe0f","native":"🧎🏻♂️"},{"unified":"1f9ce-1f3fc-200d-2642-fe0f","native":"🧎🏼♂️"},{"unified":"1f9ce-1f3fd-200d-2642-fe0f","native":"🧎🏽♂️"},{"unified":"1f9ce-1f3fe-200d-2642-fe0f","native":"🧎🏾♂️"},{"unified":"1f9ce-1f3ff-200d-2642-fe0f","native":"🧎🏿♂️"}],"version":12},"woman_kneeling":{"id":"woman_kneeling","name":"Woman Kneeling","keywords":["respectful","pray"],"skins":[{"unified":"1f9ce-200d-2640-fe0f","native":"🧎♀️"},{"unified":"1f9ce-1f3fb-200d-2640-fe0f","native":"🧎🏻♀️"},{"unified":"1f9ce-1f3fc-200d-2640-fe0f","native":"🧎🏼♀️"},{"unified":"1f9ce-1f3fd-200d-2640-fe0f","native":"🧎🏽♀️"},{"unified":"1f9ce-1f3fe-200d-2640-fe0f","native":"🧎🏾♀️"},{"unified":"1f9ce-1f3ff-200d-2640-fe0f","native":"🧎🏿♀️"}],"version":12},"person_with_probing_cane":{"id":"person_with_probing_cane","name":"Person with White Cane","keywords":["probing","blind"],"skins":[{"unified":"1f9d1-200d-1f9af","native":"🧑🦯"},{"unified":"1f9d1-1f3fb-200d-1f9af","native":"🧑🏻🦯"},{"unified":"1f9d1-1f3fc-200d-1f9af","native":"🧑🏼🦯"},{"unified":"1f9d1-1f3fd-200d-1f9af","native":"🧑🏽🦯"},{"unified":"1f9d1-1f3fe-200d-1f9af","native":"🧑🏾🦯"},{"unified":"1f9d1-1f3ff-200d-1f9af","native":"🧑🏿🦯"}],"version":12.1},"man_with_probing_cane":{"id":"man_with_probing_cane","name":"Man with White Cane","keywords":["probing","blind"],"skins":[{"unified":"1f468-200d-1f9af","native":"👨🦯"},{"unified":"1f468-1f3fb-200d-1f9af","native":"👨🏻🦯"},{"unified":"1f468-1f3fc-200d-1f9af","native":"👨🏼🦯"},{"unified":"1f468-1f3fd-200d-1f9af","native":"👨🏽🦯"},{"unified":"1f468-1f3fe-200d-1f9af","native":"👨🏾🦯"},{"unified":"1f468-1f3ff-200d-1f9af","native":"👨🏿🦯"}],"version":12},"woman_with_probing_cane":{"id":"woman_with_probing_cane","name":"Woman with White Cane","keywords":["probing","blind"],"skins":[{"unified":"1f469-200d-1f9af","native":"👩🦯"},{"unified":"1f469-1f3fb-200d-1f9af","native":"👩🏻🦯"},{"unified":"1f469-1f3fc-200d-1f9af","native":"👩🏼🦯"},{"unified":"1f469-1f3fd-200d-1f9af","native":"👩🏽🦯"},{"unified":"1f469-1f3fe-200d-1f9af","native":"👩🏾🦯"},{"unified":"1f469-1f3ff-200d-1f9af","native":"👩🏿🦯"}],"version":12},"person_in_motorized_wheelchair":{"id":"person_in_motorized_wheelchair","name":"Person in Motorized Wheelchair","keywords":["disability","accessibility"],"skins":[{"unified":"1f9d1-200d-1f9bc","native":"🧑🦼"},{"unified":"1f9d1-1f3fb-200d-1f9bc","native":"🧑🏻🦼"},{"unified":"1f9d1-1f3fc-200d-1f9bc","native":"🧑🏼🦼"},{"unified":"1f9d1-1f3fd-200d-1f9bc","native":"🧑🏽🦼"},{"unified":"1f9d1-1f3fe-200d-1f9bc","native":"🧑🏾🦼"},{"unified":"1f9d1-1f3ff-200d-1f9bc","native":"🧑🏿🦼"}],"version":12.1},"man_in_motorized_wheelchair":{"id":"man_in_motorized_wheelchair","name":"Man in Motorized Wheelchair","keywords":["disability","accessibility"],"skins":[{"unified":"1f468-200d-1f9bc","native":"👨🦼"},{"unified":"1f468-1f3fb-200d-1f9bc","native":"👨🏻🦼"},{"unified":"1f468-1f3fc-200d-1f9bc","native":"👨🏼🦼"},{"unified":"1f468-1f3fd-200d-1f9bc","native":"👨🏽🦼"},{"unified":"1f468-1f3fe-200d-1f9bc","native":"👨🏾🦼"},{"unified":"1f468-1f3ff-200d-1f9bc","native":"👨🏿🦼"}],"version":12},"woman_in_motorized_wheelchair":{"id":"woman_in_motorized_wheelchair","name":"Woman in Motorized Wheelchair","keywords":["disability","accessibility"],"skins":[{"unified":"1f469-200d-1f9bc","native":"👩🦼"},{"unified":"1f469-1f3fb-200d-1f9bc","native":"👩🏻🦼"},{"unified":"1f469-1f3fc-200d-1f9bc","native":"👩🏼🦼"},{"unified":"1f469-1f3fd-200d-1f9bc","native":"👩🏽🦼"},{"unified":"1f469-1f3fe-200d-1f9bc","native":"👩🏾🦼"},{"unified":"1f469-1f3ff-200d-1f9bc","native":"👩🏿🦼"}],"version":12},"person_in_manual_wheelchair":{"id":"person_in_manual_wheelchair","name":"Person in Manual Wheelchair","keywords":["disability","accessibility"],"skins":[{"unified":"1f9d1-200d-1f9bd","native":"🧑🦽"},{"unified":"1f9d1-1f3fb-200d-1f9bd","native":"🧑🏻🦽"},{"unified":"1f9d1-1f3fc-200d-1f9bd","native":"🧑🏼🦽"},{"unified":"1f9d1-1f3fd-200d-1f9bd","native":"🧑🏽🦽"},{"unified":"1f9d1-1f3fe-200d-1f9bd","native":"🧑🏾🦽"},{"unified":"1f9d1-1f3ff-200d-1f9bd","native":"🧑🏿🦽"}],"version":12.1},"man_in_manual_wheelchair":{"id":"man_in_manual_wheelchair","name":"Man in Manual Wheelchair","keywords":["disability","accessibility"],"skins":[{"unified":"1f468-200d-1f9bd","native":"👨🦽"},{"unified":"1f468-1f3fb-200d-1f9bd","native":"👨🏻🦽"},{"unified":"1f468-1f3fc-200d-1f9bd","native":"👨🏼🦽"},{"unified":"1f468-1f3fd-200d-1f9bd","native":"👨🏽🦽"},{"unified":"1f468-1f3fe-200d-1f9bd","native":"👨🏾🦽"},{"unified":"1f468-1f3ff-200d-1f9bd","native":"👨🏿🦽"}],"version":12},"woman_in_manual_wheelchair":{"id":"woman_in_manual_wheelchair","name":"Woman in Manual Wheelchair","keywords":["disability","accessibility"],"skins":[{"unified":"1f469-200d-1f9bd","native":"👩🦽"},{"unified":"1f469-1f3fb-200d-1f9bd","native":"👩🏻🦽"},{"unified":"1f469-1f3fc-200d-1f9bd","native":"👩🏼🦽"},{"unified":"1f469-1f3fd-200d-1f9bd","native":"👩🏽🦽"},{"unified":"1f469-1f3fe-200d-1f9bd","native":"👩🏾🦽"},{"unified":"1f469-1f3ff-200d-1f9bd","native":"👩🏿🦽"}],"version":12},"runner":{"id":"runner","name":"Runner","keywords":["running","person","move"],"skins":[{"unified":"1f3c3","native":"🏃"},{"unified":"1f3c3-1f3fb","native":"🏃🏻"},{"unified":"1f3c3-1f3fc","native":"🏃🏼"},{"unified":"1f3c3-1f3fd","native":"🏃🏽"},{"unified":"1f3c3-1f3fe","native":"🏃🏾"},{"unified":"1f3c3-1f3ff","native":"🏃🏿"}],"version":1},"man-running":{"id":"man-running","name":"Man Running","keywords":["walking","exercise","race"],"skins":[{"unified":"1f3c3-200d-2642-fe0f","native":"🏃♂️"},{"unified":"1f3c3-1f3fb-200d-2642-fe0f","native":"🏃🏻♂️"},{"unified":"1f3c3-1f3fc-200d-2642-fe0f","native":"🏃🏼♂️"},{"unified":"1f3c3-1f3fd-200d-2642-fe0f","native":"🏃🏽♂️"},{"unified":"1f3c3-1f3fe-200d-2642-fe0f","native":"🏃🏾♂️"},{"unified":"1f3c3-1f3ff-200d-2642-fe0f","native":"🏃🏿♂️"}],"version":4},"woman-running":{"id":"woman-running","name":"Woman Running","keywords":["walking","exercise","race","female"],"skins":[{"unified":"1f3c3-200d-2640-fe0f","native":"🏃♀️"},{"unified":"1f3c3-1f3fb-200d-2640-fe0f","native":"🏃🏻♀️"},{"unified":"1f3c3-1f3fc-200d-2640-fe0f","native":"🏃🏼♀️"},{"unified":"1f3c3-1f3fd-200d-2640-fe0f","native":"🏃🏽♀️"},{"unified":"1f3c3-1f3fe-200d-2640-fe0f","native":"🏃🏾♀️"},{"unified":"1f3c3-1f3ff-200d-2640-fe0f","native":"🏃🏿♀️"}],"version":4},"dancer":{"id":"dancer","name":"Dancer","keywords":["woman","dancing","female","girl","fun"],"skins":[{"unified":"1f483","native":"💃"},{"unified":"1f483-1f3fb","native":"💃🏻"},{"unified":"1f483-1f3fc","native":"💃🏼"},{"unified":"1f483-1f3fd","native":"💃🏽"},{"unified":"1f483-1f3fe","native":"💃🏾"},{"unified":"1f483-1f3ff","native":"💃🏿"}],"version":1},"man_dancing":{"id":"man_dancing","name":"Man Dancing","keywords":["male","boy","fun","dancer"],"skins":[{"unified":"1f57a","native":"🕺"},{"unified":"1f57a-1f3fb","native":"🕺🏻"},{"unified":"1f57a-1f3fc","native":"🕺🏼"},{"unified":"1f57a-1f3fd","native":"🕺🏽"},{"unified":"1f57a-1f3fe","native":"🕺🏾"},{"unified":"1f57a-1f3ff","native":"🕺🏿"}],"version":3},"man_in_business_suit_levitating":{"id":"man_in_business_suit_levitating","name":"Person in Suit Levitating","keywords":["man","business","levitate","hover","jump"],"skins":[{"unified":"1f574-fe0f","native":"🕴️"},{"unified":"1f574-1f3fb","native":"🕴🏻"},{"unified":"1f574-1f3fc","native":"🕴🏼"},{"unified":"1f574-1f3fd","native":"🕴🏽"},{"unified":"1f574-1f3fe","native":"🕴🏾"},{"unified":"1f574-1f3ff","native":"🕴🏿"}],"version":1},"dancers":{"id":"dancers","name":"Woman with Bunny Ears","keywords":["dancers","people","perform","costume"],"skins":[{"unified":"1f46f","native":"👯"}],"version":1},"men-with-bunny-ears-partying":{"id":"men-with-bunny-ears-partying","name":"Men with Bunny Ears","keywords":["with-bunny-ears-partying","man","male","boys"],"skins":[{"unified":"1f46f-200d-2642-fe0f","native":"👯♂️"}],"version":4},"women-with-bunny-ears-partying":{"id":"women-with-bunny-ears-partying","name":"Women with Bunny Ears","keywords":["with-bunny-ears-partying","woman","female","girls"],"skins":[{"unified":"1f46f-200d-2640-fe0f","native":"👯♀️"}],"version":4},"person_in_steamy_room":{"id":"person_in_steamy_room","name":"Person in Steamy Room","keywords":["relax","spa"],"skins":[{"unified":"1f9d6","native":"🧖"},{"unified":"1f9d6-1f3fb","native":"🧖🏻"},{"unified":"1f9d6-1f3fc","native":"🧖🏼"},{"unified":"1f9d6-1f3fd","native":"🧖🏽"},{"unified":"1f9d6-1f3fe","native":"🧖🏾"},{"unified":"1f9d6-1f3ff","native":"🧖🏿"}],"version":5},"man_in_steamy_room":{"id":"man_in_steamy_room","name":"Man in Steamy Room","keywords":["male","spa","steamroom","sauna"],"skins":[{"unified":"1f9d6-200d-2642-fe0f","native":"🧖♂️"},{"unified":"1f9d6-1f3fb-200d-2642-fe0f","native":"🧖🏻♂️"},{"unified":"1f9d6-1f3fc-200d-2642-fe0f","native":"🧖🏼♂️"},{"unified":"1f9d6-1f3fd-200d-2642-fe0f","native":"🧖🏽♂️"},{"unified":"1f9d6-1f3fe-200d-2642-fe0f","native":"🧖🏾♂️"},{"unified":"1f9d6-1f3ff-200d-2642-fe0f","native":"🧖🏿♂️"}],"version":5},"woman_in_steamy_room":{"id":"woman_in_steamy_room","name":"Woman in Steamy Room","keywords":["female","spa","steamroom","sauna"],"skins":[{"unified":"1f9d6-200d-2640-fe0f","native":"🧖♀️"},{"unified":"1f9d6-1f3fb-200d-2640-fe0f","native":"🧖🏻♀️"},{"unified":"1f9d6-1f3fc-200d-2640-fe0f","native":"🧖🏼♀️"},{"unified":"1f9d6-1f3fd-200d-2640-fe0f","native":"🧖🏽♀️"},{"unified":"1f9d6-1f3fe-200d-2640-fe0f","native":"🧖🏾♀️"},{"unified":"1f9d6-1f3ff-200d-2640-fe0f","native":"🧖🏿♀️"}],"version":5},"person_climbing":{"id":"person_climbing","name":"Person Climbing","keywords":["sport"],"skins":[{"unified":"1f9d7","native":"🧗"},{"unified":"1f9d7-1f3fb","native":"🧗🏻"},{"unified":"1f9d7-1f3fc","native":"🧗🏼"},{"unified":"1f9d7-1f3fd","native":"🧗🏽"},{"unified":"1f9d7-1f3fe","native":"🧗🏾"},{"unified":"1f9d7-1f3ff","native":"🧗🏿"}],"version":5},"man_climbing":{"id":"man_climbing","name":"Man Climbing","keywords":["sports","hobby","male","rock"],"skins":[{"unified":"1f9d7-200d-2642-fe0f","native":"🧗♂️"},{"unified":"1f9d7-1f3fb-200d-2642-fe0f","native":"🧗🏻♂️"},{"unified":"1f9d7-1f3fc-200d-2642-fe0f","native":"🧗🏼♂️"},{"unified":"1f9d7-1f3fd-200d-2642-fe0f","native":"🧗🏽♂️"},{"unified":"1f9d7-1f3fe-200d-2642-fe0f","native":"🧗🏾♂️"},{"unified":"1f9d7-1f3ff-200d-2642-fe0f","native":"🧗🏿♂️"}],"version":5},"woman_climbing":{"id":"woman_climbing","name":"Woman Climbing","keywords":["sports","hobby","female","rock"],"skins":[{"unified":"1f9d7-200d-2640-fe0f","native":"🧗♀️"},{"unified":"1f9d7-1f3fb-200d-2640-fe0f","native":"🧗🏻♀️"},{"unified":"1f9d7-1f3fc-200d-2640-fe0f","native":"🧗🏼♀️"},{"unified":"1f9d7-1f3fd-200d-2640-fe0f","native":"🧗🏽♀️"},{"unified":"1f9d7-1f3fe-200d-2640-fe0f","native":"🧗🏾♀️"},{"unified":"1f9d7-1f3ff-200d-2640-fe0f","native":"🧗🏿♀️"}],"version":5},"fencer":{"id":"fencer","name":"Fencer","keywords":["person","fencing","sports","sword"],"skins":[{"unified":"1f93a","native":"🤺"}],"version":3},"horse_racing":{"id":"horse_racing","name":"Horse Racing","keywords":["animal","betting","competition","gambling","luck"],"skins":[{"unified":"1f3c7","native":"🏇"},{"unified":"1f3c7-1f3fb","native":"🏇🏻"},{"unified":"1f3c7-1f3fc","native":"🏇🏼"},{"unified":"1f3c7-1f3fd","native":"🏇🏽"},{"unified":"1f3c7-1f3fe","native":"🏇🏾"},{"unified":"1f3c7-1f3ff","native":"🏇🏿"}],"version":1},"skier":{"id":"skier","name":"Skier","keywords":["sports","winter","snow"],"skins":[{"unified":"26f7-fe0f","native":"⛷️"}],"version":1},"snowboarder":{"id":"snowboarder","name":"Snowboarder","keywords":["sports","winter"],"skins":[{"unified":"1f3c2","native":"🏂"},{"unified":"1f3c2-1f3fb","native":"🏂🏻"},{"unified":"1f3c2-1f3fc","native":"🏂🏼"},{"unified":"1f3c2-1f3fd","native":"🏂🏽"},{"unified":"1f3c2-1f3fe","native":"🏂🏾"},{"unified":"1f3c2-1f3ff","native":"🏂🏿"}],"version":1},"golfer":{"id":"golfer","name":"Person Golfing","keywords":["golfer","sports","business"],"skins":[{"unified":"1f3cc-fe0f","native":"🏌️"},{"unified":"1f3cc-1f3fb","native":"🏌🏻"},{"unified":"1f3cc-1f3fc","native":"🏌🏼"},{"unified":"1f3cc-1f3fd","native":"🏌🏽"},{"unified":"1f3cc-1f3fe","native":"🏌🏾"},{"unified":"1f3cc-1f3ff","native":"🏌🏿"}],"version":1},"man-golfing":{"id":"man-golfing","name":"Man Golfing","keywords":["sport"],"skins":[{"unified":"1f3cc-fe0f-200d-2642-fe0f","native":"🏌️♂️"},{"unified":"1f3cc-1f3fb-200d-2642-fe0f","native":"🏌🏻♂️"},{"unified":"1f3cc-1f3fc-200d-2642-fe0f","native":"🏌🏼♂️"},{"unified":"1f3cc-1f3fd-200d-2642-fe0f","native":"🏌🏽♂️"},{"unified":"1f3cc-1f3fe-200d-2642-fe0f","native":"🏌🏾♂️"},{"unified":"1f3cc-1f3ff-200d-2642-fe0f","native":"🏌🏿♂️"}],"version":4},"woman-golfing":{"id":"woman-golfing","name":"Woman Golfing","keywords":["sports","business","female"],"skins":[{"unified":"1f3cc-fe0f-200d-2640-fe0f","native":"🏌️♀️"},{"unified":"1f3cc-1f3fb-200d-2640-fe0f","native":"🏌🏻♀️"},{"unified":"1f3cc-1f3fc-200d-2640-fe0f","native":"🏌🏼♀️"},{"unified":"1f3cc-1f3fd-200d-2640-fe0f","native":"🏌🏽♀️"},{"unified":"1f3cc-1f3fe-200d-2640-fe0f","native":"🏌🏾♀️"},{"unified":"1f3cc-1f3ff-200d-2640-fe0f","native":"🏌🏿♀️"}],"version":4},"surfer":{"id":"surfer","name":"Surfer","keywords":["person","surfing","sport","sea"],"skins":[{"unified":"1f3c4","native":"🏄"},{"unified":"1f3c4-1f3fb","native":"🏄🏻"},{"unified":"1f3c4-1f3fc","native":"🏄🏼"},{"unified":"1f3c4-1f3fd","native":"🏄🏽"},{"unified":"1f3c4-1f3fe","native":"🏄🏾"},{"unified":"1f3c4-1f3ff","native":"🏄🏿"}],"version":1},"man-surfing":{"id":"man-surfing","name":"Man Surfing","keywords":["sports","ocean","sea","summer","beach"],"skins":[{"unified":"1f3c4-200d-2642-fe0f","native":"🏄♂️"},{"unified":"1f3c4-1f3fb-200d-2642-fe0f","native":"🏄🏻♂️"},{"unified":"1f3c4-1f3fc-200d-2642-fe0f","native":"🏄🏼♂️"},{"unified":"1f3c4-1f3fd-200d-2642-fe0f","native":"🏄🏽♂️"},{"unified":"1f3c4-1f3fe-200d-2642-fe0f","native":"🏄🏾♂️"},{"unified":"1f3c4-1f3ff-200d-2642-fe0f","native":"🏄🏿♂️"}],"version":4},"woman-surfing":{"id":"woman-surfing","name":"Woman Surfing","keywords":["sports","ocean","sea","summer","beach","female"],"skins":[{"unified":"1f3c4-200d-2640-fe0f","native":"🏄♀️"},{"unified":"1f3c4-1f3fb-200d-2640-fe0f","native":"🏄🏻♀️"},{"unified":"1f3c4-1f3fc-200d-2640-fe0f","native":"🏄🏼♀️"},{"unified":"1f3c4-1f3fd-200d-2640-fe0f","native":"🏄🏽♀️"},{"unified":"1f3c4-1f3fe-200d-2640-fe0f","native":"🏄🏾♀️"},{"unified":"1f3c4-1f3ff-200d-2640-fe0f","native":"🏄🏿♀️"}],"version":4},"rowboat":{"id":"rowboat","name":"Rowboat","keywords":["person","rowing","boat","sport","move"],"skins":[{"unified":"1f6a3","native":"🚣"},{"unified":"1f6a3-1f3fb","native":"🚣🏻"},{"unified":"1f6a3-1f3fc","native":"🚣🏼"},{"unified":"1f6a3-1f3fd","native":"🚣🏽"},{"unified":"1f6a3-1f3fe","native":"🚣🏾"},{"unified":"1f6a3-1f3ff","native":"🚣🏿"}],"version":1},"man-rowing-boat":{"id":"man-rowing-boat","name":"Man Rowing Boat","keywords":["rowing-boat","sports","hobby","water","ship"],"skins":[{"unified":"1f6a3-200d-2642-fe0f","native":"🚣♂️"},{"unified":"1f6a3-1f3fb-200d-2642-fe0f","native":"🚣🏻♂️"},{"unified":"1f6a3-1f3fc-200d-2642-fe0f","native":"🚣🏼♂️"},{"unified":"1f6a3-1f3fd-200d-2642-fe0f","native":"🚣🏽♂️"},{"unified":"1f6a3-1f3fe-200d-2642-fe0f","native":"🚣🏾♂️"},{"unified":"1f6a3-1f3ff-200d-2642-fe0f","native":"🚣🏿♂️"}],"version":4},"woman-rowing-boat":{"id":"woman-rowing-boat","name":"Woman Rowing Boat","keywords":["rowing-boat","sports","hobby","water","ship","female"],"skins":[{"unified":"1f6a3-200d-2640-fe0f","native":"🚣♀️"},{"unified":"1f6a3-1f3fb-200d-2640-fe0f","native":"🚣🏻♀️"},{"unified":"1f6a3-1f3fc-200d-2640-fe0f","native":"🚣🏼♀️"},{"unified":"1f6a3-1f3fd-200d-2640-fe0f","native":"🚣🏽♀️"},{"unified":"1f6a3-1f3fe-200d-2640-fe0f","native":"🚣🏾♀️"},{"unified":"1f6a3-1f3ff-200d-2640-fe0f","native":"🚣🏿♀️"}],"version":4},"swimmer":{"id":"swimmer","name":"Swimmer","keywords":["person","swimming","sport","pool"],"skins":[{"unified":"1f3ca","native":"🏊"},{"unified":"1f3ca-1f3fb","native":"🏊🏻"},{"unified":"1f3ca-1f3fc","native":"🏊🏼"},{"unified":"1f3ca-1f3fd","native":"🏊🏽"},{"unified":"1f3ca-1f3fe","native":"🏊🏾"},{"unified":"1f3ca-1f3ff","native":"🏊🏿"}],"version":1},"man-swimming":{"id":"man-swimming","name":"Man Swimming","keywords":["sports","exercise","human","athlete","water","summer"],"skins":[{"unified":"1f3ca-200d-2642-fe0f","native":"🏊♂️"},{"unified":"1f3ca-1f3fb-200d-2642-fe0f","native":"🏊🏻♂️"},{"unified":"1f3ca-1f3fc-200d-2642-fe0f","native":"🏊🏼♂️"},{"unified":"1f3ca-1f3fd-200d-2642-fe0f","native":"🏊🏽♂️"},{"unified":"1f3ca-1f3fe-200d-2642-fe0f","native":"🏊🏾♂️"},{"unified":"1f3ca-1f3ff-200d-2642-fe0f","native":"🏊🏿♂️"}],"version":4},"woman-swimming":{"id":"woman-swimming","name":"Woman Swimming","keywords":["sports","exercise","human","athlete","water","summer","female"],"skins":[{"unified":"1f3ca-200d-2640-fe0f","native":"🏊♀️"},{"unified":"1f3ca-1f3fb-200d-2640-fe0f","native":"🏊🏻♀️"},{"unified":"1f3ca-1f3fc-200d-2640-fe0f","native":"🏊🏼♀️"},{"unified":"1f3ca-1f3fd-200d-2640-fe0f","native":"🏊🏽♀️"},{"unified":"1f3ca-1f3fe-200d-2640-fe0f","native":"🏊🏾♀️"},{"unified":"1f3ca-1f3ff-200d-2640-fe0f","native":"🏊🏿♀️"}],"version":4},"person_with_ball":{"id":"person_with_ball","name":"Person Bouncing Ball","keywords":["with","sports","human"],"skins":[{"unified":"26f9-fe0f","native":"⛹️"},{"unified":"26f9-1f3fb","native":"⛹🏻"},{"unified":"26f9-1f3fc","native":"⛹🏼"},{"unified":"26f9-1f3fd","native":"⛹🏽"},{"unified":"26f9-1f3fe","native":"⛹🏾"},{"unified":"26f9-1f3ff","native":"⛹🏿"}],"version":1},"man-bouncing-ball":{"id":"man-bouncing-ball","name":"Man Bouncing Ball","keywords":["bouncing-ball","sport"],"skins":[{"unified":"26f9-fe0f-200d-2642-fe0f","native":"⛹️♂️"},{"unified":"26f9-1f3fb-200d-2642-fe0f","native":"⛹🏻♂️"},{"unified":"26f9-1f3fc-200d-2642-fe0f","native":"⛹🏼♂️"},{"unified":"26f9-1f3fd-200d-2642-fe0f","native":"⛹🏽♂️"},{"unified":"26f9-1f3fe-200d-2642-fe0f","native":"⛹🏾♂️"},{"unified":"26f9-1f3ff-200d-2642-fe0f","native":"⛹🏿♂️"}],"version":4},"woman-bouncing-ball":{"id":"woman-bouncing-ball","name":"Woman Bouncing Ball","keywords":["bouncing-ball","sports","human","female"],"skins":[{"unified":"26f9-fe0f-200d-2640-fe0f","native":"⛹️♀️"},{"unified":"26f9-1f3fb-200d-2640-fe0f","native":"⛹🏻♀️"},{"unified":"26f9-1f3fc-200d-2640-fe0f","native":"⛹🏼♀️"},{"unified":"26f9-1f3fd-200d-2640-fe0f","native":"⛹🏽♀️"},{"unified":"26f9-1f3fe-200d-2640-fe0f","native":"⛹🏾♀️"},{"unified":"26f9-1f3ff-200d-2640-fe0f","native":"⛹🏿♀️"}],"version":4},"weight_lifter":{"id":"weight_lifter","name":"Person Lifting Weights","keywords":["weight","lifter","sports","training","exercise"],"skins":[{"unified":"1f3cb-fe0f","native":"🏋️"},{"unified":"1f3cb-1f3fb","native":"🏋🏻"},{"unified":"1f3cb-1f3fc","native":"🏋🏼"},{"unified":"1f3cb-1f3fd","native":"🏋🏽"},{"unified":"1f3cb-1f3fe","native":"🏋🏾"},{"unified":"1f3cb-1f3ff","native":"🏋🏿"}],"version":1},"man-lifting-weights":{"id":"man-lifting-weights","name":"Man Lifting Weights","keywords":["lifting-weights","sport"],"skins":[{"unified":"1f3cb-fe0f-200d-2642-fe0f","native":"🏋️♂️"},{"unified":"1f3cb-1f3fb-200d-2642-fe0f","native":"🏋🏻♂️"},{"unified":"1f3cb-1f3fc-200d-2642-fe0f","native":"🏋🏼♂️"},{"unified":"1f3cb-1f3fd-200d-2642-fe0f","native":"🏋🏽♂️"},{"unified":"1f3cb-1f3fe-200d-2642-fe0f","native":"🏋🏾♂️"},{"unified":"1f3cb-1f3ff-200d-2642-fe0f","native":"🏋🏿♂️"}],"version":4},"woman-lifting-weights":{"id":"woman-lifting-weights","name":"Woman Lifting Weights","keywords":["lifting-weights","sports","training","exercise","female"],"skins":[{"unified":"1f3cb-fe0f-200d-2640-fe0f","native":"🏋️♀️"},{"unified":"1f3cb-1f3fb-200d-2640-fe0f","native":"🏋🏻♀️"},{"unified":"1f3cb-1f3fc-200d-2640-fe0f","native":"🏋🏼♀️"},{"unified":"1f3cb-1f3fd-200d-2640-fe0f","native":"🏋🏽♀️"},{"unified":"1f3cb-1f3fe-200d-2640-fe0f","native":"🏋🏾♀️"},{"unified":"1f3cb-1f3ff-200d-2640-fe0f","native":"🏋🏿♀️"}],"version":4},"bicyclist":{"id":"bicyclist","name":"Bicyclist","keywords":["person","biking","sport","move"],"skins":[{"unified":"1f6b4","native":"🚴"},{"unified":"1f6b4-1f3fb","native":"🚴🏻"},{"unified":"1f6b4-1f3fc","native":"🚴🏼"},{"unified":"1f6b4-1f3fd","native":"🚴🏽"},{"unified":"1f6b4-1f3fe","native":"🚴🏾"},{"unified":"1f6b4-1f3ff","native":"🚴🏿"}],"version":1},"man-biking":{"id":"man-biking","name":"Man Biking","keywords":["sports","bike","exercise","hipster"],"skins":[{"unified":"1f6b4-200d-2642-fe0f","native":"🚴♂️"},{"unified":"1f6b4-1f3fb-200d-2642-fe0f","native":"🚴🏻♂️"},{"unified":"1f6b4-1f3fc-200d-2642-fe0f","native":"🚴🏼♂️"},{"unified":"1f6b4-1f3fd-200d-2642-fe0f","native":"🚴🏽♂️"},{"unified":"1f6b4-1f3fe-200d-2642-fe0f","native":"🚴🏾♂️"},{"unified":"1f6b4-1f3ff-200d-2642-fe0f","native":"🚴🏿♂️"}],"version":4},"woman-biking":{"id":"woman-biking","name":"Woman Biking","keywords":["sports","bike","exercise","hipster","female"],"skins":[{"unified":"1f6b4-200d-2640-fe0f","native":"🚴♀️"},{"unified":"1f6b4-1f3fb-200d-2640-fe0f","native":"🚴🏻♀️"},{"unified":"1f6b4-1f3fc-200d-2640-fe0f","native":"🚴🏼♀️"},{"unified":"1f6b4-1f3fd-200d-2640-fe0f","native":"🚴🏽♀️"},{"unified":"1f6b4-1f3fe-200d-2640-fe0f","native":"🚴🏾♀️"},{"unified":"1f6b4-1f3ff-200d-2640-fe0f","native":"🚴🏿♀️"}],"version":4},"mountain_bicyclist":{"id":"mountain_bicyclist","name":"Mountain Bicyclist","keywords":["person","biking","sport","move"],"skins":[{"unified":"1f6b5","native":"🚵"},{"unified":"1f6b5-1f3fb","native":"🚵🏻"},{"unified":"1f6b5-1f3fc","native":"🚵🏼"},{"unified":"1f6b5-1f3fd","native":"🚵🏽"},{"unified":"1f6b5-1f3fe","native":"🚵🏾"},{"unified":"1f6b5-1f3ff","native":"🚵🏿"}],"version":1},"man-mountain-biking":{"id":"man-mountain-biking","name":"Man Mountain Biking","keywords":["mountain-biking","transportation","sports","human","race","bike"],"skins":[{"unified":"1f6b5-200d-2642-fe0f","native":"🚵♂️"},{"unified":"1f6b5-1f3fb-200d-2642-fe0f","native":"🚵🏻♂️"},{"unified":"1f6b5-1f3fc-200d-2642-fe0f","native":"🚵🏼♂️"},{"unified":"1f6b5-1f3fd-200d-2642-fe0f","native":"🚵🏽♂️"},{"unified":"1f6b5-1f3fe-200d-2642-fe0f","native":"🚵🏾♂️"},{"unified":"1f6b5-1f3ff-200d-2642-fe0f","native":"🚵🏿♂️"}],"version":4},"woman-mountain-biking":{"id":"woman-mountain-biking","name":"Woman Mountain Biking","keywords":["mountain-biking","transportation","sports","human","race","bike","female"],"skins":[{"unified":"1f6b5-200d-2640-fe0f","native":"🚵♀️"},{"unified":"1f6b5-1f3fb-200d-2640-fe0f","native":"🚵🏻♀️"},{"unified":"1f6b5-1f3fc-200d-2640-fe0f","native":"🚵🏼♀️"},{"unified":"1f6b5-1f3fd-200d-2640-fe0f","native":"🚵🏽♀️"},{"unified":"1f6b5-1f3fe-200d-2640-fe0f","native":"🚵🏾♀️"},{"unified":"1f6b5-1f3ff-200d-2640-fe0f","native":"🚵🏿♀️"}],"version":4},"person_doing_cartwheel":{"id":"person_doing_cartwheel","name":"Person Cartwheeling","keywords":["doing","cartwheel","sport","gymnastic"],"skins":[{"unified":"1f938","native":"🤸"},{"unified":"1f938-1f3fb","native":"🤸🏻"},{"unified":"1f938-1f3fc","native":"🤸🏼"},{"unified":"1f938-1f3fd","native":"🤸🏽"},{"unified":"1f938-1f3fe","native":"🤸🏾"},{"unified":"1f938-1f3ff","native":"🤸🏿"}],"version":3},"man-cartwheeling":{"id":"man-cartwheeling","name":"Man Cartwheeling","keywords":["gymnastics"],"skins":[{"unified":"1f938-200d-2642-fe0f","native":"🤸♂️"},{"unified":"1f938-1f3fb-200d-2642-fe0f","native":"🤸🏻♂️"},{"unified":"1f938-1f3fc-200d-2642-fe0f","native":"🤸🏼♂️"},{"unified":"1f938-1f3fd-200d-2642-fe0f","native":"🤸🏽♂️"},{"unified":"1f938-1f3fe-200d-2642-fe0f","native":"🤸🏾♂️"},{"unified":"1f938-1f3ff-200d-2642-fe0f","native":"🤸🏿♂️"}],"version":4},"woman-cartwheeling":{"id":"woman-cartwheeling","name":"Woman Cartwheeling","keywords":["gymnastics"],"skins":[{"unified":"1f938-200d-2640-fe0f","native":"🤸♀️"},{"unified":"1f938-1f3fb-200d-2640-fe0f","native":"🤸🏻♀️"},{"unified":"1f938-1f3fc-200d-2640-fe0f","native":"🤸🏼♀️"},{"unified":"1f938-1f3fd-200d-2640-fe0f","native":"🤸🏽♀️"},{"unified":"1f938-1f3fe-200d-2640-fe0f","native":"🤸🏾♀️"},{"unified":"1f938-1f3ff-200d-2640-fe0f","native":"🤸🏿♀️"}],"version":4},"wrestlers":{"id":"wrestlers","name":"Wrestlers","keywords":["people","wrestling","sport"],"skins":[{"unified":"1f93c","native":"🤼"}],"version":3},"man-wrestling":{"id":"man-wrestling","name":"Men Wrestling","keywords":["man","sports","wrestlers"],"skins":[{"unified":"1f93c-200d-2642-fe0f","native":"🤼♂️"}],"version":4},"woman-wrestling":{"id":"woman-wrestling","name":"Women Wrestling","keywords":["woman","sports","wrestlers"],"skins":[{"unified":"1f93c-200d-2640-fe0f","native":"🤼♀️"}],"version":4},"water_polo":{"id":"water_polo","name":"Water Polo","keywords":["person","playing","sport"],"skins":[{"unified":"1f93d","native":"🤽"},{"unified":"1f93d-1f3fb","native":"🤽🏻"},{"unified":"1f93d-1f3fc","native":"🤽🏼"},{"unified":"1f93d-1f3fd","native":"🤽🏽"},{"unified":"1f93d-1f3fe","native":"🤽🏾"},{"unified":"1f93d-1f3ff","native":"🤽🏿"}],"version":3},"man-playing-water-polo":{"id":"man-playing-water-polo","name":"Man Playing Water Polo","keywords":["playing-water-polo","sports","pool"],"skins":[{"unified":"1f93d-200d-2642-fe0f","native":"🤽♂️"},{"unified":"1f93d-1f3fb-200d-2642-fe0f","native":"🤽🏻♂️"},{"unified":"1f93d-1f3fc-200d-2642-fe0f","native":"🤽🏼♂️"},{"unified":"1f93d-1f3fd-200d-2642-fe0f","native":"🤽🏽♂️"},{"unified":"1f93d-1f3fe-200d-2642-fe0f","native":"🤽🏾♂️"},{"unified":"1f93d-1f3ff-200d-2642-fe0f","native":"🤽🏿♂️"}],"version":4},"woman-playing-water-polo":{"id":"woman-playing-water-polo","name":"Woman Playing Water Polo","keywords":["playing-water-polo","sports","pool"],"skins":[{"unified":"1f93d-200d-2640-fe0f","native":"🤽♀️"},{"unified":"1f93d-1f3fb-200d-2640-fe0f","native":"🤽🏻♀️"},{"unified":"1f93d-1f3fc-200d-2640-fe0f","native":"🤽🏼♀️"},{"unified":"1f93d-1f3fd-200d-2640-fe0f","native":"🤽🏽♀️"},{"unified":"1f93d-1f3fe-200d-2640-fe0f","native":"🤽🏾♀️"},{"unified":"1f93d-1f3ff-200d-2640-fe0f","native":"🤽🏿♀️"}],"version":4},"handball":{"id":"handball","name":"Handball","keywords":["person","playing","sport"],"skins":[{"unified":"1f93e","native":"🤾"},{"unified":"1f93e-1f3fb","native":"🤾🏻"},{"unified":"1f93e-1f3fc","native":"🤾🏼"},{"unified":"1f93e-1f3fd","native":"🤾🏽"},{"unified":"1f93e-1f3fe","native":"🤾🏾"},{"unified":"1f93e-1f3ff","native":"🤾🏿"}],"version":3},"man-playing-handball":{"id":"man-playing-handball","name":"Man Playing Handball","keywords":["playing-handball","sports"],"skins":[{"unified":"1f93e-200d-2642-fe0f","native":"🤾♂️"},{"unified":"1f93e-1f3fb-200d-2642-fe0f","native":"🤾🏻♂️"},{"unified":"1f93e-1f3fc-200d-2642-fe0f","native":"🤾🏼♂️"},{"unified":"1f93e-1f3fd-200d-2642-fe0f","native":"🤾🏽♂️"},{"unified":"1f93e-1f3fe-200d-2642-fe0f","native":"🤾🏾♂️"},{"unified":"1f93e-1f3ff-200d-2642-fe0f","native":"🤾🏿♂️"}],"version":4},"woman-playing-handball":{"id":"woman-playing-handball","name":"Woman Playing Handball","keywords":["playing-handball","sports"],"skins":[{"unified":"1f93e-200d-2640-fe0f","native":"🤾♀️"},{"unified":"1f93e-1f3fb-200d-2640-fe0f","native":"🤾🏻♀️"},{"unified":"1f93e-1f3fc-200d-2640-fe0f","native":"🤾🏼♀️"},{"unified":"1f93e-1f3fd-200d-2640-fe0f","native":"🤾🏽♀️"},{"unified":"1f93e-1f3fe-200d-2640-fe0f","native":"🤾🏾♀️"},{"unified":"1f93e-1f3ff-200d-2640-fe0f","native":"🤾🏿♀️"}],"version":4},"juggling":{"id":"juggling","name":"Juggling","keywords":["person","performance","balance"],"skins":[{"unified":"1f939","native":"🤹"},{"unified":"1f939-1f3fb","native":"🤹🏻"},{"unified":"1f939-1f3fc","native":"🤹🏼"},{"unified":"1f939-1f3fd","native":"🤹🏽"},{"unified":"1f939-1f3fe","native":"🤹🏾"},{"unified":"1f939-1f3ff","native":"🤹🏿"}],"version":3},"man-juggling":{"id":"man-juggling","name":"Man Juggling","keywords":["juggle","balance","skill","multitask"],"skins":[{"unified":"1f939-200d-2642-fe0f","native":"🤹♂️"},{"unified":"1f939-1f3fb-200d-2642-fe0f","native":"🤹🏻♂️"},{"unified":"1f939-1f3fc-200d-2642-fe0f","native":"🤹🏼♂️"},{"unified":"1f939-1f3fd-200d-2642-fe0f","native":"🤹🏽♂️"},{"unified":"1f939-1f3fe-200d-2642-fe0f","native":"🤹🏾♂️"},{"unified":"1f939-1f3ff-200d-2642-fe0f","native":"🤹🏿♂️"}],"version":4},"woman-juggling":{"id":"woman-juggling","name":"Woman Juggling","keywords":["juggle","balance","skill","multitask"],"skins":[{"unified":"1f939-200d-2640-fe0f","native":"🤹♀️"},{"unified":"1f939-1f3fb-200d-2640-fe0f","native":"🤹🏻♀️"},{"unified":"1f939-1f3fc-200d-2640-fe0f","native":"🤹🏼♀️"},{"unified":"1f939-1f3fd-200d-2640-fe0f","native":"🤹🏽♀️"},{"unified":"1f939-1f3fe-200d-2640-fe0f","native":"🤹🏾♀️"},{"unified":"1f939-1f3ff-200d-2640-fe0f","native":"🤹🏿♀️"}],"version":4},"person_in_lotus_position":{"id":"person_in_lotus_position","name":"Person in Lotus Position","keywords":["meditate"],"skins":[{"unified":"1f9d8","native":"🧘"},{"unified":"1f9d8-1f3fb","native":"🧘🏻"},{"unified":"1f9d8-1f3fc","native":"🧘🏼"},{"unified":"1f9d8-1f3fd","native":"🧘🏽"},{"unified":"1f9d8-1f3fe","native":"🧘🏾"},{"unified":"1f9d8-1f3ff","native":"🧘🏿"}],"version":5},"man_in_lotus_position":{"id":"man_in_lotus_position","name":"Man in Lotus Position","keywords":["male","meditation","yoga","serenity","zen","mindfulness"],"skins":[{"unified":"1f9d8-200d-2642-fe0f","native":"🧘♂️"},{"unified":"1f9d8-1f3fb-200d-2642-fe0f","native":"🧘🏻♂️"},{"unified":"1f9d8-1f3fc-200d-2642-fe0f","native":"🧘🏼♂️"},{"unified":"1f9d8-1f3fd-200d-2642-fe0f","native":"🧘🏽♂️"},{"unified":"1f9d8-1f3fe-200d-2642-fe0f","native":"🧘🏾♂️"},{"unified":"1f9d8-1f3ff-200d-2642-fe0f","native":"🧘🏿♂️"}],"version":5},"woman_in_lotus_position":{"id":"woman_in_lotus_position","name":"Woman in Lotus Position","keywords":["female","meditation","yoga","serenity","zen","mindfulness"],"skins":[{"unified":"1f9d8-200d-2640-fe0f","native":"🧘♀️"},{"unified":"1f9d8-1f3fb-200d-2640-fe0f","native":"🧘🏻♀️"},{"unified":"1f9d8-1f3fc-200d-2640-fe0f","native":"🧘🏼♀️"},{"unified":"1f9d8-1f3fd-200d-2640-fe0f","native":"🧘🏽♀️"},{"unified":"1f9d8-1f3fe-200d-2640-fe0f","native":"🧘🏾♀️"},{"unified":"1f9d8-1f3ff-200d-2640-fe0f","native":"🧘🏿♀️"}],"version":5},"bath":{"id":"bath","name":"Bath","keywords":["person","taking","clean","shower","bathroom"],"skins":[{"unified":"1f6c0","native":"🛀"},{"unified":"1f6c0-1f3fb","native":"🛀🏻"},{"unified":"1f6c0-1f3fc","native":"🛀🏼"},{"unified":"1f6c0-1f3fd","native":"🛀🏽"},{"unified":"1f6c0-1f3fe","native":"🛀🏾"},{"unified":"1f6c0-1f3ff","native":"🛀🏿"}],"version":1},"sleeping_accommodation":{"id":"sleeping_accommodation","name":"Person in Bed","keywords":["sleeping","accommodation","rest"],"skins":[{"unified":"1f6cc","native":"🛌"},{"unified":"1f6cc-1f3fb","native":"🛌🏻"},{"unified":"1f6cc-1f3fc","native":"🛌🏼"},{"unified":"1f6cc-1f3fd","native":"🛌🏽"},{"unified":"1f6cc-1f3fe","native":"🛌🏾"},{"unified":"1f6cc-1f3ff","native":"🛌🏿"}],"version":1},"people_holding_hands":{"id":"people_holding_hands","name":"People Holding Hands","keywords":["friendship"],"skins":[{"unified":"1f9d1-200d-1f91d-200d-1f9d1","native":"🧑🤝🧑"},{"unified":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fb","native":"🧑🏻🤝🧑🏻"},{"unified":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fc","native":"🧑🏼🤝🧑🏼"},{"unified":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fd","native":"🧑🏽🤝🧑🏽"},{"unified":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fe","native":"🧑🏾🤝🧑🏾"},{"unified":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3ff","native":"🧑🏿🤝🧑🏿"}],"version":12},"two_women_holding_hands":{"id":"two_women_holding_hands","name":"Women Holding Hands","keywords":["two","pair","friendship","couple","love","like","female","people","human"],"skins":[{"unified":"1f46d","native":"👭"},{"unified":"1f46d-1f3fb","native":"👭🏻"},{"unified":"1f46d-1f3fc","native":"👭🏼"},{"unified":"1f46d-1f3fd","native":"👭🏽"},{"unified":"1f46d-1f3fe","native":"👭🏾"},{"unified":"1f46d-1f3ff","native":"👭🏿"}],"version":1},"man_and_woman_holding_hands":{"id":"man_and_woman_holding_hands","name":"Man and Woman Holding Hands","keywords":["couple","pair","people","human","love","date","dating","like","affection","valentines","marriage"],"skins":[{"unified":"1f46b","native":"👫"},{"unified":"1f46b-1f3fb","native":"👫🏻"},{"unified":"1f46b-1f3fc","native":"👫🏼"},{"unified":"1f46b-1f3fd","native":"👫🏽"},{"unified":"1f46b-1f3fe","native":"👫🏾"},{"unified":"1f46b-1f3ff","native":"👫🏿"}],"version":1},"two_men_holding_hands":{"id":"two_men_holding_hands","name":"Men Holding Hands","keywords":["two","pair","couple","love","like","bromance","friendship","people","human"],"skins":[{"unified":"1f46c","native":"👬"},{"unified":"1f46c-1f3fb","native":"👬🏻"},{"unified":"1f46c-1f3fc","native":"👬🏼"},{"unified":"1f46c-1f3fd","native":"👬🏽"},{"unified":"1f46c-1f3fe","native":"👬🏾"},{"unified":"1f46c-1f3ff","native":"👬🏿"}],"version":1},"couplekiss":{"id":"couplekiss","name":"Kiss","keywords":["couplekiss","pair","valentines","love","like","dating","marriage"],"skins":[{"unified":"1f48f","native":"💏"},{"unified":"1f48f-1f3fb","native":"💏🏻"},{"unified":"1f48f-1f3fc","native":"💏🏼"},{"unified":"1f48f-1f3fd","native":"💏🏽"},{"unified":"1f48f-1f3fe","native":"💏🏾"},{"unified":"1f48f-1f3ff","native":"💏🏿"}],"version":1},"woman-kiss-man":{"id":"woman-kiss-man","name":"Kiss: Woman, Man","keywords":["woman","kiss-man","kiss","love"],"skins":[{"unified":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f468","native":"👩❤️💋👨"},{"unified":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","native":"👩🏻❤️💋👨🏻"},{"unified":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","native":"👩🏼❤️💋👨🏼"},{"unified":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","native":"👩🏽❤️💋👨🏽"},{"unified":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","native":"👩🏾❤️💋👨🏾"},{"unified":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","native":"👩🏿❤️💋👨🏿"}],"version":2},"man-kiss-man":{"id":"man-kiss-man","name":"Kiss: Man, Man","keywords":["kiss-man","kiss","pair","valentines","love","like","dating","marriage"],"skins":[{"unified":"1f468-200d-2764-fe0f-200d-1f48b-200d-1f468","native":"👨❤️💋👨"},{"unified":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","native":"👨🏻❤️💋👨🏻"},{"unified":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","native":"👨🏼❤️💋👨🏼"},{"unified":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","native":"👨🏽❤️💋👨🏽"},{"unified":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","native":"👨🏾❤️💋👨🏾"},{"unified":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","native":"👨🏿❤️💋👨🏿"}],"version":2},"woman-kiss-woman":{"id":"woman-kiss-woman","name":"Kiss: Woman, Woman","keywords":["kiss-woman","kiss","pair","valentines","love","like","dating","marriage"],"skins":[{"unified":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f469","native":"👩❤️💋👩"},{"unified":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb","native":"👩🏻❤️💋👩🏻"},{"unified":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc","native":"👩🏼❤️💋👩🏼"},{"unified":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd","native":"👩🏽❤️💋👩🏽"},{"unified":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe","native":"👩🏾❤️💋👩🏾"},{"unified":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff","native":"👩🏿❤️💋👩🏿"}],"version":2},"couple_with_heart":{"id":"couple_with_heart","name":"Couple with Heart","keywords":["pair","love","like","affection","human","dating","valentines","marriage"],"skins":[{"unified":"1f491","native":"💑"},{"unified":"1f491-1f3fb","native":"💑🏻"},{"unified":"1f491-1f3fc","native":"💑🏼"},{"unified":"1f491-1f3fd","native":"💑🏽"},{"unified":"1f491-1f3fe","native":"💑🏾"},{"unified":"1f491-1f3ff","native":"💑🏿"}],"version":1},"woman-heart-man":{"id":"woman-heart-man","name":"Couple with Heart: Woman, Man","keywords":["woman","heart-man","heart","love"],"skins":[{"unified":"1f469-200d-2764-fe0f-200d-1f468","native":"👩❤️👨"},{"unified":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fb","native":"👩🏻❤️👨🏻"},{"unified":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fc","native":"👩🏼❤️👨🏼"},{"unified":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fd","native":"👩🏽❤️👨🏽"},{"unified":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fe","native":"👩🏾❤️👨🏾"},{"unified":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3ff","native":"👩🏿❤️👨🏿"}],"version":2},"man-heart-man":{"id":"man-heart-man","name":"Couple with Heart: Man, Man","keywords":["heart-man","heart","pair","love","like","affection","human","dating","valentines","marriage"],"skins":[{"unified":"1f468-200d-2764-fe0f-200d-1f468","native":"👨❤️👨"},{"unified":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fb","native":"👨🏻❤️👨🏻"},{"unified":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fc","native":"👨🏼❤️👨🏼"},{"unified":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fd","native":"👨🏽❤️👨🏽"},{"unified":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fe","native":"👨🏾❤️👨🏾"},{"unified":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3ff","native":"👨🏿❤️👨🏿"}],"version":2},"woman-heart-woman":{"id":"woman-heart-woman","name":"Couple with Heart: Woman, Woman","keywords":["heart-woman","heart","pair","love","like","affection","human","dating","valentines","marriage"],"skins":[{"unified":"1f469-200d-2764-fe0f-200d-1f469","native":"👩❤️👩"},{"unified":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fb","native":"👩🏻❤️👩🏻"},{"unified":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fc","native":"👩🏼❤️👩🏼"},{"unified":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fd","native":"👩🏽❤️👩🏽"},{"unified":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fe","native":"👩🏾❤️👩🏾"},{"unified":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3ff","native":"👩🏿❤️👩🏿"}],"version":2},"family":{"id":"family","name":"Family","keywords":["home","parents","child","mom","dad","father","mother","people","human"],"skins":[{"unified":"1f46a","native":"👪"}],"version":1},"man-woman-boy":{"id":"man-woman-boy","name":"Family: Man, Woman, Boy","keywords":["man","woman-boy","family","woman","love"],"skins":[{"unified":"1f468-200d-1f469-200d-1f466","native":"👨👩👦"}],"version":2},"man-woman-girl":{"id":"man-woman-girl","name":"Family: Man, Woman, Girl","keywords":["man","woman-girl","family","woman","home","parents","people","human","child"],"skins":[{"unified":"1f468-200d-1f469-200d-1f467","native":"👨👩👧"}],"version":2},"man-woman-girl-boy":{"id":"man-woman-girl-boy","name":"Family: Man, Woman, Girl, Boy","keywords":["man","woman-girl-boy","family","woman","girl","home","parents","people","human","children"],"skins":[{"unified":"1f468-200d-1f469-200d-1f467-200d-1f466","native":"👨👩👧👦"}],"version":2},"man-woman-boy-boy":{"id":"man-woman-boy-boy","name":"Family: Man, Woman, Boy, Boy","keywords":["man","woman-boy-boy","family","woman","home","parents","people","human","children"],"skins":[{"unified":"1f468-200d-1f469-200d-1f466-200d-1f466","native":"👨👩👦👦"}],"version":2},"man-woman-girl-girl":{"id":"man-woman-girl-girl","name":"Family: Man, Woman, Girl, Girl","keywords":["man","woman-girl-girl","family","woman","home","parents","people","human","children"],"skins":[{"unified":"1f468-200d-1f469-200d-1f467-200d-1f467","native":"👨👩👧👧"}],"version":2},"man-man-boy":{"id":"man-man-boy","name":"Family: Man, Man, Boy","keywords":["man","man-boy","family","home","parents","people","human","children"],"skins":[{"unified":"1f468-200d-1f468-200d-1f466","native":"👨👨👦"}],"version":2},"man-man-girl":{"id":"man-man-girl","name":"Family: Man, Man, Girl","keywords":["man","man-girl","family","home","parents","people","human","children"],"skins":[{"unified":"1f468-200d-1f468-200d-1f467","native":"👨👨👧"}],"version":2},"man-man-girl-boy":{"id":"man-man-girl-boy","name":"Family: Man, Man, Girl, Boy","keywords":["man","man-girl-boy","family","girl","home","parents","people","human","children"],"skins":[{"unified":"1f468-200d-1f468-200d-1f467-200d-1f466","native":"👨👨👧👦"}],"version":2},"man-man-boy-boy":{"id":"man-man-boy-boy","name":"Family: Man, Man, Boy, Boy","keywords":["man","man-boy-boy","family","home","parents","people","human","children"],"skins":[{"unified":"1f468-200d-1f468-200d-1f466-200d-1f466","native":"👨👨👦👦"}],"version":2},"man-man-girl-girl":{"id":"man-man-girl-girl","name":"Family: Man, Man, Girl, Girl","keywords":["man","man-girl-girl","family","home","parents","people","human","children"],"skins":[{"unified":"1f468-200d-1f468-200d-1f467-200d-1f467","native":"👨👨👧👧"}],"version":2},"woman-woman-boy":{"id":"woman-woman-boy","name":"Family: Woman, Woman, Boy","keywords":["woman","woman-boy","family","home","parents","people","human","children"],"skins":[{"unified":"1f469-200d-1f469-200d-1f466","native":"👩👩👦"}],"version":2},"woman-woman-girl":{"id":"woman-woman-girl","name":"Family: Woman, Woman, Girl","keywords":["woman","woman-girl","family","home","parents","people","human","children"],"skins":[{"unified":"1f469-200d-1f469-200d-1f467","native":"👩👩👧"}],"version":2},"woman-woman-girl-boy":{"id":"woman-woman-girl-boy","name":"Family: Woman, Woman, Girl, Boy","keywords":["woman","woman-girl-boy","family","girl","home","parents","people","human","children"],"skins":[{"unified":"1f469-200d-1f469-200d-1f467-200d-1f466","native":"👩👩👧👦"}],"version":2},"woman-woman-boy-boy":{"id":"woman-woman-boy-boy","name":"Family: Woman, Woman, Boy, Boy","keywords":["woman","woman-boy-boy","family","home","parents","people","human","children"],"skins":[{"unified":"1f469-200d-1f469-200d-1f466-200d-1f466","native":"👩👩👦👦"}],"version":2},"woman-woman-girl-girl":{"id":"woman-woman-girl-girl","name":"Family: Woman, Woman, Girl, Girl","keywords":["woman","woman-girl-girl","family","home","parents","people","human","children"],"skins":[{"unified":"1f469-200d-1f469-200d-1f467-200d-1f467","native":"👩👩👧👧"}],"version":2},"man-boy":{"id":"man-boy","name":"Family: Man, Boy","keywords":["man","family","home","parent","people","human","child"],"skins":[{"unified":"1f468-200d-1f466","native":"👨👦"}],"version":4},"man-boy-boy":{"id":"man-boy-boy","name":"Family: Man, Boy, Boy","keywords":["man","boy-boy","family","home","parent","people","human","children"],"skins":[{"unified":"1f468-200d-1f466-200d-1f466","native":"👨👦👦"}],"version":4},"man-girl":{"id":"man-girl","name":"Family: Man, Girl","keywords":["man","family","home","parent","people","human","child"],"skins":[{"unified":"1f468-200d-1f467","native":"👨👧"}],"version":4},"man-girl-boy":{"id":"man-girl-boy","name":"Family: Man, Girl, Boy","keywords":["man","girl-boy","family","girl","home","parent","people","human","children"],"skins":[{"unified":"1f468-200d-1f467-200d-1f466","native":"👨👧👦"}],"version":4},"man-girl-girl":{"id":"man-girl-girl","name":"Family: Man, Girl, Girl","keywords":["man","girl-girl","family","home","parent","people","human","children"],"skins":[{"unified":"1f468-200d-1f467-200d-1f467","native":"👨👧👧"}],"version":4},"woman-boy":{"id":"woman-boy","name":"Family: Woman, Boy","keywords":["woman","family","home","parent","people","human","child"],"skins":[{"unified":"1f469-200d-1f466","native":"👩👦"}],"version":4},"woman-boy-boy":{"id":"woman-boy-boy","name":"Family: Woman, Boy, Boy","keywords":["woman","boy-boy","family","home","parent","people","human","children"],"skins":[{"unified":"1f469-200d-1f466-200d-1f466","native":"👩👦👦"}],"version":4},"woman-girl":{"id":"woman-girl","name":"Family: Woman, Girl","keywords":["woman","family","home","parent","people","human","child"],"skins":[{"unified":"1f469-200d-1f467","native":"👩👧"}],"version":4},"woman-girl-boy":{"id":"woman-girl-boy","name":"Family: Woman, Girl, Boy","keywords":["woman","girl-boy","family","girl","home","parent","people","human","children"],"skins":[{"unified":"1f469-200d-1f467-200d-1f466","native":"👩👧👦"}],"version":4},"woman-girl-girl":{"id":"woman-girl-girl","name":"Family: Woman, Girl, Girl","keywords":["woman","girl-girl","family","home","parent","people","human","children"],"skins":[{"unified":"1f469-200d-1f467-200d-1f467","native":"👩👧👧"}],"version":4},"speaking_head_in_silhouette":{"id":"speaking_head_in_silhouette","name":"Speaking Head","keywords":["in","silhouette","user","person","human","sing","say","talk"],"skins":[{"unified":"1f5e3-fe0f","native":"🗣️"}],"version":1},"bust_in_silhouette":{"id":"bust_in_silhouette","name":"Bust in Silhouette","keywords":["user","person","human"],"skins":[{"unified":"1f464","native":"👤"}],"version":1},"busts_in_silhouette":{"id":"busts_in_silhouette","name":"Busts in Silhouette","keywords":["user","person","human","group","team"],"skins":[{"unified":"1f465","native":"👥"}],"version":1},"people_hugging":{"id":"people_hugging","name":"People Hugging","keywords":["care"],"skins":[{"unified":"1fac2","native":"🫂"}],"version":13},"footprints":{"id":"footprints","name":"Footprints","keywords":["feet","tracking","walking","beach"],"skins":[{"unified":"1f463","native":"👣"}],"version":1},"monkey_face":{"id":"monkey_face","name":"Monkey Face","emoticons":[":o)"],"keywords":["animal","nature","circus"],"skins":[{"unified":"1f435","native":"🐵"}],"version":1},"monkey":{"id":"monkey","name":"Monkey","keywords":["animal","nature","banana","circus"],"skins":[{"unified":"1f412","native":"🐒"}],"version":1},"gorilla":{"id":"gorilla","name":"Gorilla","keywords":["animal","nature","circus"],"skins":[{"unified":"1f98d","native":"🦍"}],"version":3},"orangutan":{"id":"orangutan","name":"Orangutan","keywords":["animal"],"skins":[{"unified":"1f9a7","native":"🦧"}],"version":12},"dog":{"id":"dog","name":"Dog Face","keywords":["animal","friend","nature","woof","puppy","pet","faithful"],"skins":[{"unified":"1f436","native":"🐶"}],"version":1},"dog2":{"id":"dog2","name":"Dog","keywords":["dog2","animal","nature","friend","doge","pet","faithful"],"skins":[{"unified":"1f415","native":"🐕"}],"version":1},"guide_dog":{"id":"guide_dog","name":"Guide Dog","keywords":["animal","blind"],"skins":[{"unified":"1f9ae","native":"🦮"}],"version":12},"service_dog":{"id":"service_dog","name":"Service Dog","keywords":["blind","animal"],"skins":[{"unified":"1f415-200d-1f9ba","native":"🐕🦺"}],"version":12},"poodle":{"id":"poodle","name":"Poodle","keywords":["dog","animal","101","nature","pet"],"skins":[{"unified":"1f429","native":"🐩"}],"version":1},"wolf":{"id":"wolf","name":"Wolf","keywords":["animal","nature","wild"],"skins":[{"unified":"1f43a","native":"🐺"}],"version":1},"fox_face":{"id":"fox_face","name":"Fox","keywords":["face","animal","nature"],"skins":[{"unified":"1f98a","native":"🦊"}],"version":3},"raccoon":{"id":"raccoon","name":"Raccoon","keywords":["animal","nature"],"skins":[{"unified":"1f99d","native":"🦝"}],"version":11},"cat":{"id":"cat","name":"Cat Face","keywords":["animal","meow","nature","pet","kitten"],"skins":[{"unified":"1f431","native":"🐱"}],"version":1},"cat2":{"id":"cat2","name":"Cat","keywords":["cat2","animal","meow","pet","cats"],"skins":[{"unified":"1f408","native":"🐈"}],"version":1},"black_cat":{"id":"black_cat","name":"Black Cat","keywords":["superstition","luck"],"skins":[{"unified":"1f408-200d-2b1b","native":"🐈⬛"}],"version":13},"lion_face":{"id":"lion_face","name":"Lion","keywords":["face","animal","nature"],"skins":[{"unified":"1f981","native":"🦁"}],"version":1},"tiger":{"id":"tiger","name":"Tiger Face","keywords":["animal","cat","danger","wild","nature","roar"],"skins":[{"unified":"1f42f","native":"🐯"}],"version":1},"tiger2":{"id":"tiger2","name":"Tiger","keywords":["tiger2","animal","nature","roar"],"skins":[{"unified":"1f405","native":"🐅"}],"version":1},"leopard":{"id":"leopard","name":"Leopard","keywords":["animal","nature"],"skins":[{"unified":"1f406","native":"🐆"}],"version":1},"horse":{"id":"horse","name":"Horse Face","keywords":["animal","brown","nature"],"skins":[{"unified":"1f434","native":"🐴"}],"version":1},"moose":{"id":"moose","name":"Moose","keywords":["shrek","canada","sweden","sven","cool"],"skins":[{"unified":"1face","native":"🫎"}],"version":15},"donkey":{"id":"donkey","name":"Donkey","keywords":["eeyore","mule"],"skins":[{"unified":"1facf","native":"🫏"}],"version":15},"racehorse":{"id":"racehorse","name":"Horse","keywords":["racehorse","animal","gamble","luck"],"skins":[{"unified":"1f40e","native":"🐎"}],"version":1},"unicorn_face":{"id":"unicorn_face","name":"Unicorn","keywords":["face","animal","nature","mystical"],"skins":[{"unified":"1f984","native":"🦄"}],"version":1},"zebra_face":{"id":"zebra_face","name":"Zebra","keywords":["face","animal","nature","stripes","safari"],"skins":[{"unified":"1f993","native":"🦓"}],"version":5},"deer":{"id":"deer","name":"Deer","keywords":["animal","nature","horns","venison"],"skins":[{"unified":"1f98c","native":"🦌"}],"version":3},"bison":{"id":"bison","name":"Bison","keywords":["ox"],"skins":[{"unified":"1f9ac","native":"🦬"}],"version":13},"cow":{"id":"cow","name":"Cow Face","keywords":["beef","ox","animal","nature","moo","milk"],"skins":[{"unified":"1f42e","native":"🐮"}],"version":1},"ox":{"id":"ox","name":"Ox","keywords":["animal","cow","beef"],"skins":[{"unified":"1f402","native":"🐂"}],"version":1},"water_buffalo":{"id":"water_buffalo","name":"Water Buffalo","keywords":["animal","nature","ox","cow"],"skins":[{"unified":"1f403","native":"🐃"}],"version":1},"cow2":{"id":"cow2","name":"Cow","keywords":["cow2","beef","ox","animal","nature","moo","milk"],"skins":[{"unified":"1f404","native":"🐄"}],"version":1},"pig":{"id":"pig","name":"Pig Face","keywords":["animal","oink","nature"],"skins":[{"unified":"1f437","native":"🐷"}],"version":1},"pig2":{"id":"pig2","name":"Pig","keywords":["pig2","animal","nature"],"skins":[{"unified":"1f416","native":"🐖"}],"version":1},"boar":{"id":"boar","name":"Boar","keywords":["animal","nature"],"skins":[{"unified":"1f417","native":"🐗"}],"version":1},"pig_nose":{"id":"pig_nose","name":"Pig Nose","keywords":["animal","oink"],"skins":[{"unified":"1f43d","native":"🐽"}],"version":1},"ram":{"id":"ram","name":"Ram","keywords":["animal","sheep","nature"],"skins":[{"unified":"1f40f","native":"🐏"}],"version":1},"sheep":{"id":"sheep","name":"Ewe","keywords":["sheep","animal","nature","wool","shipit"],"skins":[{"unified":"1f411","native":"🐑"}],"version":1},"goat":{"id":"goat","name":"Goat","keywords":["animal","nature"],"skins":[{"unified":"1f410","native":"🐐"}],"version":1},"dromedary_camel":{"id":"dromedary_camel","name":"Camel","keywords":["dromedary","animal","hot","desert","hump"],"skins":[{"unified":"1f42a","native":"🐪"}],"version":1},"camel":{"id":"camel","name":"Bactrian Camel","keywords":["two","hump","animal","nature","hot","desert"],"skins":[{"unified":"1f42b","native":"🐫"}],"version":1},"llama":{"id":"llama","name":"Llama","keywords":["animal","nature","alpaca"],"skins":[{"unified":"1f999","native":"🦙"}],"version":11},"giraffe_face":{"id":"giraffe_face","name":"Giraffe","keywords":["face","animal","nature","spots","safari"],"skins":[{"unified":"1f992","native":"🦒"}],"version":5},"elephant":{"id":"elephant","name":"Elephant","keywords":["animal","nature","nose","th","circus"],"skins":[{"unified":"1f418","native":"🐘"}],"version":1},"mammoth":{"id":"mammoth","name":"Mammoth","keywords":["elephant","tusks"],"skins":[{"unified":"1f9a3","native":"🦣"}],"version":13},"rhinoceros":{"id":"rhinoceros","name":"Rhinoceros","keywords":["animal","nature","horn"],"skins":[{"unified":"1f98f","native":"🦏"}],"version":3},"hippopotamus":{"id":"hippopotamus","name":"Hippopotamus","keywords":["animal","nature"],"skins":[{"unified":"1f99b","native":"🦛"}],"version":11},"mouse":{"id":"mouse","name":"Mouse Face","keywords":["animal","nature","cheese","wedge","rodent"],"skins":[{"unified":"1f42d","native":"🐭"}],"version":1},"mouse2":{"id":"mouse2","name":"Mouse","keywords":["mouse2","animal","nature","rodent"],"skins":[{"unified":"1f401","native":"🐁"}],"version":1},"rat":{"id":"rat","name":"Rat","keywords":["animal","mouse","rodent"],"skins":[{"unified":"1f400","native":"🐀"}],"version":1},"hamster":{"id":"hamster","name":"Hamster","keywords":["animal","nature"],"skins":[{"unified":"1f439","native":"🐹"}],"version":1},"rabbit":{"id":"rabbit","name":"Rabbit Face","keywords":["animal","nature","pet","spring","magic","bunny"],"skins":[{"unified":"1f430","native":"🐰"}],"version":1},"rabbit2":{"id":"rabbit2","name":"Rabbit","keywords":["rabbit2","animal","nature","pet","magic","spring"],"skins":[{"unified":"1f407","native":"🐇"}],"version":1},"chipmunk":{"id":"chipmunk","name":"Chipmunk","keywords":["animal","nature","rodent","squirrel"],"skins":[{"unified":"1f43f-fe0f","native":"🐿️"}],"version":1},"beaver":{"id":"beaver","name":"Beaver","keywords":["animal","rodent"],"skins":[{"unified":"1f9ab","native":"🦫"}],"version":13},"hedgehog":{"id":"hedgehog","name":"Hedgehog","keywords":["animal","nature","spiny"],"skins":[{"unified":"1f994","native":"🦔"}],"version":5},"bat":{"id":"bat","name":"Bat","keywords":["animal","nature","blind","vampire"],"skins":[{"unified":"1f987","native":"🦇"}],"version":3},"bear":{"id":"bear","name":"Bear","keywords":["animal","nature","wild"],"skins":[{"unified":"1f43b","native":"🐻"}],"version":1},"polar_bear":{"id":"polar_bear","name":"Polar Bear","keywords":["animal","arctic"],"skins":[{"unified":"1f43b-200d-2744-fe0f","native":"🐻❄️"}],"version":13},"koala":{"id":"koala","name":"Koala","keywords":["animal","nature"],"skins":[{"unified":"1f428","native":"🐨"}],"version":1},"panda_face":{"id":"panda_face","name":"Panda","keywords":["face","animal","nature"],"skins":[{"unified":"1f43c","native":"🐼"}],"version":1},"sloth":{"id":"sloth","name":"Sloth","keywords":["animal"],"skins":[{"unified":"1f9a5","native":"🦥"}],"version":12},"otter":{"id":"otter","name":"Otter","keywords":["animal"],"skins":[{"unified":"1f9a6","native":"🦦"}],"version":12},"skunk":{"id":"skunk","name":"Skunk","keywords":["animal"],"skins":[{"unified":"1f9a8","native":"🦨"}],"version":12},"kangaroo":{"id":"kangaroo","name":"Kangaroo","keywords":["animal","nature","australia","joey","hop","marsupial"],"skins":[{"unified":"1f998","native":"🦘"}],"version":11},"badger":{"id":"badger","name":"Badger","keywords":["animal","nature","honey"],"skins":[{"unified":"1f9a1","native":"🦡"}],"version":11},"feet":{"id":"feet","name":"Paw Prints","keywords":["feet","animal","tracking","footprints","dog","cat","pet"],"skins":[{"unified":"1f43e","native":"🐾"}],"version":1},"turkey":{"id":"turkey","name":"Turkey","keywords":["animal","bird"],"skins":[{"unified":"1f983","native":"🦃"}],"version":1},"chicken":{"id":"chicken","name":"Chicken","keywords":["animal","cluck","nature","bird"],"skins":[{"unified":"1f414","native":"🐔"}],"version":1},"rooster":{"id":"rooster","name":"Rooster","keywords":["animal","nature","chicken"],"skins":[{"unified":"1f413","native":"🐓"}],"version":1},"hatching_chick":{"id":"hatching_chick","name":"Hatching Chick","keywords":["animal","chicken","egg","born","baby","bird"],"skins":[{"unified":"1f423","native":"🐣"}],"version":1},"baby_chick":{"id":"baby_chick","name":"Baby Chick","keywords":["animal","chicken","bird"],"skins":[{"unified":"1f424","native":"🐤"}],"version":1},"hatched_chick":{"id":"hatched_chick","name":"Front-Facing Baby Chick","keywords":["hatched","front","facing","animal","chicken","bird"],"skins":[{"unified":"1f425","native":"🐥"}],"version":1},"bird":{"id":"bird","name":"Bird","keywords":["animal","nature","fly","tweet","spring"],"skins":[{"unified":"1f426","native":"🐦"}],"version":1},"penguin":{"id":"penguin","name":"Penguin","keywords":["animal","nature"],"skins":[{"unified":"1f427","native":"🐧"}],"version":1},"dove_of_peace":{"id":"dove_of_peace","name":"Dove","keywords":["of","peace","animal","bird"],"skins":[{"unified":"1f54a-fe0f","native":"🕊️"}],"version":1},"eagle":{"id":"eagle","name":"Eagle","keywords":["animal","nature","bird"],"skins":[{"unified":"1f985","native":"🦅"}],"version":3},"duck":{"id":"duck","name":"Duck","keywords":["animal","nature","bird","mallard"],"skins":[{"unified":"1f986","native":"🦆"}],"version":3},"swan":{"id":"swan","name":"Swan","keywords":["animal","nature","bird"],"skins":[{"unified":"1f9a2","native":"🦢"}],"version":11},"owl":{"id":"owl","name":"Owl","keywords":["animal","nature","bird","hoot"],"skins":[{"unified":"1f989","native":"🦉"}],"version":3},"dodo":{"id":"dodo","name":"Dodo","keywords":["animal","bird"],"skins":[{"unified":"1f9a4","native":"🦤"}],"version":13},"feather":{"id":"feather","name":"Feather","keywords":["bird","fly"],"skins":[{"unified":"1fab6","native":"🪶"}],"version":13},"flamingo":{"id":"flamingo","name":"Flamingo","keywords":["animal"],"skins":[{"unified":"1f9a9","native":"🦩"}],"version":12},"peacock":{"id":"peacock","name":"Peacock","keywords":["animal","nature","peahen","bird"],"skins":[{"unified":"1f99a","native":"🦚"}],"version":11},"parrot":{"id":"parrot","name":"Parrot","keywords":["animal","nature","bird","pirate","talk"],"skins":[{"unified":"1f99c","native":"🦜"}],"version":11},"wing":{"id":"wing","name":"Wing","keywords":["angel","birds","flying"],"skins":[{"unified":"1fabd","native":"🪽"}],"version":15},"black_bird":{"id":"black_bird","name":"Black Bird","keywords":["crow"],"skins":[{"unified":"1f426-200d-2b1b","native":"🐦⬛"}],"version":15},"goose":{"id":"goose","name":"Goose","keywords":["silly","jemima","goosebumps"],"skins":[{"unified":"1fabf","native":"🪿"}],"version":15},"frog":{"id":"frog","name":"Frog","keywords":["animal","nature","croak","toad"],"skins":[{"unified":"1f438","native":"🐸"}],"version":1},"crocodile":{"id":"crocodile","name":"Crocodile","keywords":["animal","nature","reptile","lizard","alligator"],"skins":[{"unified":"1f40a","native":"🐊"}],"version":1},"turtle":{"id":"turtle","name":"Turtle","keywords":["animal","slow","nature","tortoise"],"skins":[{"unified":"1f422","native":"🐢"}],"version":1},"lizard":{"id":"lizard","name":"Lizard","keywords":["animal","nature","reptile"],"skins":[{"unified":"1f98e","native":"🦎"}],"version":3},"snake":{"id":"snake","name":"Snake","keywords":["animal","evil","nature","hiss","python"],"skins":[{"unified":"1f40d","native":"🐍"}],"version":1},"dragon_face":{"id":"dragon_face","name":"Dragon Face","keywords":["animal","myth","nature","chinese","green"],"skins":[{"unified":"1f432","native":"🐲"}],"version":1},"dragon":{"id":"dragon","name":"Dragon","keywords":["animal","myth","nature","chinese","green"],"skins":[{"unified":"1f409","native":"🐉"}],"version":1},"sauropod":{"id":"sauropod","name":"Sauropod","keywords":["animal","nature","dinosaur","brachiosaurus","brontosaurus","diplodocus","extinct"],"skins":[{"unified":"1f995","native":"🦕"}],"version":5},"t-rex":{"id":"t-rex","name":"T-Rex","keywords":["t","rex","animal","nature","dinosaur","tyrannosaurus","extinct"],"skins":[{"unified":"1f996","native":"🦖"}],"version":5},"whale":{"id":"whale","name":"Spouting Whale","keywords":["animal","nature","sea","ocean"],"skins":[{"unified":"1f433","native":"🐳"}],"version":1},"whale2":{"id":"whale2","name":"Whale","keywords":["whale2","animal","nature","sea","ocean"],"skins":[{"unified":"1f40b","native":"🐋"}],"version":1},"dolphin":{"id":"dolphin","name":"Dolphin","keywords":["flipper","animal","nature","fish","sea","ocean","fins","beach"],"skins":[{"unified":"1f42c","native":"🐬"}],"version":1},"seal":{"id":"seal","name":"Seal","keywords":["animal","creature","sea"],"skins":[{"unified":"1f9ad","native":"🦭"}],"version":13},"fish":{"id":"fish","name":"Fish","keywords":["animal","food","nature"],"skins":[{"unified":"1f41f","native":"🐟"}],"version":1},"tropical_fish":{"id":"tropical_fish","name":"Tropical Fish","keywords":["animal","swim","ocean","beach","nemo"],"skins":[{"unified":"1f420","native":"🐠"}],"version":1},"blowfish":{"id":"blowfish","name":"Blowfish","keywords":["animal","nature","food","sea","ocean"],"skins":[{"unified":"1f421","native":"🐡"}],"version":1},"shark":{"id":"shark","name":"Shark","keywords":["animal","nature","fish","sea","ocean","jaws","fins","beach"],"skins":[{"unified":"1f988","native":"🦈"}],"version":3},"octopus":{"id":"octopus","name":"Octopus","keywords":["animal","creature","ocean","sea","nature","beach"],"skins":[{"unified":"1f419","native":"🐙"}],"version":1},"shell":{"id":"shell","name":"Spiral Shell","keywords":["nature","sea","beach"],"skins":[{"unified":"1f41a","native":"🐚"}],"version":1},"coral":{"id":"coral","name":"Coral","keywords":["ocean","sea","reef"],"skins":[{"unified":"1fab8","native":"🪸"}],"version":14},"jellyfish":{"id":"jellyfish","name":"Jellyfish","keywords":["sting","tentacles"],"skins":[{"unified":"1fabc","native":"🪼"}],"version":15},"snail":{"id":"snail","name":"Snail","keywords":["slow","animal","shell"],"skins":[{"unified":"1f40c","native":"🐌"}],"version":1},"butterfly":{"id":"butterfly","name":"Butterfly","keywords":["animal","insect","nature","caterpillar"],"skins":[{"unified":"1f98b","native":"🦋"}],"version":3},"bug":{"id":"bug","name":"Bug","keywords":["animal","insect","nature","worm"],"skins":[{"unified":"1f41b","native":"🐛"}],"version":1},"ant":{"id":"ant","name":"Ant","keywords":["animal","insect","nature","bug"],"skins":[{"unified":"1f41c","native":"🐜"}],"version":1},"bee":{"id":"bee","name":"Honeybee","keywords":["bee","animal","insect","nature","bug","spring","honey"],"skins":[{"unified":"1f41d","native":"🐝"}],"version":1},"beetle":{"id":"beetle","name":"Beetle","keywords":["insect"],"skins":[{"unified":"1fab2","native":"🪲"}],"version":13},"ladybug":{"id":"ladybug","name":"Lady Beetle","keywords":["ladybug","animal","insect","nature"],"skins":[{"unified":"1f41e","native":"🐞"}],"version":1},"cricket":{"id":"cricket","name":"Cricket","keywords":["animal","chirp"],"skins":[{"unified":"1f997","native":"🦗"}],"version":5},"cockroach":{"id":"cockroach","name":"Cockroach","keywords":["insect","pests"],"skins":[{"unified":"1fab3","native":"🪳"}],"version":13},"spider":{"id":"spider","name":"Spider","keywords":["animal","arachnid"],"skins":[{"unified":"1f577-fe0f","native":"🕷️"}],"version":1},"spider_web":{"id":"spider_web","name":"Spider Web","keywords":["animal","insect","arachnid","silk"],"skins":[{"unified":"1f578-fe0f","native":"🕸️"}],"version":1},"scorpion":{"id":"scorpion","name":"Scorpion","keywords":["animal","arachnid"],"skins":[{"unified":"1f982","native":"🦂"}],"version":1},"mosquito":{"id":"mosquito","name":"Mosquito","keywords":["animal","nature","insect","malaria"],"skins":[{"unified":"1f99f","native":"🦟"}],"version":11},"fly":{"id":"fly","name":"Fly","keywords":["insect"],"skins":[{"unified":"1fab0","native":"🪰"}],"version":13},"worm":{"id":"worm","name":"Worm","keywords":["animal"],"skins":[{"unified":"1fab1","native":"🪱"}],"version":13},"microbe":{"id":"microbe","name":"Microbe","keywords":["amoeba","bacteria","germs","virus","covid"],"skins":[{"unified":"1f9a0","native":"🦠"}],"version":11},"bouquet":{"id":"bouquet","name":"Bouquet","keywords":["flowers","nature","spring"],"skins":[{"unified":"1f490","native":"💐"}],"version":1},"cherry_blossom":{"id":"cherry_blossom","name":"Cherry Blossom","keywords":["nature","plant","spring","flower"],"skins":[{"unified":"1f338","native":"🌸"}],"version":1},"white_flower":{"id":"white_flower","name":"White Flower","keywords":["japanese","spring"],"skins":[{"unified":"1f4ae","native":"💮"}],"version":1},"lotus":{"id":"lotus","name":"Lotus","keywords":["flower","calm","meditation"],"skins":[{"unified":"1fab7","native":"🪷"}],"version":14},"rosette":{"id":"rosette","name":"Rosette","keywords":["flower","decoration","military"],"skins":[{"unified":"1f3f5-fe0f","native":"🏵️"}],"version":1},"rose":{"id":"rose","name":"Rose","keywords":["flowers","valentines","love","spring"],"skins":[{"unified":"1f339","native":"🌹"}],"version":1},"wilted_flower":{"id":"wilted_flower","name":"Wilted Flower","keywords":["plant","nature","rose"],"skins":[{"unified":"1f940","native":"🥀"}],"version":3},"hibiscus":{"id":"hibiscus","name":"Hibiscus","keywords":["plant","vegetable","flowers","beach"],"skins":[{"unified":"1f33a","native":"🌺"}],"version":1},"sunflower":{"id":"sunflower","name":"Sunflower","keywords":["nature","plant","fall"],"skins":[{"unified":"1f33b","native":"🌻"}],"version":1},"blossom":{"id":"blossom","name":"Blossom","keywords":["nature","flowers","yellow"],"skins":[{"unified":"1f33c","native":"🌼"}],"version":1},"tulip":{"id":"tulip","name":"Tulip","keywords":["flowers","plant","nature","summer","spring"],"skins":[{"unified":"1f337","native":"🌷"}],"version":1},"hyacinth":{"id":"hyacinth","name":"Hyacinth","keywords":["flower","lavender"],"skins":[{"unified":"1fabb","native":"🪻"}],"version":15},"seedling":{"id":"seedling","name":"Seedling","keywords":["plant","nature","grass","lawn","spring"],"skins":[{"unified":"1f331","native":"🌱"}],"version":1},"potted_plant":{"id":"potted_plant","name":"Potted Plant","keywords":["greenery","house"],"skins":[{"unified":"1fab4","native":"🪴"}],"version":13},"evergreen_tree":{"id":"evergreen_tree","name":"Evergreen Tree","keywords":["plant","nature"],"skins":[{"unified":"1f332","native":"🌲"}],"version":1},"deciduous_tree":{"id":"deciduous_tree","name":"Deciduous Tree","keywords":["plant","nature"],"skins":[{"unified":"1f333","native":"🌳"}],"version":1},"palm_tree":{"id":"palm_tree","name":"Palm Tree","keywords":["plant","vegetable","nature","summer","beach","mojito","tropical"],"skins":[{"unified":"1f334","native":"🌴"}],"version":1},"cactus":{"id":"cactus","name":"Cactus","keywords":["vegetable","plant","nature"],"skins":[{"unified":"1f335","native":"🌵"}],"version":1},"ear_of_rice":{"id":"ear_of_rice","name":"Ear of Rice","keywords":["sheaf","nature","plant"],"skins":[{"unified":"1f33e","native":"🌾"}],"version":1},"herb":{"id":"herb","name":"Herb","keywords":["vegetable","plant","medicine","weed","grass","lawn"],"skins":[{"unified":"1f33f","native":"🌿"}],"version":1},"shamrock":{"id":"shamrock","name":"Shamrock","keywords":["vegetable","plant","nature","irish","clover"],"skins":[{"unified":"2618-fe0f","native":"☘️"}],"version":1},"four_leaf_clover":{"id":"four_leaf_clover","name":"Four Leaf Clover","keywords":["vegetable","plant","nature","lucky","irish"],"skins":[{"unified":"1f340","native":"🍀"}],"version":1},"maple_leaf":{"id":"maple_leaf","name":"Maple Leaf","keywords":["nature","plant","vegetable","ca","fall"],"skins":[{"unified":"1f341","native":"🍁"}],"version":1},"fallen_leaf":{"id":"fallen_leaf","name":"Fallen Leaf","keywords":["nature","plant","vegetable","leaves"],"skins":[{"unified":"1f342","native":"🍂"}],"version":1},"leaves":{"id":"leaves","name":"Leaf Fluttering in Wind","keywords":["leaves","nature","plant","tree","vegetable","grass","lawn","spring"],"skins":[{"unified":"1f343","native":"🍃"}],"version":1},"empty_nest":{"id":"empty_nest","name":"Empty Nest","keywords":["bird"],"skins":[{"unified":"1fab9","native":"🪹"}],"version":14},"nest_with_eggs":{"id":"nest_with_eggs","name":"Nest with Eggs","keywords":["bird"],"skins":[{"unified":"1faba","native":"🪺"}],"version":14},"mushroom":{"id":"mushroom","name":"Mushroom","keywords":["plant","vegetable"],"skins":[{"unified":"1f344","native":"🍄"}],"version":1},"grapes":{"id":"grapes","name":"Grapes","keywords":["fruit","food","wine"],"skins":[{"unified":"1f347","native":"🍇"}],"version":1},"melon":{"id":"melon","name":"Melon","keywords":["fruit","nature","food"],"skins":[{"unified":"1f348","native":"🍈"}],"version":1},"watermelon":{"id":"watermelon","name":"Watermelon","keywords":["fruit","food","picnic","summer"],"skins":[{"unified":"1f349","native":"🍉"}],"version":1},"tangerine":{"id":"tangerine","name":"Tangerine","keywords":["food","fruit","nature","orange"],"skins":[{"unified":"1f34a","native":"🍊"}],"version":1},"lemon":{"id":"lemon","name":"Lemon","keywords":["fruit","nature"],"skins":[{"unified":"1f34b","native":"🍋"}],"version":1},"banana":{"id":"banana","name":"Banana","keywords":["fruit","food","monkey"],"skins":[{"unified":"1f34c","native":"🍌"}],"version":1},"pineapple":{"id":"pineapple","name":"Pineapple","keywords":["fruit","nature","food"],"skins":[{"unified":"1f34d","native":"🍍"}],"version":1},"mango":{"id":"mango","name":"Mango","keywords":["fruit","food","tropical"],"skins":[{"unified":"1f96d","native":"🥭"}],"version":11},"apple":{"id":"apple","name":"Red Apple","keywords":["fruit","mac","school"],"skins":[{"unified":"1f34e","native":"🍎"}],"version":1},"green_apple":{"id":"green_apple","name":"Green Apple","keywords":["fruit","nature"],"skins":[{"unified":"1f34f","native":"🍏"}],"version":1},"pear":{"id":"pear","name":"Pear","keywords":["fruit","nature","food"],"skins":[{"unified":"1f350","native":"🍐"}],"version":1},"peach":{"id":"peach","name":"Peach","keywords":["fruit","nature","food"],"skins":[{"unified":"1f351","native":"🍑"}],"version":1},"cherries":{"id":"cherries","name":"Cherries","keywords":["food","fruit"],"skins":[{"unified":"1f352","native":"🍒"}],"version":1},"strawberry":{"id":"strawberry","name":"Strawberry","keywords":["fruit","food","nature"],"skins":[{"unified":"1f353","native":"🍓"}],"version":1},"blueberries":{"id":"blueberries","name":"Blueberries","keywords":["fruit"],"skins":[{"unified":"1fad0","native":"🫐"}],"version":13},"kiwifruit":{"id":"kiwifruit","name":"Kiwifruit","keywords":["kiwi","fruit","food"],"skins":[{"unified":"1f95d","native":"🥝"}],"version":3},"tomato":{"id":"tomato","name":"Tomato","keywords":["fruit","vegetable","nature","food"],"skins":[{"unified":"1f345","native":"🍅"}],"version":1},"olive":{"id":"olive","name":"Olive","keywords":["fruit"],"skins":[{"unified":"1fad2","native":"🫒"}],"version":13},"coconut":{"id":"coconut","name":"Coconut","keywords":["fruit","nature","food","palm"],"skins":[{"unified":"1f965","native":"🥥"}],"version":5},"avocado":{"id":"avocado","name":"Avocado","keywords":["fruit","food"],"skins":[{"unified":"1f951","native":"🥑"}],"version":3},"eggplant":{"id":"eggplant","name":"Eggplant","keywords":["vegetable","nature","food","aubergine"],"skins":[{"unified":"1f346","native":"🍆"}],"version":1},"potato":{"id":"potato","name":"Potato","keywords":["food","tuber","vegatable","starch"],"skins":[{"unified":"1f954","native":"🥔"}],"version":3},"carrot":{"id":"carrot","name":"Carrot","keywords":["vegetable","food","orange"],"skins":[{"unified":"1f955","native":"🥕"}],"version":3},"corn":{"id":"corn","name":"Ear of Corn","keywords":["food","vegetable","plant"],"skins":[{"unified":"1f33d","native":"🌽"}],"version":1},"hot_pepper":{"id":"hot_pepper","name":"Hot Pepper","keywords":["food","spicy","chilli","chili"],"skins":[{"unified":"1f336-fe0f","native":"🌶️"}],"version":1},"bell_pepper":{"id":"bell_pepper","name":"Bell Pepper","keywords":["fruit","plant"],"skins":[{"unified":"1fad1","native":"🫑"}],"version":13},"cucumber":{"id":"cucumber","name":"Cucumber","keywords":["fruit","food","pickle"],"skins":[{"unified":"1f952","native":"🥒"}],"version":3},"leafy_green":{"id":"leafy_green","name":"Leafy Green","keywords":["food","vegetable","plant","bok","choy","cabbage","kale","lettuce"],"skins":[{"unified":"1f96c","native":"🥬"}],"version":11},"broccoli":{"id":"broccoli","name":"Broccoli","keywords":["fruit","food","vegetable"],"skins":[{"unified":"1f966","native":"🥦"}],"version":5},"garlic":{"id":"garlic","name":"Garlic","keywords":["food","spice","cook"],"skins":[{"unified":"1f9c4","native":"🧄"}],"version":12},"onion":{"id":"onion","name":"Onion","keywords":["cook","food","spice"],"skins":[{"unified":"1f9c5","native":"🧅"}],"version":12},"peanuts":{"id":"peanuts","name":"Peanuts","keywords":["food","nut"],"skins":[{"unified":"1f95c","native":"🥜"}],"version":3},"beans":{"id":"beans","name":"Beans","keywords":["food"],"skins":[{"unified":"1fad8","native":"🫘"}],"version":14},"chestnut":{"id":"chestnut","name":"Chestnut","keywords":["food","squirrel"],"skins":[{"unified":"1f330","native":"🌰"}],"version":1},"ginger_root":{"id":"ginger_root","name":"Ginger Root","keywords":["spice","yellow","cooking","gingerbread"],"skins":[{"unified":"1fada","native":"🫚"}],"version":15},"pea_pod":{"id":"pea_pod","name":"Pea Pod","keywords":["cozy","green"],"skins":[{"unified":"1fadb","native":"🫛"}],"version":15},"bread":{"id":"bread","name":"Bread","keywords":["food","wheat","breakfast","toast"],"skins":[{"unified":"1f35e","native":"🍞"}],"version":1},"croissant":{"id":"croissant","name":"Croissant","keywords":["food","bread","french"],"skins":[{"unified":"1f950","native":"🥐"}],"version":3},"baguette_bread":{"id":"baguette_bread","name":"Baguette Bread","keywords":["food","french","france","bakery"],"skins":[{"unified":"1f956","native":"🥖"}],"version":3},"flatbread":{"id":"flatbread","name":"Flatbread","keywords":["flour","food","bakery"],"skins":[{"unified":"1fad3","native":"🫓"}],"version":13},"pretzel":{"id":"pretzel","name":"Pretzel","keywords":["food","bread","twisted","germany","bakery"],"skins":[{"unified":"1f968","native":"🥨"}],"version":5},"bagel":{"id":"bagel","name":"Bagel","keywords":["food","bread","bakery","schmear","jewish"],"skins":[{"unified":"1f96f","native":"🥯"}],"version":11},"pancakes":{"id":"pancakes","name":"Pancakes","keywords":["food","breakfast","flapjacks","hotcakes","brunch"],"skins":[{"unified":"1f95e","native":"🥞"}],"version":3},"waffle":{"id":"waffle","name":"Waffle","keywords":["food","breakfast","brunch"],"skins":[{"unified":"1f9c7","native":"🧇"}],"version":12},"cheese_wedge":{"id":"cheese_wedge","name":"Cheese Wedge","keywords":["food","chadder","swiss"],"skins":[{"unified":"1f9c0","native":"🧀"}],"version":1},"meat_on_bone":{"id":"meat_on_bone","name":"Meat on Bone","keywords":["good","food","drumstick"],"skins":[{"unified":"1f356","native":"🍖"}],"version":1},"poultry_leg":{"id":"poultry_leg","name":"Poultry Leg","keywords":["food","meat","drumstick","bird","chicken","turkey"],"skins":[{"unified":"1f357","native":"🍗"}],"version":1},"cut_of_meat":{"id":"cut_of_meat","name":"Cut of Meat","keywords":["food","cow","chop","lambchop","porkchop"],"skins":[{"unified":"1f969","native":"🥩"}],"version":5},"bacon":{"id":"bacon","name":"Bacon","keywords":["food","breakfast","pork","pig","meat","brunch"],"skins":[{"unified":"1f953","native":"🥓"}],"version":3},"hamburger":{"id":"hamburger","name":"Hamburger","keywords":["meat","fast","food","beef","cheeseburger","mcdonalds","burger","king"],"skins":[{"unified":"1f354","native":"🍔"}],"version":1},"fries":{"id":"fries","name":"French Fries","keywords":["chips","snack","fast","food","potato"],"skins":[{"unified":"1f35f","native":"🍟"}],"version":1},"pizza":{"id":"pizza","name":"Pizza","keywords":["food","party","italy"],"skins":[{"unified":"1f355","native":"🍕"}],"version":1},"hotdog":{"id":"hotdog","name":"Hot Dog","keywords":["hotdog","food","frankfurter","america"],"skins":[{"unified":"1f32d","native":"🌭"}],"version":1},"sandwich":{"id":"sandwich","name":"Sandwich","keywords":["food","lunch","bread","toast","bakery"],"skins":[{"unified":"1f96a","native":"🥪"}],"version":5},"taco":{"id":"taco","name":"Taco","keywords":["food","mexican"],"skins":[{"unified":"1f32e","native":"🌮"}],"version":1},"burrito":{"id":"burrito","name":"Burrito","keywords":["food","mexican"],"skins":[{"unified":"1f32f","native":"🌯"}],"version":1},"tamale":{"id":"tamale","name":"Tamale","keywords":["food","masa"],"skins":[{"unified":"1fad4","native":"🫔"}],"version":13},"stuffed_flatbread":{"id":"stuffed_flatbread","name":"Stuffed Flatbread","keywords":["food","gyro","mediterranean"],"skins":[{"unified":"1f959","native":"🥙"}],"version":3},"falafel":{"id":"falafel","name":"Falafel","keywords":["food","mediterranean"],"skins":[{"unified":"1f9c6","native":"🧆"}],"version":12},"egg":{"id":"egg","name":"Egg","keywords":["food","chicken","breakfast"],"skins":[{"unified":"1f95a","native":"🥚"}],"version":3},"fried_egg":{"id":"fried_egg","name":"Cooking","keywords":["fried","egg","food","breakfast","kitchen","skillet"],"skins":[{"unified":"1f373","native":"🍳"}],"version":1},"shallow_pan_of_food":{"id":"shallow_pan_of_food","name":"Shallow Pan of Food","keywords":["cooking","casserole","paella","skillet"],"skins":[{"unified":"1f958","native":"🥘"}],"version":3},"stew":{"id":"stew","name":"Pot of Food","keywords":["stew","meat","soup","hot"],"skins":[{"unified":"1f372","native":"🍲"}],"version":1},"fondue":{"id":"fondue","name":"Fondue","keywords":["cheese","pot","food"],"skins":[{"unified":"1fad5","native":"🫕"}],"version":13},"bowl_with_spoon":{"id":"bowl_with_spoon","name":"Bowl with Spoon","keywords":["food","breakfast","cereal","oatmeal","porridge"],"skins":[{"unified":"1f963","native":"🥣"}],"version":5},"green_salad":{"id":"green_salad","name":"Green Salad","keywords":["food","healthy","lettuce","vegetable"],"skins":[{"unified":"1f957","native":"🥗"}],"version":3},"popcorn":{"id":"popcorn","name":"Popcorn","keywords":["food","movie","theater","films","snack","drama"],"skins":[{"unified":"1f37f","native":"🍿"}],"version":1},"butter":{"id":"butter","name":"Butter","keywords":["food","cook"],"skins":[{"unified":"1f9c8","native":"🧈"}],"version":12},"salt":{"id":"salt","name":"Salt","keywords":["condiment","shaker"],"skins":[{"unified":"1f9c2","native":"🧂"}],"version":11},"canned_food":{"id":"canned_food","name":"Canned Food","keywords":["soup","tomatoes"],"skins":[{"unified":"1f96b","native":"🥫"}],"version":5},"bento":{"id":"bento","name":"Bento Box","keywords":["food","japanese","lunch"],"skins":[{"unified":"1f371","native":"🍱"}],"version":1},"rice_cracker":{"id":"rice_cracker","name":"Rice Cracker","keywords":["food","japanese","snack"],"skins":[{"unified":"1f358","native":"🍘"}],"version":1},"rice_ball":{"id":"rice_ball","name":"Rice Ball","keywords":["food","japanese"],"skins":[{"unified":"1f359","native":"🍙"}],"version":1},"rice":{"id":"rice","name":"Cooked Rice","keywords":["food","asian"],"skins":[{"unified":"1f35a","native":"🍚"}],"version":1},"curry":{"id":"curry","name":"Curry Rice","keywords":["food","spicy","hot","indian"],"skins":[{"unified":"1f35b","native":"🍛"}],"version":1},"ramen":{"id":"ramen","name":"Steaming Bowl","keywords":["ramen","food","japanese","noodle","chopsticks"],"skins":[{"unified":"1f35c","native":"🍜"}],"version":1},"spaghetti":{"id":"spaghetti","name":"Spaghetti","keywords":["food","italian","pasta","noodle"],"skins":[{"unified":"1f35d","native":"🍝"}],"version":1},"sweet_potato":{"id":"sweet_potato","name":"Roasted Sweet Potato","keywords":["food","nature","plant"],"skins":[{"unified":"1f360","native":"🍠"}],"version":1},"oden":{"id":"oden","name":"Oden","keywords":["food","japanese"],"skins":[{"unified":"1f362","native":"🍢"}],"version":1},"sushi":{"id":"sushi","name":"Sushi","keywords":["food","fish","japanese","rice"],"skins":[{"unified":"1f363","native":"🍣"}],"version":1},"fried_shrimp":{"id":"fried_shrimp","name":"Fried Shrimp","keywords":["food","animal","appetizer","summer"],"skins":[{"unified":"1f364","native":"🍤"}],"version":1},"fish_cake":{"id":"fish_cake","name":"Fish Cake with Swirl","keywords":["food","japan","sea","beach","narutomaki","pink","kamaboko","surimi","ramen"],"skins":[{"unified":"1f365","native":"🍥"}],"version":1},"moon_cake":{"id":"moon_cake","name":"Moon Cake","keywords":["food","autumn","dessert"],"skins":[{"unified":"1f96e","native":"🥮"}],"version":11},"dango":{"id":"dango","name":"Dango","keywords":["food","dessert","sweet","japanese","barbecue","meat"],"skins":[{"unified":"1f361","native":"🍡"}],"version":1},"dumpling":{"id":"dumpling","name":"Dumpling","keywords":["food","empanada","pierogi","potsticker","gyoza"],"skins":[{"unified":"1f95f","native":"🥟"}],"version":5},"fortune_cookie":{"id":"fortune_cookie","name":"Fortune Cookie","keywords":["food","prophecy","dessert"],"skins":[{"unified":"1f960","native":"🥠"}],"version":5},"takeout_box":{"id":"takeout_box","name":"Takeout Box","keywords":["food","leftovers"],"skins":[{"unified":"1f961","native":"🥡"}],"version":5},"crab":{"id":"crab","name":"Crab","keywords":["animal","crustacean"],"skins":[{"unified":"1f980","native":"🦀"}],"version":1},"lobster":{"id":"lobster","name":"Lobster","keywords":["animal","nature","bisque","claws","seafood"],"skins":[{"unified":"1f99e","native":"🦞"}],"version":11},"shrimp":{"id":"shrimp","name":"Shrimp","keywords":["animal","ocean","nature","seafood"],"skins":[{"unified":"1f990","native":"🦐"}],"version":3},"squid":{"id":"squid","name":"Squid","keywords":["animal","nature","ocean","sea"],"skins":[{"unified":"1f991","native":"🦑"}],"version":3},"oyster":{"id":"oyster","name":"Oyster","keywords":["food"],"skins":[{"unified":"1f9aa","native":"🦪"}],"version":12},"icecream":{"id":"icecream","name":"Soft Ice Cream","keywords":["icecream","food","hot","dessert","summer"],"skins":[{"unified":"1f366","native":"🍦"}],"version":1},"shaved_ice":{"id":"shaved_ice","name":"Shaved Ice","keywords":["hot","dessert","summer"],"skins":[{"unified":"1f367","native":"🍧"}],"version":1},"ice_cream":{"id":"ice_cream","name":"Ice Cream","keywords":["food","hot","dessert"],"skins":[{"unified":"1f368","native":"🍨"}],"version":1},"doughnut":{"id":"doughnut","name":"Doughnut","keywords":["food","dessert","snack","sweet","donut"],"skins":[{"unified":"1f369","native":"🍩"}],"version":1},"cookie":{"id":"cookie","name":"Cookie","keywords":["food","snack","oreo","chocolate","sweet","dessert"],"skins":[{"unified":"1f36a","native":"🍪"}],"version":1},"birthday":{"id":"birthday","name":"Birthday Cake","keywords":["food","dessert"],"skins":[{"unified":"1f382","native":"🎂"}],"version":1},"cake":{"id":"cake","name":"Shortcake","keywords":["cake","food","dessert"],"skins":[{"unified":"1f370","native":"🍰"}],"version":1},"cupcake":{"id":"cupcake","name":"Cupcake","keywords":["food","dessert","bakery","sweet"],"skins":[{"unified":"1f9c1","native":"🧁"}],"version":11},"pie":{"id":"pie","name":"Pie","keywords":["food","dessert","pastry"],"skins":[{"unified":"1f967","native":"🥧"}],"version":5},"chocolate_bar":{"id":"chocolate_bar","name":"Chocolate Bar","keywords":["food","snack","dessert","sweet"],"skins":[{"unified":"1f36b","native":"🍫"}],"version":1},"candy":{"id":"candy","name":"Candy","keywords":["snack","dessert","sweet","lolly"],"skins":[{"unified":"1f36c","native":"🍬"}],"version":1},"lollipop":{"id":"lollipop","name":"Lollipop","keywords":["food","snack","candy","sweet"],"skins":[{"unified":"1f36d","native":"🍭"}],"version":1},"custard":{"id":"custard","name":"Custard","keywords":["dessert","food"],"skins":[{"unified":"1f36e","native":"🍮"}],"version":1},"honey_pot":{"id":"honey_pot","name":"Honey Pot","keywords":["bees","sweet","kitchen"],"skins":[{"unified":"1f36f","native":"🍯"}],"version":1},"baby_bottle":{"id":"baby_bottle","name":"Baby Bottle","keywords":["food","container","milk"],"skins":[{"unified":"1f37c","native":"🍼"}],"version":1},"glass_of_milk":{"id":"glass_of_milk","name":"Glass of Milk","keywords":["beverage","drink","cow"],"skins":[{"unified":"1f95b","native":"🥛"}],"version":3},"coffee":{"id":"coffee","name":"Hot Beverage","keywords":["coffee","caffeine","latte","espresso","mug"],"skins":[{"unified":"2615","native":"☕"}],"version":1},"teapot":{"id":"teapot","name":"Teapot","keywords":["drink","hot"],"skins":[{"unified":"1fad6","native":"🫖"}],"version":13},"tea":{"id":"tea","name":"Teacup Without Handle","keywords":["tea","drink","bowl","breakfast","green","british"],"skins":[{"unified":"1f375","native":"🍵"}],"version":1},"sake":{"id":"sake","name":"Sake","keywords":["wine","drink","drunk","beverage","japanese","alcohol","booze"],"skins":[{"unified":"1f376","native":"🍶"}],"version":1},"champagne":{"id":"champagne","name":"Bottle with Popping Cork","keywords":["champagne","drink","wine","celebration"],"skins":[{"unified":"1f37e","native":"🍾"}],"version":1},"wine_glass":{"id":"wine_glass","name":"Wine Glass","keywords":["drink","beverage","drunk","alcohol","booze"],"skins":[{"unified":"1f377","native":"🍷"}],"version":1},"cocktail":{"id":"cocktail","name":"Cocktail Glass","keywords":["drink","drunk","alcohol","beverage","booze","mojito"],"skins":[{"unified":"1f378","native":"🍸"}],"version":1},"tropical_drink":{"id":"tropical_drink","name":"Tropical Drink","keywords":["beverage","cocktail","summer","beach","alcohol","booze","mojito"],"skins":[{"unified":"1f379","native":"🍹"}],"version":1},"beer":{"id":"beer","name":"Beer Mug","keywords":["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],"skins":[{"unified":"1f37a","native":"🍺"}],"version":1},"beers":{"id":"beers","name":"Clinking Beer Mugs","keywords":["beers","relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],"skins":[{"unified":"1f37b","native":"🍻"}],"version":1},"clinking_glasses":{"id":"clinking_glasses","name":"Clinking Glasses","keywords":["beverage","drink","party","alcohol","celebrate","cheers","wine","champagne","toast"],"skins":[{"unified":"1f942","native":"🥂"}],"version":3},"tumbler_glass":{"id":"tumbler_glass","name":"Tumbler Glass","keywords":["drink","beverage","drunk","alcohol","liquor","booze","bourbon","scotch","whisky","shot"],"skins":[{"unified":"1f943","native":"🥃"}],"version":3},"pouring_liquid":{"id":"pouring_liquid","name":"Pouring Liquid","keywords":["cup","water"],"skins":[{"unified":"1fad7","native":"🫗"}],"version":14},"cup_with_straw":{"id":"cup_with_straw","name":"Cup with Straw","keywords":["drink","soda"],"skins":[{"unified":"1f964","native":"🥤"}],"version":5},"bubble_tea":{"id":"bubble_tea","name":"Bubble Tea","keywords":["taiwan","boba","milk","straw"],"skins":[{"unified":"1f9cb","native":"🧋"}],"version":13},"beverage_box":{"id":"beverage_box","name":"Beverage Box","keywords":["drink"],"skins":[{"unified":"1f9c3","native":"🧃"}],"version":12},"mate_drink":{"id":"mate_drink","name":"Mate","keywords":["drink","tea","beverage"],"skins":[{"unified":"1f9c9","native":"🧉"}],"version":12},"ice_cube":{"id":"ice_cube","name":"Ice","keywords":["cube","water","cold"],"skins":[{"unified":"1f9ca","native":"🧊"}],"version":12},"chopsticks":{"id":"chopsticks","name":"Chopsticks","keywords":["food"],"skins":[{"unified":"1f962","native":"🥢"}],"version":5},"knife_fork_plate":{"id":"knife_fork_plate","name":"Fork and Knife with Plate","keywords":["food","eat","meal","lunch","dinner","restaurant"],"skins":[{"unified":"1f37d-fe0f","native":"🍽️"}],"version":1},"fork_and_knife":{"id":"fork_and_knife","name":"Fork and Knife","keywords":["cutlery","kitchen"],"skins":[{"unified":"1f374","native":"🍴"}],"version":1},"spoon":{"id":"spoon","name":"Spoon","keywords":["cutlery","kitchen","tableware"],"skins":[{"unified":"1f944","native":"🥄"}],"version":3},"hocho":{"id":"hocho","name":"Hocho","keywords":["knife","kitchen","blade","cutlery","weapon"],"skins":[{"unified":"1f52a","native":"🔪"}],"version":1},"jar":{"id":"jar","name":"Jar","keywords":["container","sauce"],"skins":[{"unified":"1fad9","native":"🫙"}],"version":14},"amphora":{"id":"amphora","name":"Amphora","keywords":["vase","jar"],"skins":[{"unified":"1f3fa","native":"🏺"}],"version":1},"earth_africa":{"id":"earth_africa","name":"Earth Globe Europe-Africa","keywords":["africa","showing","europe","world","international"],"skins":[{"unified":"1f30d","native":"🌍"}],"version":1},"earth_americas":{"id":"earth_americas","name":"Earth Globe Americas","keywords":["showing","world","USA","international"],"skins":[{"unified":"1f30e","native":"🌎"}],"version":1},"earth_asia":{"id":"earth_asia","name":"Earth Globe Asia-Australia","keywords":["asia","showing","australia","world","east","international"],"skins":[{"unified":"1f30f","native":"🌏"}],"version":1},"globe_with_meridians":{"id":"globe_with_meridians","name":"Globe with Meridians","keywords":["earth","international","world","internet","interweb","i18n"],"skins":[{"unified":"1f310","native":"🌐"}],"version":1},"world_map":{"id":"world_map","name":"World Map","keywords":["location","direction"],"skins":[{"unified":"1f5fa-fe0f","native":"🗺️"}],"version":1},"japan":{"id":"japan","name":"Map of Japan","keywords":["nation","country","japanese","asia"],"skins":[{"unified":"1f5fe","native":"🗾"}],"version":1},"compass":{"id":"compass","name":"Compass","keywords":["magnetic","navigation","orienteering"],"skins":[{"unified":"1f9ed","native":"🧭"}],"version":11},"snow_capped_mountain":{"id":"snow_capped_mountain","name":"Snow-Capped Mountain","keywords":["snow","capped","photo","nature","environment","winter","cold"],"skins":[{"unified":"1f3d4-fe0f","native":"🏔️"}],"version":1},"mountain":{"id":"mountain","name":"Mountain","keywords":["photo","nature","environment"],"skins":[{"unified":"26f0-fe0f","native":"⛰️"}],"version":1},"volcano":{"id":"volcano","name":"Volcano","keywords":["photo","nature","disaster"],"skins":[{"unified":"1f30b","native":"🌋"}],"version":1},"mount_fuji":{"id":"mount_fuji","name":"Mount Fuji","keywords":["photo","mountain","nature","japanese"],"skins":[{"unified":"1f5fb","native":"🗻"}],"version":1},"camping":{"id":"camping","name":"Camping","keywords":["photo","outdoors","tent"],"skins":[{"unified":"1f3d5-fe0f","native":"🏕️"}],"version":1},"beach_with_umbrella":{"id":"beach_with_umbrella","name":"Beach with Umbrella","keywords":["weather","summer","sunny","sand","mojito"],"skins":[{"unified":"1f3d6-fe0f","native":"🏖️"}],"version":1},"desert":{"id":"desert","name":"Desert","keywords":["photo","warm","saharah"],"skins":[{"unified":"1f3dc-fe0f","native":"🏜️"}],"version":1},"desert_island":{"id":"desert_island","name":"Desert Island","keywords":["photo","tropical","mojito"],"skins":[{"unified":"1f3dd-fe0f","native":"🏝️"}],"version":1},"national_park":{"id":"national_park","name":"National Park","keywords":["photo","environment","nature"],"skins":[{"unified":"1f3de-fe0f","native":"🏞️"}],"version":1},"stadium":{"id":"stadium","name":"Stadium","keywords":["photo","place","sports","concert","venue"],"skins":[{"unified":"1f3df-fe0f","native":"🏟️"}],"version":1},"classical_building":{"id":"classical_building","name":"Classical Building","keywords":["art","culture","history"],"skins":[{"unified":"1f3db-fe0f","native":"🏛️"}],"version":1},"building_construction":{"id":"building_construction","name":"Building Construction","keywords":["wip","working","progress"],"skins":[{"unified":"1f3d7-fe0f","native":"🏗️"}],"version":1},"bricks":{"id":"bricks","name":"Brick","keywords":["bricks"],"skins":[{"unified":"1f9f1","native":"🧱"}],"version":11},"rock":{"id":"rock","name":"Rock","keywords":["stone"],"skins":[{"unified":"1faa8","native":"🪨"}],"version":13},"wood":{"id":"wood","name":"Wood","keywords":["nature","timber","trunk"],"skins":[{"unified":"1fab5","native":"🪵"}],"version":13},"hut":{"id":"hut","name":"Hut","keywords":["house","structure"],"skins":[{"unified":"1f6d6","native":"🛖"}],"version":13},"house_buildings":{"id":"house_buildings","name":"Houses","keywords":["house","buildings","photo"],"skins":[{"unified":"1f3d8-fe0f","native":"🏘️"}],"version":1},"derelict_house_building":{"id":"derelict_house_building","name":"Derelict House","keywords":["building","abandon","evict","broken"],"skins":[{"unified":"1f3da-fe0f","native":"🏚️"}],"version":1},"house":{"id":"house","name":"House","keywords":["building","home"],"skins":[{"unified":"1f3e0","native":"🏠"}],"version":1},"house_with_garden":{"id":"house_with_garden","name":"House with Garden","keywords":["home","plant","nature"],"skins":[{"unified":"1f3e1","native":"🏡"}],"version":1},"office":{"id":"office","name":"Office Building","keywords":["bureau","work"],"skins":[{"unified":"1f3e2","native":"🏢"}],"version":1},"post_office":{"id":"post_office","name":"Japanese Post Office","keywords":["building","envelope","communication"],"skins":[{"unified":"1f3e3","native":"🏣"}],"version":1},"european_post_office":{"id":"european_post_office","name":"Post Office","keywords":["european","building","email"],"skins":[{"unified":"1f3e4","native":"🏤"}],"version":1},"hospital":{"id":"hospital","name":"Hospital","keywords":["building","health","surgery","doctor"],"skins":[{"unified":"1f3e5","native":"🏥"}],"version":1},"bank":{"id":"bank","name":"Bank","keywords":["building","money","sales","cash","business","enterprise"],"skins":[{"unified":"1f3e6","native":"🏦"}],"version":1},"hotel":{"id":"hotel","name":"Hotel","keywords":["building","accomodation","checkin"],"skins":[{"unified":"1f3e8","native":"🏨"}],"version":1},"love_hotel":{"id":"love_hotel","name":"Love Hotel","keywords":["like","affection","dating"],"skins":[{"unified":"1f3e9","native":"🏩"}],"version":1},"convenience_store":{"id":"convenience_store","name":"Convenience Store","keywords":["building","shopping","groceries"],"skins":[{"unified":"1f3ea","native":"🏪"}],"version":1},"school":{"id":"school","name":"School","keywords":["building","student","education","learn","teach"],"skins":[{"unified":"1f3eb","native":"🏫"}],"version":1},"department_store":{"id":"department_store","name":"Department Store","keywords":["building","shopping","mall"],"skins":[{"unified":"1f3ec","native":"🏬"}],"version":1},"factory":{"id":"factory","name":"Factory","keywords":["building","industry","pollution","smoke"],"skins":[{"unified":"1f3ed","native":"🏭"}],"version":1},"japanese_castle":{"id":"japanese_castle","name":"Japanese Castle","keywords":["photo","building"],"skins":[{"unified":"1f3ef","native":"🏯"}],"version":1},"european_castle":{"id":"european_castle","name":"Castle","keywords":["european","building","royalty","history"],"skins":[{"unified":"1f3f0","native":"🏰"}],"version":1},"wedding":{"id":"wedding","name":"Wedding","keywords":["love","like","affection","couple","marriage","bride","groom"],"skins":[{"unified":"1f492","native":"💒"}],"version":1},"tokyo_tower":{"id":"tokyo_tower","name":"Tokyo Tower","keywords":["photo","japanese"],"skins":[{"unified":"1f5fc","native":"🗼"}],"version":1},"statue_of_liberty":{"id":"statue_of_liberty","name":"Statue of Liberty","keywords":["american","newyork"],"skins":[{"unified":"1f5fd","native":"🗽"}],"version":1},"church":{"id":"church","name":"Church","keywords":["building","religion","christ"],"skins":[{"unified":"26ea","native":"⛪"}],"version":1},"mosque":{"id":"mosque","name":"Mosque","keywords":["islam","worship","minaret"],"skins":[{"unified":"1f54c","native":"🕌"}],"version":1},"hindu_temple":{"id":"hindu_temple","name":"Hindu Temple","keywords":["religion"],"skins":[{"unified":"1f6d5","native":"🛕"}],"version":12},"synagogue":{"id":"synagogue","name":"Synagogue","keywords":["judaism","worship","temple","jewish"],"skins":[{"unified":"1f54d","native":"🕍"}],"version":1},"shinto_shrine":{"id":"shinto_shrine","name":"Shinto Shrine","keywords":["temple","japan","kyoto"],"skins":[{"unified":"26e9-fe0f","native":"⛩️"}],"version":1},"kaaba":{"id":"kaaba","name":"Kaaba","keywords":["mecca","mosque","islam"],"skins":[{"unified":"1f54b","native":"🕋"}],"version":1},"fountain":{"id":"fountain","name":"Fountain","keywords":["photo","summer","water","fresh"],"skins":[{"unified":"26f2","native":"⛲"}],"version":1},"tent":{"id":"tent","name":"Tent","keywords":["photo","camping","outdoors"],"skins":[{"unified":"26fa","native":"⛺"}],"version":1},"foggy":{"id":"foggy","name":"Foggy","keywords":["photo","mountain"],"skins":[{"unified":"1f301","native":"🌁"}],"version":1},"night_with_stars":{"id":"night_with_stars","name":"Night with Stars","keywords":["evening","city","downtown"],"skins":[{"unified":"1f303","native":"🌃"}],"version":1},"cityscape":{"id":"cityscape","name":"Cityscape","keywords":["photo","night","life","urban"],"skins":[{"unified":"1f3d9-fe0f","native":"🏙️"}],"version":1},"sunrise_over_mountains":{"id":"sunrise_over_mountains","name":"Sunrise over Mountains","keywords":["view","vacation","photo"],"skins":[{"unified":"1f304","native":"🌄"}],"version":1},"sunrise":{"id":"sunrise","name":"Sunrise","keywords":["morning","view","vacation","photo"],"skins":[{"unified":"1f305","native":"🌅"}],"version":1},"city_sunset":{"id":"city_sunset","name":"Cityscape at Dusk","keywords":["city","sunset","photo","evening","sky","buildings"],"skins":[{"unified":"1f306","native":"🌆"}],"version":1},"city_sunrise":{"id":"city_sunrise","name":"Sunset","keywords":["city","sunrise","photo","good","morning","dawn"],"skins":[{"unified":"1f307","native":"🌇"}],"version":1},"bridge_at_night":{"id":"bridge_at_night","name":"Bridge at Night","keywords":["photo","sanfrancisco"],"skins":[{"unified":"1f309","native":"🌉"}],"version":1},"hotsprings":{"id":"hotsprings","name":"Hot Springs","keywords":["hotsprings","bath","warm","relax"],"skins":[{"unified":"2668-fe0f","native":"♨️"}],"version":1},"carousel_horse":{"id":"carousel_horse","name":"Carousel Horse","keywords":["photo","carnival"],"skins":[{"unified":"1f3a0","native":"🎠"}],"version":1},"playground_slide":{"id":"playground_slide","name":"Playground Slide","keywords":["fun","park"],"skins":[{"unified":"1f6dd","native":"🛝"}],"version":14},"ferris_wheel":{"id":"ferris_wheel","name":"Ferris Wheel","keywords":["photo","carnival","londoneye"],"skins":[{"unified":"1f3a1","native":"🎡"}],"version":1},"roller_coaster":{"id":"roller_coaster","name":"Roller Coaster","keywords":["carnival","playground","photo","fun"],"skins":[{"unified":"1f3a2","native":"🎢"}],"version":1},"barber":{"id":"barber","name":"Barber Pole","keywords":["hair","salon","style"],"skins":[{"unified":"1f488","native":"💈"}],"version":1},"circus_tent":{"id":"circus_tent","name":"Circus Tent","keywords":["festival","carnival","party"],"skins":[{"unified":"1f3aa","native":"🎪"}],"version":1},"steam_locomotive":{"id":"steam_locomotive","name":"Locomotive","keywords":["steam","transportation","vehicle","train"],"skins":[{"unified":"1f682","native":"🚂"}],"version":1},"railway_car":{"id":"railway_car","name":"Railway Car","keywords":["transportation","vehicle"],"skins":[{"unified":"1f683","native":"🚃"}],"version":1},"bullettrain_side":{"id":"bullettrain_side","name":"High-Speed Train","keywords":["bullettrain","side","high","speed","transportation","vehicle"],"skins":[{"unified":"1f684","native":"🚄"}],"version":1},"bullettrain_front":{"id":"bullettrain_front","name":"Bullet Train","keywords":["bullettrain","front","transportation","vehicle","speed","fast","public","travel"],"skins":[{"unified":"1f685","native":"🚅"}],"version":1},"train2":{"id":"train2","name":"Train","keywords":["train2","transportation","vehicle"],"skins":[{"unified":"1f686","native":"🚆"}],"version":1},"metro":{"id":"metro","name":"Metro","keywords":["transportation","blue","square","mrt","underground","tube"],"skins":[{"unified":"1f687","native":"🚇"}],"version":1},"light_rail":{"id":"light_rail","name":"Light Rail","keywords":["transportation","vehicle"],"skins":[{"unified":"1f688","native":"🚈"}],"version":1},"station":{"id":"station","name":"Station","keywords":["transportation","vehicle","public"],"skins":[{"unified":"1f689","native":"🚉"}],"version":1},"tram":{"id":"tram","name":"Tram","keywords":["transportation","vehicle"],"skins":[{"unified":"1f68a","native":"🚊"}],"version":1},"monorail":{"id":"monorail","name":"Monorail","keywords":["transportation","vehicle"],"skins":[{"unified":"1f69d","native":"🚝"}],"version":1},"mountain_railway":{"id":"mountain_railway","name":"Mountain Railway","keywords":["transportation","vehicle"],"skins":[{"unified":"1f69e","native":"🚞"}],"version":1},"train":{"id":"train","name":"Tram Car","keywords":["train","transportation","vehicle","carriage","public","travel"],"skins":[{"unified":"1f68b","native":"🚋"}],"version":1},"bus":{"id":"bus","name":"Bus","keywords":["car","vehicle","transportation"],"skins":[{"unified":"1f68c","native":"🚌"}],"version":1},"oncoming_bus":{"id":"oncoming_bus","name":"Oncoming Bus","keywords":["vehicle","transportation"],"skins":[{"unified":"1f68d","native":"🚍"}],"version":1},"trolleybus":{"id":"trolleybus","name":"Trolleybus","keywords":["bart","transportation","vehicle"],"skins":[{"unified":"1f68e","native":"🚎"}],"version":1},"minibus":{"id":"minibus","name":"Minibus","keywords":["vehicle","car","transportation"],"skins":[{"unified":"1f690","native":"🚐"}],"version":1},"ambulance":{"id":"ambulance","name":"Ambulance","keywords":["health","911","hospital"],"skins":[{"unified":"1f691","native":"🚑"}],"version":1},"fire_engine":{"id":"fire_engine","name":"Fire Engine","keywords":["transportation","cars","vehicle"],"skins":[{"unified":"1f692","native":"🚒"}],"version":1},"police_car":{"id":"police_car","name":"Police Car","keywords":["vehicle","cars","transportation","law","legal","enforcement"],"skins":[{"unified":"1f693","native":"🚓"}],"version":1},"oncoming_police_car":{"id":"oncoming_police_car","name":"Oncoming Police Car","keywords":["vehicle","law","legal","enforcement","911"],"skins":[{"unified":"1f694","native":"🚔"}],"version":1},"taxi":{"id":"taxi","name":"Taxi","keywords":["uber","vehicle","cars","transportation"],"skins":[{"unified":"1f695","native":"🚕"}],"version":1},"oncoming_taxi":{"id":"oncoming_taxi","name":"Oncoming Taxi","keywords":["vehicle","cars","uber"],"skins":[{"unified":"1f696","native":"🚖"}],"version":1},"car":{"id":"car","name":"Automobile","keywords":["car","red","transportation","vehicle"],"skins":[{"unified":"1f697","native":"🚗"}],"version":1},"oncoming_automobile":{"id":"oncoming_automobile","name":"Oncoming Automobile","keywords":["car","vehicle","transportation"],"skins":[{"unified":"1f698","native":"🚘"}],"version":1},"blue_car":{"id":"blue_car","name":"Recreational Vehicle","keywords":["blue","car","sport","utility","transportation"],"skins":[{"unified":"1f699","native":"🚙"}],"version":1},"pickup_truck":{"id":"pickup_truck","name":"Pickup Truck","keywords":["car","transportation"],"skins":[{"unified":"1f6fb","native":"🛻"}],"version":13},"truck":{"id":"truck","name":"Delivery Truck","keywords":["cars","transportation"],"skins":[{"unified":"1f69a","native":"🚚"}],"version":1},"articulated_lorry":{"id":"articulated_lorry","name":"Articulated Lorry","keywords":["vehicle","cars","transportation","express"],"skins":[{"unified":"1f69b","native":"🚛"}],"version":1},"tractor":{"id":"tractor","name":"Tractor","keywords":["vehicle","car","farming","agriculture"],"skins":[{"unified":"1f69c","native":"🚜"}],"version":1},"racing_car":{"id":"racing_car","name":"Racing Car","keywords":["sports","race","fast","formula","f1"],"skins":[{"unified":"1f3ce-fe0f","native":"🏎️"}],"version":1},"racing_motorcycle":{"id":"racing_motorcycle","name":"Motorcycle","keywords":["racing","race","sports","fast"],"skins":[{"unified":"1f3cd-fe0f","native":"🏍️"}],"version":1},"motor_scooter":{"id":"motor_scooter","name":"Motor Scooter","keywords":["vehicle","vespa","sasha"],"skins":[{"unified":"1f6f5","native":"🛵"}],"version":3},"manual_wheelchair":{"id":"manual_wheelchair","name":"Manual Wheelchair","keywords":["accessibility"],"skins":[{"unified":"1f9bd","native":"🦽"}],"version":12},"motorized_wheelchair":{"id":"motorized_wheelchair","name":"Motorized Wheelchair","keywords":["accessibility"],"skins":[{"unified":"1f9bc","native":"🦼"}],"version":12},"auto_rickshaw":{"id":"auto_rickshaw","name":"Auto Rickshaw","keywords":["move","transportation"],"skins":[{"unified":"1f6fa","native":"🛺"}],"version":12},"bike":{"id":"bike","name":"Bicycle","keywords":["bike","sports","exercise","hipster"],"skins":[{"unified":"1f6b2","native":"🚲"}],"version":1},"scooter":{"id":"scooter","name":"Scooter","keywords":["kick","vehicle","razor"],"skins":[{"unified":"1f6f4","native":"🛴"}],"version":3},"skateboard":{"id":"skateboard","name":"Skateboard","keywords":["board"],"skins":[{"unified":"1f6f9","native":"🛹"}],"version":11},"roller_skate":{"id":"roller_skate","name":"Roller Skate","keywords":["footwear","sports"],"skins":[{"unified":"1f6fc","native":"🛼"}],"version":13},"busstop":{"id":"busstop","name":"Bus Stop","keywords":["busstop","transportation","wait"],"skins":[{"unified":"1f68f","native":"🚏"}],"version":1},"motorway":{"id":"motorway","name":"Motorway","keywords":["road","cupertino","interstate","highway"],"skins":[{"unified":"1f6e3-fe0f","native":"🛣️"}],"version":1},"railway_track":{"id":"railway_track","name":"Railway Track","keywords":["train","transportation"],"skins":[{"unified":"1f6e4-fe0f","native":"🛤️"}],"version":1},"oil_drum":{"id":"oil_drum","name":"Oil Drum","keywords":["barrell"],"skins":[{"unified":"1f6e2-fe0f","native":"🛢️"}],"version":1},"fuelpump":{"id":"fuelpump","name":"Fuel Pump","keywords":["fuelpump","gas","station","petroleum"],"skins":[{"unified":"26fd","native":"⛽"}],"version":1},"wheel":{"id":"wheel","name":"Wheel","keywords":["car","transport"],"skins":[{"unified":"1f6de","native":"🛞"}],"version":14},"rotating_light":{"id":"rotating_light","name":"Police Car Light","keywords":["rotating","ambulance","911","emergency","alert","error","pinged","law","legal"],"skins":[{"unified":"1f6a8","native":"🚨"}],"version":1},"traffic_light":{"id":"traffic_light","name":"Horizontal Traffic Light","keywords":["transportation","signal"],"skins":[{"unified":"1f6a5","native":"🚥"}],"version":1},"vertical_traffic_light":{"id":"vertical_traffic_light","name":"Vertical Traffic Light","keywords":["transportation","driving"],"skins":[{"unified":"1f6a6","native":"🚦"}],"version":1},"octagonal_sign":{"id":"octagonal_sign","name":"Stop Sign","keywords":["octagonal"],"skins":[{"unified":"1f6d1","native":"🛑"}],"version":3},"construction":{"id":"construction","name":"Construction","keywords":["wip","progress","caution","warning"],"skins":[{"unified":"1f6a7","native":"🚧"}],"version":1},"anchor":{"id":"anchor","name":"Anchor","keywords":["ship","ferry","sea","boat"],"skins":[{"unified":"2693","native":"⚓"}],"version":1},"ring_buoy":{"id":"ring_buoy","name":"Ring Buoy","keywords":["life","saver","preserver"],"skins":[{"unified":"1f6df","native":"🛟"}],"version":14},"boat":{"id":"boat","name":"Sailboat","keywords":["boat","ship","summer","transportation","water","sailing"],"skins":[{"unified":"26f5","native":"⛵"}],"version":1},"canoe":{"id":"canoe","name":"Canoe","keywords":["boat","paddle","water","ship"],"skins":[{"unified":"1f6f6","native":"🛶"}],"version":3},"speedboat":{"id":"speedboat","name":"Speedboat","keywords":["ship","transportation","vehicle","summer"],"skins":[{"unified":"1f6a4","native":"🚤"}],"version":1},"passenger_ship":{"id":"passenger_ship","name":"Passenger Ship","keywords":["yacht","cruise","ferry"],"skins":[{"unified":"1f6f3-fe0f","native":"🛳️"}],"version":1},"ferry":{"id":"ferry","name":"Ferry","keywords":["boat","ship","yacht"],"skins":[{"unified":"26f4-fe0f","native":"⛴️"}],"version":1},"motor_boat":{"id":"motor_boat","name":"Motor Boat","keywords":["ship"],"skins":[{"unified":"1f6e5-fe0f","native":"🛥️"}],"version":1},"ship":{"id":"ship","name":"Ship","keywords":["transportation","titanic","deploy"],"skins":[{"unified":"1f6a2","native":"🚢"}],"version":1},"airplane":{"id":"airplane","name":"Airplane","keywords":["vehicle","transportation","flight","fly"],"skins":[{"unified":"2708-fe0f","native":"✈️"}],"version":1},"small_airplane":{"id":"small_airplane","name":"Small Airplane","keywords":["flight","transportation","fly","vehicle"],"skins":[{"unified":"1f6e9-fe0f","native":"🛩️"}],"version":1},"airplane_departure":{"id":"airplane_departure","name":"Airplane Departure","keywords":["airport","flight","landing"],"skins":[{"unified":"1f6eb","native":"🛫"}],"version":1},"airplane_arriving":{"id":"airplane_arriving","name":"Airplane Arrival","keywords":["arriving","airport","flight","boarding"],"skins":[{"unified":"1f6ec","native":"🛬"}],"version":1},"parachute":{"id":"parachute","name":"Parachute","keywords":["fly","glide"],"skins":[{"unified":"1fa82","native":"🪂"}],"version":12},"seat":{"id":"seat","name":"Seat","keywords":["sit","airplane","transport","bus","flight","fly"],"skins":[{"unified":"1f4ba","native":"💺"}],"version":1},"helicopter":{"id":"helicopter","name":"Helicopter","keywords":["transportation","vehicle","fly"],"skins":[{"unified":"1f681","native":"🚁"}],"version":1},"suspension_railway":{"id":"suspension_railway","name":"Suspension Railway","keywords":["vehicle","transportation"],"skins":[{"unified":"1f69f","native":"🚟"}],"version":1},"mountain_cableway":{"id":"mountain_cableway","name":"Mountain Cableway","keywords":["transportation","vehicle","ski"],"skins":[{"unified":"1f6a0","native":"🚠"}],"version":1},"aerial_tramway":{"id":"aerial_tramway","name":"Aerial Tramway","keywords":["transportation","vehicle","ski"],"skins":[{"unified":"1f6a1","native":"🚡"}],"version":1},"satellite":{"id":"satellite","name":"Satellite","keywords":["communication","gps","orbit","spaceflight","NASA","ISS"],"skins":[{"unified":"1f6f0-fe0f","native":"🛰️"}],"version":1},"rocket":{"id":"rocket","name":"Rocket","keywords":["launch","ship","staffmode","NASA","outer","space","fly"],"skins":[{"unified":"1f680","native":"🚀"}],"version":1},"flying_saucer":{"id":"flying_saucer","name":"Flying Saucer","keywords":["transportation","vehicle","ufo"],"skins":[{"unified":"1f6f8","native":"🛸"}],"version":5},"bellhop_bell":{"id":"bellhop_bell","name":"Bellhop Bell","keywords":["service"],"skins":[{"unified":"1f6ce-fe0f","native":"🛎️"}],"version":1},"luggage":{"id":"luggage","name":"Luggage","keywords":["packing","travel"],"skins":[{"unified":"1f9f3","native":"🧳"}],"version":11},"hourglass":{"id":"hourglass","name":"Hourglass","keywords":["done","time","clock","oldschool","limit","exam","quiz","test"],"skins":[{"unified":"231b","native":"⌛"}],"version":1},"hourglass_flowing_sand":{"id":"hourglass_flowing_sand","name":"Hourglass Not Done","keywords":["flowing","sand","oldschool","time","countdown"],"skins":[{"unified":"23f3","native":"⏳"}],"version":1},"watch":{"id":"watch","name":"Watch","keywords":["time","accessories"],"skins":[{"unified":"231a","native":"⌚"}],"version":1},"alarm_clock":{"id":"alarm_clock","name":"Alarm Clock","keywords":["time","wake"],"skins":[{"unified":"23f0","native":"⏰"}],"version":1},"stopwatch":{"id":"stopwatch","name":"Stopwatch","keywords":["time","deadline"],"skins":[{"unified":"23f1-fe0f","native":"⏱️"}],"version":1},"timer_clock":{"id":"timer_clock","name":"Timer Clock","keywords":["alarm"],"skins":[{"unified":"23f2-fe0f","native":"⏲️"}],"version":1},"mantelpiece_clock":{"id":"mantelpiece_clock","name":"Mantelpiece Clock","keywords":["time"],"skins":[{"unified":"1f570-fe0f","native":"🕰️"}],"version":1},"clock12":{"id":"clock12","name":"Twelve O’clock","keywords":["clock12","o","clock","12","00:00","0000","12:00","1200","time","noon","midnight","midday","late","early","schedule"],"skins":[{"unified":"1f55b","native":"🕛"}],"version":1},"clock1230":{"id":"clock1230","name":"Twelve-Thirty","keywords":["clock1230","twelve","thirty","00:30","0030","12:30","1230","time","late","early","schedule"],"skins":[{"unified":"1f567","native":"🕧"}],"version":1},"clock1":{"id":"clock1","name":"One O’clock","keywords":["clock1","o","clock","1","1:00","100","13:00","1300","time","late","early","schedule"],"skins":[{"unified":"1f550","native":"🕐"}],"version":1},"clock130":{"id":"clock130","name":"One-Thirty","keywords":["clock130","one","thirty","1:30","130","13:30","1330","time","late","early","schedule"],"skins":[{"unified":"1f55c","native":"🕜"}],"version":1},"clock2":{"id":"clock2","name":"Two O’clock","keywords":["clock2","o","clock","2","2:00","200","14:00","1400","time","late","early","schedule"],"skins":[{"unified":"1f551","native":"🕑"}],"version":1},"clock230":{"id":"clock230","name":"Two-Thirty","keywords":["clock230","two","thirty","2:30","230","14:30","1430","time","late","early","schedule"],"skins":[{"unified":"1f55d","native":"🕝"}],"version":1},"clock3":{"id":"clock3","name":"Three O’clock","keywords":["clock3","o","clock","3","3:00","300","15:00","1500","time","late","early","schedule"],"skins":[{"unified":"1f552","native":"🕒"}],"version":1},"clock330":{"id":"clock330","name":"Three-Thirty","keywords":["clock330","three","thirty","3:30","330","15:30","1530","time","late","early","schedule"],"skins":[{"unified":"1f55e","native":"🕞"}],"version":1},"clock4":{"id":"clock4","name":"Four O’clock","keywords":["clock4","o","clock","4","4:00","400","16:00","1600","time","late","early","schedule"],"skins":[{"unified":"1f553","native":"🕓"}],"version":1},"clock430":{"id":"clock430","name":"Four-Thirty","keywords":["clock430","four","thirty","4:30","430","16:30","1630","time","late","early","schedule"],"skins":[{"unified":"1f55f","native":"🕟"}],"version":1},"clock5":{"id":"clock5","name":"Five O’clock","keywords":["clock5","o","clock","5","5:00","500","17:00","1700","time","late","early","schedule"],"skins":[{"unified":"1f554","native":"🕔"}],"version":1},"clock530":{"id":"clock530","name":"Five-Thirty","keywords":["clock530","five","thirty","5:30","530","17:30","1730","time","late","early","schedule"],"skins":[{"unified":"1f560","native":"🕠"}],"version":1},"clock6":{"id":"clock6","name":"Six O’clock","keywords":["clock6","o","clock","6","6:00","600","18:00","1800","time","late","early","schedule","dawn","dusk"],"skins":[{"unified":"1f555","native":"🕕"}],"version":1},"clock630":{"id":"clock630","name":"Six-Thirty","keywords":["clock630","six","thirty","6:30","630","18:30","1830","time","late","early","schedule"],"skins":[{"unified":"1f561","native":"🕡"}],"version":1},"clock7":{"id":"clock7","name":"Seven O’clock","keywords":["clock7","o","clock","7","7:00","700","19:00","1900","time","late","early","schedule"],"skins":[{"unified":"1f556","native":"🕖"}],"version":1},"clock730":{"id":"clock730","name":"Seven-Thirty","keywords":["clock730","seven","thirty","7:30","730","19:30","1930","time","late","early","schedule"],"skins":[{"unified":"1f562","native":"🕢"}],"version":1},"clock8":{"id":"clock8","name":"Eight O’clock","keywords":["clock8","o","clock","8","8:00","800","20:00","2000","time","late","early","schedule"],"skins":[{"unified":"1f557","native":"🕗"}],"version":1},"clock830":{"id":"clock830","name":"Eight-Thirty","keywords":["clock830","eight","thirty","8:30","830","20:30","2030","time","late","early","schedule"],"skins":[{"unified":"1f563","native":"🕣"}],"version":1},"clock9":{"id":"clock9","name":"Nine O’clock","keywords":["clock9","o","clock","9","9:00","900","21:00","2100","time","late","early","schedule"],"skins":[{"unified":"1f558","native":"🕘"}],"version":1},"clock930":{"id":"clock930","name":"Nine-Thirty","keywords":["clock930","nine","thirty","9:30","930","21:30","2130","time","late","early","schedule"],"skins":[{"unified":"1f564","native":"🕤"}],"version":1},"clock10":{"id":"clock10","name":"Ten O’clock","keywords":["clock10","o","clock","10","10:00","1000","22:00","2200","time","late","early","schedule"],"skins":[{"unified":"1f559","native":"🕙"}],"version":1},"clock1030":{"id":"clock1030","name":"Ten-Thirty","keywords":["clock1030","ten","thirty","10:30","1030","22:30","2230","time","late","early","schedule"],"skins":[{"unified":"1f565","native":"🕥"}],"version":1},"clock11":{"id":"clock11","name":"Eleven O’clock","keywords":["clock11","o","clock","11","11:00","1100","23:00","2300","time","late","early","schedule"],"skins":[{"unified":"1f55a","native":"🕚"}],"version":1},"clock1130":{"id":"clock1130","name":"Eleven-Thirty","keywords":["clock1130","eleven","thirty","11:30","1130","23:30","2330","time","late","early","schedule"],"skins":[{"unified":"1f566","native":"🕦"}],"version":1},"new_moon":{"id":"new_moon","name":"New Moon","keywords":["nature","twilight","planet","space","night","evening","sleep"],"skins":[{"unified":"1f311","native":"🌑"}],"version":1},"waxing_crescent_moon":{"id":"waxing_crescent_moon","name":"Waxing Crescent Moon","keywords":["nature","twilight","planet","space","night","evening","sleep"],"skins":[{"unified":"1f312","native":"🌒"}],"version":1},"first_quarter_moon":{"id":"first_quarter_moon","name":"First Quarter Moon","keywords":["nature","twilight","planet","space","night","evening","sleep"],"skins":[{"unified":"1f313","native":"🌓"}],"version":1},"moon":{"id":"moon","name":"Waxing Gibbous Moon","keywords":["nature","night","sky","gray","twilight","planet","space","evening","sleep"],"skins":[{"unified":"1f314","native":"🌔"}],"version":1},"full_moon":{"id":"full_moon","name":"Full Moon","keywords":["nature","yellow","twilight","planet","space","night","evening","sleep"],"skins":[{"unified":"1f315","native":"🌕"}],"version":1},"waning_gibbous_moon":{"id":"waning_gibbous_moon","name":"Waning Gibbous Moon","keywords":["nature","twilight","planet","space","night","evening","sleep","waxing"],"skins":[{"unified":"1f316","native":"🌖"}],"version":1},"last_quarter_moon":{"id":"last_quarter_moon","name":"Last Quarter Moon","keywords":["nature","twilight","planet","space","night","evening","sleep"],"skins":[{"unified":"1f317","native":"🌗"}],"version":1},"waning_crescent_moon":{"id":"waning_crescent_moon","name":"Waning Crescent Moon","keywords":["nature","twilight","planet","space","night","evening","sleep"],"skins":[{"unified":"1f318","native":"🌘"}],"version":1},"crescent_moon":{"id":"crescent_moon","name":"Crescent Moon","keywords":["night","sleep","sky","evening","magic"],"skins":[{"unified":"1f319","native":"🌙"}],"version":1},"new_moon_with_face":{"id":"new_moon_with_face","name":"New Moon Face","keywords":["with","nature","twilight","planet","space","night","evening","sleep"],"skins":[{"unified":"1f31a","native":"🌚"}],"version":1},"first_quarter_moon_with_face":{"id":"first_quarter_moon_with_face","name":"First Quarter Moon Face","keywords":["with","nature","twilight","planet","space","night","evening","sleep"],"skins":[{"unified":"1f31b","native":"🌛"}],"version":1},"last_quarter_moon_with_face":{"id":"last_quarter_moon_with_face","name":"Last Quarter Moon Face","keywords":["with","nature","twilight","planet","space","night","evening","sleep"],"skins":[{"unified":"1f31c","native":"🌜"}],"version":1},"thermometer":{"id":"thermometer","name":"Thermometer","keywords":["weather","temperature","hot","cold"],"skins":[{"unified":"1f321-fe0f","native":"🌡️"}],"version":1},"sunny":{"id":"sunny","name":"Sun","keywords":["sunny","weather","nature","brightness","summer","beach","spring"],"skins":[{"unified":"2600-fe0f","native":"☀️"}],"version":1},"full_moon_with_face":{"id":"full_moon_with_face","name":"Full Moon Face","keywords":["with","nature","twilight","planet","space","night","evening","sleep"],"skins":[{"unified":"1f31d","native":"🌝"}],"version":1},"sun_with_face":{"id":"sun_with_face","name":"Sun with Face","keywords":["nature","morning","sky"],"skins":[{"unified":"1f31e","native":"🌞"}],"version":1},"ringed_planet":{"id":"ringed_planet","name":"Ringed Planet","keywords":["outerspace"],"skins":[{"unified":"1fa90","native":"🪐"}],"version":12},"star":{"id":"star","name":"Star","keywords":["night","yellow"],"skins":[{"unified":"2b50","native":"⭐"}],"version":1},"star2":{"id":"star2","name":"Glowing Star","keywords":["star2","night","sparkle","awesome","good","magic"],"skins":[{"unified":"1f31f","native":"🌟"}],"version":1},"stars":{"id":"stars","name":"Shooting Star","keywords":["stars","night","photo"],"skins":[{"unified":"1f320","native":"🌠"}],"version":1},"milky_way":{"id":"milky_way","name":"Milky Way","keywords":["photo","space","stars"],"skins":[{"unified":"1f30c","native":"🌌"}],"version":1},"cloud":{"id":"cloud","name":"Cloud","keywords":["weather","sky"],"skins":[{"unified":"2601-fe0f","native":"☁️"}],"version":1},"partly_sunny":{"id":"partly_sunny","name":"Sun Behind Cloud","keywords":["partly","sunny","weather","nature","cloudy","morning","fall","spring"],"skins":[{"unified":"26c5","native":"⛅"}],"version":1},"thunder_cloud_and_rain":{"id":"thunder_cloud_and_rain","name":"Cloud with Lightning and Rain","keywords":["thunder","weather"],"skins":[{"unified":"26c8-fe0f","native":"⛈️"}],"version":1},"mostly_sunny":{"id":"mostly_sunny","name":"Sun Behind Small Cloud","keywords":["mostly","sunny","weather"],"skins":[{"unified":"1f324-fe0f","native":"🌤️"}],"version":1},"barely_sunny":{"id":"barely_sunny","name":"Sun Behind Large Cloud","keywords":["barely","sunny","weather"],"skins":[{"unified":"1f325-fe0f","native":"🌥️"}],"version":1},"partly_sunny_rain":{"id":"partly_sunny_rain","name":"Sun Behind Rain Cloud","keywords":["partly","sunny","weather"],"skins":[{"unified":"1f326-fe0f","native":"🌦️"}],"version":1},"rain_cloud":{"id":"rain_cloud","name":"Cloud with Rain","keywords":["weather"],"skins":[{"unified":"1f327-fe0f","native":"🌧️"}],"version":1},"snow_cloud":{"id":"snow_cloud","name":"Cloud with Snow","keywords":["weather"],"skins":[{"unified":"1f328-fe0f","native":"🌨️"}],"version":1},"lightning":{"id":"lightning","name":"Cloud with Lightning","keywords":["weather","thunder"],"skins":[{"unified":"1f329-fe0f","native":"🌩️"}],"version":1},"tornado":{"id":"tornado","name":"Tornado","keywords":["cloud","weather","cyclone","twister"],"skins":[{"unified":"1f32a-fe0f","native":"🌪️"}],"version":1},"fog":{"id":"fog","name":"Fog","keywords":["weather"],"skins":[{"unified":"1f32b-fe0f","native":"🌫️"}],"version":1},"wind_blowing_face":{"id":"wind_blowing_face","name":"Wind Face","keywords":["blowing","gust","air"],"skins":[{"unified":"1f32c-fe0f","native":"🌬️"}],"version":1},"cyclone":{"id":"cyclone","name":"Cyclone","keywords":["weather","swirl","blue","cloud","vortex","spiral","whirlpool","spin","tornado","hurricane","typhoon"],"skins":[{"unified":"1f300","native":"🌀"}],"version":1},"rainbow":{"id":"rainbow","name":"Rainbow","keywords":["nature","happy","unicorn","face","photo","sky","spring"],"skins":[{"unified":"1f308","native":"🌈"}],"version":1},"closed_umbrella":{"id":"closed_umbrella","name":"Closed Umbrella","keywords":["weather","rain","drizzle"],"skins":[{"unified":"1f302","native":"🌂"}],"version":1},"umbrella":{"id":"umbrella","name":"Umbrella","keywords":["weather","spring"],"skins":[{"unified":"2602-fe0f","native":"☂️"}],"version":1},"umbrella_with_rain_drops":{"id":"umbrella_with_rain_drops","name":"Umbrella with Rain Drops","keywords":["rainy","weather","spring"],"skins":[{"unified":"2614","native":"☔"}],"version":1},"umbrella_on_ground":{"id":"umbrella_on_ground","name":"Umbrella on Ground","keywords":["weather","summer"],"skins":[{"unified":"26f1-fe0f","native":"⛱️"}],"version":1},"zap":{"id":"zap","name":"High Voltage","keywords":["zap","thunder","weather","lightning","bolt","fast"],"skins":[{"unified":"26a1","native":"⚡"}],"version":1},"snowflake":{"id":"snowflake","name":"Snowflake","keywords":["winter","season","cold","weather","christmas","xmas"],"skins":[{"unified":"2744-fe0f","native":"❄️"}],"version":1},"snowman":{"id":"snowman","name":"Snowman","keywords":["winter","season","cold","weather","christmas","xmas","frozen"],"skins":[{"unified":"2603-fe0f","native":"☃️"}],"version":1},"snowman_without_snow":{"id":"snowman_without_snow","name":"Snowman Without Snow","keywords":["winter","season","cold","weather","christmas","xmas","frozen"],"skins":[{"unified":"26c4","native":"⛄"}],"version":1},"comet":{"id":"comet","name":"Comet","keywords":["space"],"skins":[{"unified":"2604-fe0f","native":"☄️"}],"version":1},"fire":{"id":"fire","name":"Fire","keywords":["hot","cook","flame"],"skins":[{"unified":"1f525","native":"🔥"}],"version":1},"droplet":{"id":"droplet","name":"Droplet","keywords":["water","drip","faucet","spring"],"skins":[{"unified":"1f4a7","native":"💧"}],"version":1},"ocean":{"id":"ocean","name":"Water Wave","keywords":["ocean","sea","nature","tsunami","disaster"],"skins":[{"unified":"1f30a","native":"🌊"}],"version":1},"jack_o_lantern":{"id":"jack_o_lantern","name":"Jack-O-Lantern","keywords":["jack","o","lantern","halloween","light","pumpkin","creepy","fall"],"skins":[{"unified":"1f383","native":"🎃"}],"version":1},"christmas_tree":{"id":"christmas_tree","name":"Christmas Tree","keywords":["festival","vacation","december","xmas","celebration"],"skins":[{"unified":"1f384","native":"🎄"}],"version":1},"fireworks":{"id":"fireworks","name":"Fireworks","keywords":["photo","festival","carnival","congratulations"],"skins":[{"unified":"1f386","native":"🎆"}],"version":1},"sparkler":{"id":"sparkler","name":"Sparkler","keywords":["stars","night","shine"],"skins":[{"unified":"1f387","native":"🎇"}],"version":1},"firecracker":{"id":"firecracker","name":"Firecracker","keywords":["dynamite","boom","explode","explosion","explosive"],"skins":[{"unified":"1f9e8","native":"🧨"}],"version":11},"sparkles":{"id":"sparkles","name":"Sparkles","keywords":["stars","shine","shiny","cool","awesome","good","magic"],"skins":[{"unified":"2728","native":"✨"}],"version":1},"balloon":{"id":"balloon","name":"Balloon","keywords":["party","celebration","birthday","circus"],"skins":[{"unified":"1f388","native":"🎈"}],"version":1},"tada":{"id":"tada","name":"Party Popper","keywords":["tada","congratulations","birthday","magic","circus","celebration"],"skins":[{"unified":"1f389","native":"🎉"}],"version":1},"confetti_ball":{"id":"confetti_ball","name":"Confetti Ball","keywords":["festival","party","birthday","circus"],"skins":[{"unified":"1f38a","native":"🎊"}],"version":1},"tanabata_tree":{"id":"tanabata_tree","name":"Tanabata Tree","keywords":["plant","nature","branch","summer","bamboo","wish","star","festival","tanzaku"],"skins":[{"unified":"1f38b","native":"🎋"}],"version":1},"bamboo":{"id":"bamboo","name":"Pine Decoration","keywords":["bamboo","japanese","plant","nature","vegetable","panda","new","years"],"skins":[{"unified":"1f38d","native":"🎍"}],"version":1},"dolls":{"id":"dolls","name":"Japanese Dolls","keywords":["toy","kimono"],"skins":[{"unified":"1f38e","native":"🎎"}],"version":1},"flags":{"id":"flags","name":"Carp Streamer","keywords":["flags","fish","japanese","koinobori","banner"],"skins":[{"unified":"1f38f","native":"🎏"}],"version":1},"wind_chime":{"id":"wind_chime","name":"Wind Chime","keywords":["nature","ding","spring","bell"],"skins":[{"unified":"1f390","native":"🎐"}],"version":1},"rice_scene":{"id":"rice_scene","name":"Moon Viewing Ceremony","keywords":["rice","scene","photo","japan","asia","tsukimi"],"skins":[{"unified":"1f391","native":"🎑"}],"version":1},"red_envelope":{"id":"red_envelope","name":"Red Envelope","keywords":["gift"],"skins":[{"unified":"1f9e7","native":"🧧"}],"version":11},"ribbon":{"id":"ribbon","name":"Ribbon","keywords":["decoration","pink","girl","bowtie"],"skins":[{"unified":"1f380","native":"🎀"}],"version":1},"gift":{"id":"gift","name":"Wrapped Gift","keywords":["present","birthday","christmas","xmas"],"skins":[{"unified":"1f381","native":"🎁"}],"version":1},"reminder_ribbon":{"id":"reminder_ribbon","name":"Reminder Ribbon","keywords":["sports","cause","support","awareness"],"skins":[{"unified":"1f397-fe0f","native":"🎗️"}],"version":1},"admission_tickets":{"id":"admission_tickets","name":"Admission Tickets","keywords":["sports","concert","entrance"],"skins":[{"unified":"1f39f-fe0f","native":"🎟️"}],"version":1},"ticket":{"id":"ticket","name":"Ticket","keywords":["event","concert","pass"],"skins":[{"unified":"1f3ab","native":"🎫"}],"version":1},"medal":{"id":"medal","name":"Military Medal","keywords":["award","winning","army"],"skins":[{"unified":"1f396-fe0f","native":"🎖️"}],"version":1},"trophy":{"id":"trophy","name":"Trophy","keywords":["win","award","contest","place","ftw","ceremony"],"skins":[{"unified":"1f3c6","native":"🏆"}],"version":1},"sports_medal":{"id":"sports_medal","name":"Sports Medal","keywords":["award","winning"],"skins":[{"unified":"1f3c5","native":"🏅"}],"version":1},"first_place_medal":{"id":"first_place_medal","name":"1st Place Medal","keywords":["first","award","winning"],"skins":[{"unified":"1f947","native":"🥇"}],"version":3},"second_place_medal":{"id":"second_place_medal","name":"2nd Place Medal","keywords":["second","award"],"skins":[{"unified":"1f948","native":"🥈"}],"version":3},"third_place_medal":{"id":"third_place_medal","name":"3rd Place Medal","keywords":["third","award"],"skins":[{"unified":"1f949","native":"🥉"}],"version":3},"soccer":{"id":"soccer","name":"Soccer Ball","keywords":["sports","football"],"skins":[{"unified":"26bd","native":"⚽"}],"version":1},"baseball":{"id":"baseball","name":"Baseball","keywords":["sports","balls"],"skins":[{"unified":"26be","native":"⚾"}],"version":1},"softball":{"id":"softball","name":"Softball","keywords":["sports","balls"],"skins":[{"unified":"1f94e","native":"🥎"}],"version":11},"basketball":{"id":"basketball","name":"Basketball","keywords":["sports","balls","NBA"],"skins":[{"unified":"1f3c0","native":"🏀"}],"version":1},"volleyball":{"id":"volleyball","name":"Volleyball","keywords":["sports","balls"],"skins":[{"unified":"1f3d0","native":"🏐"}],"version":1},"football":{"id":"football","name":"American Football","keywords":["sports","balls","NFL"],"skins":[{"unified":"1f3c8","native":"🏈"}],"version":1},"rugby_football":{"id":"rugby_football","name":"Rugby Football","keywords":["sports","team"],"skins":[{"unified":"1f3c9","native":"🏉"}],"version":1},"tennis":{"id":"tennis","name":"Tennis","keywords":["sports","balls","green"],"skins":[{"unified":"1f3be","native":"🎾"}],"version":1},"flying_disc":{"id":"flying_disc","name":"Flying Disc","keywords":["sports","frisbee","ultimate"],"skins":[{"unified":"1f94f","native":"🥏"}],"version":11},"bowling":{"id":"bowling","name":"Bowling","keywords":["sports","fun","play"],"skins":[{"unified":"1f3b3","native":"🎳"}],"version":1},"cricket_bat_and_ball":{"id":"cricket_bat_and_ball","name":"Cricket Game","keywords":["bat","and","ball","sports"],"skins":[{"unified":"1f3cf","native":"🏏"}],"version":1},"field_hockey_stick_and_ball":{"id":"field_hockey_stick_and_ball","name":"Field Hockey","keywords":["stick","and","ball","sports"],"skins":[{"unified":"1f3d1","native":"🏑"}],"version":1},"ice_hockey_stick_and_puck":{"id":"ice_hockey_stick_and_puck","name":"Ice Hockey","keywords":["stick","and","puck","sports"],"skins":[{"unified":"1f3d2","native":"🏒"}],"version":1},"lacrosse":{"id":"lacrosse","name":"Lacrosse","keywords":["sports","ball","stick"],"skins":[{"unified":"1f94d","native":"🥍"}],"version":11},"table_tennis_paddle_and_ball":{"id":"table_tennis_paddle_and_ball","name":"Ping Pong","keywords":["table","tennis","paddle","and","ball","sports","pingpong"],"skins":[{"unified":"1f3d3","native":"🏓"}],"version":1},"badminton_racquet_and_shuttlecock":{"id":"badminton_racquet_and_shuttlecock","name":"Badminton","keywords":["racquet","and","shuttlecock","sports"],"skins":[{"unified":"1f3f8","native":"🏸"}],"version":1},"boxing_glove":{"id":"boxing_glove","name":"Boxing Glove","keywords":["sports","fighting"],"skins":[{"unified":"1f94a","native":"🥊"}],"version":3},"martial_arts_uniform":{"id":"martial_arts_uniform","name":"Martial Arts Uniform","keywords":["judo","karate","taekwondo"],"skins":[{"unified":"1f94b","native":"🥋"}],"version":3},"goal_net":{"id":"goal_net","name":"Goal Net","keywords":["sports"],"skins":[{"unified":"1f945","native":"🥅"}],"version":3},"golf":{"id":"golf","name":"Flag in Hole","keywords":["golf","sports","business","summer"],"skins":[{"unified":"26f3","native":"⛳"}],"version":1},"ice_skate":{"id":"ice_skate","name":"Ice Skate","keywords":["sports"],"skins":[{"unified":"26f8-fe0f","native":"⛸️"}],"version":1},"fishing_pole_and_fish":{"id":"fishing_pole_and_fish","name":"Fishing Pole","keywords":["and","fish","food","hobby","summer"],"skins":[{"unified":"1f3a3","native":"🎣"}],"version":1},"diving_mask":{"id":"diving_mask","name":"Diving Mask","keywords":["sport","ocean"],"skins":[{"unified":"1f93f","native":"🤿"}],"version":12},"running_shirt_with_sash":{"id":"running_shirt_with_sash","name":"Running Shirt","keywords":["with","sash","play","pageant"],"skins":[{"unified":"1f3bd","native":"🎽"}],"version":1},"ski":{"id":"ski","name":"Skis","keywords":["ski","sports","winter","cold","snow"],"skins":[{"unified":"1f3bf","native":"🎿"}],"version":1},"sled":{"id":"sled","name":"Sled","keywords":["sleigh","luge","toboggan"],"skins":[{"unified":"1f6f7","native":"🛷"}],"version":5},"curling_stone":{"id":"curling_stone","name":"Curling Stone","keywords":["sports"],"skins":[{"unified":"1f94c","native":"🥌"}],"version":5},"dart":{"id":"dart","name":"Bullseye","keywords":["dart","direct","hit","game","play","bar","target"],"skins":[{"unified":"1f3af","native":"🎯"}],"version":1},"yo-yo":{"id":"yo-yo","name":"Yo-Yo","keywords":["yo","toy"],"skins":[{"unified":"1fa80","native":"🪀"}],"version":12},"kite":{"id":"kite","name":"Kite","keywords":["wind","fly"],"skins":[{"unified":"1fa81","native":"🪁"}],"version":12},"gun":{"id":"gun","name":"Pistol","keywords":["gun","violence","weapon","revolver"],"skins":[{"unified":"1f52b","native":"🔫"}],"version":1},"8ball":{"id":"8ball","name":"Billiards","keywords":["8ball","pool","8","ball","hobby","game","luck","magic"],"skins":[{"unified":"1f3b1","native":"🎱"}],"version":1},"crystal_ball":{"id":"crystal_ball","name":"Crystal Ball","keywords":["disco","party","magic","circus","fortune","teller"],"skins":[{"unified":"1f52e","native":"🔮"}],"version":1},"magic_wand":{"id":"magic_wand","name":"Magic Wand","keywords":["supernature","power"],"skins":[{"unified":"1fa84","native":"🪄"}],"version":13},"video_game":{"id":"video_game","name":"Video Game","keywords":["play","console","PS4","controller"],"skins":[{"unified":"1f3ae","native":"🎮"}],"version":1},"joystick":{"id":"joystick","name":"Joystick","keywords":["game","play"],"skins":[{"unified":"1f579-fe0f","native":"🕹️"}],"version":1},"slot_machine":{"id":"slot_machine","name":"Slot Machine","keywords":["bet","gamble","vegas","fruit","luck","casino"],"skins":[{"unified":"1f3b0","native":"🎰"}],"version":1},"game_die":{"id":"game_die","name":"Game Die","keywords":["dice","random","tabletop","play","luck"],"skins":[{"unified":"1f3b2","native":"🎲"}],"version":1},"jigsaw":{"id":"jigsaw","name":"Puzzle Piece","keywords":["jigsaw","interlocking"],"skins":[{"unified":"1f9e9","native":"🧩"}],"version":11},"teddy_bear":{"id":"teddy_bear","name":"Teddy Bear","keywords":["plush","stuffed"],"skins":[{"unified":"1f9f8","native":"🧸"}],"version":11},"pinata":{"id":"pinata","name":"Pinata","keywords":["mexico","candy","celebration"],"skins":[{"unified":"1fa85","native":"🪅"}],"version":13},"mirror_ball":{"id":"mirror_ball","name":"Mirror Ball","keywords":["disco","dance","party"],"skins":[{"unified":"1faa9","native":"🪩"}],"version":14},"nesting_dolls":{"id":"nesting_dolls","name":"Nesting Dolls","keywords":["matryoshka","toy"],"skins":[{"unified":"1fa86","native":"🪆"}],"version":13},"spades":{"id":"spades","name":"Spade Suit","keywords":["spades","poker","cards","suits","magic"],"skins":[{"unified":"2660-fe0f","native":"♠️"}],"version":1},"hearts":{"id":"hearts","name":"Heart Suit","keywords":["hearts","poker","cards","magic","suits"],"skins":[{"unified":"2665-fe0f","native":"♥️"}],"version":1},"diamonds":{"id":"diamonds","name":"Diamond Suit","keywords":["diamonds","poker","cards","magic","suits"],"skins":[{"unified":"2666-fe0f","native":"♦️"}],"version":1},"clubs":{"id":"clubs","name":"Club Suit","keywords":["clubs","poker","cards","magic","suits"],"skins":[{"unified":"2663-fe0f","native":"♣️"}],"version":1},"chess_pawn":{"id":"chess_pawn","name":"Chess Pawn","keywords":["expendable"],"skins":[{"unified":"265f-fe0f","native":"♟️"}],"version":11},"black_joker":{"id":"black_joker","name":"Joker","keywords":["black","poker","cards","game","play","magic"],"skins":[{"unified":"1f0cf","native":"🃏"}],"version":1},"mahjong":{"id":"mahjong","name":"Mahjong Red Dragon","keywords":["game","play","chinese","kanji"],"skins":[{"unified":"1f004","native":"🀄"}],"version":1},"flower_playing_cards":{"id":"flower_playing_cards","name":"Flower Playing Cards","keywords":["game","sunset","red"],"skins":[{"unified":"1f3b4","native":"🎴"}],"version":1},"performing_arts":{"id":"performing_arts","name":"Performing Arts","keywords":["acting","theater","drama"],"skins":[{"unified":"1f3ad","native":"🎭"}],"version":1},"frame_with_picture":{"id":"frame_with_picture","name":"Framed Picture","keywords":["frame","with","photography"],"skins":[{"unified":"1f5bc-fe0f","native":"🖼️"}],"version":1},"art":{"id":"art","name":"Artist Palette","keywords":["art","design","paint","draw","colors"],"skins":[{"unified":"1f3a8","native":"🎨"}],"version":1},"thread":{"id":"thread","name":"Thread","keywords":["needle","sewing","spool","string"],"skins":[{"unified":"1f9f5","native":"🧵"}],"version":11},"sewing_needle":{"id":"sewing_needle","name":"Sewing Needle","keywords":["stitches"],"skins":[{"unified":"1faa1","native":"🪡"}],"version":13},"yarn":{"id":"yarn","name":"Yarn","keywords":["ball","crochet","knit"],"skins":[{"unified":"1f9f6","native":"🧶"}],"version":11},"knot":{"id":"knot","name":"Knot","keywords":["rope","scout"],"skins":[{"unified":"1faa2","native":"🪢"}],"version":13},"eyeglasses":{"id":"eyeglasses","name":"Glasses","keywords":["eyeglasses","fashion","accessories","eyesight","nerdy","dork","geek"],"skins":[{"unified":"1f453","native":"👓"}],"version":1},"dark_sunglasses":{"id":"dark_sunglasses","name":"Sunglasses","keywords":["dark","face","cool","accessories"],"skins":[{"unified":"1f576-fe0f","native":"🕶️"}],"version":1},"goggles":{"id":"goggles","name":"Goggles","keywords":["eyes","protection","safety"],"skins":[{"unified":"1f97d","native":"🥽"}],"version":11},"lab_coat":{"id":"lab_coat","name":"Lab Coat","keywords":["doctor","experiment","scientist","chemist"],"skins":[{"unified":"1f97c","native":"🥼"}],"version":11},"safety_vest":{"id":"safety_vest","name":"Safety Vest","keywords":["protection"],"skins":[{"unified":"1f9ba","native":"🦺"}],"version":12},"necktie":{"id":"necktie","name":"Necktie","keywords":["shirt","suitup","formal","fashion","cloth","business"],"skins":[{"unified":"1f454","native":"👔"}],"version":1},"shirt":{"id":"shirt","name":"T-Shirt","keywords":["shirt","tshirt","t","fashion","cloth","casual","tee"],"skins":[{"unified":"1f455","native":"👕"}],"version":1},"jeans":{"id":"jeans","name":"Jeans","keywords":["fashion","shopping"],"skins":[{"unified":"1f456","native":"👖"}],"version":1},"scarf":{"id":"scarf","name":"Scarf","keywords":["neck","winter","clothes"],"skins":[{"unified":"1f9e3","native":"🧣"}],"version":5},"gloves":{"id":"gloves","name":"Gloves","keywords":["hands","winter","clothes"],"skins":[{"unified":"1f9e4","native":"🧤"}],"version":5},"coat":{"id":"coat","name":"Coat","keywords":["jacket"],"skins":[{"unified":"1f9e5","native":"🧥"}],"version":5},"socks":{"id":"socks","name":"Socks","keywords":["stockings","clothes"],"skins":[{"unified":"1f9e6","native":"🧦"}],"version":5},"dress":{"id":"dress","name":"Dress","keywords":["clothes","fashion","shopping"],"skins":[{"unified":"1f457","native":"👗"}],"version":1},"kimono":{"id":"kimono","name":"Kimono","keywords":["dress","fashion","women","female","japanese"],"skins":[{"unified":"1f458","native":"👘"}],"version":1},"sari":{"id":"sari","name":"Sari","keywords":["dress"],"skins":[{"unified":"1f97b","native":"🥻"}],"version":12},"one-piece_swimsuit":{"id":"one-piece_swimsuit","name":"One-Piece Swimsuit","keywords":["one","piece","fashion"],"skins":[{"unified":"1fa71","native":"🩱"}],"version":12},"briefs":{"id":"briefs","name":"Briefs","keywords":["clothing"],"skins":[{"unified":"1fa72","native":"🩲"}],"version":12},"shorts":{"id":"shorts","name":"Shorts","keywords":["clothing"],"skins":[{"unified":"1fa73","native":"🩳"}],"version":12},"bikini":{"id":"bikini","name":"Bikini","keywords":["swimming","female","woman","girl","fashion","beach","summer"],"skins":[{"unified":"1f459","native":"👙"}],"version":1},"womans_clothes":{"id":"womans_clothes","name":"Womans Clothes","keywords":["woman","s","fashion","shopping","bags","female"],"skins":[{"unified":"1f45a","native":"👚"}],"version":1},"folding_hand_fan":{"id":"folding_hand_fan","name":"Folding Hand Fan","keywords":["flamenco","hot"],"skins":[{"unified":"1faad","native":"🪭"}],"version":15},"purse":{"id":"purse","name":"Purse","keywords":["fashion","accessories","money","sales","shopping"],"skins":[{"unified":"1f45b","native":"👛"}],"version":1},"handbag":{"id":"handbag","name":"Handbag","keywords":["fashion","accessory","accessories","shopping"],"skins":[{"unified":"1f45c","native":"👜"}],"version":1},"pouch":{"id":"pouch","name":"Pouch","keywords":["clutch","bag","accessories","shopping"],"skins":[{"unified":"1f45d","native":"👝"}],"version":1},"shopping_bags":{"id":"shopping_bags","name":"Shopping Bags","keywords":["mall","buy","purchase"],"skins":[{"unified":"1f6cd-fe0f","native":"🛍️"}],"version":1},"school_satchel":{"id":"school_satchel","name":"Backpack","keywords":["school","satchel","student","education","bag"],"skins":[{"unified":"1f392","native":"🎒"}],"version":1},"thong_sandal":{"id":"thong_sandal","name":"Thong Sandal","keywords":["footwear","summer"],"skins":[{"unified":"1fa74","native":"🩴"}],"version":13},"mans_shoe":{"id":"mans_shoe","name":"Mans Shoe","keywords":["man","s","fashion","male"],"skins":[{"unified":"1f45e","native":"👞"}],"version":1},"athletic_shoe":{"id":"athletic_shoe","name":"Running Shoe","keywords":["athletic","shoes","sports","sneakers"],"skins":[{"unified":"1f45f","native":"👟"}],"version":1},"hiking_boot":{"id":"hiking_boot","name":"Hiking Boot","keywords":["backpacking","camping"],"skins":[{"unified":"1f97e","native":"🥾"}],"version":11},"womans_flat_shoe":{"id":"womans_flat_shoe","name":"Flat Shoe","keywords":["womans","ballet","slip","on","slipper"],"skins":[{"unified":"1f97f","native":"🥿"}],"version":11},"high_heel":{"id":"high_heel","name":"High-Heeled Shoe","keywords":["high","heel","heeled","fashion","shoes","female","pumps","stiletto"],"skins":[{"unified":"1f460","native":"👠"}],"version":1},"sandal":{"id":"sandal","name":"Womans Sandal","keywords":["woman","s","shoes","fashion","flip","flops"],"skins":[{"unified":"1f461","native":"👡"}],"version":1},"ballet_shoes":{"id":"ballet_shoes","name":"Ballet Shoes","keywords":["dance"],"skins":[{"unified":"1fa70","native":"🩰"}],"version":12},"boot":{"id":"boot","name":"Womans Boots","keywords":["boot","woman","s","shoes","fashion"],"skins":[{"unified":"1f462","native":"👢"}],"version":1},"hair_pick":{"id":"hair_pick","name":"Hair Pick","keywords":["afro","comb"],"skins":[{"unified":"1faae","native":"🪮"}],"version":15},"crown":{"id":"crown","name":"Crown","keywords":["king","kod","leader","royalty","lord"],"skins":[{"unified":"1f451","native":"👑"}],"version":1},"womans_hat":{"id":"womans_hat","name":"Womans Hat","keywords":["woman","s","fashion","accessories","female","lady","spring"],"skins":[{"unified":"1f452","native":"👒"}],"version":1},"tophat":{"id":"tophat","name":"Top Hat","keywords":["tophat","magic","gentleman","classy","circus"],"skins":[{"unified":"1f3a9","native":"🎩"}],"version":1},"mortar_board":{"id":"mortar_board","name":"Graduation Cap","keywords":["mortar","board","school","college","degree","university","hat","legal","learn","education"],"skins":[{"unified":"1f393","native":"🎓"}],"version":1},"billed_cap":{"id":"billed_cap","name":"Billed Cap","keywords":["baseball"],"skins":[{"unified":"1f9e2","native":"🧢"}],"version":5},"military_helmet":{"id":"military_helmet","name":"Military Helmet","keywords":["army","protection"],"skins":[{"unified":"1fa96","native":"🪖"}],"version":13},"helmet_with_white_cross":{"id":"helmet_with_white_cross","name":"Rescue Worker’s Helmet","keywords":["with","white","cross","worker","s","construction","build"],"skins":[{"unified":"26d1-fe0f","native":"⛑️"}],"version":1},"prayer_beads":{"id":"prayer_beads","name":"Prayer Beads","keywords":["dhikr","religious"],"skins":[{"unified":"1f4ff","native":"📿"}],"version":1},"lipstick":{"id":"lipstick","name":"Lipstick","keywords":["female","girl","fashion","woman"],"skins":[{"unified":"1f484","native":"💄"}],"version":1},"ring":{"id":"ring","name":"Ring","keywords":["wedding","propose","marriage","valentines","diamond","fashion","jewelry","gem","engagement"],"skins":[{"unified":"1f48d","native":"💍"}],"version":1},"gem":{"id":"gem","name":"Gem Stone","keywords":["blue","ruby","diamond","jewelry"],"skins":[{"unified":"1f48e","native":"💎"}],"version":1},"mute":{"id":"mute","name":"Muted Speaker","keywords":["mute","sound","volume","silence","quiet"],"skins":[{"unified":"1f507","native":"🔇"}],"version":1},"speaker":{"id":"speaker","name":"Speaker","keywords":["low","volume","sound","silence","broadcast"],"skins":[{"unified":"1f508","native":"🔈"}],"version":1},"sound":{"id":"sound","name":"Speaker Medium Volume","keywords":["sound","broadcast"],"skins":[{"unified":"1f509","native":"🔉"}],"version":1},"loud_sound":{"id":"loud_sound","name":"Speaker High Volume","keywords":["loud","sound","noise","noisy","broadcast"],"skins":[{"unified":"1f50a","native":"🔊"}],"version":1},"loudspeaker":{"id":"loudspeaker","name":"Loudspeaker","keywords":["volume","sound"],"skins":[{"unified":"1f4e2","native":"📢"}],"version":1},"mega":{"id":"mega","name":"Megaphone","keywords":["mega","sound","speaker","volume"],"skins":[{"unified":"1f4e3","native":"📣"}],"version":1},"postal_horn":{"id":"postal_horn","name":"Postal Horn","keywords":["instrument","music"],"skins":[{"unified":"1f4ef","native":"📯"}],"version":1},"bell":{"id":"bell","name":"Bell","keywords":["sound","notification","christmas","xmas","chime"],"skins":[{"unified":"1f514","native":"🔔"}],"version":1},"no_bell":{"id":"no_bell","name":"Bell with Slash","keywords":["no","sound","volume","mute","quiet","silent"],"skins":[{"unified":"1f515","native":"🔕"}],"version":1},"musical_score":{"id":"musical_score","name":"Musical Score","keywords":["treble","clef","compose"],"skins":[{"unified":"1f3bc","native":"🎼"}],"version":1},"musical_note":{"id":"musical_note","name":"Musical Note","keywords":["score","tone","sound"],"skins":[{"unified":"1f3b5","native":"🎵"}],"version":1},"notes":{"id":"notes","name":"Musical Notes","keywords":["music","score"],"skins":[{"unified":"1f3b6","native":"🎶"}],"version":1},"studio_microphone":{"id":"studio_microphone","name":"Studio Microphone","keywords":["sing","recording","artist","talkshow"],"skins":[{"unified":"1f399-fe0f","native":"🎙️"}],"version":1},"level_slider":{"id":"level_slider","name":"Level Slider","keywords":["scale"],"skins":[{"unified":"1f39a-fe0f","native":"🎚️"}],"version":1},"control_knobs":{"id":"control_knobs","name":"Control Knobs","keywords":["dial"],"skins":[{"unified":"1f39b-fe0f","native":"🎛️"}],"version":1},"microphone":{"id":"microphone","name":"Microphone","keywords":["sound","music","PA","sing","talkshow"],"skins":[{"unified":"1f3a4","native":"🎤"}],"version":1},"headphones":{"id":"headphones","name":"Headphone","keywords":["headphones","music","score","gadgets"],"skins":[{"unified":"1f3a7","native":"🎧"}],"version":1},"radio":{"id":"radio","name":"Radio","keywords":["communication","music","podcast","program"],"skins":[{"unified":"1f4fb","native":"📻"}],"version":1},"saxophone":{"id":"saxophone","name":"Saxophone","keywords":["music","instrument","jazz","blues"],"skins":[{"unified":"1f3b7","native":"🎷"}],"version":1},"accordion":{"id":"accordion","name":"Accordion","keywords":["music"],"skins":[{"unified":"1fa97","native":"🪗"}],"version":13},"guitar":{"id":"guitar","name":"Guitar","keywords":["music","instrument"],"skins":[{"unified":"1f3b8","native":"🎸"}],"version":1},"musical_keyboard":{"id":"musical_keyboard","name":"Musical Keyboard","keywords":["piano","instrument","compose"],"skins":[{"unified":"1f3b9","native":"🎹"}],"version":1},"trumpet":{"id":"trumpet","name":"Trumpet","keywords":["music","brass"],"skins":[{"unified":"1f3ba","native":"🎺"}],"version":1},"violin":{"id":"violin","name":"Violin","keywords":["music","instrument","orchestra","symphony"],"skins":[{"unified":"1f3bb","native":"🎻"}],"version":1},"banjo":{"id":"banjo","name":"Banjo","keywords":["music","instructment"],"skins":[{"unified":"1fa95","native":"🪕"}],"version":12},"drum_with_drumsticks":{"id":"drum_with_drumsticks","name":"Drum","keywords":["with","drumsticks","music","instrument","snare"],"skins":[{"unified":"1f941","native":"🥁"}],"version":3},"long_drum":{"id":"long_drum","name":"Long Drum","keywords":["music"],"skins":[{"unified":"1fa98","native":"🪘"}],"version":13},"maracas":{"id":"maracas","name":"Maracas","keywords":["music","instrument","percussion"],"skins":[{"unified":"1fa87","native":"🪇"}],"version":15},"flute":{"id":"flute","name":"Flute","keywords":["bamboo","music","instrument","pied","piper"],"skins":[{"unified":"1fa88","native":"🪈"}],"version":15},"iphone":{"id":"iphone","name":"Mobile Phone","keywords":["iphone","technology","apple","gadgets","dial"],"skins":[{"unified":"1f4f1","native":"📱"}],"version":1},"calling":{"id":"calling","name":"Mobile Phone with Arrow","keywords":["calling","iphone","incoming"],"skins":[{"unified":"1f4f2","native":"📲"}],"version":1},"phone":{"id":"phone","name":"Telephone","keywords":["phone","technology","communication","dial"],"skins":[{"unified":"260e-fe0f","native":"☎️"}],"version":1},"telephone_receiver":{"id":"telephone_receiver","name":"Telephone Receiver","keywords":["technology","communication","dial"],"skins":[{"unified":"1f4de","native":"📞"}],"version":1},"pager":{"id":"pager","name":"Pager","keywords":["bbcall","oldschool","90s"],"skins":[{"unified":"1f4df","native":"📟"}],"version":1},"fax":{"id":"fax","name":"Fax Machine","keywords":["communication","technology"],"skins":[{"unified":"1f4e0","native":"📠"}],"version":1},"battery":{"id":"battery","name":"Battery","keywords":["power","energy","sustain"],"skins":[{"unified":"1f50b","native":"🔋"}],"version":1},"low_battery":{"id":"low_battery","name":"Low Battery","keywords":["drained","dead"],"skins":[{"unified":"1faab","native":"🪫"}],"version":14},"electric_plug":{"id":"electric_plug","name":"Electric Plug","keywords":["charger","power"],"skins":[{"unified":"1f50c","native":"🔌"}],"version":1},"computer":{"id":"computer","name":"Laptop","keywords":["computer","technology","screen","display","monitor"],"skins":[{"unified":"1f4bb","native":"💻"}],"version":1},"desktop_computer":{"id":"desktop_computer","name":"Desktop Computer","keywords":["technology","computing","screen"],"skins":[{"unified":"1f5a5-fe0f","native":"🖥️"}],"version":1},"printer":{"id":"printer","name":"Printer","keywords":["paper","ink"],"skins":[{"unified":"1f5a8-fe0f","native":"🖨️"}],"version":1},"keyboard":{"id":"keyboard","name":"Keyboard","keywords":["technology","computer","type","input","text"],"skins":[{"unified":"2328-fe0f","native":"⌨️"}],"version":1},"three_button_mouse":{"id":"three_button_mouse","name":"Computer Mouse","keywords":["three","button","click"],"skins":[{"unified":"1f5b1-fe0f","native":"🖱️"}],"version":1},"trackball":{"id":"trackball","name":"Trackball","keywords":["technology","trackpad"],"skins":[{"unified":"1f5b2-fe0f","native":"🖲️"}],"version":1},"minidisc":{"id":"minidisc","name":"Minidisc","keywords":["computer","disk","technology","record","data","90s"],"skins":[{"unified":"1f4bd","native":"💽"}],"version":1},"floppy_disk":{"id":"floppy_disk","name":"Floppy Disk","keywords":["oldschool","technology","save","90s","80s"],"skins":[{"unified":"1f4be","native":"💾"}],"version":1},"cd":{"id":"cd","name":"Optical Disc","keywords":["cd","disk","technology","dvd","90s"],"skins":[{"unified":"1f4bf","native":"💿"}],"version":1},"dvd":{"id":"dvd","name":"Dvd","keywords":["cd","disk","disc"],"skins":[{"unified":"1f4c0","native":"📀"}],"version":1},"abacus":{"id":"abacus","name":"Abacus","keywords":["calculation"],"skins":[{"unified":"1f9ee","native":"🧮"}],"version":11},"movie_camera":{"id":"movie_camera","name":"Movie Camera","keywords":["film","record"],"skins":[{"unified":"1f3a5","native":"🎥"}],"version":1},"film_frames":{"id":"film_frames","name":"Film Frames","keywords":["movie"],"skins":[{"unified":"1f39e-fe0f","native":"🎞️"}],"version":1},"film_projector":{"id":"film_projector","name":"Film Projector","keywords":["video","tape","record","movie"],"skins":[{"unified":"1f4fd-fe0f","native":"📽️"}],"version":1},"clapper":{"id":"clapper","name":"Clapper Board","keywords":["movie","film","record"],"skins":[{"unified":"1f3ac","native":"🎬"}],"version":1},"tv":{"id":"tv","name":"Television","keywords":["tv","technology","program","oldschool","show"],"skins":[{"unified":"1f4fa","native":"📺"}],"version":1},"camera":{"id":"camera","name":"Camera","keywords":["gadgets","photography"],"skins":[{"unified":"1f4f7","native":"📷"}],"version":1},"camera_with_flash":{"id":"camera_with_flash","name":"Camera with Flash","keywords":["photography","gadgets"],"skins":[{"unified":"1f4f8","native":"📸"}],"version":1},"video_camera":{"id":"video_camera","name":"Video Camera","keywords":["film","record"],"skins":[{"unified":"1f4f9","native":"📹"}],"version":1},"vhs":{"id":"vhs","name":"Videocassette","keywords":["vhs","record","video","oldschool","90s","80s"],"skins":[{"unified":"1f4fc","native":"📼"}],"version":1},"mag":{"id":"mag","name":"Magnifying Glass Tilted Left","keywords":["mag","search","zoom","find","detective"],"skins":[{"unified":"1f50d","native":"🔍"}],"version":1},"mag_right":{"id":"mag_right","name":"Magnifying Glass Tilted Right","keywords":["mag","search","zoom","find","detective"],"skins":[{"unified":"1f50e","native":"🔎"}],"version":1},"candle":{"id":"candle","name":"Candle","keywords":["fire","wax"],"skins":[{"unified":"1f56f-fe0f","native":"🕯️"}],"version":1},"bulb":{"id":"bulb","name":"Light Bulb","keywords":["electricity","idea"],"skins":[{"unified":"1f4a1","native":"💡"}],"version":1},"flashlight":{"id":"flashlight","name":"Flashlight","keywords":["dark","camping","sight","night"],"skins":[{"unified":"1f526","native":"🔦"}],"version":1},"izakaya_lantern":{"id":"izakaya_lantern","name":"Izakaya Lantern","keywords":["red","paper","light","halloween","spooky"],"skins":[{"unified":"1f3ee","native":"🏮"}],"version":1},"diya_lamp":{"id":"diya_lamp","name":"Diya Lamp","keywords":["lighting"],"skins":[{"unified":"1fa94","native":"🪔"}],"version":12},"notebook_with_decorative_cover":{"id":"notebook_with_decorative_cover","name":"Notebook with Decorative Cover","keywords":["classroom","notes","record","paper","study"],"skins":[{"unified":"1f4d4","native":"📔"}],"version":1},"closed_book":{"id":"closed_book","name":"Closed Book","keywords":["read","library","knowledge","textbook","learn"],"skins":[{"unified":"1f4d5","native":"📕"}],"version":1},"book":{"id":"book","name":"Open Book","keywords":["read","library","knowledge","literature","learn","study"],"skins":[{"unified":"1f4d6","native":"📖"}],"version":1},"green_book":{"id":"green_book","name":"Green Book","keywords":["read","library","knowledge","study"],"skins":[{"unified":"1f4d7","native":"📗"}],"version":1},"blue_book":{"id":"blue_book","name":"Blue Book","keywords":["read","library","knowledge","learn","study"],"skins":[{"unified":"1f4d8","native":"📘"}],"version":1},"orange_book":{"id":"orange_book","name":"Orange Book","keywords":["read","library","knowledge","textbook","study"],"skins":[{"unified":"1f4d9","native":"📙"}],"version":1},"books":{"id":"books","name":"Books","keywords":["literature","library","study"],"skins":[{"unified":"1f4da","native":"📚"}],"version":1},"notebook":{"id":"notebook","name":"Notebook","keywords":["stationery","record","notes","paper","study"],"skins":[{"unified":"1f4d3","native":"📓"}],"version":1},"ledger":{"id":"ledger","name":"Ledger","keywords":["notes","paper"],"skins":[{"unified":"1f4d2","native":"📒"}],"version":1},"page_with_curl":{"id":"page_with_curl","name":"Page with Curl","keywords":["documents","office","paper"],"skins":[{"unified":"1f4c3","native":"📃"}],"version":1},"scroll":{"id":"scroll","name":"Scroll","keywords":["documents","ancient","history","paper"],"skins":[{"unified":"1f4dc","native":"📜"}],"version":1},"page_facing_up":{"id":"page_facing_up","name":"Page Facing Up","keywords":["documents","office","paper","information"],"skins":[{"unified":"1f4c4","native":"📄"}],"version":1},"newspaper":{"id":"newspaper","name":"Newspaper","keywords":["press","headline"],"skins":[{"unified":"1f4f0","native":"📰"}],"version":1},"rolled_up_newspaper":{"id":"rolled_up_newspaper","name":"Rolled-Up Newspaper","keywords":["rolled","up","press","headline"],"skins":[{"unified":"1f5de-fe0f","native":"🗞️"}],"version":1},"bookmark_tabs":{"id":"bookmark_tabs","name":"Bookmark Tabs","keywords":["favorite","save","order","tidy"],"skins":[{"unified":"1f4d1","native":"📑"}],"version":1},"bookmark":{"id":"bookmark","name":"Bookmark","keywords":["favorite","label","save"],"skins":[{"unified":"1f516","native":"🔖"}],"version":1},"label":{"id":"label","name":"Label","keywords":["sale","tag"],"skins":[{"unified":"1f3f7-fe0f","native":"🏷️"}],"version":1},"moneybag":{"id":"moneybag","name":"Money Bag","keywords":["moneybag","dollar","payment","coins","sale"],"skins":[{"unified":"1f4b0","native":"💰"}],"version":1},"coin":{"id":"coin","name":"Coin","keywords":["money","currency"],"skins":[{"unified":"1fa99","native":"🪙"}],"version":13},"yen":{"id":"yen","name":"Yen Banknote","keywords":["money","sales","japanese","dollar","currency"],"skins":[{"unified":"1f4b4","native":"💴"}],"version":1},"dollar":{"id":"dollar","name":"Dollar Banknote","keywords":["money","sales","bill","currency"],"skins":[{"unified":"1f4b5","native":"💵"}],"version":1},"euro":{"id":"euro","name":"Euro Banknote","keywords":["money","sales","dollar","currency"],"skins":[{"unified":"1f4b6","native":"💶"}],"version":1},"pound":{"id":"pound","name":"Pound Banknote","keywords":["british","sterling","money","sales","bills","uk","england","currency"],"skins":[{"unified":"1f4b7","native":"💷"}],"version":1},"money_with_wings":{"id":"money_with_wings","name":"Money with Wings","keywords":["dollar","bills","payment","sale"],"skins":[{"unified":"1f4b8","native":"💸"}],"version":1},"credit_card":{"id":"credit_card","name":"Credit Card","keywords":["money","sales","dollar","bill","payment","shopping"],"skins":[{"unified":"1f4b3","native":"💳"}],"version":1},"receipt":{"id":"receipt","name":"Receipt","keywords":["accounting","expenses"],"skins":[{"unified":"1f9fe","native":"🧾"}],"version":11},"chart":{"id":"chart","name":"Chart Increasing with Yen","keywords":["green","square","graph","presentation","stats"],"skins":[{"unified":"1f4b9","native":"💹"}],"version":1},"email":{"id":"email","name":"Envelope","keywords":["email","letter","postal","inbox","communication"],"skins":[{"unified":"2709-fe0f","native":"✉️"}],"version":1},"e-mail":{"id":"e-mail","name":"E-Mail","keywords":["e","mail","communication","inbox"],"skins":[{"unified":"1f4e7","native":"📧"}],"version":1},"incoming_envelope":{"id":"incoming_envelope","name":"Incoming Envelope","keywords":["email","inbox"],"skins":[{"unified":"1f4e8","native":"📨"}],"version":1},"envelope_with_arrow":{"id":"envelope_with_arrow","name":"Envelope with Arrow","keywords":["email","communication"],"skins":[{"unified":"1f4e9","native":"📩"}],"version":1},"outbox_tray":{"id":"outbox_tray","name":"Outbox Tray","keywords":["inbox","email"],"skins":[{"unified":"1f4e4","native":"📤"}],"version":1},"inbox_tray":{"id":"inbox_tray","name":"Inbox Tray","keywords":["email","documents"],"skins":[{"unified":"1f4e5","native":"📥"}],"version":1},"package":{"id":"package","name":"Package","keywords":["mail","gift","cardboard","box","moving"],"skins":[{"unified":"1f4e6","native":"📦"}],"version":1},"mailbox":{"id":"mailbox","name":"Closed Mailbox with Raised Flag","keywords":["email","inbox","communication"],"skins":[{"unified":"1f4eb","native":"📫"}],"version":1},"mailbox_closed":{"id":"mailbox_closed","name":"Closed Mailbox with Lowered Flag","keywords":["email","communication","inbox"],"skins":[{"unified":"1f4ea","native":"📪"}],"version":1},"mailbox_with_mail":{"id":"mailbox_with_mail","name":"Open Mailbox with Raised Flag","keywords":["mail","email","inbox","communication"],"skins":[{"unified":"1f4ec","native":"📬"}],"version":1},"mailbox_with_no_mail":{"id":"mailbox_with_no_mail","name":"Open Mailbox with Lowered Flag","keywords":["no","mail","email","inbox"],"skins":[{"unified":"1f4ed","native":"📭"}],"version":1},"postbox":{"id":"postbox","name":"Postbox","keywords":["email","letter","envelope"],"skins":[{"unified":"1f4ee","native":"📮"}],"version":1},"ballot_box_with_ballot":{"id":"ballot_box_with_ballot","name":"Ballot Box with Ballot","keywords":["election","vote"],"skins":[{"unified":"1f5f3-fe0f","native":"🗳️"}],"version":1},"pencil2":{"id":"pencil2","name":"Pencil","keywords":["pencil2","stationery","write","paper","writing","school","study"],"skins":[{"unified":"270f-fe0f","native":"✏️"}],"version":1},"black_nib":{"id":"black_nib","name":"Black Nib","keywords":["pen","stationery","writing","write"],"skins":[{"unified":"2712-fe0f","native":"✒️"}],"version":1},"lower_left_fountain_pen":{"id":"lower_left_fountain_pen","name":"Fountain Pen","keywords":["lower","left","stationery","writing","write"],"skins":[{"unified":"1f58b-fe0f","native":"🖋️"}],"version":1},"lower_left_ballpoint_pen":{"id":"lower_left_ballpoint_pen","name":"Pen","keywords":["lower","left","ballpoint","stationery","writing","write"],"skins":[{"unified":"1f58a-fe0f","native":"🖊️"}],"version":1},"lower_left_paintbrush":{"id":"lower_left_paintbrush","name":"Paintbrush","keywords":["lower","left","drawing","creativity","art"],"skins":[{"unified":"1f58c-fe0f","native":"🖌️"}],"version":1},"lower_left_crayon":{"id":"lower_left_crayon","name":"Crayon","keywords":["lower","left","drawing","creativity"],"skins":[{"unified":"1f58d-fe0f","native":"🖍️"}],"version":1},"memo":{"id":"memo","name":"Memo","keywords":["pencil","write","documents","stationery","paper","writing","legal","exam","quiz","test","study","compose"],"skins":[{"unified":"1f4dd","native":"📝"}],"version":1},"briefcase":{"id":"briefcase","name":"Briefcase","keywords":["business","documents","work","law","legal","job","career"],"skins":[{"unified":"1f4bc","native":"💼"}],"version":1},"file_folder":{"id":"file_folder","name":"File Folder","keywords":["documents","business","office"],"skins":[{"unified":"1f4c1","native":"📁"}],"version":1},"open_file_folder":{"id":"open_file_folder","name":"Open File Folder","keywords":["documents","load"],"skins":[{"unified":"1f4c2","native":"📂"}],"version":1},"card_index_dividers":{"id":"card_index_dividers","name":"Card Index Dividers","keywords":["organizing","business","stationery"],"skins":[{"unified":"1f5c2-fe0f","native":"🗂️"}],"version":1},"date":{"id":"date","name":"Calendar","keywords":["date","schedule"],"skins":[{"unified":"1f4c5","native":"📅"}],"version":1},"calendar":{"id":"calendar","name":"Tear-off Calendar","keywords":["tear","off","schedule","date","planning"],"skins":[{"unified":"1f4c6","native":"📆"}],"version":1},"spiral_note_pad":{"id":"spiral_note_pad","name":"Spiral Notepad","keywords":["note","pad","memo","stationery"],"skins":[{"unified":"1f5d2-fe0f","native":"🗒️"}],"version":1},"spiral_calendar_pad":{"id":"spiral_calendar_pad","name":"Spiral Calendar","keywords":["pad","date","schedule","planning"],"skins":[{"unified":"1f5d3-fe0f","native":"🗓️"}],"version":1},"card_index":{"id":"card_index","name":"Card Index","keywords":["business","stationery"],"skins":[{"unified":"1f4c7","native":"📇"}],"version":1},"chart_with_upwards_trend":{"id":"chart_with_upwards_trend","name":"Chart Increasing","keywords":["with","upwards","trend","graph","presentation","stats","recovery","business","economics","money","sales","good","success"],"skins":[{"unified":"1f4c8","native":"📈"}],"version":1},"chart_with_downwards_trend":{"id":"chart_with_downwards_trend","name":"Chart Decreasing","keywords":["with","downwards","trend","graph","presentation","stats","recession","business","economics","money","sales","bad","failure"],"skins":[{"unified":"1f4c9","native":"📉"}],"version":1},"bar_chart":{"id":"bar_chart","name":"Bar Chart","keywords":["graph","presentation","stats"],"skins":[{"unified":"1f4ca","native":"📊"}],"version":1},"clipboard":{"id":"clipboard","name":"Clipboard","keywords":["stationery","documents"],"skins":[{"unified":"1f4cb","native":"📋"}],"version":1},"pushpin":{"id":"pushpin","name":"Pushpin","keywords":["stationery","mark","here"],"skins":[{"unified":"1f4cc","native":"📌"}],"version":1},"round_pushpin":{"id":"round_pushpin","name":"Round Pushpin","keywords":["stationery","location","map","here"],"skins":[{"unified":"1f4cd","native":"📍"}],"version":1},"paperclip":{"id":"paperclip","name":"Paperclip","keywords":["documents","stationery"],"skins":[{"unified":"1f4ce","native":"📎"}],"version":1},"linked_paperclips":{"id":"linked_paperclips","name":"Linked Paperclips","keywords":["documents","stationery"],"skins":[{"unified":"1f587-fe0f","native":"🖇️"}],"version":1},"straight_ruler":{"id":"straight_ruler","name":"Straight Ruler","keywords":["stationery","calculate","length","math","school","drawing","architect","sketch"],"skins":[{"unified":"1f4cf","native":"📏"}],"version":1},"triangular_ruler":{"id":"triangular_ruler","name":"Triangular Ruler","keywords":["stationery","math","architect","sketch"],"skins":[{"unified":"1f4d0","native":"📐"}],"version":1},"scissors":{"id":"scissors","name":"Scissors","keywords":["stationery","cut"],"skins":[{"unified":"2702-fe0f","native":"✂️"}],"version":1},"card_file_box":{"id":"card_file_box","name":"Card File Box","keywords":["business","stationery"],"skins":[{"unified":"1f5c3-fe0f","native":"🗃️"}],"version":1},"file_cabinet":{"id":"file_cabinet","name":"File Cabinet","keywords":["filing","organizing"],"skins":[{"unified":"1f5c4-fe0f","native":"🗄️"}],"version":1},"wastebasket":{"id":"wastebasket","name":"Wastebasket","keywords":["bin","trash","rubbish","garbage","toss"],"skins":[{"unified":"1f5d1-fe0f","native":"🗑️"}],"version":1},"lock":{"id":"lock","name":"Lock","keywords":["locked","security","password","padlock"],"skins":[{"unified":"1f512","native":"🔒"}],"version":1},"unlock":{"id":"unlock","name":"Unlocked","keywords":["unlock","privacy","security"],"skins":[{"unified":"1f513","native":"🔓"}],"version":1},"lock_with_ink_pen":{"id":"lock_with_ink_pen","name":"Locked with Pen","keywords":["lock","ink","security","secret"],"skins":[{"unified":"1f50f","native":"🔏"}],"version":1},"closed_lock_with_key":{"id":"closed_lock_with_key","name":"Locked with Key","keywords":["closed","lock","security","privacy"],"skins":[{"unified":"1f510","native":"🔐"}],"version":1},"key":{"id":"key","name":"Key","keywords":["lock","door","password"],"skins":[{"unified":"1f511","native":"🔑"}],"version":1},"old_key":{"id":"old_key","name":"Old Key","keywords":["lock","door","password"],"skins":[{"unified":"1f5dd-fe0f","native":"🗝️"}],"version":1},"hammer":{"id":"hammer","name":"Hammer","keywords":["tools","build","create"],"skins":[{"unified":"1f528","native":"🔨"}],"version":1},"axe":{"id":"axe","name":"Axe","keywords":["tool","chop","cut"],"skins":[{"unified":"1fa93","native":"🪓"}],"version":12},"pick":{"id":"pick","name":"Pick","keywords":["tools","dig"],"skins":[{"unified":"26cf-fe0f","native":"⛏️"}],"version":1},"hammer_and_pick":{"id":"hammer_and_pick","name":"Hammer and Pick","keywords":["tools","build","create"],"skins":[{"unified":"2692-fe0f","native":"⚒️"}],"version":1},"hammer_and_wrench":{"id":"hammer_and_wrench","name":"Hammer and Wrench","keywords":["tools","build","create"],"skins":[{"unified":"1f6e0-fe0f","native":"🛠️"}],"version":1},"dagger_knife":{"id":"dagger_knife","name":"Dagger","keywords":["knife","weapon"],"skins":[{"unified":"1f5e1-fe0f","native":"🗡️"}],"version":1},"crossed_swords":{"id":"crossed_swords","name":"Crossed Swords","keywords":["weapon"],"skins":[{"unified":"2694-fe0f","native":"⚔️"}],"version":1},"bomb":{"id":"bomb","name":"Bomb","keywords":["boom","explode","explosion","terrorism"],"skins":[{"unified":"1f4a3","native":"💣"}],"version":1},"boomerang":{"id":"boomerang","name":"Boomerang","keywords":["weapon"],"skins":[{"unified":"1fa83","native":"🪃"}],"version":13},"bow_and_arrow":{"id":"bow_and_arrow","name":"Bow and Arrow","keywords":["sports"],"skins":[{"unified":"1f3f9","native":"🏹"}],"version":1},"shield":{"id":"shield","name":"Shield","keywords":["protection","security"],"skins":[{"unified":"1f6e1-fe0f","native":"🛡️"}],"version":1},"carpentry_saw":{"id":"carpentry_saw","name":"Carpentry Saw","keywords":["cut","chop"],"skins":[{"unified":"1fa9a","native":"🪚"}],"version":13},"wrench":{"id":"wrench","name":"Wrench","keywords":["tools","diy","ikea","fix","maintainer"],"skins":[{"unified":"1f527","native":"🔧"}],"version":1},"screwdriver":{"id":"screwdriver","name":"Screwdriver","keywords":["tools"],"skins":[{"unified":"1fa9b","native":"🪛"}],"version":13},"nut_and_bolt":{"id":"nut_and_bolt","name":"Nut and Bolt","keywords":["handy","tools","fix"],"skins":[{"unified":"1f529","native":"🔩"}],"version":1},"gear":{"id":"gear","name":"Gear","keywords":["cog"],"skins":[{"unified":"2699-fe0f","native":"⚙️"}],"version":1},"compression":{"id":"compression","name":"Clamp","keywords":["compression","tool"],"skins":[{"unified":"1f5dc-fe0f","native":"🗜️"}],"version":1},"scales":{"id":"scales","name":"Balance Scale","keywords":["scales","law","fairness","weight"],"skins":[{"unified":"2696-fe0f","native":"⚖️"}],"version":1},"probing_cane":{"id":"probing_cane","name":"White Cane","keywords":["probing","accessibility"],"skins":[{"unified":"1f9af","native":"🦯"}],"version":12},"link":{"id":"link","name":"Link","keywords":["rings","url"],"skins":[{"unified":"1f517","native":"🔗"}],"version":1},"chains":{"id":"chains","name":"Chains","keywords":["lock","arrest"],"skins":[{"unified":"26d3-fe0f","native":"⛓️"}],"version":1},"hook":{"id":"hook","name":"Hook","keywords":["tools"],"skins":[{"unified":"1fa9d","native":"🪝"}],"version":13},"toolbox":{"id":"toolbox","name":"Toolbox","keywords":["tools","diy","fix","maintainer","mechanic"],"skins":[{"unified":"1f9f0","native":"🧰"}],"version":11},"magnet":{"id":"magnet","name":"Magnet","keywords":["attraction","magnetic"],"skins":[{"unified":"1f9f2","native":"🧲"}],"version":11},"ladder":{"id":"ladder","name":"Ladder","keywords":["tools"],"skins":[{"unified":"1fa9c","native":"🪜"}],"version":13},"alembic":{"id":"alembic","name":"Alembic","keywords":["distilling","science","experiment","chemistry"],"skins":[{"unified":"2697-fe0f","native":"⚗️"}],"version":1},"test_tube":{"id":"test_tube","name":"Test Tube","keywords":["chemistry","experiment","lab","science"],"skins":[{"unified":"1f9ea","native":"🧪"}],"version":11},"petri_dish":{"id":"petri_dish","name":"Petri Dish","keywords":["bacteria","biology","culture","lab"],"skins":[{"unified":"1f9eb","native":"🧫"}],"version":11},"dna":{"id":"dna","name":"Dna","keywords":["biologist","genetics","life"],"skins":[{"unified":"1f9ec","native":"🧬"}],"version":11},"microscope":{"id":"microscope","name":"Microscope","keywords":["laboratory","experiment","zoomin","science","study"],"skins":[{"unified":"1f52c","native":"🔬"}],"version":1},"telescope":{"id":"telescope","name":"Telescope","keywords":["stars","space","zoom","science","astronomy"],"skins":[{"unified":"1f52d","native":"🔭"}],"version":1},"satellite_antenna":{"id":"satellite_antenna","name":"Satellite Antenna","keywords":["communication","future","radio","space"],"skins":[{"unified":"1f4e1","native":"📡"}],"version":1},"syringe":{"id":"syringe","name":"Syringe","keywords":["health","hospital","drugs","blood","medicine","needle","doctor","nurse"],"skins":[{"unified":"1f489","native":"💉"}],"version":1},"drop_of_blood":{"id":"drop_of_blood","name":"Drop of Blood","keywords":["period","hurt","harm","wound"],"skins":[{"unified":"1fa78","native":"🩸"}],"version":12},"pill":{"id":"pill","name":"Pill","keywords":["health","medicine","doctor","pharmacy","drug"],"skins":[{"unified":"1f48a","native":"💊"}],"version":1},"adhesive_bandage":{"id":"adhesive_bandage","name":"Adhesive Bandage","keywords":["heal"],"skins":[{"unified":"1fa79","native":"🩹"}],"version":12},"crutch":{"id":"crutch","name":"Crutch","keywords":["accessibility","assist"],"skins":[{"unified":"1fa7c","native":"🩼"}],"version":14},"stethoscope":{"id":"stethoscope","name":"Stethoscope","keywords":["health"],"skins":[{"unified":"1fa7a","native":"🩺"}],"version":12},"x-ray":{"id":"x-ray","name":"X-Ray","keywords":["x","ray","skeleton","medicine"],"skins":[{"unified":"1fa7b","native":"🩻"}],"version":14},"door":{"id":"door","name":"Door","keywords":["house","entry","exit"],"skins":[{"unified":"1f6aa","native":"🚪"}],"version":1},"elevator":{"id":"elevator","name":"Elevator","keywords":["lift"],"skins":[{"unified":"1f6d7","native":"🛗"}],"version":13},"mirror":{"id":"mirror","name":"Mirror","keywords":["reflection"],"skins":[{"unified":"1fa9e","native":"🪞"}],"version":13},"window":{"id":"window","name":"Window","keywords":["scenery"],"skins":[{"unified":"1fa9f","native":"🪟"}],"version":13},"bed":{"id":"bed","name":"Bed","keywords":["sleep","rest"],"skins":[{"unified":"1f6cf-fe0f","native":"🛏️"}],"version":1},"couch_and_lamp":{"id":"couch_and_lamp","name":"Couch and Lamp","keywords":["read","chill"],"skins":[{"unified":"1f6cb-fe0f","native":"🛋️"}],"version":1},"chair":{"id":"chair","name":"Chair","keywords":["sit","furniture"],"skins":[{"unified":"1fa91","native":"🪑"}],"version":12},"toilet":{"id":"toilet","name":"Toilet","keywords":["restroom","wc","washroom","bathroom","potty"],"skins":[{"unified":"1f6bd","native":"🚽"}],"version":1},"plunger":{"id":"plunger","name":"Plunger","keywords":["toilet"],"skins":[{"unified":"1faa0","native":"🪠"}],"version":13},"shower":{"id":"shower","name":"Shower","keywords":["clean","water","bathroom"],"skins":[{"unified":"1f6bf","native":"🚿"}],"version":1},"bathtub":{"id":"bathtub","name":"Bathtub","keywords":["clean","shower","bathroom"],"skins":[{"unified":"1f6c1","native":"🛁"}],"version":1},"mouse_trap":{"id":"mouse_trap","name":"Mouse Trap","keywords":["cheese"],"skins":[{"unified":"1faa4","native":"🪤"}],"version":13},"razor":{"id":"razor","name":"Razor","keywords":["cut"],"skins":[{"unified":"1fa92","native":"🪒"}],"version":12},"lotion_bottle":{"id":"lotion_bottle","name":"Lotion Bottle","keywords":["moisturizer","sunscreen"],"skins":[{"unified":"1f9f4","native":"🧴"}],"version":11},"safety_pin":{"id":"safety_pin","name":"Safety Pin","keywords":["diaper"],"skins":[{"unified":"1f9f7","native":"🧷"}],"version":11},"broom":{"id":"broom","name":"Broom","keywords":["cleaning","sweeping","witch"],"skins":[{"unified":"1f9f9","native":"🧹"}],"version":11},"basket":{"id":"basket","name":"Basket","keywords":["laundry"],"skins":[{"unified":"1f9fa","native":"🧺"}],"version":11},"roll_of_paper":{"id":"roll_of_paper","name":"Roll of Paper","keywords":[],"skins":[{"unified":"1f9fb","native":"🧻"}],"version":11},"bucket":{"id":"bucket","name":"Bucket","keywords":["water","container"],"skins":[{"unified":"1faa3","native":"🪣"}],"version":13},"soap":{"id":"soap","name":"Soap","keywords":["bar","bathing","cleaning","lather"],"skins":[{"unified":"1f9fc","native":"🧼"}],"version":11},"bubbles":{"id":"bubbles","name":"Bubbles","keywords":["soap","fun","carbonation","sparkling"],"skins":[{"unified":"1fae7","native":"🫧"}],"version":14},"toothbrush":{"id":"toothbrush","name":"Toothbrush","keywords":["hygiene","dental"],"skins":[{"unified":"1faa5","native":"🪥"}],"version":13},"sponge":{"id":"sponge","name":"Sponge","keywords":["absorbing","cleaning","porous"],"skins":[{"unified":"1f9fd","native":"🧽"}],"version":11},"fire_extinguisher":{"id":"fire_extinguisher","name":"Fire Extinguisher","keywords":["quench"],"skins":[{"unified":"1f9ef","native":"🧯"}],"version":11},"shopping_trolley":{"id":"shopping_trolley","name":"Shopping Cart","keywords":["trolley"],"skins":[{"unified":"1f6d2","native":"🛒"}],"version":3},"smoking":{"id":"smoking","name":"Cigarette","keywords":["smoking","kills","tobacco","joint","smoke"],"skins":[{"unified":"1f6ac","native":"🚬"}],"version":1},"coffin":{"id":"coffin","name":"Coffin","keywords":["vampire","dead","die","death","rip","graveyard","cemetery","casket","funeral","box"],"skins":[{"unified":"26b0-fe0f","native":"⚰️"}],"version":1},"headstone":{"id":"headstone","name":"Headstone","keywords":["death","rip","grave"],"skins":[{"unified":"1faa6","native":"🪦"}],"version":13},"funeral_urn":{"id":"funeral_urn","name":"Funeral Urn","keywords":["dead","die","death","rip","ashes"],"skins":[{"unified":"26b1-fe0f","native":"⚱️"}],"version":1},"nazar_amulet":{"id":"nazar_amulet","name":"Nazar Amulet","keywords":["bead","charm"],"skins":[{"unified":"1f9ff","native":"🧿"}],"version":11},"hamsa":{"id":"hamsa","name":"Hamsa","keywords":["religion","protection"],"skins":[{"unified":"1faac","native":"🪬"}],"version":14},"moyai":{"id":"moyai","name":"Moai","keywords":["moyai","rock","easter","island"],"skins":[{"unified":"1f5ff","native":"🗿"}],"version":1},"placard":{"id":"placard","name":"Placard","keywords":["announcement"],"skins":[{"unified":"1faa7","native":"🪧"}],"version":13},"identification_card":{"id":"identification_card","name":"Identification Card","keywords":["document"],"skins":[{"unified":"1faaa","native":"🪪"}],"version":14},"atm":{"id":"atm","name":"Atm Sign","keywords":["money","sales","cash","blue","square","payment","bank"],"skins":[{"unified":"1f3e7","native":"🏧"}],"version":1},"put_litter_in_its_place":{"id":"put_litter_in_its_place","name":"Litter in Bin Sign","keywords":["put","its","place","blue","square","human","info"],"skins":[{"unified":"1f6ae","native":"🚮"}],"version":1},"potable_water":{"id":"potable_water","name":"Potable Water","keywords":["blue","square","liquid","restroom","cleaning","faucet"],"skins":[{"unified":"1f6b0","native":"🚰"}],"version":1},"wheelchair":{"id":"wheelchair","name":"Wheelchair Symbol","keywords":["blue","square","disabled","accessibility"],"skins":[{"unified":"267f","native":"♿"}],"version":1},"mens":{"id":"mens","name":"Men’s Room","keywords":["mens","men","s","toilet","restroom","wc","blue","square","gender","male"],"skins":[{"unified":"1f6b9","native":"🚹"}],"version":1},"womens":{"id":"womens","name":"Women’s Room","keywords":["womens","women","s","purple","square","woman","female","toilet","loo","restroom","gender"],"skins":[{"unified":"1f6ba","native":"🚺"}],"version":1},"restroom":{"id":"restroom","name":"Restroom","keywords":["blue","square","toilet","refresh","wc","gender"],"skins":[{"unified":"1f6bb","native":"🚻"}],"version":1},"baby_symbol":{"id":"baby_symbol","name":"Baby Symbol","keywords":["orange","square","child"],"skins":[{"unified":"1f6bc","native":"🚼"}],"version":1},"wc":{"id":"wc","name":"Water Closet","keywords":["wc","toilet","restroom","blue","square"],"skins":[{"unified":"1f6be","native":"🚾"}],"version":1},"passport_control":{"id":"passport_control","name":"Passport Control","keywords":["custom","blue","square"],"skins":[{"unified":"1f6c2","native":"🛂"}],"version":1},"customs":{"id":"customs","name":"Customs","keywords":["passport","border","blue","square"],"skins":[{"unified":"1f6c3","native":"🛃"}],"version":1},"baggage_claim":{"id":"baggage_claim","name":"Baggage Claim","keywords":["blue","square","airport","transport"],"skins":[{"unified":"1f6c4","native":"🛄"}],"version":1},"left_luggage":{"id":"left_luggage","name":"Left Luggage","keywords":["blue","square","travel"],"skins":[{"unified":"1f6c5","native":"🛅"}],"version":1},"warning":{"id":"warning","name":"Warning","keywords":["exclamation","wip","alert","error","problem","issue"],"skins":[{"unified":"26a0-fe0f","native":"⚠️"}],"version":1},"children_crossing":{"id":"children_crossing","name":"Children Crossing","keywords":["school","warning","danger","sign","driving","yellow","diamond"],"skins":[{"unified":"1f6b8","native":"🚸"}],"version":1},"no_entry":{"id":"no_entry","name":"No Entry","keywords":["limit","security","privacy","bad","denied","stop","circle"],"skins":[{"unified":"26d4","native":"⛔"}],"version":1},"no_entry_sign":{"id":"no_entry_sign","name":"Prohibited","keywords":["no","entry","sign","forbid","stop","limit","denied","disallow","circle"],"skins":[{"unified":"1f6ab","native":"🚫"}],"version":1},"no_bicycles":{"id":"no_bicycles","name":"No Bicycles","keywords":["cyclist","prohibited","circle"],"skins":[{"unified":"1f6b3","native":"🚳"}],"version":1},"no_smoking":{"id":"no_smoking","name":"No Smoking","keywords":["cigarette","blue","square","smell","smoke"],"skins":[{"unified":"1f6ad","native":"🚭"}],"version":1},"do_not_litter":{"id":"do_not_litter","name":"No Littering","keywords":["do","not","litter","trash","bin","garbage","circle"],"skins":[{"unified":"1f6af","native":"🚯"}],"version":1},"non-potable_water":{"id":"non-potable_water","name":"Non-Potable Water","keywords":["non","potable","drink","faucet","tap","circle"],"skins":[{"unified":"1f6b1","native":"🚱"}],"version":1},"no_pedestrians":{"id":"no_pedestrians","name":"No Pedestrians","keywords":["rules","crossing","walking","circle"],"skins":[{"unified":"1f6b7","native":"🚷"}],"version":1},"no_mobile_phones":{"id":"no_mobile_phones","name":"No Mobile Phones","keywords":["iphone","mute","circle"],"skins":[{"unified":"1f4f5","native":"📵"}],"version":1},"underage":{"id":"underage","name":"No One Under Eighteen","keywords":["underage","18","drink","pub","night","minor","circle"],"skins":[{"unified":"1f51e","native":"🔞"}],"version":1},"radioactive_sign":{"id":"radioactive_sign","name":"Radioactive","keywords":["sign","nuclear","danger"],"skins":[{"unified":"2622-fe0f","native":"☢️"}],"version":1},"biohazard_sign":{"id":"biohazard_sign","name":"Biohazard","keywords":["sign","danger"],"skins":[{"unified":"2623-fe0f","native":"☣️"}],"version":1},"arrow_up":{"id":"arrow_up","name":"Up Arrow","keywords":["blue","square","continue","top","direction"],"skins":[{"unified":"2b06-fe0f","native":"⬆️"}],"version":1},"arrow_upper_right":{"id":"arrow_upper_right","name":"Up-Right Arrow","keywords":["upper","right","up","blue","square","point","direction","diagonal","northeast"],"skins":[{"unified":"2197-fe0f","native":"↗️"}],"version":1},"arrow_right":{"id":"arrow_right","name":"Right Arrow","keywords":["blue","square","next"],"skins":[{"unified":"27a1-fe0f","native":"➡️"}],"version":1},"arrow_lower_right":{"id":"arrow_lower_right","name":"South East Arrow","keywords":["lower","right","down","blue","square","direction","diagonal","southeast"],"skins":[{"unified":"2198-fe0f","native":"↘️"}],"version":1},"arrow_down":{"id":"arrow_down","name":"Down Arrow","keywords":["blue","square","direction","bottom"],"skins":[{"unified":"2b07-fe0f","native":"⬇️"}],"version":1},"arrow_lower_left":{"id":"arrow_lower_left","name":"Down-Left Arrow","keywords":["lower","left","down","blue","square","direction","diagonal","southwest"],"skins":[{"unified":"2199-fe0f","native":"↙️"}],"version":1},"arrow_left":{"id":"arrow_left","name":"Left Arrow","keywords":["blue","square","previous","back"],"skins":[{"unified":"2b05-fe0f","native":"⬅️"}],"version":1},"arrow_upper_left":{"id":"arrow_upper_left","name":"Up-Left Arrow","keywords":["upper","left","up","blue","square","point","direction","diagonal","northwest"],"skins":[{"unified":"2196-fe0f","native":"↖️"}],"version":1},"arrow_up_down":{"id":"arrow_up_down","name":"Up Down Arrow","keywords":["blue","square","direction","way","vertical"],"skins":[{"unified":"2195-fe0f","native":"↕️"}],"version":1},"left_right_arrow":{"id":"left_right_arrow","name":"Left Right Arrow","keywords":["shape","direction","horizontal","sideways"],"skins":[{"unified":"2194-fe0f","native":"↔️"}],"version":1},"leftwards_arrow_with_hook":{"id":"leftwards_arrow_with_hook","name":"Right Arrow Curving Left","keywords":["leftwards","with","hook","back","return","blue","square","undo","enter"],"skins":[{"unified":"21a9-fe0f","native":"↩️"}],"version":1},"arrow_right_hook":{"id":"arrow_right_hook","name":"Left Arrow Curving Right","keywords":["hook","blue","square","return","rotate","direction"],"skins":[{"unified":"21aa-fe0f","native":"↪️"}],"version":1},"arrow_heading_up":{"id":"arrow_heading_up","name":"Right Arrow Curving Up","keywords":["heading","blue","square","direction","top"],"skins":[{"unified":"2934-fe0f","native":"⤴️"}],"version":1},"arrow_heading_down":{"id":"arrow_heading_down","name":"Right Arrow Curving Down","keywords":["heading","blue","square","direction","bottom"],"skins":[{"unified":"2935-fe0f","native":"⤵️"}],"version":1},"arrows_clockwise":{"id":"arrows_clockwise","name":"Clockwise Vertical Arrows","keywords":["sync","cycle","round","repeat"],"skins":[{"unified":"1f503","native":"🔃"}],"version":1},"arrows_counterclockwise":{"id":"arrows_counterclockwise","name":"Counterclockwise Arrows Button","keywords":["blue","square","sync","cycle"],"skins":[{"unified":"1f504","native":"🔄"}],"version":1},"back":{"id":"back","name":"Back Arrow","keywords":["words","return"],"skins":[{"unified":"1f519","native":"🔙"}],"version":1},"end":{"id":"end","name":"End Arrow","keywords":["words"],"skins":[{"unified":"1f51a","native":"🔚"}],"version":1},"on":{"id":"on","name":"On! Arrow","keywords":["on","words"],"skins":[{"unified":"1f51b","native":"🔛"}],"version":1},"soon":{"id":"soon","name":"Soon Arrow","keywords":["words"],"skins":[{"unified":"1f51c","native":"🔜"}],"version":1},"top":{"id":"top","name":"Top Arrow","keywords":["words","blue","square"],"skins":[{"unified":"1f51d","native":"🔝"}],"version":1},"place_of_worship":{"id":"place_of_worship","name":"Place of Worship","keywords":["religion","church","temple","prayer"],"skins":[{"unified":"1f6d0","native":"🛐"}],"version":1},"atom_symbol":{"id":"atom_symbol","name":"Atom Symbol","keywords":["science","physics","chemistry"],"skins":[{"unified":"269b-fe0f","native":"⚛️"}],"version":1},"om_symbol":{"id":"om_symbol","name":"Om","keywords":["symbol","hinduism","buddhism","sikhism","jainism"],"skins":[{"unified":"1f549-fe0f","native":"🕉️"}],"version":1},"star_of_david":{"id":"star_of_david","name":"Star of David","keywords":["judaism"],"skins":[{"unified":"2721-fe0f","native":"✡️"}],"version":1},"wheel_of_dharma":{"id":"wheel_of_dharma","name":"Wheel of Dharma","keywords":["hinduism","buddhism","sikhism","jainism"],"skins":[{"unified":"2638-fe0f","native":"☸️"}],"version":1},"yin_yang":{"id":"yin_yang","name":"Yin Yang","keywords":["balance"],"skins":[{"unified":"262f-fe0f","native":"☯️"}],"version":1},"latin_cross":{"id":"latin_cross","name":"Latin Cross","keywords":["christianity"],"skins":[{"unified":"271d-fe0f","native":"✝️"}],"version":1},"orthodox_cross":{"id":"orthodox_cross","name":"Orthodox Cross","keywords":["suppedaneum","religion"],"skins":[{"unified":"2626-fe0f","native":"☦️"}],"version":1},"star_and_crescent":{"id":"star_and_crescent","name":"Star and Crescent","keywords":["islam"],"skins":[{"unified":"262a-fe0f","native":"☪️"}],"version":1},"peace_symbol":{"id":"peace_symbol","name":"Peace Symbol","keywords":["hippie"],"skins":[{"unified":"262e-fe0f","native":"☮️"}],"version":1},"menorah_with_nine_branches":{"id":"menorah_with_nine_branches","name":"Menorah","keywords":["with","nine","branches","hanukkah","candles","jewish"],"skins":[{"unified":"1f54e","native":"🕎"}],"version":1},"six_pointed_star":{"id":"six_pointed_star","name":"Dotted Six-Pointed Star","keywords":["six","pointed","purple","square","religion","jewish","hexagram"],"skins":[{"unified":"1f52f","native":"🔯"}],"version":1},"khanda":{"id":"khanda","name":"Khanda","keywords":["Sikhism","religion"],"skins":[{"unified":"1faaf","native":"🪯"}],"version":15},"aries":{"id":"aries","name":"Aries","keywords":["sign","purple","square","zodiac","astrology"],"skins":[{"unified":"2648","native":"♈"}],"version":1},"taurus":{"id":"taurus","name":"Taurus","keywords":["purple","square","sign","zodiac","astrology"],"skins":[{"unified":"2649","native":"♉"}],"version":1},"gemini":{"id":"gemini","name":"Gemini","keywords":["sign","zodiac","purple","square","astrology"],"skins":[{"unified":"264a","native":"♊"}],"version":1},"cancer":{"id":"cancer","name":"Cancer","keywords":["sign","zodiac","purple","square","astrology"],"skins":[{"unified":"264b","native":"♋"}],"version":1},"leo":{"id":"leo","name":"Leo","keywords":["sign","purple","square","zodiac","astrology"],"skins":[{"unified":"264c","native":"♌"}],"version":1},"virgo":{"id":"virgo","name":"Virgo","keywords":["sign","zodiac","purple","square","astrology"],"skins":[{"unified":"264d","native":"♍"}],"version":1},"libra":{"id":"libra","name":"Libra","keywords":["sign","purple","square","zodiac","astrology"],"skins":[{"unified":"264e","native":"♎"}],"version":1},"scorpius":{"id":"scorpius","name":"Scorpio","keywords":["scorpius","sign","zodiac","purple","square","astrology"],"skins":[{"unified":"264f","native":"♏"}],"version":1},"sagittarius":{"id":"sagittarius","name":"Sagittarius","keywords":["sign","zodiac","purple","square","astrology"],"skins":[{"unified":"2650","native":"♐"}],"version":1},"capricorn":{"id":"capricorn","name":"Capricorn","keywords":["sign","zodiac","purple","square","astrology"],"skins":[{"unified":"2651","native":"♑"}],"version":1},"aquarius":{"id":"aquarius","name":"Aquarius","keywords":["sign","purple","square","zodiac","astrology"],"skins":[{"unified":"2652","native":"♒"}],"version":1},"pisces":{"id":"pisces","name":"Pisces","keywords":["purple","square","sign","zodiac","astrology"],"skins":[{"unified":"2653","native":"♓"}],"version":1},"ophiuchus":{"id":"ophiuchus","name":"Ophiuchus","keywords":["sign","purple","square","constellation","astrology"],"skins":[{"unified":"26ce","native":"⛎"}],"version":1},"twisted_rightwards_arrows":{"id":"twisted_rightwards_arrows","name":"Shuffle Tracks Button","keywords":["twisted","rightwards","arrows","blue","square","music","random"],"skins":[{"unified":"1f500","native":"🔀"}],"version":1},"repeat":{"id":"repeat","name":"Repeat Button","keywords":["loop","record"],"skins":[{"unified":"1f501","native":"🔁"}],"version":1},"repeat_one":{"id":"repeat_one","name":"Repeat Single Button","keywords":["one","blue","square","loop"],"skins":[{"unified":"1f502","native":"🔂"}],"version":1},"arrow_forward":{"id":"arrow_forward","name":"Play Button","keywords":["arrow","forward","blue","square","right","direction"],"skins":[{"unified":"25b6-fe0f","native":"▶️"}],"version":1},"fast_forward":{"id":"fast_forward","name":"Fast-Forward Button","keywords":["fast","forward","blue","square","play","speed","continue"],"skins":[{"unified":"23e9","native":"⏩"}],"version":1},"black_right_pointing_double_triangle_with_vertical_bar":{"id":"black_right_pointing_double_triangle_with_vertical_bar","name":"Next Track Button","keywords":["black","right","pointing","double","triangle","with","vertical","bar","forward","blue","square"],"skins":[{"unified":"23ed-fe0f","native":"⏭️"}],"version":1},"black_right_pointing_triangle_with_double_vertical_bar":{"id":"black_right_pointing_triangle_with_double_vertical_bar","name":"Play or Pause Button","keywords":["black","right","pointing","triangle","with","double","vertical","bar","blue","square"],"skins":[{"unified":"23ef-fe0f","native":"⏯️"}],"version":1},"arrow_backward":{"id":"arrow_backward","name":"Reverse Button","keywords":["arrow","backward","blue","square","left","direction"],"skins":[{"unified":"25c0-fe0f","native":"◀️"}],"version":1},"rewind":{"id":"rewind","name":"Fast Reverse Button","keywords":["rewind","play","blue","square"],"skins":[{"unified":"23ea","native":"⏪"}],"version":1},"black_left_pointing_double_triangle_with_vertical_bar":{"id":"black_left_pointing_double_triangle_with_vertical_bar","name":"Last Track Button","keywords":["black","left","pointing","double","triangle","with","vertical","bar","backward"],"skins":[{"unified":"23ee-fe0f","native":"⏮️"}],"version":1},"arrow_up_small":{"id":"arrow_up_small","name":"Upwards Button","keywords":["arrow","up","small","blue","square","triangle","direction","point","forward","top"],"skins":[{"unified":"1f53c","native":"🔼"}],"version":1},"arrow_double_up":{"id":"arrow_double_up","name":"Fast Up Button","keywords":["arrow","double","blue","square","direction","top"],"skins":[{"unified":"23eb","native":"⏫"}],"version":1},"arrow_down_small":{"id":"arrow_down_small","name":"Downwards Button","keywords":["arrow","down","small","blue","square","direction","bottom"],"skins":[{"unified":"1f53d","native":"🔽"}],"version":1},"arrow_double_down":{"id":"arrow_double_down","name":"Fast Down Button","keywords":["arrow","double","blue","square","direction","bottom"],"skins":[{"unified":"23ec","native":"⏬"}],"version":1},"double_vertical_bar":{"id":"double_vertical_bar","name":"Pause Button","keywords":["double","vertical","bar","blue","square"],"skins":[{"unified":"23f8-fe0f","native":"⏸️"}],"version":1},"black_square_for_stop":{"id":"black_square_for_stop","name":"Stop Button","keywords":["black","square","for","blue"],"skins":[{"unified":"23f9-fe0f","native":"⏹️"}],"version":1},"black_circle_for_record":{"id":"black_circle_for_record","name":"Record Button","keywords":["black","circle","for","blue","square"],"skins":[{"unified":"23fa-fe0f","native":"⏺️"}],"version":1},"eject":{"id":"eject","name":"Eject Button","keywords":["blue","square"],"skins":[{"unified":"23cf-fe0f","native":"⏏️"}],"version":1},"cinema":{"id":"cinema","name":"Cinema","keywords":["blue","square","record","film","movie","curtain","stage","theater"],"skins":[{"unified":"1f3a6","native":"🎦"}],"version":1},"low_brightness":{"id":"low_brightness","name":"Dim Button","keywords":["low","brightness","sun","afternoon","warm","summer"],"skins":[{"unified":"1f505","native":"🔅"}],"version":1},"high_brightness":{"id":"high_brightness","name":"Bright Button","keywords":["high","brightness","sun","light"],"skins":[{"unified":"1f506","native":"🔆"}],"version":1},"signal_strength":{"id":"signal_strength","name":"Antenna Bars","keywords":["signal","strength","blue","square","reception","phone","internet","connection","wifi","bluetooth"],"skins":[{"unified":"1f4f6","native":"📶"}],"version":1},"wireless":{"id":"wireless","name":"Wireless","keywords":["wifi","internet","contactless","signal"],"skins":[{"unified":"1f6dc","native":"🛜"}],"version":15},"vibration_mode":{"id":"vibration_mode","name":"Vibration Mode","keywords":["orange","square","phone"],"skins":[{"unified":"1f4f3","native":"📳"}],"version":1},"mobile_phone_off":{"id":"mobile_phone_off","name":"Mobile Phone off","keywords":["mute","orange","square","silence","quiet"],"skins":[{"unified":"1f4f4","native":"📴"}],"version":1},"female_sign":{"id":"female_sign","name":"Female Sign","keywords":["woman","women","lady","girl"],"skins":[{"unified":"2640-fe0f","native":"♀️"}],"version":4},"male_sign":{"id":"male_sign","name":"Male Sign","keywords":["man","boy","men"],"skins":[{"unified":"2642-fe0f","native":"♂️"}],"version":4},"transgender_symbol":{"id":"transgender_symbol","name":"Transgender Symbol","keywords":["lgbtq"],"skins":[{"unified":"26a7-fe0f","native":"⚧️"}],"version":13},"heavy_multiplication_x":{"id":"heavy_multiplication_x","name":"Multiply","keywords":["heavy","multiplication","x","sign","math","calculation"],"skins":[{"unified":"2716-fe0f","native":"✖️"}],"version":1},"heavy_plus_sign":{"id":"heavy_plus_sign","name":"Plus","keywords":["heavy","sign","math","calculation","addition","more","increase"],"skins":[{"unified":"2795","native":"➕"}],"version":1},"heavy_minus_sign":{"id":"heavy_minus_sign","name":"Minus","keywords":["heavy","sign","math","calculation","subtract","less"],"skins":[{"unified":"2796","native":"➖"}],"version":1},"heavy_division_sign":{"id":"heavy_division_sign","name":"Divide","keywords":["heavy","division","sign","math","calculation"],"skins":[{"unified":"2797","native":"➗"}],"version":1},"heavy_equals_sign":{"id":"heavy_equals_sign","name":"Heavy Equals Sign","keywords":["math"],"skins":[{"unified":"1f7f0","native":"🟰"}],"version":14},"infinity":{"id":"infinity","name":"Infinity","keywords":["forever"],"skins":[{"unified":"267e-fe0f","native":"♾️"}],"version":11},"bangbang":{"id":"bangbang","name":"Double Exclamation Mark","keywords":["bangbang","surprise"],"skins":[{"unified":"203c-fe0f","native":"‼️"}],"version":1},"interrobang":{"id":"interrobang","name":"Exclamation Question Mark","keywords":["interrobang","wat","punctuation","surprise"],"skins":[{"unified":"2049-fe0f","native":"⁉️"}],"version":1},"question":{"id":"question","name":"Red Question Mark","keywords":["doubt","confused"],"skins":[{"unified":"2753","native":"❓"}],"version":1},"grey_question":{"id":"grey_question","name":"White Question Mark","keywords":["grey","doubts","gray","huh","confused"],"skins":[{"unified":"2754","native":"❔"}],"version":1},"grey_exclamation":{"id":"grey_exclamation","name":"White Exclamation Mark","keywords":["grey","surprise","punctuation","gray","wow","warning"],"skins":[{"unified":"2755","native":"❕"}],"version":1},"exclamation":{"id":"exclamation","name":"Red Exclamation Mark","keywords":["heavy","danger","surprise","punctuation","wow","warning"],"skins":[{"unified":"2757","native":"❗"}],"version":1},"wavy_dash":{"id":"wavy_dash","name":"Wavy Dash","keywords":["draw","line","moustache","mustache","squiggle","scribble"],"skins":[{"unified":"3030-fe0f","native":"〰️"}],"version":1},"currency_exchange":{"id":"currency_exchange","name":"Currency Exchange","keywords":["money","sales","dollar","travel"],"skins":[{"unified":"1f4b1","native":"💱"}],"version":1},"heavy_dollar_sign":{"id":"heavy_dollar_sign","name":"Heavy Dollar Sign","keywords":["money","sales","payment","currency","buck"],"skins":[{"unified":"1f4b2","native":"💲"}],"version":1},"medical_symbol":{"id":"medical_symbol","name":"Medical Symbol","keywords":["staff","of","aesculapius","health","hospital"],"skins":[{"unified":"2695-fe0f","native":"⚕️"}],"version":4},"recycle":{"id":"recycle","name":"Recycling Symbol","keywords":["recycle","arrow","environment","garbage","trash"],"skins":[{"unified":"267b-fe0f","native":"♻️"}],"version":1},"fleur_de_lis":{"id":"fleur_de_lis","name":"Fleur-De-Lis","keywords":["fleur","de","lis","decorative","scout"],"skins":[{"unified":"269c-fe0f","native":"⚜️"}],"version":1},"trident":{"id":"trident","name":"Trident Emblem","keywords":["weapon","spear"],"skins":[{"unified":"1f531","native":"🔱"}],"version":1},"name_badge":{"id":"name_badge","name":"Name Badge","keywords":["fire","forbid"],"skins":[{"unified":"1f4db","native":"📛"}],"version":1},"beginner":{"id":"beginner","name":"Japanese Symbol for Beginner","keywords":["badge","shield"],"skins":[{"unified":"1f530","native":"🔰"}],"version":1},"o":{"id":"o","name":"Hollow Red Circle","keywords":["o","round"],"skins":[{"unified":"2b55","native":"⭕"}],"version":1},"white_check_mark":{"id":"white_check_mark","name":"Check Mark Button","keywords":["white","green","square","ok","agree","vote","election","answer","tick"],"skins":[{"unified":"2705","native":"✅"}],"version":1},"ballot_box_with_check":{"id":"ballot_box_with_check","name":"Check Box with Check","keywords":["ballot","ok","agree","confirm","black","square","vote","election","yes","tick"],"skins":[{"unified":"2611-fe0f","native":"☑️"}],"version":1},"heavy_check_mark":{"id":"heavy_check_mark","name":"Check Mark","keywords":["heavy","ok","nike","answer","yes","tick"],"skins":[{"unified":"2714-fe0f","native":"✔️"}],"version":1},"x":{"id":"x","name":"Cross Mark","keywords":["x","no","delete","remove","cancel","red"],"skins":[{"unified":"274c","native":"❌"}],"version":1},"negative_squared_cross_mark":{"id":"negative_squared_cross_mark","name":"Cross Mark Button","keywords":["negative","squared","x","green","square","no","deny"],"skins":[{"unified":"274e","native":"❎"}],"version":1},"curly_loop":{"id":"curly_loop","name":"Curly Loop","keywords":["scribble","draw","shape","squiggle"],"skins":[{"unified":"27b0","native":"➰"}],"version":1},"loop":{"id":"loop","name":"Double Curly Loop","keywords":["tape","cassette"],"skins":[{"unified":"27bf","native":"➿"}],"version":1},"part_alternation_mark":{"id":"part_alternation_mark","name":"Part Alternation Mark","keywords":["graph","presentation","stats","business","economics","bad"],"skins":[{"unified":"303d-fe0f","native":"〽️"}],"version":1},"eight_spoked_asterisk":{"id":"eight_spoked_asterisk","name":"Eight Spoked Asterisk","keywords":["star","sparkle","green","square"],"skins":[{"unified":"2733-fe0f","native":"✳️"}],"version":1},"eight_pointed_black_star":{"id":"eight_pointed_black_star","name":"Eight-Pointed Star","keywords":["eight","pointed","black","orange","square","shape","polygon"],"skins":[{"unified":"2734-fe0f","native":"✴️"}],"version":1},"sparkle":{"id":"sparkle","name":"Sparkle","keywords":["stars","green","square","awesome","good","fireworks"],"skins":[{"unified":"2747-fe0f","native":"❇️"}],"version":1},"copyright":{"id":"copyright","name":"Copyright","keywords":["ip","license","circle","law","legal"],"skins":[{"unified":"00a9-fe0f","native":"©️"}],"version":1},"registered":{"id":"registered","name":"Registered","keywords":["alphabet","circle"],"skins":[{"unified":"00ae-fe0f","native":"®️"}],"version":1},"tm":{"id":"tm","name":"Trade Mark","keywords":["tm","trademark","brand","law","legal"],"skins":[{"unified":"2122-fe0f","native":"™️"}],"version":1},"hash":{"id":"hash","name":"Hash Key","keywords":["keycap","","symbol","blue","square","twitter"],"skins":[{"unified":"0023-fe0f-20e3","native":"#️⃣"}],"version":1},"keycap_star":{"id":"keycap_star","name":"Keycap: *","keywords":["keycap","star",""],"skins":[{"unified":"002a-fe0f-20e3","native":"*️⃣"}],"version":2},"zero":{"id":"zero","name":"Keycap 0","keywords":["zero","numbers","blue","square","null"],"skins":[{"unified":"0030-fe0f-20e3","native":"0️⃣"}],"version":1},"one":{"id":"one","name":"Keycap 1","keywords":["one","blue","square","numbers"],"skins":[{"unified":"0031-fe0f-20e3","native":"1️⃣"}],"version":1},"two":{"id":"two","name":"Keycap 2","keywords":["two","numbers","prime","blue","square"],"skins":[{"unified":"0032-fe0f-20e3","native":"2️⃣"}],"version":1},"three":{"id":"three","name":"Keycap 3","keywords":["three","numbers","prime","blue","square"],"skins":[{"unified":"0033-fe0f-20e3","native":"3️⃣"}],"version":1},"four":{"id":"four","name":"Keycap 4","keywords":["four","numbers","blue","square"],"skins":[{"unified":"0034-fe0f-20e3","native":"4️⃣"}],"version":1},"five":{"id":"five","name":"Keycap 5","keywords":["five","numbers","blue","square","prime"],"skins":[{"unified":"0035-fe0f-20e3","native":"5️⃣"}],"version":1},"six":{"id":"six","name":"Keycap 6","keywords":["six","numbers","blue","square"],"skins":[{"unified":"0036-fe0f-20e3","native":"6️⃣"}],"version":1},"seven":{"id":"seven","name":"Keycap 7","keywords":["seven","numbers","blue","square","prime"],"skins":[{"unified":"0037-fe0f-20e3","native":"7️⃣"}],"version":1},"eight":{"id":"eight","name":"Keycap 8","keywords":["eight","blue","square","numbers"],"skins":[{"unified":"0038-fe0f-20e3","native":"8️⃣"}],"version":1},"nine":{"id":"nine","name":"Keycap 9","keywords":["nine","blue","square","numbers"],"skins":[{"unified":"0039-fe0f-20e3","native":"9️⃣"}],"version":1},"keycap_ten":{"id":"keycap_ten","name":"Keycap 10","keywords":["ten","numbers","blue","square"],"skins":[{"unified":"1f51f","native":"🔟"}],"version":1},"capital_abcd":{"id":"capital_abcd","name":"Input Latin Uppercase","keywords":["capital","abcd","alphabet","words","blue","square"],"skins":[{"unified":"1f520","native":"🔠"}],"version":1},"abcd":{"id":"abcd","name":"Input Latin Lowercase","keywords":["abcd","blue","square","alphabet"],"skins":[{"unified":"1f521","native":"🔡"}],"version":1},"symbols":{"id":"symbols","name":"Input Symbols","keywords":["blue","square","music","note","ampersand","percent","glyphs","characters"],"skins":[{"unified":"1f523","native":"🔣"}],"version":1},"abc":{"id":"abc","name":"Input Latin Letters","keywords":["abc","blue","square","alphabet"],"skins":[{"unified":"1f524","native":"🔤"}],"version":1},"a":{"id":"a","name":"A Button (blood Type)","keywords":["red","square","alphabet","letter"],"skins":[{"unified":"1f170-fe0f","native":"🅰️"}],"version":1},"ab":{"id":"ab","name":"Negative Squared Ab","keywords":["button","red","square","alphabet"],"skins":[{"unified":"1f18e","native":"🆎"}],"version":1},"b":{"id":"b","name":"B Button (blood Type)","keywords":["red","square","alphabet","letter"],"skins":[{"unified":"1f171-fe0f","native":"🅱️"}],"version":1},"cl":{"id":"cl","name":"Cl Button","keywords":["alphabet","words","red","square"],"skins":[{"unified":"1f191","native":"🆑"}],"version":1},"cool":{"id":"cool","name":"Cool Button","keywords":["words","blue","square"],"skins":[{"unified":"1f192","native":"🆒"}],"version":1},"free":{"id":"free","name":"Free Button","keywords":["blue","square","words"],"skins":[{"unified":"1f193","native":"🆓"}],"version":1},"information_source":{"id":"information_source","name":"Information","keywords":["source","blue","square","alphabet","letter"],"skins":[{"unified":"2139-fe0f","native":"ℹ️"}],"version":1},"id":{"id":"id","name":"Id Button","keywords":["purple","square","words"],"skins":[{"unified":"1f194","native":"🆔"}],"version":1},"m":{"id":"m","name":"Circled M","keywords":["alphabet","blue","circle","letter"],"skins":[{"unified":"24c2-fe0f","native":"Ⓜ️"}],"version":1},"new":{"id":"new","name":"New Button","keywords":["blue","square","words","start"],"skins":[{"unified":"1f195","native":"🆕"}],"version":1},"ng":{"id":"ng","name":"Ng Button","keywords":["blue","square","words","shape","icon"],"skins":[{"unified":"1f196","native":"🆖"}],"version":1},"o2":{"id":"o2","name":"O Button (blood Type)","keywords":["o2","alphabet","red","square","letter"],"skins":[{"unified":"1f17e-fe0f","native":"🅾️"}],"version":1},"ok":{"id":"ok","name":"Ok Button","keywords":["good","agree","yes","blue","square"],"skins":[{"unified":"1f197","native":"🆗"}],"version":1},"parking":{"id":"parking","name":"P Button","keywords":["parking","cars","blue","square","alphabet","letter"],"skins":[{"unified":"1f17f-fe0f","native":"🅿️"}],"version":1},"sos":{"id":"sos","name":"Sos Button","keywords":["help","red","square","words","emergency","911"],"skins":[{"unified":"1f198","native":"🆘"}],"version":1},"up":{"id":"up","name":"Up! Button","keywords":["up","blue","square","above","high"],"skins":[{"unified":"1f199","native":"🆙"}],"version":1},"vs":{"id":"vs","name":"Vs Button","keywords":["words","orange","square"],"skins":[{"unified":"1f19a","native":"🆚"}],"version":1},"koko":{"id":"koko","name":"Squared Katakana Koko","keywords":["japanese","here","button","blue","square","destination"],"skins":[{"unified":"1f201","native":"🈁"}],"version":1},"sa":{"id":"sa","name":"Squared Katakana Sa","keywords":["japanese","service","charge","button","blue","square"],"skins":[{"unified":"1f202-fe0f","native":"🈂️"}],"version":1},"u6708":{"id":"u6708","name":"Japanese “monthly Amount” Button","keywords":["u6708","monthly","amount","chinese","month","moon","orange","square","kanji"],"skins":[{"unified":"1f237-fe0f","native":"🈷️"}],"version":1},"u6709":{"id":"u6709","name":"Squared Cjk Unified Ideograph-6709","keywords":["u6709","japanese","not","free","of","charge","button","orange","square","chinese","have","kanji"],"skins":[{"unified":"1f236","native":"🈶"}],"version":1},"u6307":{"id":"u6307","name":"Japanese “reserved” Button","keywords":["u6307","reserved","chinese","point","green","square","kanji"],"skins":[{"unified":"1f22f","native":"🈯"}],"version":1},"ideograph_advantage":{"id":"ideograph_advantage","name":"Japanese “bargain” Button","keywords":["ideograph","advantage","bargain","chinese","kanji","obtain","get","circle"],"skins":[{"unified":"1f250","native":"🉐"}],"version":1},"u5272":{"id":"u5272","name":"Japanese “discount” Button","keywords":["u5272","discount","cut","divide","chinese","kanji","pink","square"],"skins":[{"unified":"1f239","native":"🈹"}],"version":1},"u7121":{"id":"u7121","name":"Japanese “free of Charge” Button","keywords":["u7121","free","charge","nothing","chinese","kanji","orange","square"],"skins":[{"unified":"1f21a","native":"🈚"}],"version":1},"u7981":{"id":"u7981","name":"Japanese “prohibited” Button","keywords":["u7981","prohibited","kanji","chinese","forbidden","limit","restricted","red","square"],"skins":[{"unified":"1f232","native":"🈲"}],"version":1},"accept":{"id":"accept","name":"Circled Ideograph Accept","keywords":["japanese","acceptable","button","ok","good","chinese","kanji","agree","yes","orange","circle"],"skins":[{"unified":"1f251","native":"🉑"}],"version":1},"u7533":{"id":"u7533","name":"Japanese “application” Button","keywords":["u7533","application","chinese","kanji","orange","square"],"skins":[{"unified":"1f238","native":"🈸"}],"version":1},"u5408":{"id":"u5408","name":"Japanese “passing Grade” Button","keywords":["u5408","passing","grade","chinese","join","kanji","red","square"],"skins":[{"unified":"1f234","native":"🈴"}],"version":1},"u7a7a":{"id":"u7a7a","name":"Japanese “vacancy” Button","keywords":["u7a7a","vacancy","kanji","chinese","empty","sky","blue","square"],"skins":[{"unified":"1f233","native":"🈳"}],"version":1},"congratulations":{"id":"congratulations","name":"Circled Ideograph Congratulation","keywords":["congratulations","japanese","button","chinese","kanji","red","circle"],"skins":[{"unified":"3297-fe0f","native":"㊗️"}],"version":1},"secret":{"id":"secret","name":"Circled Ideograph Secret","keywords":["japanese","button","privacy","chinese","sshh","kanji","red","circle"],"skins":[{"unified":"3299-fe0f","native":"㊙️"}],"version":1},"u55b6":{"id":"u55b6","name":"Squared Cjk Unified Ideograph-55b6","keywords":["u55b6","japanese","open","for","business","button","opening","hours","orange","square"],"skins":[{"unified":"1f23a","native":"🈺"}],"version":1},"u6e80":{"id":"u6e80","name":"Japanese “no Vacancy” Button","keywords":["u6e80","no","vacancy","full","chinese","red","square","kanji"],"skins":[{"unified":"1f235","native":"🈵"}],"version":1},"red_circle":{"id":"red_circle","name":"Red Circle","keywords":["shape","error","danger"],"skins":[{"unified":"1f534","native":"🔴"}],"version":1},"large_orange_circle":{"id":"large_orange_circle","name":"Orange Circle","keywords":["large","round"],"skins":[{"unified":"1f7e0","native":"🟠"}],"version":12},"large_yellow_circle":{"id":"large_yellow_circle","name":"Yellow Circle","keywords":["large","round"],"skins":[{"unified":"1f7e1","native":"🟡"}],"version":12},"large_green_circle":{"id":"large_green_circle","name":"Green Circle","keywords":["large","round"],"skins":[{"unified":"1f7e2","native":"🟢"}],"version":12},"large_blue_circle":{"id":"large_blue_circle","name":"Blue Circle","keywords":["large","shape","icon","button"],"skins":[{"unified":"1f535","native":"🔵"}],"version":1},"large_purple_circle":{"id":"large_purple_circle","name":"Purple Circle","keywords":["large","round"],"skins":[{"unified":"1f7e3","native":"🟣"}],"version":12},"large_brown_circle":{"id":"large_brown_circle","name":"Brown Circle","keywords":["large","round"],"skins":[{"unified":"1f7e4","native":"🟤"}],"version":12},"black_circle":{"id":"black_circle","name":"Black Circle","keywords":["shape","button","round"],"skins":[{"unified":"26ab","native":"⚫"}],"version":1},"white_circle":{"id":"white_circle","name":"White Circle","keywords":["shape","round"],"skins":[{"unified":"26aa","native":"⚪"}],"version":1},"large_red_square":{"id":"large_red_square","name":"Red Square","keywords":["large"],"skins":[{"unified":"1f7e5","native":"🟥"}],"version":12},"large_orange_square":{"id":"large_orange_square","name":"Orange Square","keywords":["large"],"skins":[{"unified":"1f7e7","native":"🟧"}],"version":12},"large_yellow_square":{"id":"large_yellow_square","name":"Yellow Square","keywords":["large"],"skins":[{"unified":"1f7e8","native":"🟨"}],"version":12},"large_green_square":{"id":"large_green_square","name":"Green Square","keywords":["large"],"skins":[{"unified":"1f7e9","native":"🟩"}],"version":12},"large_blue_square":{"id":"large_blue_square","name":"Blue Square","keywords":["large"],"skins":[{"unified":"1f7e6","native":"🟦"}],"version":12},"large_purple_square":{"id":"large_purple_square","name":"Purple Square","keywords":["large"],"skins":[{"unified":"1f7ea","native":"🟪"}],"version":12},"large_brown_square":{"id":"large_brown_square","name":"Brown Square","keywords":["large"],"skins":[{"unified":"1f7eb","native":"🟫"}],"version":12},"black_large_square":{"id":"black_large_square","name":"Black Large Square","keywords":["shape","icon","button"],"skins":[{"unified":"2b1b","native":"⬛"}],"version":1},"white_large_square":{"id":"white_large_square","name":"White Large Square","keywords":["shape","icon","stone","button"],"skins":[{"unified":"2b1c","native":"⬜"}],"version":1},"black_medium_square":{"id":"black_medium_square","name":"Black Medium Square","keywords":["shape","button","icon"],"skins":[{"unified":"25fc-fe0f","native":"◼️"}],"version":1},"white_medium_square":{"id":"white_medium_square","name":"White Medium Square","keywords":["shape","stone","icon"],"skins":[{"unified":"25fb-fe0f","native":"◻️"}],"version":1},"black_medium_small_square":{"id":"black_medium_small_square","name":"Black Medium Small Square","keywords":["icon","shape","button"],"skins":[{"unified":"25fe","native":"◾"}],"version":1},"white_medium_small_square":{"id":"white_medium_small_square","name":"White Medium Small Square","keywords":["shape","stone","icon","button"],"skins":[{"unified":"25fd","native":"◽"}],"version":1},"black_small_square":{"id":"black_small_square","name":"Black Small Square","keywords":["shape","icon"],"skins":[{"unified":"25aa-fe0f","native":"▪️"}],"version":1},"white_small_square":{"id":"white_small_square","name":"White Small Square","keywords":["shape","icon"],"skins":[{"unified":"25ab-fe0f","native":"▫️"}],"version":1},"large_orange_diamond":{"id":"large_orange_diamond","name":"Large Orange Diamond","keywords":["shape","jewel","gem"],"skins":[{"unified":"1f536","native":"🔶"}],"version":1},"large_blue_diamond":{"id":"large_blue_diamond","name":"Large Blue Diamond","keywords":["shape","jewel","gem"],"skins":[{"unified":"1f537","native":"🔷"}],"version":1},"small_orange_diamond":{"id":"small_orange_diamond","name":"Small Orange Diamond","keywords":["shape","jewel","gem"],"skins":[{"unified":"1f538","native":"🔸"}],"version":1},"small_blue_diamond":{"id":"small_blue_diamond","name":"Small Blue Diamond","keywords":["shape","jewel","gem"],"skins":[{"unified":"1f539","native":"🔹"}],"version":1},"small_red_triangle":{"id":"small_red_triangle","name":"Red Triangle Pointed Up","keywords":["small","shape","direction","top"],"skins":[{"unified":"1f53a","native":"🔺"}],"version":1},"small_red_triangle_down":{"id":"small_red_triangle_down","name":"Red Triangle Pointed Down","keywords":["small","shape","direction","bottom"],"skins":[{"unified":"1f53b","native":"🔻"}],"version":1},"diamond_shape_with_a_dot_inside":{"id":"diamond_shape_with_a_dot_inside","name":"Diamond with a Dot","keywords":["shape","inside","jewel","blue","gem","crystal","fancy"],"skins":[{"unified":"1f4a0","native":"💠"}],"version":1},"radio_button":{"id":"radio_button","name":"Radio Button","keywords":["input","old","music","circle"],"skins":[{"unified":"1f518","native":"🔘"}],"version":1},"white_square_button":{"id":"white_square_button","name":"White Square Button","keywords":["shape","input"],"skins":[{"unified":"1f533","native":"🔳"}],"version":1},"black_square_button":{"id":"black_square_button","name":"Black Square Button","keywords":["shape","input","frame"],"skins":[{"unified":"1f532","native":"🔲"}],"version":1},"checkered_flag":{"id":"checkered_flag","name":"Chequered Flag","keywords":["checkered","contest","finishline","race","gokart"],"skins":[{"unified":"1f3c1","native":"🏁"}],"version":1},"triangular_flag_on_post":{"id":"triangular_flag_on_post","name":"Triangular Flag","keywords":["on","post","mark","milestone","place"],"skins":[{"unified":"1f6a9","native":"🚩"}],"version":1},"crossed_flags":{"id":"crossed_flags","name":"Crossed Flags","keywords":["japanese","nation","country","border"],"skins":[{"unified":"1f38c","native":"🎌"}],"version":1},"waving_black_flag":{"id":"waving_black_flag","name":"Black Flag","keywords":["waving","pirate"],"skins":[{"unified":"1f3f4","native":"🏴"}],"version":1},"waving_white_flag":{"id":"waving_white_flag","name":"White Flag","keywords":["waving","losing","loser","lost","surrender","give","up","fail"],"skins":[{"unified":"1f3f3-fe0f","native":"🏳️"}],"version":1},"rainbow-flag":{"id":"rainbow-flag","name":"Rainbow Flag","keywords":["pride","gay","lgbt","glbt","queer","homosexual","lesbian","bisexual","transgender"],"skins":[{"unified":"1f3f3-fe0f-200d-1f308","native":"🏳️🌈"}],"version":4},"transgender_flag":{"id":"transgender_flag","name":"Transgender Flag","keywords":["lgbtq"],"skins":[{"unified":"1f3f3-fe0f-200d-26a7-fe0f","native":"🏳️⚧️"}],"version":13},"pirate_flag":{"id":"pirate_flag","name":"Pirate Flag","keywords":["skull","crossbones","banner"],"skins":[{"unified":"1f3f4-200d-2620-fe0f","native":"🏴☠️"}],"version":11},"flag-ac":{"id":"flag-ac","name":"Ascension Island Flag","keywords":["ac"],"skins":[{"unified":"1f1e6-1f1e8","native":"🇦🇨"}],"version":2},"flag-ad":{"id":"flag-ad","name":"Andorra Flag","keywords":["ad","nation","country","banner"],"skins":[{"unified":"1f1e6-1f1e9","native":"🇦🇩"}],"version":2},"flag-ae":{"id":"flag-ae","name":"United Arab Emirates Flag","keywords":["ae","nation","country","banner"],"skins":[{"unified":"1f1e6-1f1ea","native":"🇦🇪"}],"version":2},"flag-af":{"id":"flag-af","name":"Afghanistan Flag","keywords":["af","nation","country","banner"],"skins":[{"unified":"1f1e6-1f1eb","native":"🇦🇫"}],"version":2},"flag-ag":{"id":"flag-ag","name":"Antigua & Barbuda Flag","keywords":["ag","nation","country","banner"],"skins":[{"unified":"1f1e6-1f1ec","native":"🇦🇬"}],"version":2},"flag-ai":{"id":"flag-ai","name":"Anguilla Flag","keywords":["ai","nation","country","banner"],"skins":[{"unified":"1f1e6-1f1ee","native":"🇦🇮"}],"version":2},"flag-al":{"id":"flag-al","name":"Albania Flag","keywords":["al","nation","country","banner"],"skins":[{"unified":"1f1e6-1f1f1","native":"🇦🇱"}],"version":2},"flag-am":{"id":"flag-am","name":"Armenia Flag","keywords":["am","nation","country","banner"],"skins":[{"unified":"1f1e6-1f1f2","native":"🇦🇲"}],"version":2},"flag-ao":{"id":"flag-ao","name":"Angola Flag","keywords":["ao","nation","country","banner"],"skins":[{"unified":"1f1e6-1f1f4","native":"🇦🇴"}],"version":2},"flag-aq":{"id":"flag-aq","name":"Antarctica Flag","keywords":["aq","nation","country","banner"],"skins":[{"unified":"1f1e6-1f1f6","native":"🇦🇶"}],"version":2},"flag-ar":{"id":"flag-ar","name":"Argentina Flag","keywords":["ar","nation","country","banner"],"skins":[{"unified":"1f1e6-1f1f7","native":"🇦🇷"}],"version":2},"flag-as":{"id":"flag-as","name":"American Samoa Flag","keywords":["as","ws","nation","country","banner"],"skins":[{"unified":"1f1e6-1f1f8","native":"🇦🇸"}],"version":2},"flag-at":{"id":"flag-at","name":"Austria Flag","keywords":["at","nation","country","banner"],"skins":[{"unified":"1f1e6-1f1f9","native":"🇦🇹"}],"version":2},"flag-au":{"id":"flag-au","name":"Australia Flag","keywords":["au","nation","country","banner"],"skins":[{"unified":"1f1e6-1f1fa","native":"🇦🇺"}],"version":2},"flag-aw":{"id":"flag-aw","name":"Aruba Flag","keywords":["aw","nation","country","banner"],"skins":[{"unified":"1f1e6-1f1fc","native":"🇦🇼"}],"version":2},"flag-ax":{"id":"flag-ax","name":"Åland Islands Flag","keywords":["ax","aland","Aland","nation","country","banner"],"skins":[{"unified":"1f1e6-1f1fd","native":"🇦🇽"}],"version":2},"flag-az":{"id":"flag-az","name":"Azerbaijan Flag","keywords":["az","nation","country","banner"],"skins":[{"unified":"1f1e6-1f1ff","native":"🇦🇿"}],"version":2},"flag-ba":{"id":"flag-ba","name":"Bosnia & Herzegovina Flag","keywords":["ba","nation","country","banner"],"skins":[{"unified":"1f1e7-1f1e6","native":"🇧🇦"}],"version":2},"flag-bb":{"id":"flag-bb","name":"Barbados Flag","keywords":["bb","nation","country","banner"],"skins":[{"unified":"1f1e7-1f1e7","native":"🇧🇧"}],"version":2},"flag-bd":{"id":"flag-bd","name":"Bangladesh Flag","keywords":["bd","nation","country","banner"],"skins":[{"unified":"1f1e7-1f1e9","native":"🇧🇩"}],"version":2},"flag-be":{"id":"flag-be","name":"Belgium Flag","keywords":["be","nation","country","banner"],"skins":[{"unified":"1f1e7-1f1ea","native":"🇧🇪"}],"version":2},"flag-bf":{"id":"flag-bf","name":"Burkina Faso Flag","keywords":["bf","nation","country","banner"],"skins":[{"unified":"1f1e7-1f1eb","native":"🇧🇫"}],"version":2},"flag-bg":{"id":"flag-bg","name":"Bulgaria Flag","keywords":["bg","nation","country","banner"],"skins":[{"unified":"1f1e7-1f1ec","native":"🇧🇬"}],"version":2},"flag-bh":{"id":"flag-bh","name":"Bahrain Flag","keywords":["bh","nation","country","banner"],"skins":[{"unified":"1f1e7-1f1ed","native":"🇧🇭"}],"version":2},"flag-bi":{"id":"flag-bi","name":"Burundi Flag","keywords":["bi","nation","country","banner"],"skins":[{"unified":"1f1e7-1f1ee","native":"🇧🇮"}],"version":2},"flag-bj":{"id":"flag-bj","name":"Benin Flag","keywords":["bj","nation","country","banner"],"skins":[{"unified":"1f1e7-1f1ef","native":"🇧🇯"}],"version":2},"flag-bl":{"id":"flag-bl","name":"St. Barthélemy Flag","keywords":["bl","st","barthelemy","saint","nation","country","banner"],"skins":[{"unified":"1f1e7-1f1f1","native":"🇧🇱"}],"version":2},"flag-bm":{"id":"flag-bm","name":"Bermuda Flag","keywords":["bm","nation","country","banner"],"skins":[{"unified":"1f1e7-1f1f2","native":"🇧🇲"}],"version":2},"flag-bn":{"id":"flag-bn","name":"Brunei Flag","keywords":["bn","darussalam","nation","country","banner"],"skins":[{"unified":"1f1e7-1f1f3","native":"🇧🇳"}],"version":2},"flag-bo":{"id":"flag-bo","name":"Bolivia Flag","keywords":["bo","nation","country","banner"],"skins":[{"unified":"1f1e7-1f1f4","native":"🇧🇴"}],"version":2},"flag-bq":{"id":"flag-bq","name":"Caribbean Netherlands Flag","keywords":["bq","bonaire","nation","country","banner"],"skins":[{"unified":"1f1e7-1f1f6","native":"🇧🇶"}],"version":2},"flag-br":{"id":"flag-br","name":"Brazil Flag","keywords":["br","nation","country","banner"],"skins":[{"unified":"1f1e7-1f1f7","native":"🇧🇷"}],"version":2},"flag-bs":{"id":"flag-bs","name":"Bahamas Flag","keywords":["bs","nation","country","banner"],"skins":[{"unified":"1f1e7-1f1f8","native":"🇧🇸"}],"version":2},"flag-bt":{"id":"flag-bt","name":"Bhutan Flag","keywords":["bt","nation","country","banner"],"skins":[{"unified":"1f1e7-1f1f9","native":"🇧🇹"}],"version":2},"flag-bv":{"id":"flag-bv","name":"Bouvet Island Flag","keywords":["bv","norway"],"skins":[{"unified":"1f1e7-1f1fb","native":"🇧🇻"}],"version":2},"flag-bw":{"id":"flag-bw","name":"Botswana Flag","keywords":["bw","nation","country","banner"],"skins":[{"unified":"1f1e7-1f1fc","native":"🇧🇼"}],"version":2},"flag-by":{"id":"flag-by","name":"Belarus Flag","keywords":["by","nation","country","banner"],"skins":[{"unified":"1f1e7-1f1fe","native":"🇧🇾"}],"version":2},"flag-bz":{"id":"flag-bz","name":"Belize Flag","keywords":["bz","nation","country","banner"],"skins":[{"unified":"1f1e7-1f1ff","native":"🇧🇿"}],"version":2},"flag-ca":{"id":"flag-ca","name":"Canada Flag","keywords":["ca","nation","country","banner"],"skins":[{"unified":"1f1e8-1f1e6","native":"🇨🇦"}],"version":2},"flag-cc":{"id":"flag-cc","name":"Cocos (keeling) Islands Flag","keywords":["cc","keeling","nation","country","banner"],"skins":[{"unified":"1f1e8-1f1e8","native":"🇨🇨"}],"version":2},"flag-cd":{"id":"flag-cd","name":"Congo - Kinshasa Flag","keywords":["cd","democratic","republic","nation","country","banner"],"skins":[{"unified":"1f1e8-1f1e9","native":"🇨🇩"}],"version":2},"flag-cf":{"id":"flag-cf","name":"Central African Republic Flag","keywords":["cf","nation","country","banner"],"skins":[{"unified":"1f1e8-1f1eb","native":"🇨🇫"}],"version":2},"flag-cg":{"id":"flag-cg","name":"Congo - Brazzaville Flag","keywords":["cg","nation","country","banner"],"skins":[{"unified":"1f1e8-1f1ec","native":"🇨🇬"}],"version":2},"flag-ch":{"id":"flag-ch","name":"Switzerland Flag","keywords":["ch","nation","country","banner"],"skins":[{"unified":"1f1e8-1f1ed","native":"🇨🇭"}],"version":2},"flag-ci":{"id":"flag-ci","name":"Côte D’ivoire Flag","keywords":["ci","cote","d","ivoire","ivory","coast","nation","country","banner"],"skins":[{"unified":"1f1e8-1f1ee","native":"🇨🇮"}],"version":2},"flag-ck":{"id":"flag-ck","name":"Cook Islands Flag","keywords":["ck","nation","country","banner"],"skins":[{"unified":"1f1e8-1f1f0","native":"🇨🇰"}],"version":2},"flag-cl":{"id":"flag-cl","name":"Chile Flag","keywords":["cl","nation","country","banner"],"skins":[{"unified":"1f1e8-1f1f1","native":"🇨🇱"}],"version":2},"flag-cm":{"id":"flag-cm","name":"Cameroon Flag","keywords":["cm","nation","country","banner"],"skins":[{"unified":"1f1e8-1f1f2","native":"🇨🇲"}],"version":2},"cn":{"id":"cn","name":"China Flag","keywords":["cn","chinese","prc","country","nation","banner"],"skins":[{"unified":"1f1e8-1f1f3","native":"🇨🇳"}],"version":1},"flag-co":{"id":"flag-co","name":"Colombia Flag","keywords":["co","nation","country","banner"],"skins":[{"unified":"1f1e8-1f1f4","native":"🇨🇴"}],"version":2},"flag-cp":{"id":"flag-cp","name":"Clipperton Island Flag","keywords":["cp"],"skins":[{"unified":"1f1e8-1f1f5","native":"🇨🇵"}],"version":2},"flag-cr":{"id":"flag-cr","name":"Costa Rica Flag","keywords":["cr","nation","country","banner"],"skins":[{"unified":"1f1e8-1f1f7","native":"🇨🇷"}],"version":2},"flag-cu":{"id":"flag-cu","name":"Cuba Flag","keywords":["cu","nation","country","banner"],"skins":[{"unified":"1f1e8-1f1fa","native":"🇨🇺"}],"version":2},"flag-cv":{"id":"flag-cv","name":"Cape Verde Flag","keywords":["cv","cabo","nation","country","banner"],"skins":[{"unified":"1f1e8-1f1fb","native":"🇨🇻"}],"version":2},"flag-cw":{"id":"flag-cw","name":"Curaçao Flag","keywords":["cw","curacao","nation","country","banner"],"skins":[{"unified":"1f1e8-1f1fc","native":"🇨🇼"}],"version":2},"flag-cx":{"id":"flag-cx","name":"Christmas Island Flag","keywords":["cx","nation","country","banner"],"skins":[{"unified":"1f1e8-1f1fd","native":"🇨🇽"}],"version":2},"flag-cy":{"id":"flag-cy","name":"Cyprus Flag","keywords":["cy","nation","country","banner"],"skins":[{"unified":"1f1e8-1f1fe","native":"🇨🇾"}],"version":2},"flag-cz":{"id":"flag-cz","name":"Czechia Flag","keywords":["cz","nation","country","banner"],"skins":[{"unified":"1f1e8-1f1ff","native":"🇨🇿"}],"version":2},"de":{"id":"de","name":"Germany Flag","keywords":["de","german","nation","country","banner"],"skins":[{"unified":"1f1e9-1f1ea","native":"🇩🇪"}],"version":1},"flag-dg":{"id":"flag-dg","name":"Diego Garcia Flag","keywords":["dg"],"skins":[{"unified":"1f1e9-1f1ec","native":"🇩🇬"}],"version":2},"flag-dj":{"id":"flag-dj","name":"Djibouti Flag","keywords":["dj","nation","country","banner"],"skins":[{"unified":"1f1e9-1f1ef","native":"🇩🇯"}],"version":2},"flag-dk":{"id":"flag-dk","name":"Denmark Flag","keywords":["dk","nation","country","banner"],"skins":[{"unified":"1f1e9-1f1f0","native":"🇩🇰"}],"version":2},"flag-dm":{"id":"flag-dm","name":"Dominica Flag","keywords":["dm","nation","country","banner"],"skins":[{"unified":"1f1e9-1f1f2","native":"🇩🇲"}],"version":2},"flag-do":{"id":"flag-do","name":"Dominican Republic Flag","keywords":["do","nation","country","banner"],"skins":[{"unified":"1f1e9-1f1f4","native":"🇩🇴"}],"version":2},"flag-dz":{"id":"flag-dz","name":"Algeria Flag","keywords":["dz","nation","country","banner"],"skins":[{"unified":"1f1e9-1f1ff","native":"🇩🇿"}],"version":2},"flag-ea":{"id":"flag-ea","name":"Ceuta & Melilla Flag","keywords":["ea"],"skins":[{"unified":"1f1ea-1f1e6","native":"🇪🇦"}],"version":2},"flag-ec":{"id":"flag-ec","name":"Ecuador Flag","keywords":["ec","nation","country","banner"],"skins":[{"unified":"1f1ea-1f1e8","native":"🇪🇨"}],"version":2},"flag-ee":{"id":"flag-ee","name":"Estonia Flag","keywords":["ee","nation","country","banner"],"skins":[{"unified":"1f1ea-1f1ea","native":"🇪🇪"}],"version":2},"flag-eg":{"id":"flag-eg","name":"Egypt Flag","keywords":["eg","nation","country","banner"],"skins":[{"unified":"1f1ea-1f1ec","native":"🇪🇬"}],"version":2},"flag-eh":{"id":"flag-eh","name":"Western Sahara Flag","keywords":["eh","nation","country","banner"],"skins":[{"unified":"1f1ea-1f1ed","native":"🇪🇭"}],"version":2},"flag-er":{"id":"flag-er","name":"Eritrea Flag","keywords":["er","nation","country","banner"],"skins":[{"unified":"1f1ea-1f1f7","native":"🇪🇷"}],"version":2},"es":{"id":"es","name":"Spain Flag","keywords":["es","nation","country","banner"],"skins":[{"unified":"1f1ea-1f1f8","native":"🇪🇸"}],"version":1},"flag-et":{"id":"flag-et","name":"Ethiopia Flag","keywords":["et","nation","country","banner"],"skins":[{"unified":"1f1ea-1f1f9","native":"🇪🇹"}],"version":2},"flag-eu":{"id":"flag-eu","name":"European Union Flag","keywords":["eu","banner"],"skins":[{"unified":"1f1ea-1f1fa","native":"🇪🇺"}],"version":2},"flag-fi":{"id":"flag-fi","name":"Finland Flag","keywords":["fi","nation","country","banner"],"skins":[{"unified":"1f1eb-1f1ee","native":"🇫🇮"}],"version":2},"flag-fj":{"id":"flag-fj","name":"Fiji Flag","keywords":["fj","nation","country","banner"],"skins":[{"unified":"1f1eb-1f1ef","native":"🇫🇯"}],"version":2},"flag-fk":{"id":"flag-fk","name":"Falkland Islands Flag","keywords":["fk","malvinas","nation","country","banner"],"skins":[{"unified":"1f1eb-1f1f0","native":"🇫🇰"}],"version":2},"flag-fm":{"id":"flag-fm","name":"Micronesia Flag","keywords":["fm","federated","states","nation","country","banner"],"skins":[{"unified":"1f1eb-1f1f2","native":"🇫🇲"}],"version":2},"flag-fo":{"id":"flag-fo","name":"Faroe Islands Flag","keywords":["fo","nation","country","banner"],"skins":[{"unified":"1f1eb-1f1f4","native":"🇫🇴"}],"version":2},"fr":{"id":"fr","name":"France Flag","keywords":["fr","banner","nation","french","country"],"skins":[{"unified":"1f1eb-1f1f7","native":"🇫🇷"}],"version":1},"flag-ga":{"id":"flag-ga","name":"Gabon Flag","keywords":["ga","nation","country","banner"],"skins":[{"unified":"1f1ec-1f1e6","native":"🇬🇦"}],"version":2},"gb":{"id":"gb","name":"United Kingdom Flag","keywords":["gb","uk","great","britain","northern","ireland","nation","country","banner","british","UK","english","england","union","jack"],"skins":[{"unified":"1f1ec-1f1e7","native":"🇬🇧"}],"version":1},"flag-gd":{"id":"flag-gd","name":"Grenada Flag","keywords":["gd","nation","country","banner"],"skins":[{"unified":"1f1ec-1f1e9","native":"🇬🇩"}],"version":2},"flag-ge":{"id":"flag-ge","name":"Georgia Flag","keywords":["ge","nation","country","banner"],"skins":[{"unified":"1f1ec-1f1ea","native":"🇬🇪"}],"version":2},"flag-gf":{"id":"flag-gf","name":"French Guiana Flag","keywords":["gf","nation","country","banner"],"skins":[{"unified":"1f1ec-1f1eb","native":"🇬🇫"}],"version":2},"flag-gg":{"id":"flag-gg","name":"Guernsey Flag","keywords":["gg","nation","country","banner"],"skins":[{"unified":"1f1ec-1f1ec","native":"🇬🇬"}],"version":2},"flag-gh":{"id":"flag-gh","name":"Ghana Flag","keywords":["gh","nation","country","banner"],"skins":[{"unified":"1f1ec-1f1ed","native":"🇬🇭"}],"version":2},"flag-gi":{"id":"flag-gi","name":"Gibraltar Flag","keywords":["gi","nation","country","banner"],"skins":[{"unified":"1f1ec-1f1ee","native":"🇬🇮"}],"version":2},"flag-gl":{"id":"flag-gl","name":"Greenland Flag","keywords":["gl","nation","country","banner"],"skins":[{"unified":"1f1ec-1f1f1","native":"🇬🇱"}],"version":2},"flag-gm":{"id":"flag-gm","name":"Gambia Flag","keywords":["gm","nation","country","banner"],"skins":[{"unified":"1f1ec-1f1f2","native":"🇬🇲"}],"version":2},"flag-gn":{"id":"flag-gn","name":"Guinea Flag","keywords":["gn","nation","country","banner"],"skins":[{"unified":"1f1ec-1f1f3","native":"🇬🇳"}],"version":2},"flag-gp":{"id":"flag-gp","name":"Guadeloupe Flag","keywords":["gp","nation","country","banner"],"skins":[{"unified":"1f1ec-1f1f5","native":"🇬🇵"}],"version":2},"flag-gq":{"id":"flag-gq","name":"Equatorial Guinea Flag","keywords":["gq","gn","nation","country","banner"],"skins":[{"unified":"1f1ec-1f1f6","native":"🇬🇶"}],"version":2},"flag-gr":{"id":"flag-gr","name":"Greece Flag","keywords":["gr","nation","country","banner"],"skins":[{"unified":"1f1ec-1f1f7","native":"🇬🇷"}],"version":2},"flag-gs":{"id":"flag-gs","name":"South Georgia & South Sandwich Islands Flag","keywords":["gs","nation","country","banner"],"skins":[{"unified":"1f1ec-1f1f8","native":"🇬🇸"}],"version":2},"flag-gt":{"id":"flag-gt","name":"Guatemala Flag","keywords":["gt","nation","country","banner"],"skins":[{"unified":"1f1ec-1f1f9","native":"🇬🇹"}],"version":2},"flag-gu":{"id":"flag-gu","name":"Guam Flag","keywords":["gu","nation","country","banner"],"skins":[{"unified":"1f1ec-1f1fa","native":"🇬🇺"}],"version":2},"flag-gw":{"id":"flag-gw","name":"Guinea-Bissau Flag","keywords":["gw","guinea","bissau","nation","country","banner"],"skins":[{"unified":"1f1ec-1f1fc","native":"🇬🇼"}],"version":2},"flag-gy":{"id":"flag-gy","name":"Guyana Flag","keywords":["gy","nation","country","banner"],"skins":[{"unified":"1f1ec-1f1fe","native":"🇬🇾"}],"version":2},"flag-hk":{"id":"flag-hk","name":"Hong Kong Sar China Flag","keywords":["hk","nation","country","banner"],"skins":[{"unified":"1f1ed-1f1f0","native":"🇭🇰"}],"version":2},"flag-hm":{"id":"flag-hm","name":"Heard & Mcdonald Islands Flag","keywords":["hm"],"skins":[{"unified":"1f1ed-1f1f2","native":"🇭🇲"}],"version":2},"flag-hn":{"id":"flag-hn","name":"Honduras Flag","keywords":["hn","nation","country","banner"],"skins":[{"unified":"1f1ed-1f1f3","native":"🇭🇳"}],"version":2},"flag-hr":{"id":"flag-hr","name":"Croatia Flag","keywords":["hr","nation","country","banner"],"skins":[{"unified":"1f1ed-1f1f7","native":"🇭🇷"}],"version":2},"flag-ht":{"id":"flag-ht","name":"Haiti Flag","keywords":["ht","nation","country","banner"],"skins":[{"unified":"1f1ed-1f1f9","native":"🇭🇹"}],"version":2},"flag-hu":{"id":"flag-hu","name":"Hungary Flag","keywords":["hu","nation","country","banner"],"skins":[{"unified":"1f1ed-1f1fa","native":"🇭🇺"}],"version":2},"flag-ic":{"id":"flag-ic","name":"Canary Islands Flag","keywords":["ic","nation","country","banner"],"skins":[{"unified":"1f1ee-1f1e8","native":"🇮🇨"}],"version":2},"flag-id":{"id":"flag-id","name":"Indonesia Flag","keywords":["id","nation","country","banner"],"skins":[{"unified":"1f1ee-1f1e9","native":"🇮🇩"}],"version":2},"flag-ie":{"id":"flag-ie","name":"Ireland Flag","keywords":["ie","nation","country","banner"],"skins":[{"unified":"1f1ee-1f1ea","native":"🇮🇪"}],"version":2},"flag-il":{"id":"flag-il","name":"Israel Flag","keywords":["il","nation","country","banner"],"skins":[{"unified":"1f1ee-1f1f1","native":"🇮🇱"}],"version":2},"flag-im":{"id":"flag-im","name":"Isle of Man Flag","keywords":["im","nation","country","banner"],"skins":[{"unified":"1f1ee-1f1f2","native":"🇮🇲"}],"version":2},"flag-in":{"id":"flag-in","name":"India Flag","keywords":["in","nation","country","banner"],"skins":[{"unified":"1f1ee-1f1f3","native":"🇮🇳"}],"version":2},"flag-io":{"id":"flag-io","name":"British Indian Ocean Territory Flag","keywords":["io","nation","country","banner"],"skins":[{"unified":"1f1ee-1f1f4","native":"🇮🇴"}],"version":2},"flag-iq":{"id":"flag-iq","name":"Iraq Flag","keywords":["iq","nation","country","banner"],"skins":[{"unified":"1f1ee-1f1f6","native":"🇮🇶"}],"version":2},"flag-ir":{"id":"flag-ir","name":"Iran Flag","keywords":["ir","islamic","republic","nation","country","banner"],"skins":[{"unified":"1f1ee-1f1f7","native":"🇮🇷"}],"version":2},"flag-is":{"id":"flag-is","name":"Iceland Flag","keywords":["is","nation","country","banner"],"skins":[{"unified":"1f1ee-1f1f8","native":"🇮🇸"}],"version":2},"it":{"id":"it","name":"Italy Flag","keywords":["it","nation","country","banner"],"skins":[{"unified":"1f1ee-1f1f9","native":"🇮🇹"}],"version":1},"flag-je":{"id":"flag-je","name":"Jersey Flag","keywords":["je","nation","country","banner"],"skins":[{"unified":"1f1ef-1f1ea","native":"🇯🇪"}],"version":2},"flag-jm":{"id":"flag-jm","name":"Jamaica Flag","keywords":["jm","nation","country","banner"],"skins":[{"unified":"1f1ef-1f1f2","native":"🇯🇲"}],"version":2},"flag-jo":{"id":"flag-jo","name":"Jordan Flag","keywords":["jo","nation","country","banner"],"skins":[{"unified":"1f1ef-1f1f4","native":"🇯🇴"}],"version":2},"jp":{"id":"jp","name":"Japan Flag","keywords":["jp","japanese","nation","country","banner","ja"],"skins":[{"unified":"1f1ef-1f1f5","native":"🇯🇵"}],"version":1},"flag-ke":{"id":"flag-ke","name":"Kenya Flag","keywords":["ke","nation","country","banner"],"skins":[{"unified":"1f1f0-1f1ea","native":"🇰🇪"}],"version":2},"flag-kg":{"id":"flag-kg","name":"Kyrgyzstan Flag","keywords":["kg","nation","country","banner"],"skins":[{"unified":"1f1f0-1f1ec","native":"🇰🇬"}],"version":2},"flag-kh":{"id":"flag-kh","name":"Cambodia Flag","keywords":["kh","nation","country","banner"],"skins":[{"unified":"1f1f0-1f1ed","native":"🇰🇭"}],"version":2},"flag-ki":{"id":"flag-ki","name":"Kiribati Flag","keywords":["ki","nation","country","banner"],"skins":[{"unified":"1f1f0-1f1ee","native":"🇰🇮"}],"version":2},"flag-km":{"id":"flag-km","name":"Comoros Flag","keywords":["km","nation","country","banner"],"skins":[{"unified":"1f1f0-1f1f2","native":"🇰🇲"}],"version":2},"flag-kn":{"id":"flag-kn","name":"St. Kitts & Nevis Flag","keywords":["kn","st","saint","nation","country","banner"],"skins":[{"unified":"1f1f0-1f1f3","native":"🇰🇳"}],"version":2},"flag-kp":{"id":"flag-kp","name":"North Korea Flag","keywords":["kp","nation","country","banner"],"skins":[{"unified":"1f1f0-1f1f5","native":"🇰🇵"}],"version":2},"kr":{"id":"kr","name":"South Korea Flag","keywords":["kr","nation","country","banner"],"skins":[{"unified":"1f1f0-1f1f7","native":"🇰🇷"}],"version":1},"flag-kw":{"id":"flag-kw","name":"Kuwait Flag","keywords":["kw","nation","country","banner"],"skins":[{"unified":"1f1f0-1f1fc","native":"🇰🇼"}],"version":2},"flag-ky":{"id":"flag-ky","name":"Cayman Islands Flag","keywords":["ky","nation","country","banner"],"skins":[{"unified":"1f1f0-1f1fe","native":"🇰🇾"}],"version":2},"flag-kz":{"id":"flag-kz","name":"Kazakhstan Flag","keywords":["kz","nation","country","banner"],"skins":[{"unified":"1f1f0-1f1ff","native":"🇰🇿"}],"version":2},"flag-la":{"id":"flag-la","name":"Laos Flag","keywords":["la","lao","democratic","republic","nation","country","banner"],"skins":[{"unified":"1f1f1-1f1e6","native":"🇱🇦"}],"version":2},"flag-lb":{"id":"flag-lb","name":"Lebanon Flag","keywords":["lb","nation","country","banner"],"skins":[{"unified":"1f1f1-1f1e7","native":"🇱🇧"}],"version":2},"flag-lc":{"id":"flag-lc","name":"St. Lucia Flag","keywords":["lc","st","saint","nation","country","banner"],"skins":[{"unified":"1f1f1-1f1e8","native":"🇱🇨"}],"version":2},"flag-li":{"id":"flag-li","name":"Liechtenstein Flag","keywords":["li","nation","country","banner"],"skins":[{"unified":"1f1f1-1f1ee","native":"🇱🇮"}],"version":2},"flag-lk":{"id":"flag-lk","name":"Sri Lanka Flag","keywords":["lk","nation","country","banner"],"skins":[{"unified":"1f1f1-1f1f0","native":"🇱🇰"}],"version":2},"flag-lr":{"id":"flag-lr","name":"Liberia Flag","keywords":["lr","nation","country","banner"],"skins":[{"unified":"1f1f1-1f1f7","native":"🇱🇷"}],"version":2},"flag-ls":{"id":"flag-ls","name":"Lesotho Flag","keywords":["ls","nation","country","banner"],"skins":[{"unified":"1f1f1-1f1f8","native":"🇱🇸"}],"version":2},"flag-lt":{"id":"flag-lt","name":"Lithuania Flag","keywords":["lt","nation","country","banner"],"skins":[{"unified":"1f1f1-1f1f9","native":"🇱🇹"}],"version":2},"flag-lu":{"id":"flag-lu","name":"Luxembourg Flag","keywords":["lu","nation","country","banner"],"skins":[{"unified":"1f1f1-1f1fa","native":"🇱🇺"}],"version":2},"flag-lv":{"id":"flag-lv","name":"Latvia Flag","keywords":["lv","nation","country","banner"],"skins":[{"unified":"1f1f1-1f1fb","native":"🇱🇻"}],"version":2},"flag-ly":{"id":"flag-ly","name":"Libya Flag","keywords":["ly","nation","country","banner"],"skins":[{"unified":"1f1f1-1f1fe","native":"🇱🇾"}],"version":2},"flag-ma":{"id":"flag-ma","name":"Morocco Flag","keywords":["ma","nation","country","banner"],"skins":[{"unified":"1f1f2-1f1e6","native":"🇲🇦"}],"version":2},"flag-mc":{"id":"flag-mc","name":"Monaco Flag","keywords":["mc","nation","country","banner"],"skins":[{"unified":"1f1f2-1f1e8","native":"🇲🇨"}],"version":2},"flag-md":{"id":"flag-md","name":"Moldova Flag","keywords":["md","republic","nation","country","banner"],"skins":[{"unified":"1f1f2-1f1e9","native":"🇲🇩"}],"version":2},"flag-me":{"id":"flag-me","name":"Montenegro Flag","keywords":["me","nation","country","banner"],"skins":[{"unified":"1f1f2-1f1ea","native":"🇲🇪"}],"version":2},"flag-mf":{"id":"flag-mf","name":"St. Martin Flag","keywords":["mf","st"],"skins":[{"unified":"1f1f2-1f1eb","native":"🇲🇫"}],"version":2},"flag-mg":{"id":"flag-mg","name":"Madagascar Flag","keywords":["mg","nation","country","banner"],"skins":[{"unified":"1f1f2-1f1ec","native":"🇲🇬"}],"version":2},"flag-mh":{"id":"flag-mh","name":"Marshall Islands Flag","keywords":["mh","nation","country","banner"],"skins":[{"unified":"1f1f2-1f1ed","native":"🇲🇭"}],"version":2},"flag-mk":{"id":"flag-mk","name":"North Macedonia Flag","keywords":["mk","nation","country","banner"],"skins":[{"unified":"1f1f2-1f1f0","native":"🇲🇰"}],"version":2},"flag-ml":{"id":"flag-ml","name":"Mali Flag","keywords":["ml","nation","country","banner"],"skins":[{"unified":"1f1f2-1f1f1","native":"🇲🇱"}],"version":2},"flag-mm":{"id":"flag-mm","name":"Myanmar (burma) Flag","keywords":["mm","nation","country","banner"],"skins":[{"unified":"1f1f2-1f1f2","native":"🇲🇲"}],"version":2},"flag-mn":{"id":"flag-mn","name":"Mongolia Flag","keywords":["mn","nation","country","banner"],"skins":[{"unified":"1f1f2-1f1f3","native":"🇲🇳"}],"version":2},"flag-mo":{"id":"flag-mo","name":"Macao Sar China Flag","keywords":["mo","nation","country","banner"],"skins":[{"unified":"1f1f2-1f1f4","native":"🇲🇴"}],"version":2},"flag-mp":{"id":"flag-mp","name":"Northern Mariana Islands Flag","keywords":["mp","nation","country","banner"],"skins":[{"unified":"1f1f2-1f1f5","native":"🇲🇵"}],"version":2},"flag-mq":{"id":"flag-mq","name":"Martinique Flag","keywords":["mq","nation","country","banner"],"skins":[{"unified":"1f1f2-1f1f6","native":"🇲🇶"}],"version":2},"flag-mr":{"id":"flag-mr","name":"Mauritania Flag","keywords":["mr","nation","country","banner"],"skins":[{"unified":"1f1f2-1f1f7","native":"🇲🇷"}],"version":2},"flag-ms":{"id":"flag-ms","name":"Montserrat Flag","keywords":["ms","nation","country","banner"],"skins":[{"unified":"1f1f2-1f1f8","native":"🇲🇸"}],"version":2},"flag-mt":{"id":"flag-mt","name":"Malta Flag","keywords":["mt","nation","country","banner"],"skins":[{"unified":"1f1f2-1f1f9","native":"🇲🇹"}],"version":2},"flag-mu":{"id":"flag-mu","name":"Mauritius Flag","keywords":["mu","nation","country","banner"],"skins":[{"unified":"1f1f2-1f1fa","native":"🇲🇺"}],"version":2},"flag-mv":{"id":"flag-mv","name":"Maldives Flag","keywords":["mv","nation","country","banner"],"skins":[{"unified":"1f1f2-1f1fb","native":"🇲🇻"}],"version":2},"flag-mw":{"id":"flag-mw","name":"Malawi Flag","keywords":["mw","nation","country","banner"],"skins":[{"unified":"1f1f2-1f1fc","native":"🇲🇼"}],"version":2},"flag-mx":{"id":"flag-mx","name":"Mexico Flag","keywords":["mx","nation","country","banner"],"skins":[{"unified":"1f1f2-1f1fd","native":"🇲🇽"}],"version":2},"flag-my":{"id":"flag-my","name":"Malaysia Flag","keywords":["my","nation","country","banner"],"skins":[{"unified":"1f1f2-1f1fe","native":"🇲🇾"}],"version":2},"flag-mz":{"id":"flag-mz","name":"Mozambique Flag","keywords":["mz","nation","country","banner"],"skins":[{"unified":"1f1f2-1f1ff","native":"🇲🇿"}],"version":2},"flag-na":{"id":"flag-na","name":"Namibia Flag","keywords":["na","nation","country","banner"],"skins":[{"unified":"1f1f3-1f1e6","native":"🇳🇦"}],"version":2},"flag-nc":{"id":"flag-nc","name":"New Caledonia Flag","keywords":["nc","nation","country","banner"],"skins":[{"unified":"1f1f3-1f1e8","native":"🇳🇨"}],"version":2},"flag-ne":{"id":"flag-ne","name":"Niger Flag","keywords":["ne","nation","country","banner"],"skins":[{"unified":"1f1f3-1f1ea","native":"🇳🇪"}],"version":2},"flag-nf":{"id":"flag-nf","name":"Norfolk Island Flag","keywords":["nf","nation","country","banner"],"skins":[{"unified":"1f1f3-1f1eb","native":"🇳🇫"}],"version":2},"flag-ng":{"id":"flag-ng","name":"Nigeria Flag","keywords":["ng","nation","country","banner"],"skins":[{"unified":"1f1f3-1f1ec","native":"🇳🇬"}],"version":2},"flag-ni":{"id":"flag-ni","name":"Nicaragua Flag","keywords":["ni","nation","country","banner"],"skins":[{"unified":"1f1f3-1f1ee","native":"🇳🇮"}],"version":2},"flag-nl":{"id":"flag-nl","name":"Netherlands Flag","keywords":["nl","nation","country","banner"],"skins":[{"unified":"1f1f3-1f1f1","native":"🇳🇱"}],"version":2},"flag-no":{"id":"flag-no","name":"Norway Flag","keywords":["no","nation","country","banner"],"skins":[{"unified":"1f1f3-1f1f4","native":"🇳🇴"}],"version":2},"flag-np":{"id":"flag-np","name":"Nepal Flag","keywords":["np","nation","country","banner"],"skins":[{"unified":"1f1f3-1f1f5","native":"🇳🇵"}],"version":2},"flag-nr":{"id":"flag-nr","name":"Nauru Flag","keywords":["nr","nation","country","banner"],"skins":[{"unified":"1f1f3-1f1f7","native":"🇳🇷"}],"version":2},"flag-nu":{"id":"flag-nu","name":"Niue Flag","keywords":["nu","nation","country","banner"],"skins":[{"unified":"1f1f3-1f1fa","native":"🇳🇺"}],"version":2},"flag-nz":{"id":"flag-nz","name":"New Zealand Flag","keywords":["nz","nation","country","banner"],"skins":[{"unified":"1f1f3-1f1ff","native":"🇳🇿"}],"version":2},"flag-om":{"id":"flag-om","name":"Oman Flag","keywords":["om","symbol","nation","country","banner"],"skins":[{"unified":"1f1f4-1f1f2","native":"🇴🇲"}],"version":2},"flag-pa":{"id":"flag-pa","name":"Panama Flag","keywords":["pa","nation","country","banner"],"skins":[{"unified":"1f1f5-1f1e6","native":"🇵🇦"}],"version":2},"flag-pe":{"id":"flag-pe","name":"Peru Flag","keywords":["pe","nation","country","banner"],"skins":[{"unified":"1f1f5-1f1ea","native":"🇵🇪"}],"version":2},"flag-pf":{"id":"flag-pf","name":"French Polynesia Flag","keywords":["pf","nation","country","banner"],"skins":[{"unified":"1f1f5-1f1eb","native":"🇵🇫"}],"version":2},"flag-pg":{"id":"flag-pg","name":"Papua New Guinea Flag","keywords":["pg","nation","country","banner"],"skins":[{"unified":"1f1f5-1f1ec","native":"🇵🇬"}],"version":2},"flag-ph":{"id":"flag-ph","name":"Philippines Flag","keywords":["ph","nation","country","banner"],"skins":[{"unified":"1f1f5-1f1ed","native":"🇵🇭"}],"version":2},"flag-pk":{"id":"flag-pk","name":"Pakistan Flag","keywords":["pk","nation","country","banner"],"skins":[{"unified":"1f1f5-1f1f0","native":"🇵🇰"}],"version":2},"flag-pl":{"id":"flag-pl","name":"Poland Flag","keywords":["pl","nation","country","banner"],"skins":[{"unified":"1f1f5-1f1f1","native":"🇵🇱"}],"version":2},"flag-pm":{"id":"flag-pm","name":"St. Pierre & Miquelon Flag","keywords":["pm","st","saint","nation","country","banner"],"skins":[{"unified":"1f1f5-1f1f2","native":"🇵🇲"}],"version":2},"flag-pn":{"id":"flag-pn","name":"Pitcairn Islands Flag","keywords":["pn","nation","country","banner"],"skins":[{"unified":"1f1f5-1f1f3","native":"🇵🇳"}],"version":2},"flag-pr":{"id":"flag-pr","name":"Puerto Rico Flag","keywords":["pr","nation","country","banner"],"skins":[{"unified":"1f1f5-1f1f7","native":"🇵🇷"}],"version":2},"flag-ps":{"id":"flag-ps","name":"Palestinian Territories Flag","keywords":["ps","palestine","nation","country","banner"],"skins":[{"unified":"1f1f5-1f1f8","native":"🇵🇸"}],"version":2},"flag-pt":{"id":"flag-pt","name":"Portugal Flag","keywords":["pt","nation","country","banner"],"skins":[{"unified":"1f1f5-1f1f9","native":"🇵🇹"}],"version":2},"flag-pw":{"id":"flag-pw","name":"Palau Flag","keywords":["pw","nation","country","banner"],"skins":[{"unified":"1f1f5-1f1fc","native":"🇵🇼"}],"version":2},"flag-py":{"id":"flag-py","name":"Paraguay Flag","keywords":["py","nation","country","banner"],"skins":[{"unified":"1f1f5-1f1fe","native":"🇵🇾"}],"version":2},"flag-qa":{"id":"flag-qa","name":"Qatar Flag","keywords":["qa","nation","country","banner"],"skins":[{"unified":"1f1f6-1f1e6","native":"🇶🇦"}],"version":2},"flag-re":{"id":"flag-re","name":"Réunion Flag","keywords":["re","reunion","nation","country","banner"],"skins":[{"unified":"1f1f7-1f1ea","native":"🇷🇪"}],"version":2},"flag-ro":{"id":"flag-ro","name":"Romania Flag","keywords":["ro","nation","country","banner"],"skins":[{"unified":"1f1f7-1f1f4","native":"🇷🇴"}],"version":2},"flag-rs":{"id":"flag-rs","name":"Serbia Flag","keywords":["rs","nation","country","banner"],"skins":[{"unified":"1f1f7-1f1f8","native":"🇷🇸"}],"version":2},"ru":{"id":"ru","name":"Russia Flag","keywords":["ru","russian","federation","nation","country","banner"],"skins":[{"unified":"1f1f7-1f1fa","native":"🇷🇺"}],"version":1},"flag-rw":{"id":"flag-rw","name":"Rwanda Flag","keywords":["rw","nation","country","banner"],"skins":[{"unified":"1f1f7-1f1fc","native":"🇷🇼"}],"version":2},"flag-sa":{"id":"flag-sa","name":"Saudi Arabia Flag","keywords":["sa","nation","country","banner"],"skins":[{"unified":"1f1f8-1f1e6","native":"🇸🇦"}],"version":2},"flag-sb":{"id":"flag-sb","name":"Solomon Islands Flag","keywords":["sb","nation","country","banner"],"skins":[{"unified":"1f1f8-1f1e7","native":"🇸🇧"}],"version":2},"flag-sc":{"id":"flag-sc","name":"Seychelles Flag","keywords":["sc","nation","country","banner"],"skins":[{"unified":"1f1f8-1f1e8","native":"🇸🇨"}],"version":2},"flag-sd":{"id":"flag-sd","name":"Sudan Flag","keywords":["sd","nation","country","banner"],"skins":[{"unified":"1f1f8-1f1e9","native":"🇸🇩"}],"version":2},"flag-se":{"id":"flag-se","name":"Sweden Flag","keywords":["se","nation","country","banner"],"skins":[{"unified":"1f1f8-1f1ea","native":"🇸🇪"}],"version":2},"flag-sg":{"id":"flag-sg","name":"Singapore Flag","keywords":["sg","nation","country","banner"],"skins":[{"unified":"1f1f8-1f1ec","native":"🇸🇬"}],"version":2},"flag-sh":{"id":"flag-sh","name":"St. Helena Flag","keywords":["sh","st","saint","ascension","tristan","cunha","nation","country","banner"],"skins":[{"unified":"1f1f8-1f1ed","native":"🇸🇭"}],"version":2},"flag-si":{"id":"flag-si","name":"Slovenia Flag","keywords":["si","nation","country","banner"],"skins":[{"unified":"1f1f8-1f1ee","native":"🇸🇮"}],"version":2},"flag-sj":{"id":"flag-sj","name":"Svalbard & Jan Mayen Flag","keywords":["sj"],"skins":[{"unified":"1f1f8-1f1ef","native":"🇸🇯"}],"version":2},"flag-sk":{"id":"flag-sk","name":"Slovakia Flag","keywords":["sk","nation","country","banner"],"skins":[{"unified":"1f1f8-1f1f0","native":"🇸🇰"}],"version":2},"flag-sl":{"id":"flag-sl","name":"Sierra Leone Flag","keywords":["sl","nation","country","banner"],"skins":[{"unified":"1f1f8-1f1f1","native":"🇸🇱"}],"version":2},"flag-sm":{"id":"flag-sm","name":"San Marino Flag","keywords":["sm","nation","country","banner"],"skins":[{"unified":"1f1f8-1f1f2","native":"🇸🇲"}],"version":2},"flag-sn":{"id":"flag-sn","name":"Senegal Flag","keywords":["sn","nation","country","banner"],"skins":[{"unified":"1f1f8-1f1f3","native":"🇸🇳"}],"version":2},"flag-so":{"id":"flag-so","name":"Somalia Flag","keywords":["so","nation","country","banner"],"skins":[{"unified":"1f1f8-1f1f4","native":"🇸🇴"}],"version":2},"flag-sr":{"id":"flag-sr","name":"Suriname Flag","keywords":["sr","nation","country","banner"],"skins":[{"unified":"1f1f8-1f1f7","native":"🇸🇷"}],"version":2},"flag-ss":{"id":"flag-ss","name":"South Sudan Flag","keywords":["ss","sd","nation","country","banner"],"skins":[{"unified":"1f1f8-1f1f8","native":"🇸🇸"}],"version":2},"flag-st":{"id":"flag-st","name":"São Tomé & Príncipe Flag","keywords":["st","sao","tome","principe","nation","country","banner"],"skins":[{"unified":"1f1f8-1f1f9","native":"🇸🇹"}],"version":2},"flag-sv":{"id":"flag-sv","name":"El Salvador Flag","keywords":["sv","nation","country","banner"],"skins":[{"unified":"1f1f8-1f1fb","native":"🇸🇻"}],"version":2},"flag-sx":{"id":"flag-sx","name":"Sint Maarten Flag","keywords":["sx","dutch","nation","country","banner"],"skins":[{"unified":"1f1f8-1f1fd","native":"🇸🇽"}],"version":2},"flag-sy":{"id":"flag-sy","name":"Syria Flag","keywords":["sy","syrian","arab","republic","nation","country","banner"],"skins":[{"unified":"1f1f8-1f1fe","native":"🇸🇾"}],"version":2},"flag-sz":{"id":"flag-sz","name":"Eswatini Flag","keywords":["sz","nation","country","banner"],"skins":[{"unified":"1f1f8-1f1ff","native":"🇸🇿"}],"version":2},"flag-ta":{"id":"flag-ta","name":"Tristan Da Cunha Flag","keywords":["ta"],"skins":[{"unified":"1f1f9-1f1e6","native":"🇹🇦"}],"version":2},"flag-tc":{"id":"flag-tc","name":"Turks & Caicos Islands Flag","keywords":["tc","nation","country","banner"],"skins":[{"unified":"1f1f9-1f1e8","native":"🇹🇨"}],"version":2},"flag-td":{"id":"flag-td","name":"Chad Flag","keywords":["td","nation","country","banner"],"skins":[{"unified":"1f1f9-1f1e9","native":"🇹🇩"}],"version":2},"flag-tf":{"id":"flag-tf","name":"French Southern Territories Flag","keywords":["tf","nation","country","banner"],"skins":[{"unified":"1f1f9-1f1eb","native":"🇹🇫"}],"version":2},"flag-tg":{"id":"flag-tg","name":"Togo Flag","keywords":["tg","nation","country","banner"],"skins":[{"unified":"1f1f9-1f1ec","native":"🇹🇬"}],"version":2},"flag-th":{"id":"flag-th","name":"Thailand Flag","keywords":["th","nation","country","banner"],"skins":[{"unified":"1f1f9-1f1ed","native":"🇹🇭"}],"version":2},"flag-tj":{"id":"flag-tj","name":"Tajikistan Flag","keywords":["tj","nation","country","banner"],"skins":[{"unified":"1f1f9-1f1ef","native":"🇹🇯"}],"version":2},"flag-tk":{"id":"flag-tk","name":"Tokelau Flag","keywords":["tk","nation","country","banner"],"skins":[{"unified":"1f1f9-1f1f0","native":"🇹🇰"}],"version":2},"flag-tl":{"id":"flag-tl","name":"Timor-Leste Flag","keywords":["tl","timor","leste","nation","country","banner"],"skins":[{"unified":"1f1f9-1f1f1","native":"🇹🇱"}],"version":2},"flag-tm":{"id":"flag-tm","name":"Turkmenistan Flag","keywords":["tm","nation","country","banner"],"skins":[{"unified":"1f1f9-1f1f2","native":"🇹🇲"}],"version":2},"flag-tn":{"id":"flag-tn","name":"Tunisia Flag","keywords":["tn","nation","country","banner"],"skins":[{"unified":"1f1f9-1f1f3","native":"🇹🇳"}],"version":2},"flag-to":{"id":"flag-to","name":"Tonga Flag","keywords":["to","nation","country","banner"],"skins":[{"unified":"1f1f9-1f1f4","native":"🇹🇴"}],"version":2},"flag-tr":{"id":"flag-tr","name":"Turkey Flag","keywords":["tr","nation","country","banner"],"skins":[{"unified":"1f1f9-1f1f7","native":"🇹🇷"}],"version":2},"flag-tt":{"id":"flag-tt","name":"Trinidad & Tobago Flag","keywords":["tt","nation","country","banner"],"skins":[{"unified":"1f1f9-1f1f9","native":"🇹🇹"}],"version":2},"flag-tv":{"id":"flag-tv","name":"Tuvalu Flag","keywords":["tv","nation","country","banner"],"skins":[{"unified":"1f1f9-1f1fb","native":"🇹🇻"}],"version":2},"flag-tw":{"id":"flag-tw","name":"Taiwan Flag","keywords":["tw","nation","country","banner"],"skins":[{"unified":"1f1f9-1f1fc","native":"🇹🇼"}],"version":2},"flag-tz":{"id":"flag-tz","name":"Tanzania Flag","keywords":["tz","united","republic","nation","country","banner"],"skins":[{"unified":"1f1f9-1f1ff","native":"🇹🇿"}],"version":2},"flag-ua":{"id":"flag-ua","name":"Ukraine Flag","keywords":["ua","nation","country","banner"],"skins":[{"unified":"1f1fa-1f1e6","native":"🇺🇦"}],"version":2},"flag-ug":{"id":"flag-ug","name":"Uganda Flag","keywords":["ug","nation","country","banner"],"skins":[{"unified":"1f1fa-1f1ec","native":"🇺🇬"}],"version":2},"flag-um":{"id":"flag-um","name":"U.s. Outlying Islands Flag","keywords":["um","u","s"],"skins":[{"unified":"1f1fa-1f1f2","native":"🇺🇲"}],"version":2},"flag-un":{"id":"flag-un","name":"United Nations Flag","keywords":["un","banner"],"skins":[{"unified":"1f1fa-1f1f3","native":"🇺🇳"}],"version":4},"us":{"id":"us","name":"United States Flag","keywords":["us","america","nation","country","banner"],"skins":[{"unified":"1f1fa-1f1f8","native":"🇺🇸"}],"version":1},"flag-uy":{"id":"flag-uy","name":"Uruguay Flag","keywords":["uy","nation","country","banner"],"skins":[{"unified":"1f1fa-1f1fe","native":"🇺🇾"}],"version":2},"flag-uz":{"id":"flag-uz","name":"Uzbekistan Flag","keywords":["uz","nation","country","banner"],"skins":[{"unified":"1f1fa-1f1ff","native":"🇺🇿"}],"version":2},"flag-va":{"id":"flag-va","name":"Vatican City Flag","keywords":["va","nation","country","banner"],"skins":[{"unified":"1f1fb-1f1e6","native":"🇻🇦"}],"version":2},"flag-vc":{"id":"flag-vc","name":"St. Vincent & Grenadines Flag","keywords":["vc","st","saint","nation","country","banner"],"skins":[{"unified":"1f1fb-1f1e8","native":"🇻🇨"}],"version":2},"flag-ve":{"id":"flag-ve","name":"Venezuela Flag","keywords":["ve","bolivarian","republic","nation","country","banner"],"skins":[{"unified":"1f1fb-1f1ea","native":"🇻🇪"}],"version":2},"flag-vg":{"id":"flag-vg","name":"British Virgin Islands Flag","keywords":["vg","bvi","nation","country","banner"],"skins":[{"unified":"1f1fb-1f1ec","native":"🇻🇬"}],"version":2},"flag-vi":{"id":"flag-vi","name":"U.s. Virgin Islands Flag","keywords":["vi","u","s","us","nation","country","banner"],"skins":[{"unified":"1f1fb-1f1ee","native":"🇻🇮"}],"version":2},"flag-vn":{"id":"flag-vn","name":"Vietnam Flag","keywords":["vn","viet","nam","nation","country","banner"],"skins":[{"unified":"1f1fb-1f1f3","native":"🇻🇳"}],"version":2},"flag-vu":{"id":"flag-vu","name":"Vanuatu Flag","keywords":["vu","nation","country","banner"],"skins":[{"unified":"1f1fb-1f1fa","native":"🇻🇺"}],"version":2},"flag-wf":{"id":"flag-wf","name":"Wallis & Futuna Flag","keywords":["wf","nation","country","banner"],"skins":[{"unified":"1f1fc-1f1eb","native":"🇼🇫"}],"version":2},"flag-ws":{"id":"flag-ws","name":"Samoa Flag","keywords":["ws","nation","country","banner"],"skins":[{"unified":"1f1fc-1f1f8","native":"🇼🇸"}],"version":2},"flag-xk":{"id":"flag-xk","name":"Kosovo Flag","keywords":["xk","nation","country","banner"],"skins":[{"unified":"1f1fd-1f1f0","native":"🇽🇰"}],"version":2},"flag-ye":{"id":"flag-ye","name":"Yemen Flag","keywords":["ye","nation","country","banner"],"skins":[{"unified":"1f1fe-1f1ea","native":"🇾🇪"}],"version":2},"flag-yt":{"id":"flag-yt","name":"Mayotte Flag","keywords":["yt","nation","country","banner"],"skins":[{"unified":"1f1fe-1f1f9","native":"🇾🇹"}],"version":2},"flag-za":{"id":"flag-za","name":"South Africa Flag","keywords":["za","nation","country","banner"],"skins":[{"unified":"1f1ff-1f1e6","native":"🇿🇦"}],"version":2},"flag-zm":{"id":"flag-zm","name":"Zambia Flag","keywords":["zm","nation","country","banner"],"skins":[{"unified":"1f1ff-1f1f2","native":"🇿🇲"}],"version":2},"flag-zw":{"id":"flag-zw","name":"Zimbabwe Flag","keywords":["zw","nation","country","banner"],"skins":[{"unified":"1f1ff-1f1fc","native":"🇿🇼"}],"version":2},"flag-england":{"id":"flag-england","name":"England Flag","keywords":["english"],"skins":[{"unified":"1f3f4-e0067-e0062-e0065-e006e-e0067-e007f","native":"🏴"}],"version":5},"flag-scotland":{"id":"flag-scotland","name":"Scotland Flag","keywords":["scottish"],"skins":[{"unified":"1f3f4-e0067-e0062-e0073-e0063-e0074-e007f","native":"🏴"}],"version":5},"flag-wales":{"id":"flag-wales","name":"Wales Flag","keywords":["welsh"],"skins":[{"unified":"1f3f4-e0067-e0062-e0077-e006c-e0073-e007f","native":"🏴"}],"version":5}}`);
+const aliases = { "satisfied": "laughing", "grinning_face_with_star_eyes": "star-struck", "grinning_face_with_one_large_and_one_small_eye": "zany_face", "smiling_face_with_smiling_eyes_and_hand_covering_mouth": "face_with_hand_over_mouth", "face_with_finger_covering_closed_lips": "shushing_face", "face_with_one_eyebrow_raised": "face_with_raised_eyebrow", "face_with_open_mouth_vomiting": "face_vomiting", "shocked_face_with_exploding_head": "exploding_head", "serious_face_with_symbols_covering_mouth": "face_with_symbols_on_mouth", "poop": "hankey", "shit": "hankey", "collision": "boom", "raised_hand": "hand", "hand_with_index_and_middle_fingers_crossed": "crossed_fingers", "sign_of_the_horns": "the_horns", "reversed_hand_with_middle_finger_extended": "middle_finger", "thumbsup": "+1", "thumbsdown": "-1", "punch": "facepunch", "mother_christmas": "mrs_claus", "running": "runner", "man-with-bunny-ears-partying": "men-with-bunny-ears-partying", "woman-with-bunny-ears-partying": "women-with-bunny-ears-partying", "women_holding_hands": "two_women_holding_hands", "woman_and_man_holding_hands": "man_and_woman_holding_hands", "couple": "man_and_woman_holding_hands", "men_holding_hands": "two_men_holding_hands", "paw_prints": "feet", "flipper": "dolphin", "honeybee": "bee", "lady_beetle": "ladybug", "cooking": "fried_egg", "knife": "hocho", "red_car": "car", "sailboat": "boat", "waxing_gibbous_moon": "moon", "sun_small_cloud": "mostly_sunny", "sun_behind_cloud": "barely_sunny", "sun_behind_rain_cloud": "partly_sunny_rain", "lightning_cloud": "lightning", "tornado_cloud": "tornado", "tshirt": "shirt", "shoe": "mans_shoe", "telephone": "phone", "lantern": "izakaya_lantern", "open_book": "book", "envelope": "email", "pencil": "memo", "heavy_exclamation_mark": "exclamation", "staff_of_aesculapius": "medical_symbol", "flag-cn": "cn", "flag-de": "de", "flag-es": "es", "flag-fr": "fr", "uk": "gb", "flag-gb": "gb", "flag-it": "it", "flag-jp": "jp", "flag-kr": "kr", "flag-ru": "ru", "flag-us": "us" };
+const sheet = { "cols": 61, "rows": 61 };
+const native = {
+ categories,
+ emojis,
+ aliases,
+ sheet
+};
+export {
+ aliases,
+ categories,
+ native as default,
+ emojis,
+ sheet
+};
diff --git a/bootstrap/ssr/assets/emoji-ui-C_DZUNyP.js b/bootstrap/ssr/assets/emoji-ui-C_DZUNyP.js
new file mode 100644
index 00000000..841cc60d
--- /dev/null
+++ b/bootstrap/ssr/assets/emoji-ui-C_DZUNyP.js
@@ -0,0 +1,2581 @@
+function $parcel$interopDefault(a) {
+ return a && a.__esModule ? a.default : a;
+}
+function $c770c458706daa72$export$2e2bcd8739ae039(obj, key, value) {
+ if (key in obj) Object.defineProperty(obj, key, {
+ value,
+ enumerable: true,
+ configurable: true,
+ writable: true
+ });
+ else obj[key] = value;
+ return obj;
+}
+var $fb96b826c0c5f37a$var$n, $fb96b826c0c5f37a$export$41c562ebe57d11e2, $fb96b826c0c5f37a$var$u, $fb96b826c0c5f37a$var$t, $fb96b826c0c5f37a$var$r, $fb96b826c0c5f37a$var$o, $fb96b826c0c5f37a$var$e = {}, $fb96b826c0c5f37a$var$c = [], $fb96b826c0c5f37a$var$s = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;
+function $fb96b826c0c5f37a$var$a(n1, l1) {
+ for (var u1 in l1) n1[u1] = l1[u1];
+ return n1;
+}
+function $fb96b826c0c5f37a$var$h(n2) {
+ var l2 = n2.parentNode;
+ l2 && l2.removeChild(n2);
+}
+function $fb96b826c0c5f37a$export$c8a8987d4410bf2d(l3, u2, i1) {
+ var t1, r1, o1, f1 = {};
+ for (o1 in u2) "key" == o1 ? t1 = u2[o1] : "ref" == o1 ? r1 = u2[o1] : f1[o1] = u2[o1];
+ if (arguments.length > 2 && (f1.children = arguments.length > 3 ? $fb96b826c0c5f37a$var$n.call(arguments, 2) : i1), "function" == typeof l3 && null != l3.defaultProps) for (o1 in l3.defaultProps) void 0 === f1[o1] && (f1[o1] = l3.defaultProps[o1]);
+ return $fb96b826c0c5f37a$var$y(l3, f1, t1, r1, null);
+}
+function $fb96b826c0c5f37a$var$y(n3, i2, t2, r2, o2) {
+ var f2 = {
+ type: n3,
+ props: i2,
+ key: t2,
+ ref: r2,
+ __k: null,
+ __: null,
+ __b: 0,
+ __e: null,
+ __d: void 0,
+ __c: null,
+ __h: null,
+ constructor: void 0,
+ __v: null == o2 ? ++$fb96b826c0c5f37a$var$u : o2
+ };
+ return null == o2 && null != $fb96b826c0c5f37a$export$41c562ebe57d11e2.vnode && $fb96b826c0c5f37a$export$41c562ebe57d11e2.vnode(f2), f2;
+}
+function $fb96b826c0c5f37a$export$7d1e3a5e95ceca43() {
+ return {
+ current: null
+ };
+}
+function $fb96b826c0c5f37a$export$ffb0004e005737fa(n4) {
+ return n4.children;
+}
+function $fb96b826c0c5f37a$export$16fa2f45be04daa8(n5, l4) {
+ this.props = n5, this.context = l4;
+}
+function $fb96b826c0c5f37a$var$k(n6, l5) {
+ if (null == l5) return n6.__ ? $fb96b826c0c5f37a$var$k(n6.__, n6.__.__k.indexOf(n6) + 1) : null;
+ for (var u3; l5 < n6.__k.length; l5++) if (null != (u3 = n6.__k[l5]) && null != u3.__e) return u3.__e;
+ return "function" == typeof n6.type ? $fb96b826c0c5f37a$var$k(n6) : null;
+}
+function $fb96b826c0c5f37a$var$b(n7) {
+ var l6, u4;
+ if (null != (n7 = n7.__) && null != n7.__c) {
+ for (n7.__e = n7.__c.base = null, l6 = 0; l6 < n7.__k.length; l6++) if (null != (u4 = n7.__k[l6]) && null != u4.__e) {
+ n7.__e = n7.__c.base = u4.__e;
+ break;
+ }
+ return $fb96b826c0c5f37a$var$b(n7);
+ }
+}
+function $fb96b826c0c5f37a$var$m(n8) {
+ (!n8.__d && (n8.__d = true) && $fb96b826c0c5f37a$var$t.push(n8) && !$fb96b826c0c5f37a$var$g.__r++ || $fb96b826c0c5f37a$var$o !== $fb96b826c0c5f37a$export$41c562ebe57d11e2.debounceRendering) && (($fb96b826c0c5f37a$var$o = $fb96b826c0c5f37a$export$41c562ebe57d11e2.debounceRendering) || $fb96b826c0c5f37a$var$r)($fb96b826c0c5f37a$var$g);
+}
+function $fb96b826c0c5f37a$var$g() {
+ for (var n9; $fb96b826c0c5f37a$var$g.__r = $fb96b826c0c5f37a$var$t.length; ) n9 = $fb96b826c0c5f37a$var$t.sort(function(n10, l7) {
+ return n10.__v.__b - l7.__v.__b;
+ }), $fb96b826c0c5f37a$var$t = [], n9.some(function(n11) {
+ var l8, u5, i3, t3, r3, o3;
+ n11.__d && (r3 = (t3 = (l8 = n11).__v).__e, (o3 = l8.__P) && (u5 = [], (i3 = $fb96b826c0c5f37a$var$a({}, t3)).__v = t3.__v + 1, $fb96b826c0c5f37a$var$j(o3, t3, i3, l8.__n, void 0 !== o3.ownerSVGElement, null != t3.__h ? [
+ r3
+ ] : null, u5, null == r3 ? $fb96b826c0c5f37a$var$k(t3) : r3, t3.__h), $fb96b826c0c5f37a$var$z(u5, t3), t3.__e != r3 && $fb96b826c0c5f37a$var$b(t3)));
+ });
+}
+function $fb96b826c0c5f37a$var$w(n12, l9, u6, i4, t4, r4, o4, f3, s1, a1) {
+ var h1, v1, p1, _1, b1, m1, g1, w1 = i4 && i4.__k || $fb96b826c0c5f37a$var$c, A1 = w1.length;
+ for (u6.__k = [], h1 = 0; h1 < l9.length; h1++) if (null != (_1 = u6.__k[h1] = null == (_1 = l9[h1]) || "boolean" == typeof _1 ? null : "string" == typeof _1 || "number" == typeof _1 || "bigint" == typeof _1 ? $fb96b826c0c5f37a$var$y(null, _1, null, null, _1) : Array.isArray(_1) ? $fb96b826c0c5f37a$var$y($fb96b826c0c5f37a$export$ffb0004e005737fa, {
+ children: _1
+ }, null, null, null) : _1.__b > 0 ? $fb96b826c0c5f37a$var$y(_1.type, _1.props, _1.key, null, _1.__v) : _1)) {
+ if (_1.__ = u6, _1.__b = u6.__b + 1, null === (p1 = w1[h1]) || p1 && _1.key == p1.key && _1.type === p1.type) w1[h1] = void 0;
+ else for (v1 = 0; v1 < A1; v1++) {
+ if ((p1 = w1[v1]) && _1.key == p1.key && _1.type === p1.type) {
+ w1[v1] = void 0;
+ break;
+ }
+ p1 = null;
+ }
+ $fb96b826c0c5f37a$var$j(n12, _1, p1 = p1 || $fb96b826c0c5f37a$var$e, t4, r4, o4, f3, s1, a1), b1 = _1.__e, (v1 = _1.ref) && p1.ref != v1 && (g1 || (g1 = []), p1.ref && g1.push(p1.ref, null, _1), g1.push(v1, _1.__c || b1, _1)), null != b1 ? (null == m1 && (m1 = b1), "function" == typeof _1.type && _1.__k === p1.__k ? _1.__d = s1 = $fb96b826c0c5f37a$var$x(_1, s1, n12) : s1 = $fb96b826c0c5f37a$var$P(n12, _1, p1, w1, b1, s1), "function" == typeof u6.type && (u6.__d = s1)) : s1 && p1.__e == s1 && s1.parentNode != n12 && (s1 = $fb96b826c0c5f37a$var$k(p1));
+ }
+ for (u6.__e = m1, h1 = A1; h1--; ) null != w1[h1] && ("function" == typeof u6.type && null != w1[h1].__e && w1[h1].__e == u6.__d && (u6.__d = $fb96b826c0c5f37a$var$k(i4, h1 + 1)), $fb96b826c0c5f37a$var$N(w1[h1], w1[h1]));
+ if (g1) for (h1 = 0; h1 < g1.length; h1++) $fb96b826c0c5f37a$var$M(g1[h1], g1[++h1], g1[++h1]);
+}
+function $fb96b826c0c5f37a$var$x(n13, l10, u7) {
+ for (var i5, t5 = n13.__k, r5 = 0; t5 && r5 < t5.length; r5++) (i5 = t5[r5]) && (i5.__ = n13, l10 = "function" == typeof i5.type ? $fb96b826c0c5f37a$var$x(i5, l10, u7) : $fb96b826c0c5f37a$var$P(u7, i5, i5, t5, i5.__e, l10));
+ return l10;
+}
+function $fb96b826c0c5f37a$export$47e4c5b300681277(n14, l11) {
+ return l11 = l11 || [], null == n14 || "boolean" == typeof n14 || (Array.isArray(n14) ? n14.some(function(n15) {
+ $fb96b826c0c5f37a$export$47e4c5b300681277(n15, l11);
+ }) : l11.push(n14)), l11;
+}
+function $fb96b826c0c5f37a$var$P(n16, l12, u8, i6, t6, r6) {
+ var o5, f4, e1;
+ if (void 0 !== l12.__d) o5 = l12.__d, l12.__d = void 0;
+ else if (null == u8 || t6 != r6 || null == t6.parentNode) n: if (null == r6 || r6.parentNode !== n16) n16.appendChild(t6), o5 = null;
+ else {
+ for (f4 = r6, e1 = 0; (f4 = f4.nextSibling) && e1 < i6.length; e1 += 2) if (f4 == t6) break n;
+ n16.insertBefore(t6, r6), o5 = r6;
+ }
+ return void 0 !== o5 ? o5 : t6.nextSibling;
+}
+function $fb96b826c0c5f37a$var$C(n17, l13, u9, i7, t7) {
+ var r7;
+ for (r7 in u9) "children" === r7 || "key" === r7 || r7 in l13 || $fb96b826c0c5f37a$var$H(n17, r7, null, u9[r7], i7);
+ for (r7 in l13) t7 && "function" != typeof l13[r7] || "children" === r7 || "key" === r7 || "value" === r7 || "checked" === r7 || u9[r7] === l13[r7] || $fb96b826c0c5f37a$var$H(n17, r7, l13[r7], u9[r7], i7);
+}
+function $fb96b826c0c5f37a$var$$(n18, l14, u10) {
+ "-" === l14[0] ? n18.setProperty(l14, u10) : n18[l14] = null == u10 ? "" : "number" != typeof u10 || $fb96b826c0c5f37a$var$s.test(l14) ? u10 : u10 + "px";
+}
+function $fb96b826c0c5f37a$var$H(n19, l15, u11, i8, t8) {
+ var r8;
+ n: if ("style" === l15) {
+ if ("string" == typeof u11) n19.style.cssText = u11;
+ else {
+ if ("string" == typeof i8 && (n19.style.cssText = i8 = ""), i8) for (l15 in i8) u11 && l15 in u11 || $fb96b826c0c5f37a$var$$(n19.style, l15, "");
+ if (u11) for (l15 in u11) i8 && u11[l15] === i8[l15] || $fb96b826c0c5f37a$var$$(n19.style, l15, u11[l15]);
+ }
+ } else if ("o" === l15[0] && "n" === l15[1]) r8 = l15 !== (l15 = l15.replace(/Capture$/, "")), l15 = l15.toLowerCase() in n19 ? l15.toLowerCase().slice(2) : l15.slice(2), n19.l || (n19.l = {}), n19.l[l15 + r8] = u11, u11 ? i8 || n19.addEventListener(l15, r8 ? $fb96b826c0c5f37a$var$T : $fb96b826c0c5f37a$var$I, r8) : n19.removeEventListener(l15, r8 ? $fb96b826c0c5f37a$var$T : $fb96b826c0c5f37a$var$I, r8);
+ else if ("dangerouslySetInnerHTML" !== l15) {
+ if (t8) l15 = l15.replace(/xlink[H:h]/, "h").replace(/sName$/, "s");
+ else if ("href" !== l15 && "list" !== l15 && "form" !== l15 && "tabIndex" !== l15 && "download" !== l15 && l15 in n19) try {
+ n19[l15] = null == u11 ? "" : u11;
+ break n;
+ } catch (n) {
+ }
+ "function" == typeof u11 || (null != u11 && (false !== u11 || "a" === l15[0] && "r" === l15[1]) ? n19.setAttribute(l15, u11) : n19.removeAttribute(l15));
+ }
+}
+function $fb96b826c0c5f37a$var$I(n20) {
+ this.l[n20.type + false]($fb96b826c0c5f37a$export$41c562ebe57d11e2.event ? $fb96b826c0c5f37a$export$41c562ebe57d11e2.event(n20) : n20);
+}
+function $fb96b826c0c5f37a$var$T(n21) {
+ this.l[n21.type + true]($fb96b826c0c5f37a$export$41c562ebe57d11e2.event ? $fb96b826c0c5f37a$export$41c562ebe57d11e2.event(n21) : n21);
+}
+function $fb96b826c0c5f37a$var$j(n22, u12, i9, t9, r9, o6, f5, e2, c1) {
+ var s2, h2, v2, y1, p2, k1, b2, m2, g2, x1, A2, P1 = u12.type;
+ if (void 0 !== u12.constructor) return null;
+ null != i9.__h && (c1 = i9.__h, e2 = u12.__e = i9.__e, u12.__h = null, o6 = [
+ e2
+ ]), (s2 = $fb96b826c0c5f37a$export$41c562ebe57d11e2.__b) && s2(u12);
+ try {
+ n: if ("function" == typeof P1) {
+ if (m2 = u12.props, g2 = (s2 = P1.contextType) && t9[s2.__c], x1 = s2 ? g2 ? g2.props.value : s2.__ : t9, i9.__c ? b2 = (h2 = u12.__c = i9.__c).__ = h2.__E : ("prototype" in P1 && P1.prototype.render ? u12.__c = h2 = new P1(m2, x1) : (u12.__c = h2 = new $fb96b826c0c5f37a$export$16fa2f45be04daa8(m2, x1), h2.constructor = P1, h2.render = $fb96b826c0c5f37a$var$O), g2 && g2.sub(h2), h2.props = m2, h2.state || (h2.state = {}), h2.context = x1, h2.__n = t9, v2 = h2.__d = true, h2.__h = []), null == h2.__s && (h2.__s = h2.state), null != P1.getDerivedStateFromProps && (h2.__s == h2.state && (h2.__s = $fb96b826c0c5f37a$var$a({}, h2.__s)), $fb96b826c0c5f37a$var$a(h2.__s, P1.getDerivedStateFromProps(m2, h2.__s))), y1 = h2.props, p2 = h2.state, v2) null == P1.getDerivedStateFromProps && null != h2.componentWillMount && h2.componentWillMount(), null != h2.componentDidMount && h2.__h.push(h2.componentDidMount);
+ else {
+ if (null == P1.getDerivedStateFromProps && m2 !== y1 && null != h2.componentWillReceiveProps && h2.componentWillReceiveProps(m2, x1), !h2.__e && null != h2.shouldComponentUpdate && false === h2.shouldComponentUpdate(m2, h2.__s, x1) || u12.__v === i9.__v) {
+ h2.props = m2, h2.state = h2.__s, u12.__v !== i9.__v && (h2.__d = false), h2.__v = u12, u12.__e = i9.__e, u12.__k = i9.__k, u12.__k.forEach(function(n23) {
+ n23 && (n23.__ = u12);
+ }), h2.__h.length && f5.push(h2);
+ break n;
+ }
+ null != h2.componentWillUpdate && h2.componentWillUpdate(m2, h2.__s, x1), null != h2.componentDidUpdate && h2.__h.push(function() {
+ h2.componentDidUpdate(y1, p2, k1);
+ });
+ }
+ h2.context = x1, h2.props = m2, h2.state = h2.__s, (s2 = $fb96b826c0c5f37a$export$41c562ebe57d11e2.__r) && s2(u12), h2.__d = false, h2.__v = u12, h2.__P = n22, s2 = h2.render(h2.props, h2.state, h2.context), h2.state = h2.__s, null != h2.getChildContext && (t9 = $fb96b826c0c5f37a$var$a($fb96b826c0c5f37a$var$a({}, t9), h2.getChildContext())), v2 || null == h2.getSnapshotBeforeUpdate || (k1 = h2.getSnapshotBeforeUpdate(y1, p2)), A2 = null != s2 && s2.type === $fb96b826c0c5f37a$export$ffb0004e005737fa && null == s2.key ? s2.props.children : s2, $fb96b826c0c5f37a$var$w(n22, Array.isArray(A2) ? A2 : [
+ A2
+ ], u12, i9, t9, r9, o6, f5, e2, c1), h2.base = u12.__e, u12.__h = null, h2.__h.length && f5.push(h2), b2 && (h2.__E = h2.__ = null), h2.__e = false;
+ } else null == o6 && u12.__v === i9.__v ? (u12.__k = i9.__k, u12.__e = i9.__e) : u12.__e = $fb96b826c0c5f37a$var$L(i9.__e, u12, i9, t9, r9, o6, f5, c1);
+ (s2 = $fb96b826c0c5f37a$export$41c562ebe57d11e2.diffed) && s2(u12);
+ } catch (n24) {
+ u12.__v = null, (c1 || null != o6) && (u12.__e = e2, u12.__h = !!c1, o6[o6.indexOf(e2)] = null), $fb96b826c0c5f37a$export$41c562ebe57d11e2.__e(n24, u12, i9);
+ }
+}
+function $fb96b826c0c5f37a$var$z(n25, u13) {
+ $fb96b826c0c5f37a$export$41c562ebe57d11e2.__c && $fb96b826c0c5f37a$export$41c562ebe57d11e2.__c(u13, n25), n25.some(function(u14) {
+ try {
+ n25 = u14.__h, u14.__h = [], n25.some(function(n26) {
+ n26.call(u14);
+ });
+ } catch (n27) {
+ $fb96b826c0c5f37a$export$41c562ebe57d11e2.__e(n27, u14.__v);
+ }
+ });
+}
+function $fb96b826c0c5f37a$var$L(l16, u15, i10, t10, r10, o7, f6, c2) {
+ var s3, a2, v3, y2 = i10.props, p3 = u15.props, d1 = u15.type, _2 = 0;
+ if ("svg" === d1 && (r10 = true), null != o7) {
+ for (; _2 < o7.length; _2++) if ((s3 = o7[_2]) && "setAttribute" in s3 == !!d1 && (d1 ? s3.localName === d1 : 3 === s3.nodeType)) {
+ l16 = s3, o7[_2] = null;
+ break;
+ }
+ }
+ if (null == l16) {
+ if (null === d1) return document.createTextNode(p3);
+ l16 = r10 ? document.createElementNS("http://www.w3.org/2000/svg", d1) : document.createElement(d1, p3.is && p3), o7 = null, c2 = false;
+ }
+ if (null === d1) y2 === p3 || c2 && l16.data === p3 || (l16.data = p3);
+ else {
+ if (o7 = o7 && $fb96b826c0c5f37a$var$n.call(l16.childNodes), a2 = (y2 = i10.props || $fb96b826c0c5f37a$var$e).dangerouslySetInnerHTML, v3 = p3.dangerouslySetInnerHTML, !c2) {
+ if (null != o7) for (y2 = {}, _2 = 0; _2 < l16.attributes.length; _2++) y2[l16.attributes[_2].name] = l16.attributes[_2].value;
+ (v3 || a2) && (v3 && (a2 && v3.__html == a2.__html || v3.__html === l16.innerHTML) || (l16.innerHTML = v3 && v3.__html || ""));
+ }
+ if ($fb96b826c0c5f37a$var$C(l16, p3, y2, r10, c2), v3) u15.__k = [];
+ else if (_2 = u15.props.children, $fb96b826c0c5f37a$var$w(l16, Array.isArray(_2) ? _2 : [
+ _2
+ ], u15, i10, t10, r10 && "foreignObject" !== d1, o7, f6, o7 ? o7[0] : i10.__k && $fb96b826c0c5f37a$var$k(i10, 0), c2), null != o7) for (_2 = o7.length; _2--; ) null != o7[_2] && $fb96b826c0c5f37a$var$h(o7[_2]);
+ c2 || ("value" in p3 && void 0 !== (_2 = p3.value) && (_2 !== y2.value || _2 !== l16.value || "progress" === d1 && !_2) && $fb96b826c0c5f37a$var$H(l16, "value", _2, y2.value, false), "checked" in p3 && void 0 !== (_2 = p3.checked) && _2 !== l16.checked && $fb96b826c0c5f37a$var$H(l16, "checked", _2, y2.checked, false));
+ }
+ return l16;
+}
+function $fb96b826c0c5f37a$var$M(n28, u16, i11) {
+ try {
+ "function" == typeof n28 ? n28(u16) : n28.current = u16;
+ } catch (n29) {
+ $fb96b826c0c5f37a$export$41c562ebe57d11e2.__e(n29, i11);
+ }
+}
+function $fb96b826c0c5f37a$var$N(n30, u17, i12) {
+ var t11, r11;
+ if ($fb96b826c0c5f37a$export$41c562ebe57d11e2.unmount && $fb96b826c0c5f37a$export$41c562ebe57d11e2.unmount(n30), (t11 = n30.ref) && (t11.current && t11.current !== n30.__e || $fb96b826c0c5f37a$var$M(t11, null, u17)), null != (t11 = n30.__c)) {
+ if (t11.componentWillUnmount) try {
+ t11.componentWillUnmount();
+ } catch (n31) {
+ $fb96b826c0c5f37a$export$41c562ebe57d11e2.__e(n31, u17);
+ }
+ t11.base = t11.__P = null;
+ }
+ if (t11 = n30.__k) for (r11 = 0; r11 < t11.length; r11++) t11[r11] && $fb96b826c0c5f37a$var$N(t11[r11], u17, "function" != typeof n30.type);
+ i12 || null == n30.__e || $fb96b826c0c5f37a$var$h(n30.__e), n30.__e = n30.__d = void 0;
+}
+function $fb96b826c0c5f37a$var$O(n32, l, u18) {
+ return this.constructor(n32, u18);
+}
+function $fb96b826c0c5f37a$export$b3890eb0ae9dca99(u19, i13, t12) {
+ var r12, o8, f7;
+ $fb96b826c0c5f37a$export$41c562ebe57d11e2.__ && $fb96b826c0c5f37a$export$41c562ebe57d11e2.__(u19, i13), o8 = (r12 = "function" == typeof t12) ? null : t12 && t12.__k || i13.__k, f7 = [], $fb96b826c0c5f37a$var$j(i13, u19 = (!r12 && t12 || i13).__k = $fb96b826c0c5f37a$export$c8a8987d4410bf2d($fb96b826c0c5f37a$export$ffb0004e005737fa, null, [
+ u19
+ ]), o8 || $fb96b826c0c5f37a$var$e, $fb96b826c0c5f37a$var$e, void 0 !== i13.ownerSVGElement, !r12 && t12 ? [
+ t12
+ ] : o8 ? null : i13.firstChild ? $fb96b826c0c5f37a$var$n.call(i13.childNodes) : null, f7, !r12 && t12 ? t12 : o8 ? o8.__e : i13.firstChild, r12), $fb96b826c0c5f37a$var$z(f7, u19);
+}
+$fb96b826c0c5f37a$var$n = $fb96b826c0c5f37a$var$c.slice, $fb96b826c0c5f37a$export$41c562ebe57d11e2 = {
+ __e: function(n39, l22) {
+ for (var u23, i16, t14; l22 = l22.__; ) if ((u23 = l22.__c) && !u23.__) try {
+ if ((i16 = u23.constructor) && null != i16.getDerivedStateFromError && (u23.setState(i16.getDerivedStateFromError(n39)), t14 = u23.__d), null != u23.componentDidCatch && (u23.componentDidCatch(n39), t14 = u23.__d), t14) return u23.__E = u23;
+ } catch (l23) {
+ n39 = l23;
+ }
+ throw n39;
+ }
+}, $fb96b826c0c5f37a$var$u = 0, $fb96b826c0c5f37a$export$16fa2f45be04daa8.prototype.setState = function(n41, l24) {
+ var u24;
+ u24 = null != this.__s && this.__s !== this.state ? this.__s : this.__s = $fb96b826c0c5f37a$var$a({}, this.state), "function" == typeof n41 && (n41 = n41($fb96b826c0c5f37a$var$a({}, u24), this.props)), n41 && $fb96b826c0c5f37a$var$a(u24, n41), null != n41 && this.__v && (l24 && this.__h.push(l24), $fb96b826c0c5f37a$var$m(this));
+}, $fb96b826c0c5f37a$export$16fa2f45be04daa8.prototype.forceUpdate = function(n42) {
+ this.__v && (this.__e = true, n42 && this.__h.push(n42), $fb96b826c0c5f37a$var$m(this));
+}, $fb96b826c0c5f37a$export$16fa2f45be04daa8.prototype.render = $fb96b826c0c5f37a$export$ffb0004e005737fa, $fb96b826c0c5f37a$var$t = [], $fb96b826c0c5f37a$var$r = "function" == typeof Promise ? Promise.prototype.then.bind(Promise.resolve()) : setTimeout, $fb96b826c0c5f37a$var$g.__r = 0;
+var $bd9dd35321b03dd4$var$o = 0;
+function $bd9dd35321b03dd4$export$34b9dba7ce09269b(_1, e1, n, t, f) {
+ var l, s, u = {};
+ for (s in e1) "ref" == s ? l = e1[s] : u[s] = e1[s];
+ var a = {
+ type: _1,
+ props: u,
+ key: n,
+ ref: l,
+ __k: null,
+ __: null,
+ __b: 0,
+ __e: null,
+ __d: void 0,
+ __c: null,
+ __h: null,
+ constructor: void 0,
+ __v: --$bd9dd35321b03dd4$var$o,
+ __source: t,
+ __self: f
+ };
+ if ("function" == typeof _1 && (l = _1.defaultProps)) for (s in l) void 0 === u[s] && (u[s] = l[s]);
+ return $fb96b826c0c5f37a$export$41c562ebe57d11e2.vnode && $fb96b826c0c5f37a$export$41c562ebe57d11e2.vnode(a), a;
+}
+function $f72b75cf796873c7$var$set(key, value) {
+ try {
+ window.localStorage[`emoji-mart.${key}`] = JSON.stringify(value);
+ } catch (error) {
+ }
+}
+function $f72b75cf796873c7$var$get(key) {
+ try {
+ const value = window.localStorage[`emoji-mart.${key}`];
+ if (value) return JSON.parse(value);
+ } catch (error) {
+ }
+}
+var $f72b75cf796873c7$export$2e2bcd8739ae039 = {
+ set: $f72b75cf796873c7$var$set,
+ get: $f72b75cf796873c7$var$get
+};
+const $c84d045dcc34faf5$var$CACHE = /* @__PURE__ */ new Map();
+const $c84d045dcc34faf5$var$VERSIONS = [
+ {
+ v: 15,
+ emoji: "🫨"
+ },
+ {
+ v: 14,
+ emoji: "🫠"
+ },
+ {
+ v: 13.1,
+ emoji: "😶🌫️"
+ },
+ {
+ v: 13,
+ emoji: "🥸"
+ },
+ {
+ v: 12.1,
+ emoji: "🧑🦰"
+ },
+ {
+ v: 12,
+ emoji: "🥱"
+ },
+ {
+ v: 11,
+ emoji: "🥰"
+ },
+ {
+ v: 5,
+ emoji: "🤩"
+ },
+ {
+ v: 4,
+ emoji: "👱♀️"
+ },
+ {
+ v: 3,
+ emoji: "🤣"
+ },
+ {
+ v: 2,
+ emoji: "👋🏻"
+ },
+ {
+ v: 1,
+ emoji: "🙃"
+ }
+];
+function $c84d045dcc34faf5$var$latestVersion() {
+ for (const { v, emoji } of $c84d045dcc34faf5$var$VERSIONS) {
+ if ($c84d045dcc34faf5$var$isSupported(emoji)) return v;
+ }
+}
+function $c84d045dcc34faf5$var$noCountryFlags() {
+ if ($c84d045dcc34faf5$var$isSupported("🇨🇦")) return false;
+ return true;
+}
+function $c84d045dcc34faf5$var$isSupported(emoji) {
+ if ($c84d045dcc34faf5$var$CACHE.has(emoji)) return $c84d045dcc34faf5$var$CACHE.get(emoji);
+ const supported = $c84d045dcc34faf5$var$isEmojiSupported(emoji);
+ $c84d045dcc34faf5$var$CACHE.set(emoji, supported);
+ return supported;
+}
+const $c84d045dcc34faf5$var$isEmojiSupported = (() => {
+ let ctx = null;
+ try {
+ if (!navigator.userAgent.includes("jsdom")) ctx = document.createElement("canvas").getContext("2d", {
+ willReadFrequently: true
+ });
+ } catch {
+ }
+ if (!ctx) return () => false;
+ const CANVAS_HEIGHT = 25;
+ const CANVAS_WIDTH = 20;
+ const textSize = Math.floor(CANVAS_HEIGHT / 2);
+ ctx.font = textSize + "px Arial, Sans-Serif";
+ ctx.textBaseline = "top";
+ ctx.canvas.width = CANVAS_WIDTH * 2;
+ ctx.canvas.height = CANVAS_HEIGHT;
+ return (unicode) => {
+ ctx.clearRect(0, 0, CANVAS_WIDTH * 2, CANVAS_HEIGHT);
+ ctx.fillStyle = "#FF0000";
+ ctx.fillText(unicode, 0, 22);
+ ctx.fillStyle = "#0000FF";
+ ctx.fillText(unicode, CANVAS_WIDTH, 22);
+ const a = ctx.getImageData(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT).data;
+ const count = a.length;
+ let i = 0;
+ for (; i < count && !a[i + 3]; i += 4) ;
+ if (i >= count) return false;
+ const x = CANVAS_WIDTH + i / 4 % CANVAS_WIDTH;
+ const y = Math.floor(i / 4 / CANVAS_WIDTH);
+ const b = ctx.getImageData(x, y, 1, 1).data;
+ if (a[i] !== b[0] || a[i + 2] !== b[2]) return false;
+ if (ctx.measureText(unicode).width >= CANVAS_WIDTH) return false;
+ return true;
+ };
+})();
+var $c84d045dcc34faf5$export$2e2bcd8739ae039 = {
+ latestVersion: $c84d045dcc34faf5$var$latestVersion,
+ noCountryFlags: $c84d045dcc34faf5$var$noCountryFlags
+};
+const $b22cfd0a55410b4f$var$DEFAULTS = [
+ "+1",
+ "grinning",
+ "kissing_heart",
+ "heart_eyes",
+ "laughing",
+ "stuck_out_tongue_winking_eye",
+ "sweat_smile",
+ "joy",
+ "scream",
+ "disappointed",
+ "unamused",
+ "weary",
+ "sob",
+ "sunglasses",
+ "heart"
+];
+let $b22cfd0a55410b4f$var$Index = null;
+function $b22cfd0a55410b4f$var$add(emoji) {
+ $b22cfd0a55410b4f$var$Index || ($b22cfd0a55410b4f$var$Index = $f72b75cf796873c7$export$2e2bcd8739ae039.get("frequently") || {});
+ const emojiId = emoji.id || emoji;
+ if (!emojiId) return;
+ $b22cfd0a55410b4f$var$Index[emojiId] || ($b22cfd0a55410b4f$var$Index[emojiId] = 0);
+ $b22cfd0a55410b4f$var$Index[emojiId] += 1;
+ $f72b75cf796873c7$export$2e2bcd8739ae039.set("last", emojiId);
+ $f72b75cf796873c7$export$2e2bcd8739ae039.set("frequently", $b22cfd0a55410b4f$var$Index);
+}
+function $b22cfd0a55410b4f$var$get({ maxFrequentRows, perLine }) {
+ if (!maxFrequentRows) return [];
+ $b22cfd0a55410b4f$var$Index || ($b22cfd0a55410b4f$var$Index = $f72b75cf796873c7$export$2e2bcd8739ae039.get("frequently"));
+ let emojiIds = [];
+ if (!$b22cfd0a55410b4f$var$Index) {
+ $b22cfd0a55410b4f$var$Index = {};
+ for (let i in $b22cfd0a55410b4f$var$DEFAULTS.slice(0, perLine)) {
+ const emojiId = $b22cfd0a55410b4f$var$DEFAULTS[i];
+ $b22cfd0a55410b4f$var$Index[emojiId] = perLine - i;
+ emojiIds.push(emojiId);
+ }
+ return emojiIds;
+ }
+ const max = maxFrequentRows * perLine;
+ const last = $f72b75cf796873c7$export$2e2bcd8739ae039.get("last");
+ for (let emojiId in $b22cfd0a55410b4f$var$Index) emojiIds.push(emojiId);
+ emojiIds.sort((a, b) => {
+ const aScore = $b22cfd0a55410b4f$var$Index[b];
+ const bScore = $b22cfd0a55410b4f$var$Index[a];
+ if (aScore == bScore) return a.localeCompare(b);
+ return aScore - bScore;
+ });
+ if (emojiIds.length > max) {
+ const removedIds = emojiIds.slice(max);
+ emojiIds = emojiIds.slice(0, max);
+ for (let removedId of removedIds) {
+ if (removedId == last) continue;
+ delete $b22cfd0a55410b4f$var$Index[removedId];
+ }
+ if (last && emojiIds.indexOf(last) == -1) {
+ delete $b22cfd0a55410b4f$var$Index[emojiIds[emojiIds.length - 1]];
+ emojiIds.splice(-1, 1, last);
+ }
+ $f72b75cf796873c7$export$2e2bcd8739ae039.set("frequently", $b22cfd0a55410b4f$var$Index);
+ }
+ return emojiIds;
+}
+var $b22cfd0a55410b4f$export$2e2bcd8739ae039 = {
+ add: $b22cfd0a55410b4f$var$add,
+ get: $b22cfd0a55410b4f$var$get,
+ DEFAULTS: $b22cfd0a55410b4f$var$DEFAULTS
+};
+var $8d50d93417ef682a$exports = {};
+$8d50d93417ef682a$exports = JSON.parse('{"search":"Search","search_no_results_1":"Oh no!","search_no_results_2":"That emoji couldn’t be found","pick":"Pick an emoji…","add_custom":"Add custom emoji","categories":{"activity":"Activity","custom":"Custom","flags":"Flags","foods":"Food & Drink","frequent":"Frequently used","nature":"Animals & Nature","objects":"Objects","people":"Smileys & People","places":"Travel & Places","search":"Search Results","symbols":"Symbols"},"skins":{"1":"Default","2":"Light","3":"Medium-Light","4":"Medium","5":"Medium-Dark","6":"Dark","choose":"Choose default skin tone"}}');
+var $b247ea80b67298d5$export$2e2bcd8739ae039 = {
+ autoFocus: {
+ value: false
+ },
+ dynamicWidth: {
+ value: false
+ },
+ emojiButtonColors: {
+ value: null
+ },
+ emojiButtonRadius: {
+ value: "100%"
+ },
+ emojiButtonSize: {
+ value: 36
+ },
+ emojiSize: {
+ value: 24
+ },
+ emojiVersion: {
+ value: 15,
+ choices: [
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 11,
+ 12,
+ 12.1,
+ 13,
+ 13.1,
+ 14,
+ 15
+ ]
+ },
+ exceptEmojis: {
+ value: []
+ },
+ icons: {
+ value: "auto",
+ choices: [
+ "auto",
+ "outline",
+ "solid"
+ ]
+ },
+ locale: {
+ value: "en",
+ choices: [
+ "en",
+ "ar",
+ "be",
+ "cs",
+ "de",
+ "es",
+ "fa",
+ "fi",
+ "fr",
+ "hi",
+ "it",
+ "ja",
+ "ko",
+ "nl",
+ "pl",
+ "pt",
+ "ru",
+ "sa",
+ "tr",
+ "uk",
+ "vi",
+ "zh"
+ ]
+ },
+ maxFrequentRows: {
+ value: 4
+ },
+ navPosition: {
+ value: "top",
+ choices: [
+ "top",
+ "bottom",
+ "none"
+ ]
+ },
+ noCountryFlags: {
+ value: false
+ },
+ noResultsEmoji: {
+ value: null
+ },
+ perLine: {
+ value: 9
+ },
+ previewEmoji: {
+ value: null
+ },
+ previewPosition: {
+ value: "bottom",
+ choices: [
+ "top",
+ "bottom",
+ "none"
+ ]
+ },
+ searchPosition: {
+ value: "sticky",
+ choices: [
+ "sticky",
+ "static",
+ "none"
+ ]
+ },
+ set: {
+ value: "native",
+ choices: [
+ "native",
+ "apple",
+ "facebook",
+ "google",
+ "twitter"
+ ]
+ },
+ skin: {
+ value: 1,
+ choices: [
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6
+ ]
+ },
+ skinTonePosition: {
+ value: "preview",
+ choices: [
+ "preview",
+ "search",
+ "none"
+ ]
+ },
+ theme: {
+ value: "auto",
+ choices: [
+ "auto",
+ "light",
+ "dark"
+ ]
+ },
+ // Data
+ categories: null,
+ categoryIcons: null,
+ custom: null,
+ data: null,
+ i18n: null,
+ // Callbacks
+ getImageURL: null,
+ getSpritesheetURL: null,
+ onAddCustomEmoji: null,
+ onClickOutside: null,
+ onEmojiSelect: null,
+ // Deprecated
+ stickySearch: {
+ deprecated: true,
+ value: true
+ }
+};
+let $7adb23b0109cc36a$export$dbe3113d60765c1a = null;
+let $7adb23b0109cc36a$export$2d0294657ab35f1b = null;
+const $7adb23b0109cc36a$var$fetchCache = {};
+async function $7adb23b0109cc36a$var$fetchJSON(src) {
+ if ($7adb23b0109cc36a$var$fetchCache[src]) return $7adb23b0109cc36a$var$fetchCache[src];
+ const response = await fetch(src);
+ const json = await response.json();
+ $7adb23b0109cc36a$var$fetchCache[src] = json;
+ return json;
+}
+let $7adb23b0109cc36a$var$promise = null;
+let $7adb23b0109cc36a$var$initCallback = null;
+let $7adb23b0109cc36a$var$initialized = false;
+function $7adb23b0109cc36a$export$2cd8252107eb640b(options, { caller } = {}) {
+ $7adb23b0109cc36a$var$promise || ($7adb23b0109cc36a$var$promise = new Promise((resolve) => {
+ $7adb23b0109cc36a$var$initCallback = resolve;
+ }));
+ if (options) $7adb23b0109cc36a$var$_init(options);
+ else if (caller && !$7adb23b0109cc36a$var$initialized) console.warn(`\`${caller}\` requires data to be initialized first. Promise will be pending until \`init\` is called.`);
+ return $7adb23b0109cc36a$var$promise;
+}
+async function $7adb23b0109cc36a$var$_init(props) {
+ $7adb23b0109cc36a$var$initialized = true;
+ let { emojiVersion, set, locale } = props;
+ emojiVersion || (emojiVersion = $b247ea80b67298d5$export$2e2bcd8739ae039.emojiVersion.value);
+ set || (set = $b247ea80b67298d5$export$2e2bcd8739ae039.set.value);
+ locale || (locale = $b247ea80b67298d5$export$2e2bcd8739ae039.locale.value);
+ if (!$7adb23b0109cc36a$export$2d0294657ab35f1b) {
+ $7adb23b0109cc36a$export$2d0294657ab35f1b = (typeof props.data === "function" ? await props.data() : props.data) || await $7adb23b0109cc36a$var$fetchJSON(`https://cdn.jsdelivr.net/npm/@emoji-mart/data@latest/sets/${emojiVersion}/${set}.json`);
+ $7adb23b0109cc36a$export$2d0294657ab35f1b.emoticons = {};
+ $7adb23b0109cc36a$export$2d0294657ab35f1b.natives = {};
+ $7adb23b0109cc36a$export$2d0294657ab35f1b.categories.unshift({
+ id: "frequent",
+ emojis: []
+ });
+ for (const alias in $7adb23b0109cc36a$export$2d0294657ab35f1b.aliases) {
+ const emojiId = $7adb23b0109cc36a$export$2d0294657ab35f1b.aliases[alias];
+ const emoji = $7adb23b0109cc36a$export$2d0294657ab35f1b.emojis[emojiId];
+ if (!emoji) continue;
+ emoji.aliases || (emoji.aliases = []);
+ emoji.aliases.push(alias);
+ }
+ $7adb23b0109cc36a$export$2d0294657ab35f1b.originalCategories = $7adb23b0109cc36a$export$2d0294657ab35f1b.categories;
+ } else $7adb23b0109cc36a$export$2d0294657ab35f1b.categories = $7adb23b0109cc36a$export$2d0294657ab35f1b.categories.filter((c) => {
+ const isCustom = !!c.name;
+ if (!isCustom) return true;
+ return false;
+ });
+ $7adb23b0109cc36a$export$dbe3113d60765c1a = (typeof props.i18n === "function" ? await props.i18n() : props.i18n) || (locale == "en" ? /* @__PURE__ */ $parcel$interopDefault($8d50d93417ef682a$exports) : await $7adb23b0109cc36a$var$fetchJSON(`https://cdn.jsdelivr.net/npm/@emoji-mart/data@latest/i18n/${locale}.json`));
+ if (props.custom) for (let i in props.custom) {
+ i = parseInt(i);
+ const category = props.custom[i];
+ const prevCategory = props.custom[i - 1];
+ if (!category.emojis || !category.emojis.length) continue;
+ category.id || (category.id = `custom_${i + 1}`);
+ category.name || (category.name = $7adb23b0109cc36a$export$dbe3113d60765c1a.categories.custom);
+ if (prevCategory && !category.icon) category.target = prevCategory.target || prevCategory;
+ $7adb23b0109cc36a$export$2d0294657ab35f1b.categories.push(category);
+ for (const emoji of category.emojis) $7adb23b0109cc36a$export$2d0294657ab35f1b.emojis[emoji.id] = emoji;
+ }
+ if (props.categories) $7adb23b0109cc36a$export$2d0294657ab35f1b.categories = $7adb23b0109cc36a$export$2d0294657ab35f1b.originalCategories.filter((c) => {
+ return props.categories.indexOf(c.id) != -1;
+ }).sort((c1, c2) => {
+ const i1 = props.categories.indexOf(c1.id);
+ const i2 = props.categories.indexOf(c2.id);
+ return i1 - i2;
+ });
+ let latestVersionSupport = null;
+ let noCountryFlags = null;
+ if (set == "native") {
+ latestVersionSupport = $c84d045dcc34faf5$export$2e2bcd8739ae039.latestVersion();
+ noCountryFlags = props.noCountryFlags || $c84d045dcc34faf5$export$2e2bcd8739ae039.noCountryFlags();
+ }
+ let categoryIndex = $7adb23b0109cc36a$export$2d0294657ab35f1b.categories.length;
+ let resetSearchIndex = false;
+ while (categoryIndex--) {
+ const category = $7adb23b0109cc36a$export$2d0294657ab35f1b.categories[categoryIndex];
+ if (category.id == "frequent") {
+ let { maxFrequentRows, perLine } = props;
+ maxFrequentRows = maxFrequentRows >= 0 ? maxFrequentRows : $b247ea80b67298d5$export$2e2bcd8739ae039.maxFrequentRows.value;
+ perLine || (perLine = $b247ea80b67298d5$export$2e2bcd8739ae039.perLine.value);
+ category.emojis = $b22cfd0a55410b4f$export$2e2bcd8739ae039.get({
+ maxFrequentRows,
+ perLine
+ });
+ }
+ if (!category.emojis || !category.emojis.length) {
+ $7adb23b0109cc36a$export$2d0294657ab35f1b.categories.splice(categoryIndex, 1);
+ continue;
+ }
+ const { categoryIcons } = props;
+ if (categoryIcons) {
+ const icon = categoryIcons[category.id];
+ if (icon && !category.icon) category.icon = icon;
+ }
+ let emojiIndex = category.emojis.length;
+ while (emojiIndex--) {
+ const emojiId = category.emojis[emojiIndex];
+ const emoji = emojiId.id ? emojiId : $7adb23b0109cc36a$export$2d0294657ab35f1b.emojis[emojiId];
+ const ignore = () => {
+ category.emojis.splice(emojiIndex, 1);
+ };
+ if (!emoji || props.exceptEmojis && props.exceptEmojis.includes(emoji.id)) {
+ ignore();
+ continue;
+ }
+ if (latestVersionSupport && emoji.version > latestVersionSupport) {
+ ignore();
+ continue;
+ }
+ if (noCountryFlags && category.id == "flags") {
+ if (!$e6eae5155b87f591$export$bcb25aa587e9cb13.includes(emoji.id)) {
+ ignore();
+ continue;
+ }
+ }
+ if (!emoji.search) {
+ resetSearchIndex = true;
+ emoji.search = "," + [
+ [
+ emoji.id,
+ false
+ ],
+ [
+ emoji.name,
+ true
+ ],
+ [
+ emoji.keywords,
+ false
+ ],
+ [
+ emoji.emoticons,
+ false
+ ]
+ ].map(([strings, split]) => {
+ if (!strings) return;
+ return (Array.isArray(strings) ? strings : [
+ strings
+ ]).map((string) => {
+ return (split ? string.split(/[-|_|\s]+/) : [
+ string
+ ]).map((s) => s.toLowerCase());
+ }).flat();
+ }).flat().filter((a) => a && a.trim()).join(",");
+ if (emoji.emoticons) for (const emoticon of emoji.emoticons) {
+ if ($7adb23b0109cc36a$export$2d0294657ab35f1b.emoticons[emoticon]) continue;
+ $7adb23b0109cc36a$export$2d0294657ab35f1b.emoticons[emoticon] = emoji.id;
+ }
+ let skinIndex = 0;
+ for (const skin of emoji.skins) {
+ if (!skin) continue;
+ skinIndex++;
+ const { native } = skin;
+ if (native) {
+ $7adb23b0109cc36a$export$2d0294657ab35f1b.natives[native] = emoji.id;
+ emoji.search += `,${native}`;
+ }
+ const skinShortcodes = skinIndex == 1 ? "" : `:skin-tone-${skinIndex}:`;
+ skin.shortcodes = `:${emoji.id}:${skinShortcodes}`;
+ }
+ }
+ }
+ }
+ if (resetSearchIndex) $c4d155af13ad4d4b$export$2e2bcd8739ae039.reset();
+ $7adb23b0109cc36a$var$initCallback();
+}
+function $7adb23b0109cc36a$export$75fe5f91d452f94b(props, defaultProps, element) {
+ props || (props = {});
+ const _props = {};
+ for (let k in defaultProps) _props[k] = $7adb23b0109cc36a$export$88c9ddb45cea7241(k, props, defaultProps, element);
+ return _props;
+}
+function $7adb23b0109cc36a$export$88c9ddb45cea7241(propName, props, defaultProps, element) {
+ const defaults = defaultProps[propName];
+ let value = element && element.getAttribute(propName) || (props[propName] != null && props[propName] != void 0 ? props[propName] : null);
+ if (!defaults) return value;
+ if (value != null && defaults.value && typeof defaults.value != typeof value) {
+ if (typeof defaults.value == "boolean") value = value == "false" ? false : true;
+ else value = defaults.value.constructor(value);
+ }
+ if (defaults.transform && value) value = defaults.transform(value);
+ if (value == null || defaults.choices && defaults.choices.indexOf(value) == -1) value = defaults.value;
+ return value;
+}
+const $c4d155af13ad4d4b$var$SHORTCODES_REGEX = /^(?:\:([^\:]+)\:)(?:\:skin-tone-(\d)\:)?$/;
+let $c4d155af13ad4d4b$var$Pool = null;
+function $c4d155af13ad4d4b$var$get(emojiId) {
+ if (emojiId.id) return emojiId;
+ return $7adb23b0109cc36a$export$2d0294657ab35f1b.emojis[emojiId] || $7adb23b0109cc36a$export$2d0294657ab35f1b.emojis[$7adb23b0109cc36a$export$2d0294657ab35f1b.aliases[emojiId]] || $7adb23b0109cc36a$export$2d0294657ab35f1b.emojis[$7adb23b0109cc36a$export$2d0294657ab35f1b.natives[emojiId]];
+}
+function $c4d155af13ad4d4b$var$reset() {
+ $c4d155af13ad4d4b$var$Pool = null;
+}
+async function $c4d155af13ad4d4b$var$search(value, { maxResults, caller } = {}) {
+ if (!value || !value.trim().length) return null;
+ maxResults || (maxResults = 90);
+ await $7adb23b0109cc36a$export$2cd8252107eb640b(null, {
+ caller: caller || "SearchIndex.search"
+ });
+ const values = value.toLowerCase().replace(/(\w)-/, "$1 ").split(/[\s|,]+/).filter((word, i, words) => {
+ return word.trim() && words.indexOf(word) == i;
+ });
+ if (!values.length) return;
+ let pool = $c4d155af13ad4d4b$var$Pool || ($c4d155af13ad4d4b$var$Pool = Object.values($7adb23b0109cc36a$export$2d0294657ab35f1b.emojis));
+ let results, scores;
+ for (const value1 of values) {
+ if (!pool.length) break;
+ results = [];
+ scores = {};
+ for (const emoji of pool) {
+ if (!emoji.search) continue;
+ const score = emoji.search.indexOf(`,${value1}`);
+ if (score == -1) continue;
+ results.push(emoji);
+ scores[emoji.id] || (scores[emoji.id] = 0);
+ scores[emoji.id] += emoji.id == value1 ? 0 : score + 1;
+ }
+ pool = results;
+ }
+ if (results.length < 2) return results;
+ results.sort((a, b) => {
+ const aScore = scores[a.id];
+ const bScore = scores[b.id];
+ if (aScore == bScore) return a.id.localeCompare(b.id);
+ return aScore - bScore;
+ });
+ if (results.length > maxResults) results = results.slice(0, maxResults);
+ return results;
+}
+var $c4d155af13ad4d4b$export$2e2bcd8739ae039 = {
+ search: $c4d155af13ad4d4b$var$search,
+ get: $c4d155af13ad4d4b$var$get,
+ reset: $c4d155af13ad4d4b$var$reset,
+ SHORTCODES_REGEX: $c4d155af13ad4d4b$var$SHORTCODES_REGEX
+};
+const $e6eae5155b87f591$export$bcb25aa587e9cb13 = [
+ "checkered_flag",
+ "crossed_flags",
+ "pirate_flag",
+ "rainbow-flag",
+ "transgender_flag",
+ "triangular_flag_on_post",
+ "waving_black_flag",
+ "waving_white_flag"
+];
+function $693b183b0a78708f$export$9cb4719e2e525b7a(a, b) {
+ return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((val, index) => val == b[index]);
+}
+async function $693b183b0a78708f$export$e772c8ff12451969(frames = 1) {
+ for (let _ in [
+ ...Array(frames).keys()
+ ]) await new Promise(requestAnimationFrame);
+}
+function $693b183b0a78708f$export$d10ac59fbe52a745(emoji, { skinIndex = 0 } = {}) {
+ const skin = emoji.skins[skinIndex] || (() => {
+ skinIndex = 0;
+ return emoji.skins[skinIndex];
+ })();
+ const emojiData = {
+ id: emoji.id,
+ name: emoji.name,
+ native: skin.native,
+ unified: skin.unified,
+ keywords: emoji.keywords,
+ shortcodes: skin.shortcodes || emoji.shortcodes
+ };
+ if (emoji.skins.length > 1) emojiData.skin = skinIndex + 1;
+ if (skin.src) emojiData.src = skin.src;
+ if (emoji.aliases && emoji.aliases.length) emojiData.aliases = emoji.aliases;
+ if (emoji.emoticons && emoji.emoticons.length) emojiData.emoticons = emoji.emoticons;
+ return emojiData;
+}
+async function $693b183b0a78708f$export$5ef5574deca44bc0(nativeString) {
+ const results = await $c4d155af13ad4d4b$export$2e2bcd8739ae039.search(nativeString, {
+ maxResults: 1,
+ caller: "getEmojiDataFromNative"
+ });
+ if (!results || !results.length) return null;
+ const emoji = results[0];
+ let skinIndex = 0;
+ for (let skin of emoji.skins) {
+ if (skin.native == nativeString) break;
+ skinIndex++;
+ }
+ return $693b183b0a78708f$export$d10ac59fbe52a745(emoji, {
+ skinIndex
+ });
+}
+const $fcccfb36ed0cde68$var$categories = {
+ activity: {
+ outline: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("svg", {
+ xmlns: "http://www.w3.org/2000/svg",
+ viewBox: "0 0 24 24",
+ children: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M12 0C5.373 0 0 5.372 0 12c0 6.627 5.373 12 12 12 6.628 0 12-5.373 12-12 0-6.628-5.372-12-12-12m9.949 11H17.05c.224-2.527 1.232-4.773 1.968-6.113A9.966 9.966 0 0 1 21.949 11M13 11V2.051a9.945 9.945 0 0 1 4.432 1.564c-.858 1.491-2.156 4.22-2.392 7.385H13zm-2 0H8.961c-.238-3.165-1.536-5.894-2.393-7.385A9.95 9.95 0 0 1 11 2.051V11zm0 2v8.949a9.937 9.937 0 0 1-4.432-1.564c.857-1.492 2.155-4.221 2.393-7.385H11zm4.04 0c.236 3.164 1.534 5.893 2.392 7.385A9.92 9.92 0 0 1 13 21.949V13h2.04zM4.982 4.887C5.718 6.227 6.726 8.473 6.951 11h-4.9a9.977 9.977 0 0 1 2.931-6.113M2.051 13h4.9c-.226 2.527-1.233 4.771-1.969 6.113A9.972 9.972 0 0 1 2.051 13m16.967 6.113c-.735-1.342-1.744-3.586-1.968-6.113h4.899a9.961 9.961 0 0 1-2.931 6.113"
+ })
+ }),
+ solid: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("svg", {
+ xmlns: "http://www.w3.org/2000/svg",
+ viewBox: "0 0 512 512",
+ children: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M16.17 337.5c0 44.98 7.565 83.54 13.98 107.9C35.22 464.3 50.46 496 174.9 496c9.566 0 19.59-.4707 29.84-1.271L17.33 307.3C16.53 317.6 16.17 327.7 16.17 337.5zM495.8 174.5c0-44.98-7.565-83.53-13.98-107.9c-4.688-17.54-18.34-31.23-36.04-35.95C435.5 27.91 392.9 16 337 16c-9.564 0-19.59 .4707-29.84 1.271l187.5 187.5C495.5 194.4 495.8 184.3 495.8 174.5zM26.77 248.8l236.3 236.3c142-36.1 203.9-150.4 222.2-221.1L248.9 26.87C106.9 62.96 45.07 177.2 26.77 248.8zM256 335.1c0 9.141-7.474 16-16 16c-4.094 0-8.188-1.564-11.31-4.689L164.7 283.3C161.6 280.2 160 276.1 160 271.1c0-8.529 6.865-16 16-16c4.095 0 8.189 1.562 11.31 4.688l64.01 64C254.4 327.8 256 331.9 256 335.1zM304 287.1c0 9.141-7.474 16-16 16c-4.094 0-8.188-1.564-11.31-4.689L212.7 235.3C209.6 232.2 208 228.1 208 223.1c0-9.141 7.473-16 16-16c4.094 0 8.188 1.562 11.31 4.688l64.01 64.01C302.5 279.8 304 283.9 304 287.1zM256 175.1c0-9.141 7.473-16 16-16c4.094 0 8.188 1.562 11.31 4.688l64.01 64.01c3.125 3.125 4.688 7.219 4.688 11.31c0 9.133-7.468 16-16 16c-4.094 0-8.189-1.562-11.31-4.688l-64.01-64.01C257.6 184.2 256 180.1 256 175.1z"
+ })
+ })
+ },
+ custom: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("svg", {
+ xmlns: "http://www.w3.org/2000/svg",
+ viewBox: "0 0 448 512",
+ children: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M417.1 368c-5.937 10.27-16.69 16-27.75 16c-5.422 0-10.92-1.375-15.97-4.281L256 311.4V448c0 17.67-14.33 32-31.1 32S192 465.7 192 448V311.4l-118.3 68.29C68.67 382.6 63.17 384 57.75 384c-11.06 0-21.81-5.734-27.75-16c-8.828-15.31-3.594-34.88 11.72-43.72L159.1 256L41.72 187.7C26.41 178.9 21.17 159.3 29.1 144C36.63 132.5 49.26 126.7 61.65 128.2C65.78 128.7 69.88 130.1 73.72 132.3L192 200.6V64c0-17.67 14.33-32 32-32S256 46.33 256 64v136.6l118.3-68.29c3.838-2.213 7.939-3.539 12.07-4.051C398.7 126.7 411.4 132.5 417.1 144c8.828 15.31 3.594 34.88-11.72 43.72L288 256l118.3 68.28C421.6 333.1 426.8 352.7 417.1 368z"
+ })
+ }),
+ flags: {
+ outline: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("svg", {
+ xmlns: "http://www.w3.org/2000/svg",
+ viewBox: "0 0 24 24",
+ children: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M0 0l6.084 24H8L1.916 0zM21 5h-4l-1-4H4l3 12h3l1 4h13L21 5zM6.563 3h7.875l2 8H8.563l-2-8zm8.832 10l-2.856 1.904L12.063 13h3.332zM19 13l-1.5-6h1.938l2 8H16l3-2z"
+ })
+ }),
+ solid: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("svg", {
+ xmlns: "http://www.w3.org/2000/svg",
+ viewBox: "0 0 512 512",
+ children: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M64 496C64 504.8 56.75 512 48 512h-32C7.25 512 0 504.8 0 496V32c0-17.75 14.25-32 32-32s32 14.25 32 32V496zM476.3 0c-6.365 0-13.01 1.35-19.34 4.233c-45.69 20.86-79.56 27.94-107.8 27.94c-59.96 0-94.81-31.86-163.9-31.87C160.9 .3055 131.6 4.867 96 15.75v350.5c32-9.984 59.87-14.1 84.85-14.1c73.63 0 124.9 31.78 198.6 31.78c31.91 0 68.02-5.971 111.1-23.09C504.1 355.9 512 344.4 512 332.1V30.73C512 11.1 495.3 0 476.3 0z"
+ })
+ })
+ },
+ foods: {
+ outline: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("svg", {
+ xmlns: "http://www.w3.org/2000/svg",
+ viewBox: "0 0 24 24",
+ children: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M17 4.978c-1.838 0-2.876.396-3.68.934.513-1.172 1.768-2.934 4.68-2.934a1 1 0 0 0 0-2c-2.921 0-4.629 1.365-5.547 2.512-.064.078-.119.162-.18.244C11.73 1.838 10.798.023 9.207.023 8.579.022 7.85.306 7 .978 5.027 2.54 5.329 3.902 6.492 4.999 3.609 5.222 0 7.352 0 12.969c0 4.582 4.961 11.009 9 11.009 1.975 0 2.371-.486 3-1 .629.514 1.025 1 3 1 4.039 0 9-6.418 9-11 0-5.953-4.055-8-7-8M8.242 2.546c.641-.508.943-.523.965-.523.426.169.975 1.405 1.357 3.055-1.527-.629-2.741-1.352-2.98-1.846.059-.112.241-.356.658-.686M15 21.978c-1.08 0-1.21-.109-1.559-.402l-.176-.146c-.367-.302-.816-.452-1.266-.452s-.898.15-1.266.452l-.176.146c-.347.292-.477.402-1.557.402-2.813 0-7-5.389-7-9.009 0-5.823 4.488-5.991 5-5.991 1.939 0 2.484.471 3.387 1.251l.323.276a1.995 1.995 0 0 0 2.58 0l.323-.276c.902-.78 1.447-1.251 3.387-1.251.512 0 5 .168 5 6 0 3.617-4.187 9-7 9"
+ })
+ }),
+ solid: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("svg", {
+ xmlns: "http://www.w3.org/2000/svg",
+ viewBox: "0 0 512 512",
+ children: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M481.9 270.1C490.9 279.1 496 291.3 496 304C496 316.7 490.9 328.9 481.9 337.9C472.9 346.9 460.7 352 448 352H64C51.27 352 39.06 346.9 30.06 337.9C21.06 328.9 16 316.7 16 304C16 291.3 21.06 279.1 30.06 270.1C39.06 261.1 51.27 256 64 256H448C460.7 256 472.9 261.1 481.9 270.1zM475.3 388.7C478.3 391.7 480 395.8 480 400V416C480 432.1 473.3 449.3 461.3 461.3C449.3 473.3 432.1 480 416 480H96C79.03 480 62.75 473.3 50.75 461.3C38.74 449.3 32 432.1 32 416V400C32 395.8 33.69 391.7 36.69 388.7C39.69 385.7 43.76 384 48 384H464C468.2 384 472.3 385.7 475.3 388.7zM50.39 220.8C45.93 218.6 42.03 215.5 38.97 211.6C35.91 207.7 33.79 203.2 32.75 198.4C31.71 193.5 31.8 188.5 32.99 183.7C54.98 97.02 146.5 32 256 32C365.5 32 457 97.02 479 183.7C480.2 188.5 480.3 193.5 479.2 198.4C478.2 203.2 476.1 207.7 473 211.6C469.1 215.5 466.1 218.6 461.6 220.8C457.2 222.9 452.3 224 447.3 224H64.67C59.73 224 54.84 222.9 50.39 220.8zM372.7 116.7C369.7 119.7 368 123.8 368 128C368 131.2 368.9 134.3 370.7 136.9C372.5 139.5 374.1 141.6 377.9 142.8C380.8 143.1 384 144.3 387.1 143.7C390.2 143.1 393.1 141.6 395.3 139.3C397.6 137.1 399.1 134.2 399.7 131.1C400.3 128 399.1 124.8 398.8 121.9C397.6 118.1 395.5 116.5 392.9 114.7C390.3 112.9 387.2 111.1 384 111.1C379.8 111.1 375.7 113.7 372.7 116.7V116.7zM244.7 84.69C241.7 87.69 240 91.76 240 96C240 99.16 240.9 102.3 242.7 104.9C244.5 107.5 246.1 109.6 249.9 110.8C252.8 111.1 256 112.3 259.1 111.7C262.2 111.1 265.1 109.6 267.3 107.3C269.6 105.1 271.1 102.2 271.7 99.12C272.3 96.02 271.1 92.8 270.8 89.88C269.6 86.95 267.5 84.45 264.9 82.7C262.3 80.94 259.2 79.1 256 79.1C251.8 79.1 247.7 81.69 244.7 84.69V84.69zM116.7 116.7C113.7 119.7 112 123.8 112 128C112 131.2 112.9 134.3 114.7 136.9C116.5 139.5 118.1 141.6 121.9 142.8C124.8 143.1 128 144.3 131.1 143.7C134.2 143.1 137.1 141.6 139.3 139.3C141.6 137.1 143.1 134.2 143.7 131.1C144.3 128 143.1 124.8 142.8 121.9C141.6 118.1 139.5 116.5 136.9 114.7C134.3 112.9 131.2 111.1 128 111.1C123.8 111.1 119.7 113.7 116.7 116.7L116.7 116.7z"
+ })
+ })
+ },
+ frequent: {
+ outline: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("svg", {
+ xmlns: "http://www.w3.org/2000/svg",
+ viewBox: "0 0 24 24",
+ children: [
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M13 4h-2l-.001 7H9v2h2v2h2v-2h4v-2h-4z"
+ }),
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0m0 22C6.486 22 2 17.514 2 12S6.486 2 12 2s10 4.486 10 10-4.486 10-10 10"
+ })
+ ]
+ }),
+ solid: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("svg", {
+ xmlns: "http://www.w3.org/2000/svg",
+ viewBox: "0 0 512 512",
+ children: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M256 512C114.6 512 0 397.4 0 256C0 114.6 114.6 0 256 0C397.4 0 512 114.6 512 256C512 397.4 397.4 512 256 512zM232 256C232 264 236 271.5 242.7 275.1L338.7 339.1C349.7 347.3 364.6 344.3 371.1 333.3C379.3 322.3 376.3 307.4 365.3 300L280 243.2V120C280 106.7 269.3 96 255.1 96C242.7 96 231.1 106.7 231.1 120L232 256z"
+ })
+ })
+ },
+ nature: {
+ outline: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("svg", {
+ xmlns: "http://www.w3.org/2000/svg",
+ viewBox: "0 0 24 24",
+ children: [
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M15.5 8a1.5 1.5 0 1 0 .001 3.001A1.5 1.5 0 0 0 15.5 8M8.5 8a1.5 1.5 0 1 0 .001 3.001A1.5 1.5 0 0 0 8.5 8"
+ }),
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M18.933 0h-.027c-.97 0-2.138.787-3.018 1.497-1.274-.374-2.612-.51-3.887-.51-1.285 0-2.616.133-3.874.517C7.245.79 6.069 0 5.093 0h-.027C3.352 0 .07 2.67.002 7.026c-.039 2.479.276 4.238 1.04 5.013.254.258.882.677 1.295.882.191 3.177.922 5.238 2.536 6.38.897.637 2.187.949 3.2 1.102C8.04 20.6 8 20.795 8 21c0 1.773 2.35 3 4 3 1.648 0 4-1.227 4-3 0-.201-.038-.393-.072-.586 2.573-.385 5.435-1.877 5.925-7.587.396-.22.887-.568 1.104-.788.763-.774 1.079-2.534 1.04-5.013C23.929 2.67 20.646 0 18.933 0M3.223 9.135c-.237.281-.837 1.155-.884 1.238-.15-.41-.368-1.349-.337-3.291.051-3.281 2.478-4.972 3.091-5.031.256.015.731.27 1.265.646-1.11 1.171-2.275 2.915-2.352 5.125-.133.546-.398.858-.783 1.313M12 22c-.901 0-1.954-.693-2-1 0-.654.475-1.236 1-1.602V20a1 1 0 1 0 2 0v-.602c.524.365 1 .947 1 1.602-.046.307-1.099 1-2 1m3-3.48v.02a4.752 4.752 0 0 0-1.262-1.02c1.092-.516 2.239-1.334 2.239-2.217 0-1.842-1.781-2.195-3.977-2.195-2.196 0-3.978.354-3.978 2.195 0 .883 1.148 1.701 2.238 2.217A4.8 4.8 0 0 0 9 18.539v-.025c-1-.076-2.182-.281-2.973-.842-1.301-.92-1.838-3.045-1.853-6.478l.023-.041c.496-.826 1.49-1.45 1.804-3.102 0-2.047 1.357-3.631 2.362-4.522C9.37 3.178 10.555 3 11.948 3c1.447 0 2.685.192 3.733.57 1 .9 2.316 2.465 2.316 4.48.313 1.651 1.307 2.275 1.803 3.102.035.058.068.117.102.178-.059 5.967-1.949 7.01-4.902 7.19m6.628-8.202c-.037-.065-.074-.13-.113-.195a7.587 7.587 0 0 0-.739-.987c-.385-.455-.648-.768-.782-1.313-.076-2.209-1.241-3.954-2.353-5.124.531-.376 1.004-.63 1.261-.647.636.071 3.044 1.764 3.096 5.031.027 1.81-.347 3.218-.37 3.235"
+ })
+ ]
+ }),
+ solid: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("svg", {
+ xmlns: "http://www.w3.org/2000/svg",
+ viewBox: "0 0 576 512",
+ children: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M332.7 19.85C334.6 8.395 344.5 0 356.1 0C363.6 0 370.6 3.52 375.1 9.502L392 32H444.1C456.8 32 469.1 37.06 478.1 46.06L496 64H552C565.3 64 576 74.75 576 88V112C576 156.2 540.2 192 496 192H426.7L421.6 222.5L309.6 158.5L332.7 19.85zM448 64C439.2 64 432 71.16 432 80C432 88.84 439.2 96 448 96C456.8 96 464 88.84 464 80C464 71.16 456.8 64 448 64zM416 256.1V480C416 497.7 401.7 512 384 512H352C334.3 512 320 497.7 320 480V364.8C295.1 377.1 268.8 384 240 384C211.2 384 184 377.1 160 364.8V480C160 497.7 145.7 512 128 512H96C78.33 512 64 497.7 64 480V249.8C35.23 238.9 12.64 214.5 4.836 183.3L.9558 167.8C-3.331 150.6 7.094 133.2 24.24 128.1C41.38 124.7 58.76 135.1 63.05 152.2L66.93 167.8C70.49 182 83.29 191.1 97.97 191.1H303.8L416 256.1z"
+ })
+ })
+ },
+ objects: {
+ outline: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("svg", {
+ xmlns: "http://www.w3.org/2000/svg",
+ viewBox: "0 0 24 24",
+ children: [
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M12 0a9 9 0 0 0-5 16.482V21s2.035 3 5 3 5-3 5-3v-4.518A9 9 0 0 0 12 0zm0 2c3.86 0 7 3.141 7 7s-3.14 7-7 7-7-3.141-7-7 3.14-7 7-7zM9 17.477c.94.332 1.946.523 3 .523s2.06-.19 3-.523v.834c-.91.436-1.925.689-3 .689a6.924 6.924 0 0 1-3-.69v-.833zm.236 3.07A8.854 8.854 0 0 0 12 21c.965 0 1.888-.167 2.758-.451C14.155 21.173 13.153 22 12 22c-1.102 0-2.117-.789-2.764-1.453z"
+ }),
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M14.745 12.449h-.004c-.852-.024-1.188-.858-1.577-1.824-.421-1.061-.703-1.561-1.182-1.566h-.009c-.481 0-.783.497-1.235 1.537-.436.982-.801 1.811-1.636 1.791l-.276-.043c-.565-.171-.853-.691-1.284-1.794-.125-.313-.202-.632-.27-.913-.051-.213-.127-.53-.195-.634C7.067 9.004 7.039 9 6.99 9A1 1 0 0 1 7 7h.01c1.662.017 2.015 1.373 2.198 2.134.486-.981 1.304-2.058 2.797-2.075 1.531.018 2.28 1.153 2.731 2.141l.002-.008C14.944 8.424 15.327 7 16.979 7h.032A1 1 0 1 1 17 9h-.011c-.149.076-.256.474-.319.709a6.484 6.484 0 0 1-.311.951c-.429.973-.79 1.789-1.614 1.789"
+ })
+ ]
+ }),
+ solid: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("svg", {
+ xmlns: "http://www.w3.org/2000/svg",
+ viewBox: "0 0 384 512",
+ children: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M112.1 454.3c0 6.297 1.816 12.44 5.284 17.69l17.14 25.69c5.25 7.875 17.17 14.28 26.64 14.28h61.67c9.438 0 21.36-6.401 26.61-14.28l17.08-25.68c2.938-4.438 5.348-12.37 5.348-17.7L272 415.1h-160L112.1 454.3zM191.4 .0132C89.44 .3257 16 82.97 16 175.1c0 44.38 16.44 84.84 43.56 115.8c16.53 18.84 42.34 58.23 52.22 91.45c.0313 .25 .0938 .5166 .125 .7823h160.2c.0313-.2656 .0938-.5166 .125-.7823c9.875-33.22 35.69-72.61 52.22-91.45C351.6 260.8 368 220.4 368 175.1C368 78.61 288.9-.2837 191.4 .0132zM192 96.01c-44.13 0-80 35.89-80 79.1C112 184.8 104.8 192 96 192S80 184.8 80 176c0-61.76 50.25-111.1 112-111.1c8.844 0 16 7.159 16 16S200.8 96.01 192 96.01z"
+ })
+ })
+ },
+ people: {
+ outline: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("svg", {
+ xmlns: "http://www.w3.org/2000/svg",
+ viewBox: "0 0 24 24",
+ children: [
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0m0 22C6.486 22 2 17.514 2 12S6.486 2 12 2s10 4.486 10 10-4.486 10-10 10"
+ }),
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M8 7a2 2 0 1 0-.001 3.999A2 2 0 0 0 8 7M16 7a2 2 0 1 0-.001 3.999A2 2 0 0 0 16 7M15.232 15c-.693 1.195-1.87 2-3.349 2-1.477 0-2.655-.805-3.347-2H15m3-2H6a6 6 0 1 0 12 0"
+ })
+ ]
+ }),
+ solid: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("svg", {
+ xmlns: "http://www.w3.org/2000/svg",
+ viewBox: "0 0 512 512",
+ children: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M0 256C0 114.6 114.6 0 256 0C397.4 0 512 114.6 512 256C512 397.4 397.4 512 256 512C114.6 512 0 397.4 0 256zM256 432C332.1 432 396.2 382 415.2 314.1C419.1 300.4 407.8 288 393.6 288H118.4C104.2 288 92.92 300.4 96.76 314.1C115.8 382 179.9 432 256 432V432zM176.4 160C158.7 160 144.4 174.3 144.4 192C144.4 209.7 158.7 224 176.4 224C194 224 208.4 209.7 208.4 192C208.4 174.3 194 160 176.4 160zM336.4 224C354 224 368.4 209.7 368.4 192C368.4 174.3 354 160 336.4 160C318.7 160 304.4 174.3 304.4 192C304.4 209.7 318.7 224 336.4 224z"
+ })
+ })
+ },
+ places: {
+ outline: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("svg", {
+ xmlns: "http://www.w3.org/2000/svg",
+ viewBox: "0 0 24 24",
+ children: [
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M6.5 12C5.122 12 4 13.121 4 14.5S5.122 17 6.5 17 9 15.879 9 14.5 7.878 12 6.5 12m0 3c-.275 0-.5-.225-.5-.5s.225-.5.5-.5.5.225.5.5-.225.5-.5.5M17.5 12c-1.378 0-2.5 1.121-2.5 2.5s1.122 2.5 2.5 2.5 2.5-1.121 2.5-2.5-1.122-2.5-2.5-2.5m0 3c-.275 0-.5-.225-.5-.5s.225-.5.5-.5.5.225.5.5-.225.5-.5.5"
+ }),
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M22.482 9.494l-1.039-.346L21.4 9h.6c.552 0 1-.439 1-.992 0-.006-.003-.008-.003-.008H23c0-1-.889-2-1.984-2h-.642l-.731-1.717C19.262 3.012 18.091 2 16.764 2H7.236C5.909 2 4.738 3.012 4.357 4.283L3.626 6h-.642C1.889 6 1 7 1 8h.003S1 8.002 1 8.008C1 8.561 1.448 9 2 9h.6l-.043.148-1.039.346a2.001 2.001 0 0 0-1.359 2.097l.751 7.508a1 1 0 0 0 .994.901H3v1c0 1.103.896 2 2 2h2c1.104 0 2-.897 2-2v-1h6v1c0 1.103.896 2 2 2h2c1.104 0 2-.897 2-2v-1h1.096a.999.999 0 0 0 .994-.901l.751-7.508a2.001 2.001 0 0 0-1.359-2.097M6.273 4.857C6.402 4.43 6.788 4 7.236 4h9.527c.448 0 .834.43.963.857L19.313 9H4.688l1.585-4.143zM7 21H5v-1h2v1zm12 0h-2v-1h2v1zm2.189-3H2.811l-.662-6.607L3 11h18l.852.393L21.189 18z"
+ })
+ ]
+ }),
+ solid: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("svg", {
+ xmlns: "http://www.w3.org/2000/svg",
+ viewBox: "0 0 512 512",
+ children: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M39.61 196.8L74.8 96.29C88.27 57.78 124.6 32 165.4 32H346.6C387.4 32 423.7 57.78 437.2 96.29L472.4 196.8C495.6 206.4 512 229.3 512 256V448C512 465.7 497.7 480 480 480H448C430.3 480 416 465.7 416 448V400H96V448C96 465.7 81.67 480 64 480H32C14.33 480 0 465.7 0 448V256C0 229.3 16.36 206.4 39.61 196.8V196.8zM109.1 192H402.9L376.8 117.4C372.3 104.6 360.2 96 346.6 96H165.4C151.8 96 139.7 104.6 135.2 117.4L109.1 192zM96 256C78.33 256 64 270.3 64 288C64 305.7 78.33 320 96 320C113.7 320 128 305.7 128 288C128 270.3 113.7 256 96 256zM416 320C433.7 320 448 305.7 448 288C448 270.3 433.7 256 416 256C398.3 256 384 270.3 384 288C384 305.7 398.3 320 416 320z"
+ })
+ })
+ },
+ symbols: {
+ outline: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("svg", {
+ xmlns: "http://www.w3.org/2000/svg",
+ viewBox: "0 0 24 24",
+ children: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M0 0h11v2H0zM4 11h3V6h4V4H0v2h4zM15.5 17c1.381 0 2.5-1.116 2.5-2.493s-1.119-2.493-2.5-2.493S13 13.13 13 14.507 14.119 17 15.5 17m0-2.986c.276 0 .5.222.5.493 0 .272-.224.493-.5.493s-.5-.221-.5-.493.224-.493.5-.493M21.5 19.014c-1.381 0-2.5 1.116-2.5 2.493S20.119 24 21.5 24s2.5-1.116 2.5-2.493-1.119-2.493-2.5-2.493m0 2.986a.497.497 0 0 1-.5-.493c0-.271.224-.493.5-.493s.5.222.5.493a.497.497 0 0 1-.5.493M22 13l-9 9 1.513 1.5 8.99-9.009zM17 11c2.209 0 4-1.119 4-2.5V2s.985-.161 1.498.949C23.01 4.055 23 6 23 6s1-1.119 1-3.135C24-.02 21 0 21 0h-2v6.347A5.853 5.853 0 0 0 17 6c-2.209 0-4 1.119-4 2.5s1.791 2.5 4 2.5M10.297 20.482l-1.475-1.585a47.54 47.54 0 0 1-1.442 1.129c-.307-.288-.989-1.016-2.045-2.183.902-.836 1.479-1.466 1.729-1.892s.376-.871.376-1.336c0-.592-.273-1.178-.818-1.759-.546-.581-1.329-.871-2.349-.871-1.008 0-1.79.293-2.344.879-.556.587-.832 1.181-.832 1.784 0 .813.419 1.748 1.256 2.805-.847.614-1.444 1.208-1.794 1.784a3.465 3.465 0 0 0-.523 1.833c0 .857.308 1.56.924 2.107.616.549 1.423.823 2.42.823 1.173 0 2.444-.379 3.813-1.137L8.235 24h2.819l-2.09-2.383 1.333-1.135zm-6.736-6.389a1.02 1.02 0 0 1 .73-.286c.31 0 .559.085.747.254a.849.849 0 0 1 .283.659c0 .518-.419 1.112-1.257 1.784-.536-.651-.805-1.231-.805-1.742a.901.901 0 0 1 .302-.669M3.74 22c-.427 0-.778-.116-1.057-.349-.279-.232-.418-.487-.418-.766 0-.594.509-1.288 1.527-2.083.968 1.134 1.717 1.946 2.248 2.438-.921.507-1.686.76-2.3.76"
+ })
+ }),
+ solid: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("svg", {
+ xmlns: "http://www.w3.org/2000/svg",
+ viewBox: "0 0 512 512",
+ children: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M500.3 7.251C507.7 13.33 512 22.41 512 31.1V175.1C512 202.5 483.3 223.1 447.1 223.1C412.7 223.1 383.1 202.5 383.1 175.1C383.1 149.5 412.7 127.1 447.1 127.1V71.03L351.1 90.23V207.1C351.1 234.5 323.3 255.1 287.1 255.1C252.7 255.1 223.1 234.5 223.1 207.1C223.1 181.5 252.7 159.1 287.1 159.1V63.1C287.1 48.74 298.8 35.61 313.7 32.62L473.7 .6198C483.1-1.261 492.9 1.173 500.3 7.251H500.3zM74.66 303.1L86.5 286.2C92.43 277.3 102.4 271.1 113.1 271.1H174.9C185.6 271.1 195.6 277.3 201.5 286.2L213.3 303.1H239.1C266.5 303.1 287.1 325.5 287.1 351.1V463.1C287.1 490.5 266.5 511.1 239.1 511.1H47.1C21.49 511.1-.0019 490.5-.0019 463.1V351.1C-.0019 325.5 21.49 303.1 47.1 303.1H74.66zM143.1 359.1C117.5 359.1 95.1 381.5 95.1 407.1C95.1 434.5 117.5 455.1 143.1 455.1C170.5 455.1 191.1 434.5 191.1 407.1C191.1 381.5 170.5 359.1 143.1 359.1zM440.3 367.1H496C502.7 367.1 508.6 372.1 510.1 378.4C513.3 384.6 511.6 391.7 506.5 396L378.5 508C372.9 512.1 364.6 513.3 358.6 508.9C352.6 504.6 350.3 496.6 353.3 489.7L391.7 399.1H336C329.3 399.1 323.4 395.9 321 389.6C318.7 383.4 320.4 376.3 325.5 371.1L453.5 259.1C459.1 255 467.4 254.7 473.4 259.1C479.4 263.4 481.6 271.4 478.7 278.3L440.3 367.1zM116.7 219.1L19.85 119.2C-8.112 90.26-6.614 42.31 24.85 15.34C51.82-8.137 93.26-3.642 118.2 21.83L128.2 32.32L137.7 21.83C162.7-3.642 203.6-8.137 231.6 15.34C262.6 42.31 264.1 90.26 236.1 119.2L139.7 219.1C133.2 225.6 122.7 225.6 116.7 219.1H116.7z"
+ })
+ })
+ }
+};
+const $fcccfb36ed0cde68$var$search = {
+ loupe: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("svg", {
+ xmlns: "http://www.w3.org/2000/svg",
+ viewBox: "0 0 20 20",
+ children: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M12.9 14.32a8 8 0 1 1 1.41-1.41l5.35 5.33-1.42 1.42-5.33-5.34zM8 14A6 6 0 1 0 8 2a6 6 0 0 0 0 12z"
+ })
+ }),
+ delete: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("svg", {
+ xmlns: "http://www.w3.org/2000/svg",
+ viewBox: "0 0 20 20",
+ children: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("path", {
+ d: "M10 8.586L2.929 1.515 1.515 2.929 8.586 10l-7.071 7.071 1.414 1.414L10 11.414l7.071 7.071 1.414-1.414L11.414 10l7.071-7.071-1.414-1.414L10 8.586z"
+ })
+ })
+};
+var $fcccfb36ed0cde68$export$2e2bcd8739ae039 = {
+ categories: $fcccfb36ed0cde68$var$categories,
+ search: $fcccfb36ed0cde68$var$search
+};
+function $254755d3f438722f$export$2e2bcd8739ae039(props) {
+ let { id, skin, emoji } = props;
+ if (props.shortcodes) {
+ const matches = props.shortcodes.match($c4d155af13ad4d4b$export$2e2bcd8739ae039.SHORTCODES_REGEX);
+ if (matches) {
+ id = matches[1];
+ if (matches[2]) skin = matches[2];
+ }
+ }
+ emoji || (emoji = $c4d155af13ad4d4b$export$2e2bcd8739ae039.get(id || props.native));
+ if (!emoji) return props.fallback;
+ const emojiSkin = emoji.skins[skin - 1] || emoji.skins[0];
+ const imageSrc = emojiSkin.src || (props.set != "native" && !props.spritesheet ? typeof props.getImageURL === "function" ? props.getImageURL(props.set, emojiSkin.unified) : `https://cdn.jsdelivr.net/npm/emoji-datasource-${props.set}@15.0.1/img/${props.set}/64/${emojiSkin.unified}.png` : void 0);
+ const spritesheetSrc = typeof props.getSpritesheetURL === "function" ? props.getSpritesheetURL(props.set) : `https://cdn.jsdelivr.net/npm/emoji-datasource-${props.set}@15.0.1/img/${props.set}/sheets-256/64.png`;
+ return /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("span", {
+ class: "emoji-mart-emoji",
+ "data-emoji-set": props.set,
+ children: imageSrc ? /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("img", {
+ style: {
+ maxWidth: props.size || "1em",
+ maxHeight: props.size || "1em",
+ display: "inline-block"
+ },
+ alt: emojiSkin.native || emojiSkin.shortcodes,
+ src: imageSrc
+ }) : props.set == "native" ? /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("span", {
+ style: {
+ fontSize: props.size,
+ fontFamily: '"EmojiMart", "Segoe UI Emoji", "Segoe UI Symbol", "Segoe UI", "Apple Color Emoji", "Twemoji Mozilla", "Noto Color Emoji", "Android Emoji"'
+ },
+ children: emojiSkin.native
+ }) : /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("span", {
+ style: {
+ display: "block",
+ width: props.size,
+ height: props.size,
+ backgroundImage: `url(${spritesheetSrc})`,
+ backgroundSize: `${100 * $7adb23b0109cc36a$export$2d0294657ab35f1b.sheet.cols}% ${100 * $7adb23b0109cc36a$export$2d0294657ab35f1b.sheet.rows}%`,
+ backgroundPosition: `${100 / ($7adb23b0109cc36a$export$2d0294657ab35f1b.sheet.cols - 1) * emojiSkin.x}% ${100 / ($7adb23b0109cc36a$export$2d0294657ab35f1b.sheet.rows - 1) * emojiSkin.y}%`
+ }
+ })
+ });
+}
+const $6f57cc9cd54c5aaa$var$WindowHTMLElement = typeof window !== "undefined" && window.HTMLElement ? window.HTMLElement : Object;
+class $6f57cc9cd54c5aaa$export$2e2bcd8739ae039 extends $6f57cc9cd54c5aaa$var$WindowHTMLElement {
+ static get observedAttributes() {
+ return Object.keys(this.Props);
+ }
+ update(props = {}) {
+ for (let k in props) this.attributeChangedCallback(k, null, props[k]);
+ }
+ attributeChangedCallback(attr, _, newValue) {
+ if (!this.component) return;
+ const value = $7adb23b0109cc36a$export$88c9ddb45cea7241(attr, {
+ [attr]: newValue
+ }, this.constructor.Props, this);
+ if (this.component.componentWillReceiveProps) this.component.componentWillReceiveProps({
+ [attr]: value
+ });
+ else {
+ this.component.props[attr] = value;
+ this.component.forceUpdate();
+ }
+ }
+ disconnectedCallback() {
+ this.disconnected = true;
+ if (this.component && this.component.unregister) this.component.unregister();
+ }
+ constructor(props = {}) {
+ super();
+ this.props = props;
+ if (props.parent || props.ref) {
+ let ref = null;
+ const parent = props.parent || (ref = props.ref && props.ref.current);
+ if (ref) ref.innerHTML = "";
+ if (parent) parent.appendChild(this);
+ }
+ }
+}
+class $26f27c338a96b1a6$export$2e2bcd8739ae039 extends $6f57cc9cd54c5aaa$export$2e2bcd8739ae039 {
+ setShadow() {
+ this.attachShadow({
+ mode: "open"
+ });
+ }
+ injectStyles(styles) {
+ if (!styles) return;
+ const style = document.createElement("style");
+ style.textContent = styles;
+ this.shadowRoot.insertBefore(style, this.shadowRoot.firstChild);
+ }
+ constructor(props, { styles } = {}) {
+ super(props);
+ this.setShadow();
+ this.injectStyles(styles);
+ }
+}
+var $3d90f6e46fb2dd47$export$2e2bcd8739ae039 = {
+ fallback: "",
+ id: "",
+ native: "",
+ shortcodes: "",
+ size: {
+ value: "",
+ transform: (value) => {
+ if (!/\D/.test(value)) return `${value}px`;
+ return value;
+ }
+ },
+ // Shared
+ set: $b247ea80b67298d5$export$2e2bcd8739ae039.set,
+ skin: $b247ea80b67298d5$export$2e2bcd8739ae039.skin
+};
+class $331b4160623139bf$export$2e2bcd8739ae039 extends $6f57cc9cd54c5aaa$export$2e2bcd8739ae039 {
+ async connectedCallback() {
+ const props = $7adb23b0109cc36a$export$75fe5f91d452f94b(this.props, $3d90f6e46fb2dd47$export$2e2bcd8739ae039, this);
+ props.element = this;
+ props.ref = (component) => {
+ this.component = component;
+ };
+ await $7adb23b0109cc36a$export$2cd8252107eb640b();
+ if (this.disconnected) return;
+ $fb96b826c0c5f37a$export$b3890eb0ae9dca99(/* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b($254755d3f438722f$export$2e2bcd8739ae039, {
+ ...props
+ }), this);
+ }
+ constructor(props) {
+ super(props);
+ }
+}
+$c770c458706daa72$export$2e2bcd8739ae039($331b4160623139bf$export$2e2bcd8739ae039, "Props", $3d90f6e46fb2dd47$export$2e2bcd8739ae039);
+if (typeof customElements !== "undefined" && !customElements.get("em-emoji")) customElements.define("em-emoji", $331b4160623139bf$export$2e2bcd8739ae039);
+var $1a9a8ef576b7773d$var$r, $1a9a8ef576b7773d$var$i = [], $1a9a8ef576b7773d$var$c = $fb96b826c0c5f37a$export$41c562ebe57d11e2.__b, $1a9a8ef576b7773d$var$f = $fb96b826c0c5f37a$export$41c562ebe57d11e2.__r, $1a9a8ef576b7773d$var$e = $fb96b826c0c5f37a$export$41c562ebe57d11e2.diffed, $1a9a8ef576b7773d$var$a = $fb96b826c0c5f37a$export$41c562ebe57d11e2.__c, $1a9a8ef576b7773d$var$v = $fb96b826c0c5f37a$export$41c562ebe57d11e2.unmount;
+function $1a9a8ef576b7773d$var$x() {
+ var t6;
+ for ($1a9a8ef576b7773d$var$i.sort(function(n11, t7) {
+ return n11.__v.__b - t7.__v.__b;
+ }); t6 = $1a9a8ef576b7773d$var$i.pop(); ) if (t6.__P) try {
+ t6.__H.__h.forEach($1a9a8ef576b7773d$var$g), t6.__H.__h.forEach($1a9a8ef576b7773d$var$j), t6.__H.__h = [];
+ } catch (u4) {
+ t6.__H.__h = [], $fb96b826c0c5f37a$export$41c562ebe57d11e2.__e(u4, t6.__v);
+ }
+}
+$fb96b826c0c5f37a$export$41c562ebe57d11e2.__b = function(n12) {
+ $1a9a8ef576b7773d$var$c && $1a9a8ef576b7773d$var$c(n12);
+}, $fb96b826c0c5f37a$export$41c562ebe57d11e2.__r = function(n13) {
+ $1a9a8ef576b7773d$var$f && $1a9a8ef576b7773d$var$f(n13);
+ var r8 = n13.__c.__H;
+ r8 && (r8.__h.forEach($1a9a8ef576b7773d$var$g), r8.__h.forEach($1a9a8ef576b7773d$var$j), r8.__h = []);
+}, $fb96b826c0c5f37a$export$41c562ebe57d11e2.diffed = function(t8) {
+ $1a9a8ef576b7773d$var$e && $1a9a8ef576b7773d$var$e(t8);
+ var o6 = t8.__c;
+ o6 && o6.__H && o6.__H.__h.length && (1 !== $1a9a8ef576b7773d$var$i.push(o6) && $1a9a8ef576b7773d$var$r === $fb96b826c0c5f37a$export$41c562ebe57d11e2.requestAnimationFrame || (($1a9a8ef576b7773d$var$r = $fb96b826c0c5f37a$export$41c562ebe57d11e2.requestAnimationFrame) || function(n14) {
+ var t9, u5 = function() {
+ clearTimeout(r9), $1a9a8ef576b7773d$var$b && cancelAnimationFrame(t9), setTimeout(n14);
+ }, r9 = setTimeout(u5, 100);
+ $1a9a8ef576b7773d$var$b && (t9 = requestAnimationFrame(u5));
+ })($1a9a8ef576b7773d$var$x));
+}, $fb96b826c0c5f37a$export$41c562ebe57d11e2.__c = function(t10, u6) {
+ u6.some(function(t11) {
+ try {
+ t11.__h.forEach($1a9a8ef576b7773d$var$g), t11.__h = t11.__h.filter(function(n15) {
+ return !n15.__ || $1a9a8ef576b7773d$var$j(n15);
+ });
+ } catch (r10) {
+ u6.some(function(n16) {
+ n16.__h && (n16.__h = []);
+ }), u6 = [], $fb96b826c0c5f37a$export$41c562ebe57d11e2.__e(r10, t11.__v);
+ }
+ }), $1a9a8ef576b7773d$var$a && $1a9a8ef576b7773d$var$a(t10, u6);
+}, $fb96b826c0c5f37a$export$41c562ebe57d11e2.unmount = function(t12) {
+ $1a9a8ef576b7773d$var$v && $1a9a8ef576b7773d$var$v(t12);
+ var u7, r11 = t12.__c;
+ r11 && r11.__H && (r11.__H.__.forEach(function(n17) {
+ try {
+ $1a9a8ef576b7773d$var$g(n17);
+ } catch (n18) {
+ u7 = n18;
+ }
+ }), u7 && $fb96b826c0c5f37a$export$41c562ebe57d11e2.__e(u7, r11.__v));
+};
+var $1a9a8ef576b7773d$var$b = "function" == typeof requestAnimationFrame;
+function $1a9a8ef576b7773d$var$g(n19) {
+ var r12 = n19.__c;
+ "function" == typeof r12 && (n19.__c = void 0, r12());
+}
+function $1a9a8ef576b7773d$var$j(n20) {
+ n20.__c = n20.__();
+}
+function $dc040a17866866fa$var$S(n1, t1) {
+ for (var e1 in t1) n1[e1] = t1[e1];
+ return n1;
+}
+function $dc040a17866866fa$var$C(n2, t2) {
+ for (var e2 in n2) if ("__source" !== e2 && !(e2 in t2)) return true;
+ for (var r1 in t2) if ("__source" !== r1 && n2[r1] !== t2[r1]) return true;
+ return false;
+}
+function $dc040a17866866fa$export$221d75b3f55bb0bd(n3) {
+ this.props = n3;
+}
+($dc040a17866866fa$export$221d75b3f55bb0bd.prototype = new $fb96b826c0c5f37a$export$16fa2f45be04daa8()).isPureReactComponent = true, $dc040a17866866fa$export$221d75b3f55bb0bd.prototype.shouldComponentUpdate = function(n6, t5) {
+ return $dc040a17866866fa$var$C(this.props, n6) || $dc040a17866866fa$var$C(this.state, t5);
+};
+var $dc040a17866866fa$var$w = $fb96b826c0c5f37a$export$41c562ebe57d11e2.__b;
+$fb96b826c0c5f37a$export$41c562ebe57d11e2.__b = function(n7) {
+ n7.type && n7.type.__f && n7.ref && (n7.props.ref = n7.ref, n7.ref = null), $dc040a17866866fa$var$w && $dc040a17866866fa$var$w(n7);
+};
+var $dc040a17866866fa$var$A = $fb96b826c0c5f37a$export$41c562ebe57d11e2.__e;
+$fb96b826c0c5f37a$export$41c562ebe57d11e2.__e = function(n12, t10, e6) {
+ if (n12.then) {
+ for (var r5, u1 = t10; u1 = u1.__; ) if ((r5 = u1.__c) && r5.__c) return null == t10.__e && (t10.__e = e6.__e, t10.__k = e6.__k), r5.__c(n12, t10);
+ }
+ $dc040a17866866fa$var$A(n12, t10, e6);
+};
+var $dc040a17866866fa$var$O = $fb96b826c0c5f37a$export$41c562ebe57d11e2.unmount;
+function $dc040a17866866fa$export$74bf444e3cd11ea5() {
+ this.__u = 0, this.t = null, this.__b = null;
+}
+function $dc040a17866866fa$var$U(n13) {
+ var t11 = n13.__.__c;
+ return t11 && t11.__e && t11.__e(n13);
+}
+function $dc040a17866866fa$export$998bcd577473dd93() {
+ this.u = null, this.o = null;
+}
+$fb96b826c0c5f37a$export$41c562ebe57d11e2.unmount = function(n17) {
+ var t13 = n17.__c;
+ t13 && t13.__R && t13.__R(), t13 && true === n17.__h && (n17.type = null), $dc040a17866866fa$var$O && $dc040a17866866fa$var$O(n17);
+}, ($dc040a17866866fa$export$74bf444e3cd11ea5.prototype = new $fb96b826c0c5f37a$export$16fa2f45be04daa8()).__c = function(n18, t14) {
+ var e8 = t14.__c, r7 = this;
+ null == r7.t && (r7.t = []), r7.t.push(e8);
+ var u4 = $dc040a17866866fa$var$U(r7.__v), o1 = false, i1 = function() {
+ o1 || (o1 = true, e8.__R = null, u4 ? u4(l1) : l1());
+ };
+ e8.__R = i1;
+ var l1 = function() {
+ if (!--r7.__u) {
+ if (r7.state.__e) {
+ var n19 = r7.state.__e;
+ r7.__v.__k[0] = (function n22(t17, e9, r8) {
+ return t17 && (t17.__v = null, t17.__k = t17.__k && t17.__k.map(function(t18) {
+ return n22(t18, e9, r8);
+ }), t17.__c && t17.__c.__P === e9 && (t17.__e && r8.insertBefore(t17.__e, t17.__d), t17.__c.__e = true, t17.__c.__P = r8)), t17;
+ })(n19, n19.__c.__P, n19.__c.__O);
+ }
+ var t15;
+ for (r7.setState({
+ __e: r7.__b = null
+ }); t15 = r7.t.pop(); ) t15.forceUpdate();
+ }
+ }, c1 = true === t14.__h;
+ r7.__u++ || c1 || r7.setState({
+ __e: r7.__b = r7.__v.__k[0]
+ }), n18.then(i1, i1);
+}, $dc040a17866866fa$export$74bf444e3cd11ea5.prototype.componentWillUnmount = function() {
+ this.t = [];
+}, $dc040a17866866fa$export$74bf444e3cd11ea5.prototype.render = function(n23, t19) {
+ if (this.__b) {
+ if (this.__v.__k) {
+ var e10 = document.createElement("div"), r9 = this.__v.__k[0].__c;
+ this.__v.__k[0] = (function n24(t20, e13, r12) {
+ return t20 && (t20.__c && t20.__c.__H && (t20.__c.__H.__.forEach(function(n25) {
+ "function" == typeof n25.__c && n25.__c();
+ }), t20.__c.__H = null), null != (t20 = $dc040a17866866fa$var$S({}, t20)).__c && (t20.__c.__P === r12 && (t20.__c.__P = e13), t20.__c = null), t20.__k = t20.__k && t20.__k.map(function(t21) {
+ return n24(t21, e13, r12);
+ })), t20;
+ })(this.__b, e10, r9.__O = r9.__P);
+ }
+ this.__b = null;
+ }
+ var u5 = t19.__e && $fb96b826c0c5f37a$export$c8a8987d4410bf2d($fb96b826c0c5f37a$export$ffb0004e005737fa, null, n23.fallback);
+ return u5 && (u5.__h = null), [
+ $fb96b826c0c5f37a$export$c8a8987d4410bf2d($fb96b826c0c5f37a$export$ffb0004e005737fa, null, t19.__e ? null : n23.children),
+ u5
+ ];
+};
+var $dc040a17866866fa$var$T = function(n26, t22, e14) {
+ if (++e14[1] === e14[0] && n26.o.delete(t22), n26.props.revealOrder && ("t" !== n26.props.revealOrder[0] || !n26.o.size)) for (e14 = n26.u; e14; ) {
+ for (; e14.length > 3; ) e14.pop()();
+ if (e14[1] < e14[0]) break;
+ n26.u = e14 = e14[2];
+ }
+};
+($dc040a17866866fa$export$998bcd577473dd93.prototype = new $fb96b826c0c5f37a$export$16fa2f45be04daa8()).__e = function(n33) {
+ var t25 = this, e16 = $dc040a17866866fa$var$U(t25.__v), r13 = t25.o.get(n33);
+ return r13[0]++, function(u6) {
+ var o2 = function() {
+ t25.props.revealOrder ? (r13.push(u6), $dc040a17866866fa$var$T(t25, n33, r13)) : u6();
+ };
+ e16 ? e16(o2) : o2();
+ };
+}, $dc040a17866866fa$export$998bcd577473dd93.prototype.render = function(n34) {
+ this.u = null, this.o = /* @__PURE__ */ new Map();
+ var t26 = $fb96b826c0c5f37a$export$47e4c5b300681277(n34.children);
+ n34.revealOrder && "b" === n34.revealOrder[0] && t26.reverse();
+ for (var e17 = t26.length; e17--; ) this.o.set(t26[e17], this.u = [
+ 1,
+ 0,
+ this.u
+ ]);
+ return n34.children;
+}, $dc040a17866866fa$export$998bcd577473dd93.prototype.componentDidUpdate = $dc040a17866866fa$export$998bcd577473dd93.prototype.componentDidMount = function() {
+ var n35 = this;
+ this.o.forEach(function(t27, e18) {
+ $dc040a17866866fa$var$T(n35, e18, t27);
+ });
+};
+var $dc040a17866866fa$var$j = "undefined" != typeof Symbol && Symbol.for && /* @__PURE__ */ Symbol.for("react.element") || 60103, $dc040a17866866fa$var$P = /^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|dominant|fill|flood|font|glyph(?!R)|horiz|marker(?!H|W|U)|overline|paint|stop|strikethrough|stroke|text(?!L)|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/, $dc040a17866866fa$var$V = "undefined" != typeof document, $dc040a17866866fa$var$z = function(n36) {
+ return ("undefined" != typeof Symbol && "symbol" == typeof /* @__PURE__ */ Symbol() ? /fil|che|rad/i : /fil|che|ra/i).test(n36);
+};
+$fb96b826c0c5f37a$export$16fa2f45be04daa8.prototype.isReactComponent = {}, [
+ "componentWillMount",
+ "componentWillReceiveProps",
+ "componentWillUpdate"
+].forEach(function(n39) {
+ Object.defineProperty($fb96b826c0c5f37a$export$16fa2f45be04daa8.prototype, n39, {
+ configurable: true,
+ get: function() {
+ return this["UNSAFE_" + n39];
+ },
+ set: function(t30) {
+ Object.defineProperty(this, n39, {
+ configurable: true,
+ writable: true,
+ value: t30
+ });
+ }
+ });
+});
+var $dc040a17866866fa$var$H = $fb96b826c0c5f37a$export$41c562ebe57d11e2.event;
+function $dc040a17866866fa$var$Z() {
+}
+function $dc040a17866866fa$var$Y() {
+ return this.cancelBubble;
+}
+function $dc040a17866866fa$var$q() {
+ return this.defaultPrevented;
+}
+$fb96b826c0c5f37a$export$41c562ebe57d11e2.event = function(n40) {
+ return $dc040a17866866fa$var$H && (n40 = $dc040a17866866fa$var$H(n40)), n40.persist = $dc040a17866866fa$var$Z, n40.isPropagationStopped = $dc040a17866866fa$var$Y, n40.isDefaultPrevented = $dc040a17866866fa$var$q, n40.nativeEvent = n40;
+};
+var $dc040a17866866fa$var$J = {
+ configurable: true,
+ get: function() {
+ return this.class;
+ }
+}, $dc040a17866866fa$var$K = $fb96b826c0c5f37a$export$41c562ebe57d11e2.vnode;
+$fb96b826c0c5f37a$export$41c562ebe57d11e2.vnode = function(n41) {
+ var t31 = n41.type, e21 = n41.props, r14 = e21;
+ if ("string" == typeof t31) {
+ var u7 = -1 === t31.indexOf("-");
+ for (var o3 in r14 = {}, e21) {
+ var i2 = e21[o3];
+ $dc040a17866866fa$var$V && "children" === o3 && "noscript" === t31 || "value" === o3 && "defaultValue" in e21 && null == i2 || ("defaultValue" === o3 && "value" in e21 && null == e21.value ? o3 = "value" : "download" === o3 && true === i2 ? i2 = "" : /ondoubleclick/i.test(o3) ? o3 = "ondblclick" : /^onchange(textarea|input)/i.test(o3 + t31) && !$dc040a17866866fa$var$z(e21.type) ? o3 = "oninput" : /^onfocus$/i.test(o3) ? o3 = "onfocusin" : /^onblur$/i.test(o3) ? o3 = "onfocusout" : /^on(Ani|Tra|Tou|BeforeInp)/.test(o3) ? o3 = o3.toLowerCase() : u7 && $dc040a17866866fa$var$P.test(o3) ? o3 = o3.replace(/[A-Z0-9]/, "-$&").toLowerCase() : null === i2 && (i2 = void 0), r14[o3] = i2);
+ }
+ "select" == t31 && r14.multiple && Array.isArray(r14.value) && (r14.value = $fb96b826c0c5f37a$export$47e4c5b300681277(e21.children).forEach(function(n42) {
+ n42.props.selected = -1 != r14.value.indexOf(n42.props.value);
+ })), "select" == t31 && null != r14.defaultValue && (r14.value = $fb96b826c0c5f37a$export$47e4c5b300681277(e21.children).forEach(function(n43) {
+ n43.props.selected = r14.multiple ? -1 != r14.defaultValue.indexOf(n43.props.value) : r14.defaultValue == n43.props.value;
+ })), n41.props = r14, e21.class != e21.className && ($dc040a17866866fa$var$J.enumerable = "className" in e21, null != e21.className && (r14.class = e21.className), Object.defineProperty(r14, "className", $dc040a17866866fa$var$J));
+ }
+ n41.$$typeof = $dc040a17866866fa$var$j, $dc040a17866866fa$var$K && $dc040a17866866fa$var$K(n41);
+};
+var $dc040a17866866fa$var$Q = $fb96b826c0c5f37a$export$41c562ebe57d11e2.__r;
+$fb96b826c0c5f37a$export$41c562ebe57d11e2.__r = function(n44) {
+ $dc040a17866866fa$var$Q && $dc040a17866866fa$var$Q(n44), n44.__c;
+};
+const $ec8c39fdad15601a$var$THEME_ICONS = {
+ light: "outline",
+ dark: "solid"
+};
+class $ec8c39fdad15601a$export$2e2bcd8739ae039 extends $dc040a17866866fa$export$221d75b3f55bb0bd {
+ renderIcon(category) {
+ const { icon } = category;
+ if (icon) {
+ if (icon.svg) return /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("span", {
+ class: "flex",
+ dangerouslySetInnerHTML: {
+ __html: icon.svg
+ }
+ });
+ if (icon.src) return /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("img", {
+ src: icon.src
+ });
+ }
+ const categoryIcons = $fcccfb36ed0cde68$export$2e2bcd8739ae039.categories[category.id] || $fcccfb36ed0cde68$export$2e2bcd8739ae039.categories.custom;
+ const style = this.props.icons == "auto" ? $ec8c39fdad15601a$var$THEME_ICONS[this.props.theme] : this.props.icons;
+ return categoryIcons[style] || categoryIcons;
+ }
+ render() {
+ let selectedCategoryIndex = null;
+ return /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("nav", {
+ id: "nav",
+ class: "padding",
+ "data-position": this.props.position,
+ dir: this.props.dir,
+ children: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ class: "flex relative",
+ children: [
+ this.categories.map((category, i) => {
+ const title = category.name || $7adb23b0109cc36a$export$dbe3113d60765c1a.categories[category.id];
+ const selected = !this.props.unfocused && category.id == this.state.categoryId;
+ if (selected) selectedCategoryIndex = i;
+ return /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("button", {
+ "aria-label": title,
+ "aria-selected": selected || void 0,
+ title,
+ type: "button",
+ class: "flex flex-grow flex-center",
+ onMouseDown: (e) => e.preventDefault(),
+ onClick: () => {
+ this.props.onClick({
+ category,
+ i
+ });
+ },
+ children: this.renderIcon(category)
+ });
+ }),
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ class: "bar",
+ style: {
+ width: `${100 / this.categories.length}%`,
+ opacity: selectedCategoryIndex == null ? 0 : 1,
+ transform: this.props.dir === "rtl" ? `scaleX(-1) translateX(${selectedCategoryIndex * 100}%)` : `translateX(${selectedCategoryIndex * 100}%)`
+ }
+ })
+ ]
+ })
+ });
+ }
+ constructor() {
+ super();
+ this.categories = $7adb23b0109cc36a$export$2d0294657ab35f1b.categories.filter((category) => {
+ return !category.target;
+ });
+ this.state = {
+ categoryId: this.categories[0].id
+ };
+ }
+}
+class $e0d4dda61265ff1e$export$2e2bcd8739ae039 extends $dc040a17866866fa$export$221d75b3f55bb0bd {
+ shouldComponentUpdate(nextProps) {
+ for (let k in nextProps) {
+ if (k == "children") continue;
+ if (nextProps[k] != this.props[k]) return true;
+ }
+ return false;
+ }
+ render() {
+ return this.props.children;
+ }
+}
+const $89bd6bb200cc8fef$var$Performance = {
+ rowsPerRender: 10
+};
+class $89bd6bb200cc8fef$export$2e2bcd8739ae039 extends $fb96b826c0c5f37a$export$16fa2f45be04daa8 {
+ getInitialState(props = this.props) {
+ return {
+ skin: $f72b75cf796873c7$export$2e2bcd8739ae039.get("skin") || props.skin,
+ theme: this.initTheme(props.theme)
+ };
+ }
+ componentWillMount() {
+ this.dir = $7adb23b0109cc36a$export$dbe3113d60765c1a.rtl ? "rtl" : "ltr";
+ this.refs = {
+ menu: $fb96b826c0c5f37a$export$7d1e3a5e95ceca43(),
+ navigation: $fb96b826c0c5f37a$export$7d1e3a5e95ceca43(),
+ scroll: $fb96b826c0c5f37a$export$7d1e3a5e95ceca43(),
+ search: $fb96b826c0c5f37a$export$7d1e3a5e95ceca43(),
+ searchInput: $fb96b826c0c5f37a$export$7d1e3a5e95ceca43(),
+ skinToneButton: $fb96b826c0c5f37a$export$7d1e3a5e95ceca43(),
+ skinToneRadio: $fb96b826c0c5f37a$export$7d1e3a5e95ceca43()
+ };
+ this.initGrid();
+ if (this.props.stickySearch == false && this.props.searchPosition == "sticky") {
+ console.warn("[EmojiMart] Deprecation warning: `stickySearch` has been renamed `searchPosition`.");
+ this.props.searchPosition = "static";
+ }
+ }
+ componentDidMount() {
+ this.register();
+ this.shadowRoot = this.base.parentNode;
+ if (this.props.autoFocus) {
+ const { searchInput } = this.refs;
+ if (searchInput.current) searchInput.current.focus();
+ }
+ }
+ componentWillReceiveProps(nextProps) {
+ this.nextState || (this.nextState = {});
+ for (const k1 in nextProps) this.nextState[k1] = nextProps[k1];
+ clearTimeout(this.nextStateTimer);
+ this.nextStateTimer = setTimeout(() => {
+ let requiresGridReset = false;
+ for (const k in this.nextState) {
+ this.props[k] = this.nextState[k];
+ if (k === "custom" || k === "categories") requiresGridReset = true;
+ }
+ delete this.nextState;
+ const nextState = this.getInitialState();
+ if (requiresGridReset) return this.reset(nextState);
+ this.setState(nextState);
+ });
+ }
+ componentWillUnmount() {
+ this.unregister();
+ }
+ async reset(nextState = {}) {
+ await $7adb23b0109cc36a$export$2cd8252107eb640b(this.props);
+ this.initGrid();
+ this.unobserve();
+ this.setState(nextState, () => {
+ this.observeCategories();
+ this.observeRows();
+ });
+ }
+ register() {
+ document.addEventListener("click", this.handleClickOutside);
+ this.observe();
+ }
+ unregister() {
+ document.removeEventListener("click", this.handleClickOutside);
+ this.darkMedia?.removeEventListener("change", this.darkMediaCallback);
+ this.unobserve();
+ }
+ observe() {
+ this.observeCategories();
+ this.observeRows();
+ }
+ unobserve({ except = [] } = {}) {
+ if (!Array.isArray(except)) except = [
+ except
+ ];
+ for (const observer of this.observers) {
+ if (except.includes(observer)) continue;
+ observer.disconnect();
+ }
+ this.observers = [].concat(except);
+ }
+ initGrid() {
+ const { categories } = $7adb23b0109cc36a$export$2d0294657ab35f1b;
+ this.refs.categories = /* @__PURE__ */ new Map();
+ const navKey = $7adb23b0109cc36a$export$2d0294657ab35f1b.categories.map((category) => category.id).join(",");
+ if (this.navKey && this.navKey != navKey) this.refs.scroll.current && (this.refs.scroll.current.scrollTop = 0);
+ this.navKey = navKey;
+ this.grid = [];
+ this.grid.setsize = 0;
+ const addRow = (rows, category) => {
+ const row = [];
+ row.__categoryId = category.id;
+ row.__index = rows.length;
+ this.grid.push(row);
+ const rowIndex = this.grid.length - 1;
+ const rowRef = rowIndex % $89bd6bb200cc8fef$var$Performance.rowsPerRender ? {} : $fb96b826c0c5f37a$export$7d1e3a5e95ceca43();
+ rowRef.index = rowIndex;
+ rowRef.posinset = this.grid.setsize + 1;
+ rows.push(rowRef);
+ return row;
+ };
+ for (let category1 of categories) {
+ const rows = [];
+ let row = addRow(rows, category1);
+ for (let emoji of category1.emojis) {
+ if (row.length == this.getPerLine()) row = addRow(rows, category1);
+ this.grid.setsize += 1;
+ row.push(emoji);
+ }
+ this.refs.categories.set(category1.id, {
+ root: $fb96b826c0c5f37a$export$7d1e3a5e95ceca43(),
+ rows
+ });
+ }
+ }
+ initTheme(theme) {
+ if (theme != "auto") return theme;
+ if (!this.darkMedia) {
+ this.darkMedia = matchMedia("(prefers-color-scheme: dark)");
+ if (this.darkMedia.media.match(/^not/)) return "light";
+ this.darkMedia.addEventListener("change", this.darkMediaCallback);
+ }
+ return this.darkMedia.matches ? "dark" : "light";
+ }
+ initDynamicPerLine(props = this.props) {
+ if (!props.dynamicWidth) return;
+ const { element, emojiButtonSize } = props;
+ const calculatePerLine = () => {
+ const { width } = element.getBoundingClientRect();
+ return Math.floor(width / emojiButtonSize);
+ };
+ const observer = new ResizeObserver(() => {
+ this.unobserve({
+ except: observer
+ });
+ this.setState({
+ perLine: calculatePerLine()
+ }, () => {
+ this.initGrid();
+ this.forceUpdate(() => {
+ this.observeCategories();
+ this.observeRows();
+ });
+ });
+ });
+ observer.observe(element);
+ this.observers.push(observer);
+ return calculatePerLine();
+ }
+ getPerLine() {
+ return this.state.perLine || this.props.perLine;
+ }
+ getEmojiByPos([p1, p2]) {
+ const grid = this.state.searchResults || this.grid;
+ const emoji = grid[p1] && grid[p1][p2];
+ if (!emoji) return;
+ return $c4d155af13ad4d4b$export$2e2bcd8739ae039.get(emoji);
+ }
+ observeCategories() {
+ const navigation = this.refs.navigation.current;
+ if (!navigation) return;
+ const visibleCategories = /* @__PURE__ */ new Map();
+ const setFocusedCategory = (categoryId) => {
+ if (categoryId != navigation.state.categoryId) navigation.setState({
+ categoryId
+ });
+ };
+ const observerOptions = {
+ root: this.refs.scroll.current,
+ threshold: [
+ 0,
+ 1
+ ]
+ };
+ const observer = new IntersectionObserver((entries) => {
+ for (const entry of entries) {
+ const id = entry.target.dataset.id;
+ visibleCategories.set(id, entry.intersectionRatio);
+ }
+ const ratios = [
+ ...visibleCategories
+ ];
+ for (const [id, ratio] of ratios) if (ratio) {
+ setFocusedCategory(id);
+ break;
+ }
+ }, observerOptions);
+ for (const { root } of this.refs.categories.values()) observer.observe(root.current);
+ this.observers.push(observer);
+ }
+ observeRows() {
+ const visibleRows = {
+ ...this.state.visibleRows
+ };
+ const observer = new IntersectionObserver((entries) => {
+ for (const entry of entries) {
+ const index = parseInt(entry.target.dataset.index);
+ if (entry.isIntersecting) visibleRows[index] = true;
+ else delete visibleRows[index];
+ }
+ this.setState({
+ visibleRows
+ });
+ }, {
+ root: this.refs.scroll.current,
+ rootMargin: `${this.props.emojiButtonSize * ($89bd6bb200cc8fef$var$Performance.rowsPerRender + 5)}px 0px ${this.props.emojiButtonSize * $89bd6bb200cc8fef$var$Performance.rowsPerRender}px`
+ });
+ for (const { rows } of this.refs.categories.values()) {
+ for (const row of rows) if (row.current) observer.observe(row.current);
+ }
+ this.observers.push(observer);
+ }
+ preventDefault(e) {
+ e.preventDefault();
+ }
+ unfocusSearch() {
+ const input = this.refs.searchInput.current;
+ if (!input) return;
+ input.blur();
+ }
+ navigate({ e, input, left, right, up, down }) {
+ const grid = this.state.searchResults || this.grid;
+ if (!grid.length) return;
+ let [p1, p2] = this.state.pos;
+ const pos = (() => {
+ if (p1 == 0) {
+ if (p2 == 0 && !e.repeat && (left || up)) return null;
+ }
+ if (p1 == -1) {
+ if (!e.repeat && (right || down) && input.selectionStart == input.value.length) return [
+ 0,
+ 0
+ ];
+ return null;
+ }
+ if (left || right) {
+ let row = grid[p1];
+ const increment = left ? -1 : 1;
+ p2 += increment;
+ if (!row[p2]) {
+ p1 += increment;
+ row = grid[p1];
+ if (!row) {
+ p1 = left ? 0 : grid.length - 1;
+ p2 = left ? 0 : grid[p1].length - 1;
+ return [
+ p1,
+ p2
+ ];
+ }
+ p2 = left ? row.length - 1 : 0;
+ }
+ return [
+ p1,
+ p2
+ ];
+ }
+ if (up || down) {
+ p1 += up ? -1 : 1;
+ const row = grid[p1];
+ if (!row) {
+ p1 = up ? 0 : grid.length - 1;
+ p2 = up ? 0 : grid[p1].length - 1;
+ return [
+ p1,
+ p2
+ ];
+ }
+ if (!row[p2]) p2 = row.length - 1;
+ return [
+ p1,
+ p2
+ ];
+ }
+ })();
+ if (pos) e.preventDefault();
+ else {
+ if (this.state.pos[0] > -1) this.setState({
+ pos: [
+ -1,
+ -1
+ ]
+ });
+ return;
+ }
+ this.setState({
+ pos,
+ keyboard: true
+ }, () => {
+ this.scrollTo({
+ row: pos[0]
+ });
+ });
+ }
+ scrollTo({ categoryId, row }) {
+ const grid = this.state.searchResults || this.grid;
+ if (!grid.length) return;
+ const scroll = this.refs.scroll.current;
+ const scrollRect = scroll.getBoundingClientRect();
+ let scrollTop = 0;
+ if (row >= 0) categoryId = grid[row].__categoryId;
+ if (categoryId) {
+ const ref = this.refs[categoryId] || this.refs.categories.get(categoryId).root;
+ const categoryRect = ref.current.getBoundingClientRect();
+ scrollTop = categoryRect.top - (scrollRect.top - scroll.scrollTop) + 1;
+ }
+ if (row >= 0) {
+ if (!row) scrollTop = 0;
+ else {
+ const rowIndex = grid[row].__index;
+ const rowTop = scrollTop + rowIndex * this.props.emojiButtonSize;
+ const rowBot = rowTop + this.props.emojiButtonSize + this.props.emojiButtonSize * 0.88;
+ if (rowTop < scroll.scrollTop) scrollTop = rowTop;
+ else if (rowBot > scroll.scrollTop + scrollRect.height) scrollTop = rowBot - scrollRect.height;
+ else return;
+ }
+ }
+ this.ignoreMouse();
+ scroll.scrollTop = scrollTop;
+ }
+ ignoreMouse() {
+ this.mouseIsIgnored = true;
+ clearTimeout(this.ignoreMouseTimer);
+ this.ignoreMouseTimer = setTimeout(() => {
+ delete this.mouseIsIgnored;
+ }, 100);
+ }
+ handleEmojiOver(pos) {
+ if (this.mouseIsIgnored || this.state.showSkins) return;
+ this.setState({
+ pos: pos || [
+ -1,
+ -1
+ ],
+ keyboard: false
+ });
+ }
+ handleEmojiClick({ e, emoji, pos }) {
+ if (!this.props.onEmojiSelect) return;
+ if (!emoji && pos) emoji = this.getEmojiByPos(pos);
+ if (emoji) {
+ const emojiData = $693b183b0a78708f$export$d10ac59fbe52a745(emoji, {
+ skinIndex: this.state.skin - 1
+ });
+ if (this.props.maxFrequentRows) $b22cfd0a55410b4f$export$2e2bcd8739ae039.add(emojiData, this.props);
+ this.props.onEmojiSelect(emojiData, e);
+ }
+ }
+ closeSkins() {
+ if (!this.state.showSkins) return;
+ this.setState({
+ showSkins: null,
+ tempSkin: null
+ });
+ this.base.removeEventListener("click", this.handleBaseClick);
+ this.base.removeEventListener("keydown", this.handleBaseKeydown);
+ }
+ handleSkinMouseOver(tempSkin) {
+ this.setState({
+ tempSkin
+ });
+ }
+ handleSkinClick(skin) {
+ this.ignoreMouse();
+ this.closeSkins();
+ this.setState({
+ skin,
+ tempSkin: null
+ });
+ $f72b75cf796873c7$export$2e2bcd8739ae039.set("skin", skin);
+ }
+ renderNav() {
+ return /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b($ec8c39fdad15601a$export$2e2bcd8739ae039, {
+ ref: this.refs.navigation,
+ icons: this.props.icons,
+ theme: this.state.theme,
+ dir: this.dir,
+ unfocused: !!this.state.searchResults,
+ position: this.props.navPosition,
+ onClick: this.handleCategoryClick
+ }, this.navKey);
+ }
+ renderPreview() {
+ const emoji = this.getEmojiByPos(this.state.pos);
+ const noSearchResults = this.state.searchResults && !this.state.searchResults.length;
+ return /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ id: "preview",
+ class: "flex flex-middle",
+ dir: this.dir,
+ "data-position": this.props.previewPosition,
+ children: [
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ class: "flex flex-middle flex-grow",
+ children: [
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ class: "flex flex-auto flex-middle flex-center",
+ style: {
+ height: this.props.emojiButtonSize,
+ fontSize: this.props.emojiButtonSize
+ },
+ children: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b($254755d3f438722f$export$2e2bcd8739ae039, {
+ emoji,
+ id: noSearchResults ? this.props.noResultsEmoji || "cry" : this.props.previewEmoji || (this.props.previewPosition == "top" ? "point_down" : "point_up"),
+ set: this.props.set,
+ size: this.props.emojiButtonSize,
+ skin: this.state.tempSkin || this.state.skin,
+ spritesheet: true,
+ getSpritesheetURL: this.props.getSpritesheetURL
+ })
+ }),
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ class: `margin-${this.dir[0]}`,
+ children: emoji || noSearchResults ? /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ class: `padding-${this.dir[2]} align-${this.dir[0]}`,
+ children: [
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ class: "preview-title ellipsis",
+ children: emoji ? emoji.name : $7adb23b0109cc36a$export$dbe3113d60765c1a.search_no_results_1
+ }),
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ class: "preview-subtitle ellipsis color-c",
+ children: emoji ? emoji.skins[0].shortcodes : $7adb23b0109cc36a$export$dbe3113d60765c1a.search_no_results_2
+ })
+ ]
+ }) : /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ class: "preview-placeholder color-c",
+ children: $7adb23b0109cc36a$export$dbe3113d60765c1a.pick
+ })
+ })
+ ]
+ }),
+ !emoji && this.props.skinTonePosition == "preview" && this.renderSkinToneButton()
+ ]
+ });
+ }
+ renderEmojiButton(emoji, { pos, posinset, grid }) {
+ const size = this.props.emojiButtonSize;
+ const skin = this.state.tempSkin || this.state.skin;
+ const emojiSkin = emoji.skins[skin - 1] || emoji.skins[0];
+ const native = emojiSkin.native;
+ const selected = $693b183b0a78708f$export$9cb4719e2e525b7a(this.state.pos, pos);
+ const key = pos.concat(emoji.id).join("");
+ return /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b($e0d4dda61265ff1e$export$2e2bcd8739ae039, {
+ selected,
+ skin,
+ size,
+ children: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("button", {
+ "aria-label": native,
+ "aria-selected": selected || void 0,
+ "aria-posinset": posinset,
+ "aria-setsize": grid.setsize,
+ "data-keyboard": this.state.keyboard,
+ title: this.props.previewPosition == "none" ? emoji.name : void 0,
+ type: "button",
+ class: "flex flex-center flex-middle",
+ tabindex: "-1",
+ onClick: (e) => this.handleEmojiClick({
+ e,
+ emoji
+ }),
+ onMouseEnter: () => this.handleEmojiOver(pos),
+ onMouseLeave: () => this.handleEmojiOver(),
+ style: {
+ width: this.props.emojiButtonSize,
+ height: this.props.emojiButtonSize,
+ fontSize: this.props.emojiSize,
+ lineHeight: 0
+ },
+ children: [
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ "aria-hidden": "true",
+ class: "background",
+ style: {
+ borderRadius: this.props.emojiButtonRadius,
+ backgroundColor: this.props.emojiButtonColors ? this.props.emojiButtonColors[(posinset - 1) % this.props.emojiButtonColors.length] : void 0
+ }
+ }),
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b($254755d3f438722f$export$2e2bcd8739ae039, {
+ emoji,
+ set: this.props.set,
+ size: this.props.emojiSize,
+ skin,
+ spritesheet: true,
+ getSpritesheetURL: this.props.getSpritesheetURL
+ })
+ ]
+ })
+ }, key);
+ }
+ renderSearch() {
+ const renderSkinTone = this.props.previewPosition == "none" || this.props.skinTonePosition == "search";
+ return /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ children: [
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ class: "spacer"
+ }),
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ class: "flex flex-middle",
+ children: [
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ class: "search relative flex-grow",
+ children: [
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("input", {
+ type: "search",
+ ref: this.refs.searchInput,
+ placeholder: $7adb23b0109cc36a$export$dbe3113d60765c1a.search,
+ onClick: this.handleSearchClick,
+ onInput: this.handleSearchInput,
+ onKeyDown: this.handleSearchKeyDown,
+ autoComplete: "off"
+ }),
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("span", {
+ class: "icon loupe flex",
+ children: $fcccfb36ed0cde68$export$2e2bcd8739ae039.search.loupe
+ }),
+ this.state.searchResults && /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("button", {
+ title: "Clear",
+ "aria-label": "Clear",
+ type: "button",
+ class: "icon delete flex",
+ onClick: this.clearSearch,
+ onMouseDown: this.preventDefault,
+ children: $fcccfb36ed0cde68$export$2e2bcd8739ae039.search.delete
+ })
+ ]
+ }),
+ renderSkinTone && this.renderSkinToneButton()
+ ]
+ })
+ ]
+ });
+ }
+ renderSearchResults() {
+ const { searchResults } = this.state;
+ if (!searchResults) return null;
+ return /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ class: "category",
+ ref: this.refs.search,
+ children: [
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ class: `sticky padding-small align-${this.dir[0]}`,
+ children: $7adb23b0109cc36a$export$dbe3113d60765c1a.categories.search
+ }),
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ children: !searchResults.length ? /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ class: `padding-small align-${this.dir[0]}`,
+ children: this.props.onAddCustomEmoji && /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("a", {
+ onClick: this.props.onAddCustomEmoji,
+ children: $7adb23b0109cc36a$export$dbe3113d60765c1a.add_custom
+ })
+ }) : searchResults.map((row, i) => {
+ return /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ class: "flex",
+ children: row.map((emoji, ii) => {
+ return this.renderEmojiButton(emoji, {
+ pos: [
+ i,
+ ii
+ ],
+ posinset: i * this.props.perLine + ii + 1,
+ grid: searchResults
+ });
+ })
+ });
+ })
+ })
+ ]
+ });
+ }
+ renderCategories() {
+ const { categories } = $7adb23b0109cc36a$export$2d0294657ab35f1b;
+ const hidden = !!this.state.searchResults;
+ const perLine = this.getPerLine();
+ return /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ style: {
+ visibility: hidden ? "hidden" : void 0,
+ display: hidden ? "none" : void 0,
+ height: "100%"
+ },
+ children: categories.map((category) => {
+ const { root, rows } = this.refs.categories.get(category.id);
+ return /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ "data-id": category.target ? category.target.id : category.id,
+ class: "category",
+ ref: root,
+ children: [
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ class: `sticky padding-small align-${this.dir[0]}`,
+ children: category.name || $7adb23b0109cc36a$export$dbe3113d60765c1a.categories[category.id]
+ }),
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ class: "relative",
+ style: {
+ height: rows.length * this.props.emojiButtonSize
+ },
+ children: rows.map((row, i) => {
+ const targetRow = row.index - row.index % $89bd6bb200cc8fef$var$Performance.rowsPerRender;
+ const visible = this.state.visibleRows[targetRow];
+ const ref = "current" in row ? row : void 0;
+ if (!visible && !ref) return null;
+ const start = i * perLine;
+ const end = start + perLine;
+ const emojiIds = category.emojis.slice(start, end);
+ if (emojiIds.length < perLine) emojiIds.push(...new Array(perLine - emojiIds.length));
+ return /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ "data-index": row.index,
+ ref,
+ class: "flex row",
+ style: {
+ top: i * this.props.emojiButtonSize
+ },
+ children: visible && emojiIds.map((emojiId, ii) => {
+ if (!emojiId) return /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ style: {
+ width: this.props.emojiButtonSize,
+ height: this.props.emojiButtonSize
+ }
+ });
+ const emoji = $c4d155af13ad4d4b$export$2e2bcd8739ae039.get(emojiId);
+ return this.renderEmojiButton(emoji, {
+ pos: [
+ row.index,
+ ii
+ ],
+ posinset: row.posinset + ii,
+ grid: this.grid
+ });
+ })
+ }, row.index);
+ })
+ })
+ ]
+ });
+ })
+ });
+ }
+ renderSkinToneButton() {
+ if (this.props.skinTonePosition == "none") return null;
+ return /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ class: "flex flex-auto flex-center flex-middle",
+ style: {
+ position: "relative",
+ width: this.props.emojiButtonSize,
+ height: this.props.emojiButtonSize
+ },
+ children: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("button", {
+ type: "button",
+ ref: this.refs.skinToneButton,
+ class: "skin-tone-button flex flex-auto flex-center flex-middle",
+ "aria-selected": this.state.showSkins ? "" : void 0,
+ "aria-label": $7adb23b0109cc36a$export$dbe3113d60765c1a.skins.choose,
+ title: $7adb23b0109cc36a$export$dbe3113d60765c1a.skins.choose,
+ onClick: this.openSkins,
+ style: {
+ width: this.props.emojiSize,
+ height: this.props.emojiSize
+ },
+ children: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("span", {
+ class: `skin-tone skin-tone-${this.state.skin}`
+ })
+ })
+ });
+ }
+ renderLiveRegion() {
+ const emoji = this.getEmojiByPos(this.state.pos);
+ const contents = emoji ? emoji.name : "";
+ return /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ "aria-live": "polite",
+ class: "sr-only",
+ children: contents
+ });
+ }
+ renderSkins() {
+ const skinToneButton = this.refs.skinToneButton.current;
+ const skinToneButtonRect = skinToneButton.getBoundingClientRect();
+ const baseRect = this.base.getBoundingClientRect();
+ const position = {};
+ if (this.dir == "ltr") position.right = baseRect.right - skinToneButtonRect.right - 3;
+ else position.left = skinToneButtonRect.left - baseRect.left - 3;
+ if (this.props.previewPosition == "bottom" && this.props.skinTonePosition == "preview") position.bottom = baseRect.bottom - skinToneButtonRect.top + 6;
+ else {
+ position.top = skinToneButtonRect.bottom - baseRect.top + 3;
+ position.bottom = "auto";
+ }
+ return /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ ref: this.refs.menu,
+ role: "radiogroup",
+ dir: this.dir,
+ "aria-label": $7adb23b0109cc36a$export$dbe3113d60765c1a.skins.choose,
+ class: "menu hidden",
+ "data-position": position.top ? "top" : "bottom",
+ style: position,
+ children: [
+ ...Array(6).keys()
+ ].map((i) => {
+ const skin = i + 1;
+ const checked = this.state.skin == skin;
+ return /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ children: [
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("input", {
+ type: "radio",
+ name: "skin-tone",
+ value: skin,
+ "aria-label": $7adb23b0109cc36a$export$dbe3113d60765c1a.skins[skin],
+ ref: checked ? this.refs.skinToneRadio : null,
+ defaultChecked: checked,
+ onChange: () => this.handleSkinMouseOver(skin),
+ onKeyDown: (e) => {
+ if (e.code == "Enter" || e.code == "Space" || e.code == "Tab") {
+ e.preventDefault();
+ this.handleSkinClick(skin);
+ }
+ }
+ }),
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("button", {
+ "aria-hidden": "true",
+ tabindex: "-1",
+ onClick: () => this.handleSkinClick(skin),
+ onMouseEnter: () => this.handleSkinMouseOver(skin),
+ onMouseLeave: () => this.handleSkinMouseOver(),
+ class: "option flex flex-grow flex-middle",
+ children: [
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("span", {
+ class: `skin-tone skin-tone-${skin}`
+ }),
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("span", {
+ class: "margin-small-lr",
+ children: $7adb23b0109cc36a$export$dbe3113d60765c1a.skins[skin]
+ })
+ ]
+ })
+ ]
+ });
+ })
+ });
+ }
+ render() {
+ const lineWidth = this.props.perLine * this.props.emojiButtonSize;
+ return /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("section", {
+ id: "root",
+ class: "flex flex-column",
+ dir: this.dir,
+ style: {
+ width: this.props.dynamicWidth ? "100%" : `calc(${lineWidth}px + (var(--padding) + var(--sidebar-width)))`
+ },
+ "data-emoji-set": this.props.set,
+ "data-theme": this.state.theme,
+ "data-menu": this.state.showSkins ? "" : void 0,
+ children: [
+ this.props.previewPosition == "top" && this.renderPreview(),
+ this.props.navPosition == "top" && this.renderNav(),
+ this.props.searchPosition == "sticky" && /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ class: "padding-lr",
+ children: this.renderSearch()
+ }),
+ /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ ref: this.refs.scroll,
+ class: "scroll flex-grow padding-lr",
+ children: /* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b("div", {
+ style: {
+ width: this.props.dynamicWidth ? "100%" : lineWidth,
+ height: "100%"
+ },
+ children: [
+ this.props.searchPosition == "static" && this.renderSearch(),
+ this.renderSearchResults(),
+ this.renderCategories()
+ ]
+ })
+ }),
+ this.props.navPosition == "bottom" && this.renderNav(),
+ this.props.previewPosition == "bottom" && this.renderPreview(),
+ this.state.showSkins && this.renderSkins(),
+ this.renderLiveRegion()
+ ]
+ });
+ }
+ constructor(props) {
+ super();
+ $c770c458706daa72$export$2e2bcd8739ae039(this, "darkMediaCallback", () => {
+ if (this.props.theme != "auto") return;
+ this.setState({
+ theme: this.darkMedia.matches ? "dark" : "light"
+ });
+ });
+ $c770c458706daa72$export$2e2bcd8739ae039(this, "handleClickOutside", (e) => {
+ const { element } = this.props;
+ if (e.target != element) {
+ if (this.state.showSkins) this.closeSkins();
+ if (this.props.onClickOutside) this.props.onClickOutside(e);
+ }
+ });
+ $c770c458706daa72$export$2e2bcd8739ae039(this, "handleBaseClick", (e) => {
+ if (!this.state.showSkins) return;
+ if (!e.target.closest(".menu")) {
+ e.preventDefault();
+ e.stopImmediatePropagation();
+ this.closeSkins();
+ }
+ });
+ $c770c458706daa72$export$2e2bcd8739ae039(this, "handleBaseKeydown", (e) => {
+ if (!this.state.showSkins) return;
+ if (e.key == "Escape") {
+ e.preventDefault();
+ e.stopImmediatePropagation();
+ this.closeSkins();
+ }
+ });
+ $c770c458706daa72$export$2e2bcd8739ae039(this, "handleSearchClick", () => {
+ const emoji = this.getEmojiByPos(this.state.pos);
+ if (!emoji) return;
+ this.setState({
+ pos: [
+ -1,
+ -1
+ ]
+ });
+ });
+ $c770c458706daa72$export$2e2bcd8739ae039(this, "handleSearchInput", async () => {
+ const input = this.refs.searchInput.current;
+ if (!input) return;
+ const { value } = input;
+ const searchResults = await $c4d155af13ad4d4b$export$2e2bcd8739ae039.search(value);
+ const afterRender = () => {
+ if (!this.refs.scroll.current) return;
+ this.refs.scroll.current.scrollTop = 0;
+ };
+ if (!searchResults) return this.setState({
+ searchResults,
+ pos: [
+ -1,
+ -1
+ ]
+ }, afterRender);
+ const pos = input.selectionStart == input.value.length ? [
+ 0,
+ 0
+ ] : [
+ -1,
+ -1
+ ];
+ const grid = [];
+ grid.setsize = searchResults.length;
+ let row = null;
+ for (let emoji of searchResults) {
+ if (!grid.length || row.length == this.getPerLine()) {
+ row = [];
+ row.__categoryId = "search";
+ row.__index = grid.length;
+ grid.push(row);
+ }
+ row.push(emoji);
+ }
+ this.ignoreMouse();
+ this.setState({
+ searchResults: grid,
+ pos
+ }, afterRender);
+ });
+ $c770c458706daa72$export$2e2bcd8739ae039(this, "handleSearchKeyDown", (e) => {
+ const input = e.currentTarget;
+ e.stopImmediatePropagation();
+ switch (e.key) {
+ case "ArrowLeft":
+ this.navigate({
+ e,
+ input,
+ left: true
+ });
+ break;
+ case "ArrowRight":
+ this.navigate({
+ e,
+ input,
+ right: true
+ });
+ break;
+ case "ArrowUp":
+ this.navigate({
+ e,
+ input,
+ up: true
+ });
+ break;
+ case "ArrowDown":
+ this.navigate({
+ e,
+ input,
+ down: true
+ });
+ break;
+ case "Enter":
+ e.preventDefault();
+ this.handleEmojiClick({
+ e,
+ pos: this.state.pos
+ });
+ break;
+ case "Escape":
+ e.preventDefault();
+ if (this.state.searchResults) this.clearSearch();
+ else this.unfocusSearch();
+ break;
+ }
+ });
+ $c770c458706daa72$export$2e2bcd8739ae039(this, "clearSearch", () => {
+ const input = this.refs.searchInput.current;
+ if (!input) return;
+ input.value = "";
+ input.focus();
+ this.handleSearchInput();
+ });
+ $c770c458706daa72$export$2e2bcd8739ae039(this, "handleCategoryClick", ({ category, i }) => {
+ this.scrollTo(i == 0 ? {
+ row: -1
+ } : {
+ categoryId: category.id
+ });
+ });
+ $c770c458706daa72$export$2e2bcd8739ae039(this, "openSkins", (e) => {
+ const { currentTarget } = e;
+ const rect = currentTarget.getBoundingClientRect();
+ this.setState({
+ showSkins: rect
+ }, async () => {
+ await $693b183b0a78708f$export$e772c8ff12451969(2);
+ const menu = this.refs.menu.current;
+ if (!menu) return;
+ menu.classList.remove("hidden");
+ this.refs.skinToneRadio.current.focus();
+ this.base.addEventListener("click", this.handleBaseClick, true);
+ this.base.addEventListener("keydown", this.handleBaseKeydown, true);
+ });
+ });
+ this.observers = [];
+ this.state = {
+ pos: [
+ -1,
+ -1
+ ],
+ perLine: this.initDynamicPerLine(props),
+ visibleRows: {
+ 0: true
+ },
+ ...this.getInitialState(props)
+ };
+ }
+}
+class $efa000751917694d$export$2e2bcd8739ae039 extends $26f27c338a96b1a6$export$2e2bcd8739ae039 {
+ async connectedCallback() {
+ const props = $7adb23b0109cc36a$export$75fe5f91d452f94b(this.props, $b247ea80b67298d5$export$2e2bcd8739ae039, this);
+ props.element = this;
+ props.ref = (component) => {
+ this.component = component;
+ };
+ await $7adb23b0109cc36a$export$2cd8252107eb640b(props);
+ if (this.disconnected) return;
+ $fb96b826c0c5f37a$export$b3890eb0ae9dca99(/* @__PURE__ */ $bd9dd35321b03dd4$export$34b9dba7ce09269b($89bd6bb200cc8fef$export$2e2bcd8739ae039, {
+ ...props
+ }), this.shadowRoot);
+ }
+ constructor(props) {
+ super(props, {
+ styles: /* @__PURE__ */ $parcel$interopDefault($329d53ba9fd7125f$exports)
+ });
+ }
+}
+$c770c458706daa72$export$2e2bcd8739ae039($efa000751917694d$export$2e2bcd8739ae039, "Props", $b247ea80b67298d5$export$2e2bcd8739ae039);
+if (typeof customElements !== "undefined" && !customElements.get("em-emoji-picker")) customElements.define("em-emoji-picker", $efa000751917694d$export$2e2bcd8739ae039);
+var $329d53ba9fd7125f$exports = {};
+$329d53ba9fd7125f$exports = ':host {\n width: min-content;\n height: 435px;\n min-height: 230px;\n border-radius: var(--border-radius);\n box-shadow: var(--shadow);\n --border-radius: 10px;\n --category-icon-size: 18px;\n --font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", sans-serif;\n --font-size: 15px;\n --preview-placeholder-size: 21px;\n --preview-title-size: 1.1em;\n --preview-subtitle-size: .9em;\n --shadow-color: 0deg 0% 0%;\n --shadow: .3px .5px 2.7px hsl(var(--shadow-color) / .14), .4px .8px 1px -3.2px hsl(var(--shadow-color) / .14), 1px 2px 2.5px -4.5px hsl(var(--shadow-color) / .14);\n display: flex;\n}\n\n[data-theme="light"] {\n --em-rgb-color: var(--rgb-color, 34, 36, 39);\n --em-rgb-accent: var(--rgb-accent, 34, 102, 237);\n --em-rgb-background: var(--rgb-background, 255, 255, 255);\n --em-rgb-input: var(--rgb-input, 255, 255, 255);\n --em-color-border: var(--color-border, rgba(0, 0, 0, .05));\n --em-color-border-over: var(--color-border-over, rgba(0, 0, 0, .1));\n}\n\n[data-theme="dark"] {\n --em-rgb-color: var(--rgb-color, 222, 222, 221);\n --em-rgb-accent: var(--rgb-accent, 58, 130, 247);\n --em-rgb-background: var(--rgb-background, 21, 22, 23);\n --em-rgb-input: var(--rgb-input, 0, 0, 0);\n --em-color-border: var(--color-border, rgba(255, 255, 255, .1));\n --em-color-border-over: var(--color-border-over, rgba(255, 255, 255, .2));\n}\n\n#root {\n --color-a: rgb(var(--em-rgb-color));\n --color-b: rgba(var(--em-rgb-color), .65);\n --color-c: rgba(var(--em-rgb-color), .45);\n --padding: 12px;\n --padding-small: calc(var(--padding) / 2);\n --sidebar-width: 16px;\n --duration: 225ms;\n --duration-fast: 125ms;\n --duration-instant: 50ms;\n --easing: cubic-bezier(.4, 0, .2, 1);\n width: 100%;\n text-align: left;\n border-radius: var(--border-radius);\n background-color: rgb(var(--em-rgb-background));\n position: relative;\n}\n\n@media (prefers-reduced-motion) {\n #root {\n --duration: 0;\n --duration-fast: 0;\n --duration-instant: 0;\n }\n}\n\n#root[data-menu] button {\n cursor: auto;\n}\n\n#root[data-menu] .menu button {\n cursor: pointer;\n}\n\n:host, #root, input, button {\n color: rgb(var(--em-rgb-color));\n font-family: var(--font-family);\n font-size: var(--font-size);\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n line-height: normal;\n}\n\n*, :before, :after {\n box-sizing: border-box;\n min-width: 0;\n margin: 0;\n padding: 0;\n}\n\n.relative {\n position: relative;\n}\n\n.flex {\n display: flex;\n}\n\n.flex-auto {\n flex: none;\n}\n\n.flex-center {\n justify-content: center;\n}\n\n.flex-column {\n flex-direction: column;\n}\n\n.flex-grow {\n flex: auto;\n}\n\n.flex-middle {\n align-items: center;\n}\n\n.flex-wrap {\n flex-wrap: wrap;\n}\n\n.padding {\n padding: var(--padding);\n}\n\n.padding-t {\n padding-top: var(--padding);\n}\n\n.padding-lr {\n padding-left: var(--padding);\n padding-right: var(--padding);\n}\n\n.padding-r {\n padding-right: var(--padding);\n}\n\n.padding-small {\n padding: var(--padding-small);\n}\n\n.padding-small-b {\n padding-bottom: var(--padding-small);\n}\n\n.padding-small-lr {\n padding-left: var(--padding-small);\n padding-right: var(--padding-small);\n}\n\n.margin {\n margin: var(--padding);\n}\n\n.margin-r {\n margin-right: var(--padding);\n}\n\n.margin-l {\n margin-left: var(--padding);\n}\n\n.margin-small-l {\n margin-left: var(--padding-small);\n}\n\n.margin-small-lr {\n margin-left: var(--padding-small);\n margin-right: var(--padding-small);\n}\n\n.align-l {\n text-align: left;\n}\n\n.align-r {\n text-align: right;\n}\n\n.color-a {\n color: var(--color-a);\n}\n\n.color-b {\n color: var(--color-b);\n}\n\n.color-c {\n color: var(--color-c);\n}\n\n.ellipsis {\n white-space: nowrap;\n max-width: 100%;\n width: auto;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\n.sr-only {\n width: 1px;\n height: 1px;\n position: absolute;\n top: auto;\n left: -10000px;\n overflow: hidden;\n}\n\na {\n cursor: pointer;\n color: rgb(var(--em-rgb-accent));\n}\n\na:hover {\n text-decoration: underline;\n}\n\n.spacer {\n height: 10px;\n}\n\n[dir="rtl"] .scroll {\n padding-left: 0;\n padding-right: var(--padding);\n}\n\n.scroll {\n padding-right: 0;\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n.scroll::-webkit-scrollbar {\n width: var(--sidebar-width);\n height: var(--sidebar-width);\n}\n\n.scroll::-webkit-scrollbar-track {\n border: 0;\n}\n\n.scroll::-webkit-scrollbar-button {\n width: 0;\n height: 0;\n display: none;\n}\n\n.scroll::-webkit-scrollbar-corner {\n background-color: rgba(0, 0, 0, 0);\n}\n\n.scroll::-webkit-scrollbar-thumb {\n min-height: 20%;\n min-height: 65px;\n border: 4px solid rgb(var(--em-rgb-background));\n border-radius: 8px;\n}\n\n.scroll::-webkit-scrollbar-thumb:hover {\n background-color: var(--em-color-border-over) !important;\n}\n\n.scroll:hover::-webkit-scrollbar-thumb {\n background-color: var(--em-color-border);\n}\n\n.sticky {\n z-index: 1;\n background-color: rgba(var(--em-rgb-background), .9);\n -webkit-backdrop-filter: blur(4px);\n backdrop-filter: blur(4px);\n font-weight: 500;\n position: sticky;\n top: -1px;\n}\n\n[dir="rtl"] .search input[type="search"] {\n padding: 10px 2.2em 10px 2em;\n}\n\n[dir="rtl"] .search .loupe {\n left: auto;\n right: .7em;\n}\n\n[dir="rtl"] .search .delete {\n left: .7em;\n right: auto;\n}\n\n.search {\n z-index: 2;\n position: relative;\n}\n\n.search input, .search button {\n font-size: calc(var(--font-size) - 1px);\n}\n\n.search input[type="search"] {\n width: 100%;\n background-color: var(--em-color-border);\n transition-duration: var(--duration);\n transition-property: background-color, box-shadow;\n transition-timing-function: var(--easing);\n border: 0;\n border-radius: 10px;\n outline: 0;\n padding: 10px 2em 10px 2.2em;\n display: block;\n}\n\n.search input[type="search"]::-ms-input-placeholder {\n color: inherit;\n opacity: .6;\n}\n\n.search input[type="search"]::placeholder {\n color: inherit;\n opacity: .6;\n}\n\n.search input[type="search"], .search input[type="search"]::-webkit-search-decoration, .search input[type="search"]::-webkit-search-cancel-button, .search input[type="search"]::-webkit-search-results-button, .search input[type="search"]::-webkit-search-results-decoration {\n -webkit-appearance: none;\n -ms-appearance: none;\n appearance: none;\n}\n\n.search input[type="search"]:focus {\n background-color: rgb(var(--em-rgb-input));\n box-shadow: inset 0 0 0 1px rgb(var(--em-rgb-accent)), 0 1px 3px rgba(65, 69, 73, .2);\n}\n\n.search .icon {\n z-index: 1;\n color: rgba(var(--em-rgb-color), .7);\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n}\n\n.search .loupe {\n pointer-events: none;\n left: .7em;\n}\n\n.search .delete {\n right: .7em;\n}\n\nsvg {\n fill: currentColor;\n width: 1em;\n height: 1em;\n}\n\nbutton {\n -webkit-appearance: none;\n -ms-appearance: none;\n appearance: none;\n cursor: pointer;\n color: currentColor;\n background-color: rgba(0, 0, 0, 0);\n border: 0;\n}\n\n#nav {\n z-index: 2;\n padding-top: 12px;\n padding-bottom: 12px;\n padding-right: var(--sidebar-width);\n position: relative;\n}\n\n#nav button {\n color: var(--color-b);\n transition: color var(--duration) var(--easing);\n}\n\n#nav button:hover {\n color: var(--color-a);\n}\n\n#nav svg, #nav img {\n width: var(--category-icon-size);\n height: var(--category-icon-size);\n}\n\n#nav[dir="rtl"] .bar {\n left: auto;\n right: 0;\n}\n\n#nav .bar {\n width: 100%;\n height: 3px;\n background-color: rgb(var(--em-rgb-accent));\n transition: transform var(--duration) var(--easing);\n border-radius: 3px 3px 0 0;\n position: absolute;\n bottom: -12px;\n left: 0;\n}\n\n#nav button[aria-selected] {\n color: rgb(var(--em-rgb-accent));\n}\n\n#preview {\n z-index: 2;\n padding: calc(var(--padding) + 4px) var(--padding);\n padding-right: var(--sidebar-width);\n position: relative;\n}\n\n#preview .preview-placeholder {\n font-size: var(--preview-placeholder-size);\n}\n\n#preview .preview-title {\n font-size: var(--preview-title-size);\n}\n\n#preview .preview-subtitle {\n font-size: var(--preview-subtitle-size);\n}\n\n#nav:before, #preview:before {\n content: "";\n height: 2px;\n position: absolute;\n left: 0;\n right: 0;\n}\n\n#nav[data-position="top"]:before, #preview[data-position="top"]:before {\n background: linear-gradient(to bottom, var(--em-color-border), transparent);\n top: 100%;\n}\n\n#nav[data-position="bottom"]:before, #preview[data-position="bottom"]:before {\n background: linear-gradient(to top, var(--em-color-border), transparent);\n bottom: 100%;\n}\n\n.category:last-child {\n min-height: calc(100% + 1px);\n}\n\n.category button {\n font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, sans-serif;\n position: relative;\n}\n\n.category button > * {\n position: relative;\n}\n\n.category button .background {\n opacity: 0;\n background-color: var(--em-color-border);\n transition: opacity var(--duration-fast) var(--easing) var(--duration-instant);\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n right: 0;\n}\n\n.category button:hover .background {\n transition-duration: var(--duration-instant);\n transition-delay: 0s;\n}\n\n.category button[aria-selected] .background {\n opacity: 1;\n}\n\n.category button[data-keyboard] .background {\n transition: none;\n}\n\n.row {\n width: 100%;\n position: absolute;\n top: 0;\n left: 0;\n}\n\n.skin-tone-button {\n border: 1px solid rgba(0, 0, 0, 0);\n border-radius: 100%;\n}\n\n.skin-tone-button:hover {\n border-color: var(--em-color-border);\n}\n\n.skin-tone-button:active .skin-tone {\n transform: scale(.85) !important;\n}\n\n.skin-tone-button .skin-tone {\n transition: transform var(--duration) var(--easing);\n}\n\n.skin-tone-button[aria-selected] {\n background-color: var(--em-color-border);\n border-top-color: rgba(0, 0, 0, .05);\n border-bottom-color: rgba(0, 0, 0, 0);\n border-left-width: 0;\n border-right-width: 0;\n}\n\n.skin-tone-button[aria-selected] .skin-tone {\n transform: scale(.9);\n}\n\n.menu {\n z-index: 2;\n white-space: nowrap;\n border: 1px solid var(--em-color-border);\n background-color: rgba(var(--em-rgb-background), .9);\n -webkit-backdrop-filter: blur(4px);\n backdrop-filter: blur(4px);\n transition-property: opacity, transform;\n transition-duration: var(--duration);\n transition-timing-function: var(--easing);\n border-radius: 10px;\n padding: 4px;\n position: absolute;\n box-shadow: 1px 1px 5px rgba(0, 0, 0, .05);\n}\n\n.menu.hidden {\n opacity: 0;\n}\n\n.menu[data-position="bottom"] {\n transform-origin: 100% 100%;\n}\n\n.menu[data-position="bottom"].hidden {\n transform: scale(.9)rotate(-3deg)translateY(5%);\n}\n\n.menu[data-position="top"] {\n transform-origin: 100% 0;\n}\n\n.menu[data-position="top"].hidden {\n transform: scale(.9)rotate(3deg)translateY(-5%);\n}\n\n.menu input[type="radio"] {\n clip: rect(0 0 0 0);\n width: 1px;\n height: 1px;\n border: 0;\n margin: 0;\n padding: 0;\n position: absolute;\n overflow: hidden;\n}\n\n.menu input[type="radio"]:checked + .option {\n box-shadow: 0 0 0 2px rgb(var(--em-rgb-accent));\n}\n\n.option {\n width: 100%;\n border-radius: 6px;\n padding: 4px 6px;\n}\n\n.option:hover {\n color: #fff;\n background-color: rgb(var(--em-rgb-accent));\n}\n\n.skin-tone {\n width: 16px;\n height: 16px;\n border-radius: 100%;\n display: inline-block;\n position: relative;\n overflow: hidden;\n}\n\n.skin-tone:after {\n content: "";\n mix-blend-mode: overlay;\n background: linear-gradient(rgba(255, 255, 255, .2), rgba(0, 0, 0, 0));\n border: 1px solid rgba(0, 0, 0, .8);\n border-radius: 100%;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n right: 0;\n box-shadow: inset 0 -2px 3px #000, inset 0 1px 2px #fff;\n}\n\n.skin-tone-1 {\n background-color: #ffc93a;\n}\n\n.skin-tone-2 {\n background-color: #ffdab7;\n}\n\n.skin-tone-3 {\n background-color: #e7b98f;\n}\n\n.skin-tone-4 {\n background-color: #c88c61;\n}\n\n.skin-tone-5 {\n background-color: #a46134;\n}\n\n.skin-tone-6 {\n background-color: #5d4437;\n}\n\n[data-index] {\n justify-content: space-between;\n}\n\n[data-emoji-set="twitter"] .skin-tone:after {\n box-shadow: none;\n border-color: rgba(0, 0, 0, .5);\n}\n\n[data-emoji-set="twitter"] .skin-tone-1 {\n background-color: #fade72;\n}\n\n[data-emoji-set="twitter"] .skin-tone-2 {\n background-color: #f3dfd0;\n}\n\n[data-emoji-set="twitter"] .skin-tone-3 {\n background-color: #eed3a8;\n}\n\n[data-emoji-set="twitter"] .skin-tone-4 {\n background-color: #cfad8d;\n}\n\n[data-emoji-set="twitter"] .skin-tone-5 {\n background-color: #a8805d;\n}\n\n[data-emoji-set="twitter"] .skin-tone-6 {\n background-color: #765542;\n}\n\n[data-emoji-set="google"] .skin-tone:after {\n box-shadow: inset 0 0 2px 2px rgba(0, 0, 0, .4);\n}\n\n[data-emoji-set="google"] .skin-tone-1 {\n background-color: #f5c748;\n}\n\n[data-emoji-set="google"] .skin-tone-2 {\n background-color: #f1d5aa;\n}\n\n[data-emoji-set="google"] .skin-tone-3 {\n background-color: #d4b48d;\n}\n\n[data-emoji-set="google"] .skin-tone-4 {\n background-color: #aa876b;\n}\n\n[data-emoji-set="google"] .skin-tone-5 {\n background-color: #916544;\n}\n\n[data-emoji-set="google"] .skin-tone-6 {\n background-color: #61493f;\n}\n\n[data-emoji-set="facebook"] .skin-tone:after {\n border-color: rgba(0, 0, 0, .4);\n box-shadow: inset 0 -2px 3px #000, inset 0 1px 4px #fff;\n}\n\n[data-emoji-set="facebook"] .skin-tone-1 {\n background-color: #f5c748;\n}\n\n[data-emoji-set="facebook"] .skin-tone-2 {\n background-color: #f1d5aa;\n}\n\n[data-emoji-set="facebook"] .skin-tone-3 {\n background-color: #d4b48d;\n}\n\n[data-emoji-set="facebook"] .skin-tone-4 {\n background-color: #aa876b;\n}\n\n[data-emoji-set="facebook"] .skin-tone-5 {\n background-color: #916544;\n}\n\n[data-emoji-set="facebook"] .skin-tone-6 {\n background-color: #61493f;\n}\n\n';
+export {
+ $7adb23b0109cc36a$export$2d0294657ab35f1b as Data,
+ $331b4160623139bf$export$2e2bcd8739ae039 as Emoji,
+ $b22cfd0a55410b4f$export$2e2bcd8739ae039 as FrequentlyUsed,
+ $7adb23b0109cc36a$export$dbe3113d60765c1a as I18n,
+ $efa000751917694d$export$2e2bcd8739ae039 as Picker,
+ $e6eae5155b87f591$export$bcb25aa587e9cb13 as SafeFlags,
+ $c4d155af13ad4d4b$export$2e2bcd8739ae039 as SearchIndex,
+ $f72b75cf796873c7$export$2e2bcd8739ae039 as Store,
+ $693b183b0a78708f$export$5ef5574deca44bc0 as getEmojiDataFromNative,
+ $7adb23b0109cc36a$export$2cd8252107eb640b as init
+};
diff --git a/bootstrap/ssr/assets/vendor-motion-yDK3iGlC.js b/bootstrap/ssr/assets/vendor-motion-yDK3iGlC.js
new file mode 100644
index 00000000..454450ad
--- /dev/null
+++ b/bootstrap/ssr/assets/vendor-motion-yDK3iGlC.js
@@ -0,0 +1,8068 @@
+import { r as reactExports, j as jsxRuntimeExports } from "./vendor-tiptap-DSw66HfW.js";
+const LayoutGroupContext = reactExports.createContext({});
+function useConstant(init) {
+ const ref = reactExports.useRef(null);
+ if (ref.current === null) {
+ ref.current = init();
+ }
+ return ref.current;
+}
+const isBrowser$1 = typeof window !== "undefined";
+const useIsomorphicLayoutEffect = isBrowser$1 ? reactExports.useLayoutEffect : reactExports.useEffect;
+const PresenceContext = /* @__PURE__ */ reactExports.createContext(null);
+function addUniqueItem(arr, item) {
+ if (arr.indexOf(item) === -1)
+ arr.push(item);
+}
+function removeItem(arr, item) {
+ const index = arr.indexOf(item);
+ if (index > -1)
+ arr.splice(index, 1);
+}
+const clamp = (min, max, v) => {
+ if (v > max)
+ return max;
+ if (v < min)
+ return min;
+ return v;
+};
+function formatErrorMessage(message, errorCode) {
+ return errorCode ? `${message}. For more information and steps for solving, visit https://motion.dev/troubleshooting/${errorCode}` : message;
+}
+let warning = () => {
+};
+let invariant = () => {
+};
+if (typeof process !== "undefined" && process.env?.NODE_ENV !== "production") {
+ warning = (check, message, errorCode) => {
+ if (!check && typeof console !== "undefined") {
+ console.warn(formatErrorMessage(message, errorCode));
+ }
+ };
+ invariant = (check, message, errorCode) => {
+ if (!check) {
+ throw new Error(formatErrorMessage(message, errorCode));
+ }
+ };
+}
+const MotionGlobalConfig = {};
+const isNumericalString = (v) => /^-?(?:\d+(?:\.\d+)?|\.\d+)$/u.test(v);
+function isObject(value) {
+ return typeof value === "object" && value !== null;
+}
+const isZeroValueString = (v) => /^0[^.\s]+$/u.test(v);
+// @__NO_SIDE_EFFECTS__
+function memo(callback) {
+ let result;
+ return () => {
+ if (result === void 0)
+ result = callback();
+ return result;
+ };
+}
+const noop = /* @__NO_SIDE_EFFECTS__ */ (any) => any;
+const combineFunctions = (a, b) => (v) => b(a(v));
+const pipe = (...transformers) => transformers.reduce(combineFunctions);
+const progress = /* @__NO_SIDE_EFFECTS__ */ (from, to, value) => {
+ const toFromDifference = to - from;
+ return toFromDifference === 0 ? 1 : (value - from) / toFromDifference;
+};
+class SubscriptionManager {
+ constructor() {
+ this.subscriptions = [];
+ }
+ add(handler) {
+ addUniqueItem(this.subscriptions, handler);
+ return () => removeItem(this.subscriptions, handler);
+ }
+ notify(a, b, c) {
+ const numSubscriptions = this.subscriptions.length;
+ if (!numSubscriptions)
+ return;
+ if (numSubscriptions === 1) {
+ this.subscriptions[0](a, b, c);
+ } else {
+ for (let i = 0; i < numSubscriptions; i++) {
+ const handler = this.subscriptions[i];
+ handler && handler(a, b, c);
+ }
+ }
+ }
+ getSize() {
+ return this.subscriptions.length;
+ }
+ clear() {
+ this.subscriptions.length = 0;
+ }
+}
+const secondsToMilliseconds = /* @__NO_SIDE_EFFECTS__ */ (seconds) => seconds * 1e3;
+const millisecondsToSeconds = /* @__NO_SIDE_EFFECTS__ */ (milliseconds) => milliseconds / 1e3;
+function velocityPerSecond(velocity, frameDuration) {
+ return frameDuration ? velocity * (1e3 / frameDuration) : 0;
+}
+const warned = /* @__PURE__ */ new Set();
+function warnOnce(condition, message, errorCode) {
+ if (condition || warned.has(message))
+ return;
+ console.warn(formatErrorMessage(message, errorCode));
+ warned.add(message);
+}
+const calcBezier = (t, a1, a2) => (((1 - 3 * a2 + 3 * a1) * t + (3 * a2 - 6 * a1)) * t + 3 * a1) * t;
+const subdivisionPrecision = 1e-7;
+const subdivisionMaxIterations = 12;
+function binarySubdivide(x, lowerBound, upperBound, mX1, mX2) {
+ let currentX;
+ let currentT;
+ let i = 0;
+ do {
+ currentT = lowerBound + (upperBound - lowerBound) / 2;
+ currentX = calcBezier(currentT, mX1, mX2) - x;
+ if (currentX > 0) {
+ upperBound = currentT;
+ } else {
+ lowerBound = currentT;
+ }
+ } while (Math.abs(currentX) > subdivisionPrecision && ++i < subdivisionMaxIterations);
+ return currentT;
+}
+function cubicBezier(mX1, mY1, mX2, mY2) {
+ if (mX1 === mY1 && mX2 === mY2)
+ return noop;
+ const getTForX = (aX) => binarySubdivide(aX, 0, 1, mX1, mX2);
+ return (t) => t === 0 || t === 1 ? t : calcBezier(getTForX(t), mY1, mY2);
+}
+const mirrorEasing = (easing) => (p) => p <= 0.5 ? easing(2 * p) / 2 : (2 - easing(2 * (1 - p))) / 2;
+const reverseEasing = (easing) => (p) => 1 - easing(1 - p);
+const backOut = /* @__PURE__ */ cubicBezier(0.33, 1.53, 0.69, 0.99);
+const backIn = /* @__PURE__ */ reverseEasing(backOut);
+const backInOut = /* @__PURE__ */ mirrorEasing(backIn);
+const anticipate = (p) => p >= 1 ? 1 : (p *= 2) < 1 ? 0.5 * backIn(p) : 0.5 * (2 - Math.pow(2, -10 * (p - 1)));
+const circIn = (p) => 1 - Math.sin(Math.acos(p));
+const circOut = reverseEasing(circIn);
+const circInOut = mirrorEasing(circIn);
+const easeIn = /* @__PURE__ */ cubicBezier(0.42, 0, 1, 1);
+const easeOut = /* @__PURE__ */ cubicBezier(0, 0, 0.58, 1);
+const easeInOut = /* @__PURE__ */ cubicBezier(0.42, 0, 0.58, 1);
+const isEasingArray = (ease2) => {
+ return Array.isArray(ease2) && typeof ease2[0] !== "number";
+};
+const isBezierDefinition = (easing) => Array.isArray(easing) && typeof easing[0] === "number";
+const easingLookup = {
+ linear: noop,
+ easeIn,
+ easeInOut,
+ easeOut,
+ circIn,
+ circInOut,
+ circOut,
+ backIn,
+ backInOut,
+ backOut,
+ anticipate
+};
+const isValidEasing = (easing) => {
+ return typeof easing === "string";
+};
+const easingDefinitionToFunction = (definition) => {
+ if (isBezierDefinition(definition)) {
+ invariant(definition.length === 4, `Cubic bezier arrays must contain four numerical values.`, "cubic-bezier-length");
+ const [x1, y1, x2, y2] = definition;
+ return cubicBezier(x1, y1, x2, y2);
+ } else if (isValidEasing(definition)) {
+ invariant(easingLookup[definition] !== void 0, `Invalid easing type '${definition}'`, "invalid-easing-type");
+ return easingLookup[definition];
+ }
+ return definition;
+};
+const stepsOrder = [
+ "setup",
+ // Compute
+ "read",
+ // Read
+ "resolveKeyframes",
+ // Write/Read/Write/Read
+ "preUpdate",
+ // Compute
+ "update",
+ // Compute
+ "preRender",
+ // Compute
+ "render",
+ // Write
+ "postRender"
+ // Compute
+];
+function createRenderStep(runNextFrame, stepName) {
+ let thisFrame = /* @__PURE__ */ new Set();
+ let nextFrame = /* @__PURE__ */ new Set();
+ let isProcessing = false;
+ let flushNextFrame = false;
+ const toKeepAlive = /* @__PURE__ */ new WeakSet();
+ let latestFrameData = {
+ delta: 0,
+ timestamp: 0,
+ isProcessing: false
+ };
+ function triggerCallback(callback) {
+ if (toKeepAlive.has(callback)) {
+ step.schedule(callback);
+ runNextFrame();
+ }
+ callback(latestFrameData);
+ }
+ const step = {
+ /**
+ * Schedule a process to run on the next frame.
+ */
+ schedule: (callback, keepAlive = false, immediate = false) => {
+ const addToCurrentFrame = immediate && isProcessing;
+ const queue = addToCurrentFrame ? thisFrame : nextFrame;
+ if (keepAlive)
+ toKeepAlive.add(callback);
+ queue.add(callback);
+ return callback;
+ },
+ /**
+ * Cancel the provided callback from running on the next frame.
+ */
+ cancel: (callback) => {
+ nextFrame.delete(callback);
+ toKeepAlive.delete(callback);
+ },
+ /**
+ * Execute all schedule callbacks.
+ */
+ process: (frameData2) => {
+ latestFrameData = frameData2;
+ if (isProcessing) {
+ flushNextFrame = true;
+ return;
+ }
+ isProcessing = true;
+ const prevFrame = thisFrame;
+ thisFrame = nextFrame;
+ nextFrame = prevFrame;
+ thisFrame.forEach(triggerCallback);
+ thisFrame.clear();
+ isProcessing = false;
+ if (flushNextFrame) {
+ flushNextFrame = false;
+ step.process(frameData2);
+ }
+ }
+ };
+ return step;
+}
+const maxElapsed = 40;
+function createRenderBatcher(scheduleNextBatch, allowKeepAlive) {
+ let runNextFrame = false;
+ let useDefaultElapsed = true;
+ const state = {
+ delta: 0,
+ timestamp: 0,
+ isProcessing: false
+ };
+ const flagRunNextFrame = () => runNextFrame = true;
+ const steps = stepsOrder.reduce((acc, key) => {
+ acc[key] = createRenderStep(flagRunNextFrame);
+ return acc;
+ }, {});
+ const { setup, read, resolveKeyframes, preUpdate, update, preRender, render, postRender } = steps;
+ const processBatch = () => {
+ const useManualTiming = MotionGlobalConfig.useManualTiming;
+ const timestamp = useManualTiming ? state.timestamp : performance.now();
+ runNextFrame = false;
+ if (!useManualTiming) {
+ state.delta = useDefaultElapsed ? 1e3 / 60 : Math.max(Math.min(timestamp - state.timestamp, maxElapsed), 1);
+ }
+ state.timestamp = timestamp;
+ state.isProcessing = true;
+ setup.process(state);
+ read.process(state);
+ resolveKeyframes.process(state);
+ preUpdate.process(state);
+ update.process(state);
+ preRender.process(state);
+ render.process(state);
+ postRender.process(state);
+ state.isProcessing = false;
+ if (runNextFrame && allowKeepAlive) {
+ useDefaultElapsed = false;
+ scheduleNextBatch(processBatch);
+ }
+ };
+ const wake = () => {
+ runNextFrame = true;
+ useDefaultElapsed = true;
+ if (!state.isProcessing) {
+ scheduleNextBatch(processBatch);
+ }
+ };
+ const schedule = stepsOrder.reduce((acc, key) => {
+ const step = steps[key];
+ acc[key] = (process2, keepAlive = false, immediate = false) => {
+ if (!runNextFrame)
+ wake();
+ return step.schedule(process2, keepAlive, immediate);
+ };
+ return acc;
+ }, {});
+ const cancel = (process2) => {
+ for (let i = 0; i < stepsOrder.length; i++) {
+ steps[stepsOrder[i]].cancel(process2);
+ }
+ };
+ return { schedule, cancel, state, steps };
+}
+const { schedule: frame, cancel: cancelFrame, state: frameData, steps: frameSteps } = /* @__PURE__ */ createRenderBatcher(typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : noop, true);
+let now;
+function clearTime() {
+ now = void 0;
+}
+const time = {
+ now: () => {
+ if (now === void 0) {
+ time.set(frameData.isProcessing || MotionGlobalConfig.useManualTiming ? frameData.timestamp : performance.now());
+ }
+ return now;
+ },
+ set: (newTime) => {
+ now = newTime;
+ queueMicrotask(clearTime);
+ }
+};
+const checkStringStartsWith = (token) => (key) => typeof key === "string" && key.startsWith(token);
+const isCSSVariableName = /* @__PURE__ */ checkStringStartsWith("--");
+const startsAsVariableToken = /* @__PURE__ */ checkStringStartsWith("var(--");
+const isCSSVariableToken = (value) => {
+ const startsWithToken = startsAsVariableToken(value);
+ if (!startsWithToken)
+ return false;
+ return singleCssVariableRegex.test(value.split("/*")[0].trim());
+};
+const singleCssVariableRegex = /var\(--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)$/iu;
+function containsCSSVariable(value) {
+ if (typeof value !== "string")
+ return false;
+ return value.split("/*")[0].includes("var(--");
+}
+const number = {
+ test: (v) => typeof v === "number",
+ parse: parseFloat,
+ transform: (v) => v
+};
+const alpha = {
+ ...number,
+ transform: (v) => clamp(0, 1, v)
+};
+const scale = {
+ ...number,
+ default: 1
+};
+const sanitize = (v) => Math.round(v * 1e5) / 1e5;
+const floatRegex = /-?(?:\d+(?:\.\d+)?|\.\d+)/gu;
+function isNullish(v) {
+ return v == null;
+}
+const singleColorRegex = /^(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))$/iu;
+const isColorString = (type, testProp) => (v) => {
+ return Boolean(typeof v === "string" && singleColorRegex.test(v) && v.startsWith(type) || testProp && !isNullish(v) && Object.prototype.hasOwnProperty.call(v, testProp));
+};
+const splitColor = (aName, bName, cName) => (v) => {
+ if (typeof v !== "string")
+ return v;
+ const [a, b, c, alpha2] = v.match(floatRegex);
+ return {
+ [aName]: parseFloat(a),
+ [bName]: parseFloat(b),
+ [cName]: parseFloat(c),
+ alpha: alpha2 !== void 0 ? parseFloat(alpha2) : 1
+ };
+};
+const clampRgbUnit = (v) => clamp(0, 255, v);
+const rgbUnit = {
+ ...number,
+ transform: (v) => Math.round(clampRgbUnit(v))
+};
+const rgba = {
+ test: /* @__PURE__ */ isColorString("rgb", "red"),
+ parse: /* @__PURE__ */ splitColor("red", "green", "blue"),
+ transform: ({ red, green, blue, alpha: alpha$1 = 1 }) => "rgba(" + rgbUnit.transform(red) + ", " + rgbUnit.transform(green) + ", " + rgbUnit.transform(blue) + ", " + sanitize(alpha.transform(alpha$1)) + ")"
+};
+function parseHex(v) {
+ let r = "";
+ let g = "";
+ let b = "";
+ let a = "";
+ if (v.length > 5) {
+ r = v.substring(1, 3);
+ g = v.substring(3, 5);
+ b = v.substring(5, 7);
+ a = v.substring(7, 9);
+ } else {
+ r = v.substring(1, 2);
+ g = v.substring(2, 3);
+ b = v.substring(3, 4);
+ a = v.substring(4, 5);
+ r += r;
+ g += g;
+ b += b;
+ a += a;
+ }
+ return {
+ red: parseInt(r, 16),
+ green: parseInt(g, 16),
+ blue: parseInt(b, 16),
+ alpha: a ? parseInt(a, 16) / 255 : 1
+ };
+}
+const hex = {
+ test: /* @__PURE__ */ isColorString("#"),
+ parse: parseHex,
+ transform: rgba.transform
+};
+const createUnitType = /* @__NO_SIDE_EFFECTS__ */ (unit) => ({
+ test: (v) => typeof v === "string" && v.endsWith(unit) && v.split(" ").length === 1,
+ parse: parseFloat,
+ transform: (v) => `${v}${unit}`
+});
+const degrees = /* @__PURE__ */ createUnitType("deg");
+const percent = /* @__PURE__ */ createUnitType("%");
+const px = /* @__PURE__ */ createUnitType("px");
+const vh = /* @__PURE__ */ createUnitType("vh");
+const vw = /* @__PURE__ */ createUnitType("vw");
+const progressPercentage = /* @__PURE__ */ (() => ({
+ ...percent,
+ parse: (v) => percent.parse(v) / 100,
+ transform: (v) => percent.transform(v * 100)
+}))();
+const hsla = {
+ test: /* @__PURE__ */ isColorString("hsl", "hue"),
+ parse: /* @__PURE__ */ splitColor("hue", "saturation", "lightness"),
+ transform: ({ hue, saturation, lightness, alpha: alpha$1 = 1 }) => {
+ return "hsla(" + Math.round(hue) + ", " + percent.transform(sanitize(saturation)) + ", " + percent.transform(sanitize(lightness)) + ", " + sanitize(alpha.transform(alpha$1)) + ")";
+ }
+};
+const color = {
+ test: (v) => rgba.test(v) || hex.test(v) || hsla.test(v),
+ parse: (v) => {
+ if (rgba.test(v)) {
+ return rgba.parse(v);
+ } else if (hsla.test(v)) {
+ return hsla.parse(v);
+ } else {
+ return hex.parse(v);
+ }
+ },
+ transform: (v) => {
+ return typeof v === "string" ? v : v.hasOwnProperty("red") ? rgba.transform(v) : hsla.transform(v);
+ },
+ getAnimatableNone: (v) => {
+ const parsed = color.parse(v);
+ parsed.alpha = 0;
+ return color.transform(parsed);
+ }
+};
+const colorRegex = /(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))/giu;
+function test(v) {
+ return isNaN(v) && typeof v === "string" && (v.match(floatRegex)?.length || 0) + (v.match(colorRegex)?.length || 0) > 0;
+}
+const NUMBER_TOKEN = "number";
+const COLOR_TOKEN = "color";
+const VAR_TOKEN = "var";
+const VAR_FUNCTION_TOKEN = "var(";
+const SPLIT_TOKEN = "${}";
+const complexRegex = /var\s*\(\s*--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)|#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\)|-?(?:\d+(?:\.\d+)?|\.\d+)/giu;
+function analyseComplexValue(value) {
+ const originalValue = value.toString();
+ const values = [];
+ const indexes = {
+ color: [],
+ number: [],
+ var: []
+ };
+ const types = [];
+ let i = 0;
+ const tokenised = originalValue.replace(complexRegex, (parsedValue) => {
+ if (color.test(parsedValue)) {
+ indexes.color.push(i);
+ types.push(COLOR_TOKEN);
+ values.push(color.parse(parsedValue));
+ } else if (parsedValue.startsWith(VAR_FUNCTION_TOKEN)) {
+ indexes.var.push(i);
+ types.push(VAR_TOKEN);
+ values.push(parsedValue);
+ } else {
+ indexes.number.push(i);
+ types.push(NUMBER_TOKEN);
+ values.push(parseFloat(parsedValue));
+ }
+ ++i;
+ return SPLIT_TOKEN;
+ });
+ const split = tokenised.split(SPLIT_TOKEN);
+ return { values, split, indexes, types };
+}
+function parseComplexValue(v) {
+ return analyseComplexValue(v).values;
+}
+function buildTransformer({ split, types }) {
+ const numSections = split.length;
+ return (v) => {
+ let output = "";
+ for (let i = 0; i < numSections; i++) {
+ output += split[i];
+ if (v[i] !== void 0) {
+ const type = types[i];
+ if (type === NUMBER_TOKEN) {
+ output += sanitize(v[i]);
+ } else if (type === COLOR_TOKEN) {
+ output += color.transform(v[i]);
+ } else {
+ output += v[i];
+ }
+ }
+ }
+ return output;
+ };
+}
+function createTransformer(source) {
+ return buildTransformer(analyseComplexValue(source));
+}
+const convertNumbersToZero = (v) => typeof v === "number" ? 0 : color.test(v) ? color.getAnimatableNone(v) : v;
+const convertToZero = (value, splitBefore) => {
+ if (typeof value === "number") {
+ return splitBefore?.trim().endsWith("/") ? value : 0;
+ }
+ return convertNumbersToZero(value);
+};
+function getAnimatableNone$1(v) {
+ const info = analyseComplexValue(v);
+ const transformer = buildTransformer(info);
+ return transformer(info.values.map((value, i) => convertToZero(value, info.split[i])));
+}
+const complex = {
+ test,
+ parse: parseComplexValue,
+ createTransformer,
+ getAnimatableNone: getAnimatableNone$1
+};
+function hueToRgb(p, q, t) {
+ if (t < 0)
+ t += 1;
+ if (t > 1)
+ t -= 1;
+ if (t < 1 / 6)
+ return p + (q - p) * 6 * t;
+ if (t < 1 / 2)
+ return q;
+ if (t < 2 / 3)
+ return p + (q - p) * (2 / 3 - t) * 6;
+ return p;
+}
+function hslaToRgba({ hue, saturation, lightness, alpha: alpha2 }) {
+ hue /= 360;
+ saturation /= 100;
+ lightness /= 100;
+ let red = 0;
+ let green = 0;
+ let blue = 0;
+ if (!saturation) {
+ red = green = blue = lightness;
+ } else {
+ const q = lightness < 0.5 ? lightness * (1 + saturation) : lightness + saturation - lightness * saturation;
+ const p = 2 * lightness - q;
+ red = hueToRgb(p, q, hue + 1 / 3);
+ green = hueToRgb(p, q, hue);
+ blue = hueToRgb(p, q, hue - 1 / 3);
+ }
+ return {
+ red: Math.round(red * 255),
+ green: Math.round(green * 255),
+ blue: Math.round(blue * 255),
+ alpha: alpha2
+ };
+}
+function mixImmediate(a, b) {
+ return (p) => p > 0 ? b : a;
+}
+const mixNumber$1 = (from, to, progress2) => {
+ return from + (to - from) * progress2;
+};
+const mixLinearColor = (from, to, v) => {
+ const fromExpo = from * from;
+ const expo = v * (to * to - fromExpo) + fromExpo;
+ return expo < 0 ? 0 : Math.sqrt(expo);
+};
+const colorTypes = [hex, rgba, hsla];
+const getColorType = (v) => colorTypes.find((type) => type.test(v));
+function asRGBA(color2) {
+ const type = getColorType(color2);
+ warning(Boolean(type), `'${color2}' is not an animatable color. Use the equivalent color code instead.`, "color-not-animatable");
+ if (!Boolean(type))
+ return false;
+ let model = type.parse(color2);
+ if (type === hsla) {
+ model = hslaToRgba(model);
+ }
+ return model;
+}
+const mixColor = (from, to) => {
+ const fromRGBA = asRGBA(from);
+ const toRGBA = asRGBA(to);
+ if (!fromRGBA || !toRGBA) {
+ return mixImmediate(from, to);
+ }
+ const blended = { ...fromRGBA };
+ return (v) => {
+ blended.red = mixLinearColor(fromRGBA.red, toRGBA.red, v);
+ blended.green = mixLinearColor(fromRGBA.green, toRGBA.green, v);
+ blended.blue = mixLinearColor(fromRGBA.blue, toRGBA.blue, v);
+ blended.alpha = mixNumber$1(fromRGBA.alpha, toRGBA.alpha, v);
+ return rgba.transform(blended);
+ };
+};
+const invisibleValues = /* @__PURE__ */ new Set(["none", "hidden"]);
+function mixVisibility(origin, target) {
+ if (invisibleValues.has(origin)) {
+ return (p) => p <= 0 ? origin : target;
+ } else {
+ return (p) => p >= 1 ? target : origin;
+ }
+}
+function mixNumber(a, b) {
+ return (p) => mixNumber$1(a, b, p);
+}
+function getMixer(a) {
+ if (typeof a === "number") {
+ return mixNumber;
+ } else if (typeof a === "string") {
+ return isCSSVariableToken(a) ? mixImmediate : color.test(a) ? mixColor : mixComplex;
+ } else if (Array.isArray(a)) {
+ return mixArray;
+ } else if (typeof a === "object") {
+ return color.test(a) ? mixColor : mixObject;
+ }
+ return mixImmediate;
+}
+function mixArray(a, b) {
+ const output = [...a];
+ const numValues = output.length;
+ const blendValue = a.map((v, i) => getMixer(v)(v, b[i]));
+ return (p) => {
+ for (let i = 0; i < numValues; i++) {
+ output[i] = blendValue[i](p);
+ }
+ return output;
+ };
+}
+function mixObject(a, b) {
+ const output = { ...a, ...b };
+ const blendValue = {};
+ for (const key in output) {
+ if (a[key] !== void 0 && b[key] !== void 0) {
+ blendValue[key] = getMixer(a[key])(a[key], b[key]);
+ }
+ }
+ return (v) => {
+ for (const key in blendValue) {
+ output[key] = blendValue[key](v);
+ }
+ return output;
+ };
+}
+function matchOrder(origin, target) {
+ const orderedOrigin = [];
+ const pointers = { color: 0, var: 0, number: 0 };
+ for (let i = 0; i < target.values.length; i++) {
+ const type = target.types[i];
+ const originIndex = origin.indexes[type][pointers[type]];
+ const originValue = origin.values[originIndex] ?? 0;
+ orderedOrigin[i] = originValue;
+ pointers[type]++;
+ }
+ return orderedOrigin;
+}
+const mixComplex = (origin, target) => {
+ const template = complex.createTransformer(target);
+ const originStats = analyseComplexValue(origin);
+ const targetStats = analyseComplexValue(target);
+ const canInterpolate = originStats.indexes.var.length === targetStats.indexes.var.length && originStats.indexes.color.length === targetStats.indexes.color.length && originStats.indexes.number.length >= targetStats.indexes.number.length;
+ if (canInterpolate) {
+ if (invisibleValues.has(origin) && !targetStats.values.length || invisibleValues.has(target) && !originStats.values.length) {
+ return mixVisibility(origin, target);
+ }
+ return pipe(mixArray(matchOrder(originStats, targetStats), targetStats.values), template);
+ } else {
+ warning(true, `Complex values '${origin}' and '${target}' too different to mix. Ensure all colors are of the same type, and that each contains the same quantity of number and color values. Falling back to instant transition.`, "complex-values-different");
+ return mixImmediate(origin, target);
+ }
+};
+function mix(from, to, p) {
+ if (typeof from === "number" && typeof to === "number" && typeof p === "number") {
+ return mixNumber$1(from, to, p);
+ }
+ const mixer = getMixer(from);
+ return mixer(from, to);
+}
+const frameloopDriver = (update) => {
+ const passTimestamp = ({ timestamp }) => update(timestamp);
+ return {
+ start: (keepAlive = true) => frame.update(passTimestamp, keepAlive),
+ stop: () => cancelFrame(passTimestamp),
+ /**
+ * If we're processing this frame we can use the
+ * framelocked timestamp to keep things in sync.
+ */
+ now: () => frameData.isProcessing ? frameData.timestamp : time.now()
+ };
+};
+const generateLinearEasing = (easing, duration, resolution = 10) => {
+ let points = "";
+ const numPoints = Math.max(Math.round(duration / resolution), 2);
+ for (let i = 0; i < numPoints; i++) {
+ points += Math.round(easing(i / (numPoints - 1)) * 1e4) / 1e4 + ", ";
+ }
+ return `linear(${points.substring(0, points.length - 2)})`;
+};
+const maxGeneratorDuration = 2e4;
+function calcGeneratorDuration(generator) {
+ let duration = 0;
+ const timeStep = 50;
+ let state = generator.next(duration);
+ while (!state.done && duration < maxGeneratorDuration) {
+ duration += timeStep;
+ state = generator.next(duration);
+ }
+ return duration >= maxGeneratorDuration ? Infinity : duration;
+}
+function createGeneratorEasing(options, scale2 = 100, createGenerator) {
+ const generator = createGenerator({ ...options, keyframes: [0, scale2] });
+ const duration = Math.min(calcGeneratorDuration(generator), maxGeneratorDuration);
+ return {
+ type: "keyframes",
+ ease: (progress2) => {
+ return generator.next(duration * progress2).value / scale2;
+ },
+ duration: /* @__PURE__ */ millisecondsToSeconds(duration)
+ };
+}
+const springDefaults = {
+ // Default spring physics
+ stiffness: 100,
+ damping: 10,
+ mass: 1,
+ velocity: 0,
+ // Default duration/bounce-based options
+ duration: 800,
+ // in ms
+ bounce: 0.3,
+ visualDuration: 0.3,
+ // in seconds
+ // Rest thresholds
+ restSpeed: {
+ granular: 0.01,
+ default: 2
+ },
+ restDelta: {
+ granular: 5e-3,
+ default: 0.5
+ },
+ // Limits
+ minDuration: 0.01,
+ // in seconds
+ maxDuration: 10,
+ // in seconds
+ minDamping: 0.05,
+ maxDamping: 1
+};
+function calcAngularFreq(undampedFreq, dampingRatio) {
+ return undampedFreq * Math.sqrt(1 - dampingRatio * dampingRatio);
+}
+const rootIterations = 12;
+function approximateRoot(envelope, derivative, initialGuess) {
+ let result = initialGuess;
+ for (let i = 1; i < rootIterations; i++) {
+ result = result - envelope(result) / derivative(result);
+ }
+ return result;
+}
+const safeMin = 1e-3;
+function findSpring({ duration = springDefaults.duration, bounce = springDefaults.bounce, velocity = springDefaults.velocity, mass = springDefaults.mass }) {
+ let envelope;
+ let derivative;
+ warning(duration <= /* @__PURE__ */ secondsToMilliseconds(springDefaults.maxDuration), "Spring duration must be 10 seconds or less", "spring-duration-limit");
+ let dampingRatio = 1 - bounce;
+ dampingRatio = clamp(springDefaults.minDamping, springDefaults.maxDamping, dampingRatio);
+ duration = clamp(springDefaults.minDuration, springDefaults.maxDuration, /* @__PURE__ */ millisecondsToSeconds(duration));
+ if (dampingRatio < 1) {
+ envelope = (undampedFreq2) => {
+ const exponentialDecay = undampedFreq2 * dampingRatio;
+ const delta = exponentialDecay * duration;
+ const a = exponentialDecay - velocity;
+ const b = calcAngularFreq(undampedFreq2, dampingRatio);
+ const c = Math.exp(-delta);
+ return safeMin - a / b * c;
+ };
+ derivative = (undampedFreq2) => {
+ const exponentialDecay = undampedFreq2 * dampingRatio;
+ const delta = exponentialDecay * duration;
+ const d = delta * velocity + velocity;
+ const e = Math.pow(dampingRatio, 2) * Math.pow(undampedFreq2, 2) * duration;
+ const f = Math.exp(-delta);
+ const g = calcAngularFreq(Math.pow(undampedFreq2, 2), dampingRatio);
+ const factor = -envelope(undampedFreq2) + safeMin > 0 ? -1 : 1;
+ return factor * ((d - e) * f) / g;
+ };
+ } else {
+ envelope = (undampedFreq2) => {
+ const a = Math.exp(-undampedFreq2 * duration);
+ const b = (undampedFreq2 - velocity) * duration + 1;
+ return -safeMin + a * b;
+ };
+ derivative = (undampedFreq2) => {
+ const a = Math.exp(-undampedFreq2 * duration);
+ const b = (velocity - undampedFreq2) * (duration * duration);
+ return a * b;
+ };
+ }
+ const initialGuess = 5 / duration;
+ const undampedFreq = approximateRoot(envelope, derivative, initialGuess);
+ duration = /* @__PURE__ */ secondsToMilliseconds(duration);
+ if (isNaN(undampedFreq)) {
+ return {
+ stiffness: springDefaults.stiffness,
+ damping: springDefaults.damping,
+ duration
+ };
+ } else {
+ const stiffness = Math.pow(undampedFreq, 2) * mass;
+ return {
+ stiffness,
+ damping: dampingRatio * 2 * Math.sqrt(mass * stiffness),
+ duration
+ };
+ }
+}
+const durationKeys = ["duration", "bounce"];
+const physicsKeys = ["stiffness", "damping", "mass"];
+function isSpringType(options, keys) {
+ return keys.some((key) => options[key] !== void 0);
+}
+function getSpringOptions(options) {
+ let springOptions = {
+ velocity: springDefaults.velocity,
+ stiffness: springDefaults.stiffness,
+ damping: springDefaults.damping,
+ mass: springDefaults.mass,
+ isResolvedFromDuration: false,
+ ...options
+ };
+ if (!isSpringType(options, physicsKeys) && isSpringType(options, durationKeys)) {
+ springOptions.velocity = 0;
+ if (options.visualDuration) {
+ const visualDuration = options.visualDuration;
+ const root = 2 * Math.PI / (visualDuration * 1.2);
+ const stiffness = root * root;
+ const damping = 2 * clamp(0.05, 1, 1 - (options.bounce || 0)) * Math.sqrt(stiffness);
+ springOptions = {
+ ...springOptions,
+ mass: springDefaults.mass,
+ stiffness,
+ damping
+ };
+ } else {
+ const derived = findSpring({ ...options, velocity: 0 });
+ springOptions = {
+ ...springOptions,
+ ...derived,
+ mass: springDefaults.mass
+ };
+ springOptions.isResolvedFromDuration = true;
+ }
+ }
+ return springOptions;
+}
+function spring(optionsOrVisualDuration = springDefaults.visualDuration, bounce = springDefaults.bounce) {
+ const options = typeof optionsOrVisualDuration !== "object" ? {
+ visualDuration: optionsOrVisualDuration,
+ keyframes: [0, 1],
+ bounce
+ } : optionsOrVisualDuration;
+ let { restSpeed, restDelta } = options;
+ const origin = options.keyframes[0];
+ const target = options.keyframes[options.keyframes.length - 1];
+ const state = { done: false, value: origin };
+ const { stiffness, damping, mass, duration, velocity, isResolvedFromDuration } = getSpringOptions({
+ ...options,
+ velocity: -/* @__PURE__ */ millisecondsToSeconds(options.velocity || 0)
+ });
+ const initialVelocity = velocity || 0;
+ const dampingRatio = damping / (2 * Math.sqrt(stiffness * mass));
+ const initialDelta = target - origin;
+ const undampedAngularFreq = /* @__PURE__ */ millisecondsToSeconds(Math.sqrt(stiffness / mass));
+ const isGranularScale = Math.abs(initialDelta) < 5;
+ restSpeed || (restSpeed = isGranularScale ? springDefaults.restSpeed.granular : springDefaults.restSpeed.default);
+ restDelta || (restDelta = isGranularScale ? springDefaults.restDelta.granular : springDefaults.restDelta.default);
+ let resolveSpring;
+ let resolveVelocity;
+ let angularFreq;
+ let A;
+ let sinCoeff;
+ let cosCoeff;
+ if (dampingRatio < 1) {
+ angularFreq = calcAngularFreq(undampedAngularFreq, dampingRatio);
+ A = (initialVelocity + dampingRatio * undampedAngularFreq * initialDelta) / angularFreq;
+ resolveSpring = (t) => {
+ const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t);
+ return target - envelope * (A * Math.sin(angularFreq * t) + initialDelta * Math.cos(angularFreq * t));
+ };
+ sinCoeff = dampingRatio * undampedAngularFreq * A + initialDelta * angularFreq;
+ cosCoeff = dampingRatio * undampedAngularFreq * initialDelta - A * angularFreq;
+ resolveVelocity = (t) => {
+ const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t);
+ return envelope * (sinCoeff * Math.sin(angularFreq * t) + cosCoeff * Math.cos(angularFreq * t));
+ };
+ } else if (dampingRatio === 1) {
+ resolveSpring = (t) => target - Math.exp(-undampedAngularFreq * t) * (initialDelta + (initialVelocity + undampedAngularFreq * initialDelta) * t);
+ const C = initialVelocity + undampedAngularFreq * initialDelta;
+ resolveVelocity = (t) => Math.exp(-undampedAngularFreq * t) * (undampedAngularFreq * C * t - initialVelocity);
+ } else {
+ const dampedAngularFreq = undampedAngularFreq * Math.sqrt(dampingRatio * dampingRatio - 1);
+ resolveSpring = (t) => {
+ const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t);
+ const freqForT = Math.min(dampedAngularFreq * t, 300);
+ return target - envelope * ((initialVelocity + dampingRatio * undampedAngularFreq * initialDelta) * Math.sinh(freqForT) + dampedAngularFreq * initialDelta * Math.cosh(freqForT)) / dampedAngularFreq;
+ };
+ const P = (initialVelocity + dampingRatio * undampedAngularFreq * initialDelta) / dampedAngularFreq;
+ const sinhCoeff = dampingRatio * undampedAngularFreq * P - initialDelta * dampedAngularFreq;
+ const coshCoeff = dampingRatio * undampedAngularFreq * initialDelta - P * dampedAngularFreq;
+ resolveVelocity = (t) => {
+ const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t);
+ const freqForT = Math.min(dampedAngularFreq * t, 300);
+ return envelope * (sinhCoeff * Math.sinh(freqForT) + coshCoeff * Math.cosh(freqForT));
+ };
+ }
+ const generator = {
+ calculatedDuration: isResolvedFromDuration ? duration || null : null,
+ velocity: (t) => /* @__PURE__ */ secondsToMilliseconds(resolveVelocity(t)),
+ next: (t) => {
+ if (!isResolvedFromDuration && dampingRatio < 1) {
+ const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t);
+ const sin = Math.sin(angularFreq * t);
+ const cos = Math.cos(angularFreq * t);
+ const current2 = target - envelope * (A * sin + initialDelta * cos);
+ const currentVelocity = /* @__PURE__ */ secondsToMilliseconds(envelope * (sinCoeff * sin + cosCoeff * cos));
+ state.done = Math.abs(currentVelocity) <= restSpeed && Math.abs(target - current2) <= restDelta;
+ state.value = state.done ? target : current2;
+ return state;
+ }
+ const current = resolveSpring(t);
+ if (!isResolvedFromDuration) {
+ const currentVelocity = /* @__PURE__ */ secondsToMilliseconds(resolveVelocity(t));
+ state.done = Math.abs(currentVelocity) <= restSpeed && Math.abs(target - current) <= restDelta;
+ } else {
+ state.done = t >= duration;
+ }
+ state.value = state.done ? target : current;
+ return state;
+ },
+ toString: () => {
+ const calculatedDuration = Math.min(calcGeneratorDuration(generator), maxGeneratorDuration);
+ const easing = generateLinearEasing((progress2) => generator.next(calculatedDuration * progress2).value, calculatedDuration, 30);
+ return calculatedDuration + "ms " + easing;
+ },
+ toTransition: () => {
+ }
+ };
+ return generator;
+}
+spring.applyToOptions = (options) => {
+ const generatorOptions = createGeneratorEasing(options, 100, spring);
+ options.ease = generatorOptions.ease;
+ options.duration = /* @__PURE__ */ secondsToMilliseconds(generatorOptions.duration);
+ options.type = "keyframes";
+ return options;
+};
+const velocitySampleDuration = 5;
+function getGeneratorVelocity(resolveValue, t, current) {
+ const prevT = Math.max(t - velocitySampleDuration, 0);
+ return velocityPerSecond(current - resolveValue(prevT), t - prevT);
+}
+function inertia({ keyframes: keyframes2, velocity = 0, power = 0.8, timeConstant = 325, bounceDamping = 10, bounceStiffness = 500, modifyTarget, min, max, restDelta = 0.5, restSpeed }) {
+ const origin = keyframes2[0];
+ const state = {
+ done: false,
+ value: origin
+ };
+ const isOutOfBounds = (v) => min !== void 0 && v < min || max !== void 0 && v > max;
+ const nearestBoundary = (v) => {
+ if (min === void 0)
+ return max;
+ if (max === void 0)
+ return min;
+ return Math.abs(min - v) < Math.abs(max - v) ? min : max;
+ };
+ let amplitude = power * velocity;
+ const ideal = origin + amplitude;
+ const target = modifyTarget === void 0 ? ideal : modifyTarget(ideal);
+ if (target !== ideal)
+ amplitude = target - origin;
+ const calcDelta = (t) => -amplitude * Math.exp(-t / timeConstant);
+ const calcLatest = (t) => target + calcDelta(t);
+ const applyFriction = (t) => {
+ const delta = calcDelta(t);
+ const latest = calcLatest(t);
+ state.done = Math.abs(delta) <= restDelta;
+ state.value = state.done ? target : latest;
+ };
+ let timeReachedBoundary;
+ let spring$1;
+ const checkCatchBoundary = (t) => {
+ if (!isOutOfBounds(state.value))
+ return;
+ timeReachedBoundary = t;
+ spring$1 = spring({
+ keyframes: [state.value, nearestBoundary(state.value)],
+ velocity: getGeneratorVelocity(calcLatest, t, state.value),
+ // TODO: This should be passing * 1000
+ damping: bounceDamping,
+ stiffness: bounceStiffness,
+ restDelta,
+ restSpeed
+ });
+ };
+ checkCatchBoundary(0);
+ return {
+ calculatedDuration: null,
+ next: (t) => {
+ let hasUpdatedFrame = false;
+ if (!spring$1 && timeReachedBoundary === void 0) {
+ hasUpdatedFrame = true;
+ applyFriction(t);
+ checkCatchBoundary(t);
+ }
+ if (timeReachedBoundary !== void 0 && t >= timeReachedBoundary) {
+ return spring$1.next(t - timeReachedBoundary);
+ } else {
+ !hasUpdatedFrame && applyFriction(t);
+ return state;
+ }
+ }
+ };
+}
+function createMixers(output, ease2, customMixer) {
+ const mixers = [];
+ const mixerFactory = customMixer || MotionGlobalConfig.mix || mix;
+ const numMixers = output.length - 1;
+ for (let i = 0; i < numMixers; i++) {
+ let mixer = mixerFactory(output[i], output[i + 1]);
+ if (ease2) {
+ const easingFunction = Array.isArray(ease2) ? ease2[i] || noop : ease2;
+ mixer = pipe(easingFunction, mixer);
+ }
+ mixers.push(mixer);
+ }
+ return mixers;
+}
+function interpolate(input, output, { clamp: isClamp = true, ease: ease2, mixer } = {}) {
+ const inputLength = input.length;
+ invariant(inputLength === output.length, "Both input and output ranges must be the same length", "range-length");
+ if (inputLength === 1)
+ return () => output[0];
+ if (inputLength === 2 && output[0] === output[1])
+ return () => output[1];
+ const isZeroDeltaRange = input[0] === input[1];
+ if (input[0] > input[inputLength - 1]) {
+ input = [...input].reverse();
+ output = [...output].reverse();
+ }
+ const mixers = createMixers(output, ease2, mixer);
+ const numMixers = mixers.length;
+ const interpolator = (v) => {
+ if (isZeroDeltaRange && v < input[0])
+ return output[0];
+ let i = 0;
+ if (numMixers > 1) {
+ for (; i < input.length - 2; i++) {
+ if (v < input[i + 1])
+ break;
+ }
+ }
+ const progressInRange = /* @__PURE__ */ progress(input[i], input[i + 1], v);
+ return mixers[i](progressInRange);
+ };
+ return isClamp ? (v) => interpolator(clamp(input[0], input[inputLength - 1], v)) : interpolator;
+}
+function fillOffset(offset, remaining) {
+ const min = offset[offset.length - 1];
+ for (let i = 1; i <= remaining; i++) {
+ const offsetProgress = /* @__PURE__ */ progress(0, remaining, i);
+ offset.push(mixNumber$1(min, 1, offsetProgress));
+ }
+}
+function defaultOffset(arr) {
+ const offset = [0];
+ fillOffset(offset, arr.length - 1);
+ return offset;
+}
+function convertOffsetToTimes(offset, duration) {
+ return offset.map((o) => o * duration);
+}
+function defaultEasing(values, easing) {
+ return values.map(() => easing || easeInOut).splice(0, values.length - 1);
+}
+function keyframes({ duration = 300, keyframes: keyframeValues, times, ease: ease2 = "easeInOut" }) {
+ const easingFunctions = isEasingArray(ease2) ? ease2.map(easingDefinitionToFunction) : easingDefinitionToFunction(ease2);
+ const state = {
+ done: false,
+ value: keyframeValues[0]
+ };
+ const absoluteTimes = convertOffsetToTimes(
+ // Only use the provided offsets if they're the correct length
+ // TODO Maybe we should warn here if there's a length mismatch
+ times && times.length === keyframeValues.length ? times : defaultOffset(keyframeValues),
+ duration
+ );
+ const mapTimeToKeyframe = interpolate(absoluteTimes, keyframeValues, {
+ ease: Array.isArray(easingFunctions) ? easingFunctions : defaultEasing(keyframeValues, easingFunctions)
+ });
+ return {
+ calculatedDuration: duration,
+ next: (t) => {
+ state.value = mapTimeToKeyframe(t);
+ state.done = t >= duration;
+ return state;
+ }
+ };
+}
+const isNotNull = (value) => value !== null;
+function getFinalKeyframe(keyframes2, { repeat, repeatType = "loop" }, finalKeyframe, speed = 1) {
+ const resolvedKeyframes = keyframes2.filter(isNotNull);
+ const useFirstKeyframe = speed < 0 || repeat && repeatType !== "loop" && repeat % 2 === 1;
+ const index = useFirstKeyframe ? 0 : resolvedKeyframes.length - 1;
+ return !index || finalKeyframe === void 0 ? resolvedKeyframes[index] : finalKeyframe;
+}
+const transitionTypeMap = {
+ decay: inertia,
+ inertia,
+ tween: keyframes,
+ keyframes,
+ spring
+};
+function replaceTransitionType(transition) {
+ if (typeof transition.type === "string") {
+ transition.type = transitionTypeMap[transition.type];
+ }
+}
+class WithPromise {
+ constructor() {
+ this.updateFinished();
+ }
+ get finished() {
+ return this._finished;
+ }
+ updateFinished() {
+ this._finished = new Promise((resolve) => {
+ this.resolve = resolve;
+ });
+ }
+ notifyFinished() {
+ this.resolve();
+ }
+ /**
+ * Allows the animation to be awaited.
+ *
+ * @deprecated Use `finished` instead.
+ */
+ then(onResolve, onReject) {
+ return this.finished.then(onResolve, onReject);
+ }
+}
+const percentToProgress = (percent2) => percent2 / 100;
+class JSAnimation extends WithPromise {
+ constructor(options) {
+ super();
+ this.state = "idle";
+ this.startTime = null;
+ this.isStopped = false;
+ this.currentTime = 0;
+ this.holdTime = null;
+ this.playbackSpeed = 1;
+ this.delayState = {
+ done: false,
+ value: void 0
+ };
+ this.stop = () => {
+ const { motionValue: motionValue2 } = this.options;
+ if (motionValue2 && motionValue2.updatedAt !== time.now()) {
+ this.tick(time.now());
+ }
+ this.isStopped = true;
+ if (this.state === "idle")
+ return;
+ this.teardown();
+ this.options.onStop?.();
+ };
+ this.options = options;
+ this.initAnimation();
+ this.play();
+ if (options.autoplay === false)
+ this.pause();
+ }
+ initAnimation() {
+ const { options } = this;
+ replaceTransitionType(options);
+ const { type = keyframes, repeat = 0, repeatDelay = 0, repeatType, velocity = 0 } = options;
+ let { keyframes: keyframes$1 } = options;
+ const generatorFactory = type || keyframes;
+ if (process.env.NODE_ENV !== "production" && generatorFactory !== keyframes) {
+ invariant(keyframes$1.length <= 2, `Only two keyframes currently supported with spring and inertia animations. Trying to animate ${keyframes$1}`, "spring-two-frames");
+ }
+ if (generatorFactory !== keyframes && typeof keyframes$1[0] !== "number") {
+ this.mixKeyframes = pipe(percentToProgress, mix(keyframes$1[0], keyframes$1[1]));
+ keyframes$1 = [0, 100];
+ }
+ const generator = generatorFactory({ ...options, keyframes: keyframes$1 });
+ if (repeatType === "mirror") {
+ this.mirroredGenerator = generatorFactory({
+ ...options,
+ keyframes: [...keyframes$1].reverse(),
+ velocity: -velocity
+ });
+ }
+ if (generator.calculatedDuration === null) {
+ generator.calculatedDuration = calcGeneratorDuration(generator);
+ }
+ const { calculatedDuration } = generator;
+ this.calculatedDuration = calculatedDuration;
+ this.resolvedDuration = calculatedDuration + repeatDelay;
+ this.totalDuration = this.resolvedDuration * (repeat + 1) - repeatDelay;
+ this.generator = generator;
+ }
+ updateTime(timestamp) {
+ const animationTime = Math.round(timestamp - this.startTime) * this.playbackSpeed;
+ if (this.holdTime !== null) {
+ this.currentTime = this.holdTime;
+ } else {
+ this.currentTime = animationTime;
+ }
+ }
+ tick(timestamp, sample = false) {
+ const { generator, totalDuration, mixKeyframes, mirroredGenerator, resolvedDuration, calculatedDuration } = this;
+ if (this.startTime === null)
+ return generator.next(0);
+ const { delay: delay2 = 0, keyframes: keyframes2, repeat, repeatType, repeatDelay, type, onUpdate, finalKeyframe } = this.options;
+ if (this.speed > 0) {
+ this.startTime = Math.min(this.startTime, timestamp);
+ } else if (this.speed < 0) {
+ this.startTime = Math.min(timestamp - totalDuration / this.speed, this.startTime);
+ }
+ if (sample) {
+ this.currentTime = timestamp;
+ } else {
+ this.updateTime(timestamp);
+ }
+ const timeWithoutDelay = this.currentTime - delay2 * (this.playbackSpeed >= 0 ? 1 : -1);
+ const isInDelayPhase = this.playbackSpeed >= 0 ? timeWithoutDelay < 0 : timeWithoutDelay > totalDuration;
+ this.currentTime = Math.max(timeWithoutDelay, 0);
+ if (this.state === "finished" && this.holdTime === null) {
+ this.currentTime = totalDuration;
+ }
+ let elapsed = this.currentTime;
+ let frameGenerator = generator;
+ if (repeat) {
+ const progress2 = Math.min(this.currentTime, totalDuration) / resolvedDuration;
+ let currentIteration = Math.floor(progress2);
+ let iterationProgress = progress2 % 1;
+ if (!iterationProgress && progress2 >= 1) {
+ iterationProgress = 1;
+ }
+ iterationProgress === 1 && currentIteration--;
+ currentIteration = Math.min(currentIteration, repeat + 1);
+ const isOddIteration = Boolean(currentIteration % 2);
+ if (isOddIteration) {
+ if (repeatType === "reverse") {
+ iterationProgress = 1 - iterationProgress;
+ if (repeatDelay) {
+ iterationProgress -= repeatDelay / resolvedDuration;
+ }
+ } else if (repeatType === "mirror") {
+ frameGenerator = mirroredGenerator;
+ }
+ }
+ elapsed = clamp(0, 1, iterationProgress) * resolvedDuration;
+ }
+ let state;
+ if (isInDelayPhase) {
+ this.delayState.value = keyframes2[0];
+ state = this.delayState;
+ } else {
+ state = frameGenerator.next(elapsed);
+ }
+ if (mixKeyframes && !isInDelayPhase) {
+ state.value = mixKeyframes(state.value);
+ }
+ let { done } = state;
+ if (!isInDelayPhase && calculatedDuration !== null) {
+ done = this.playbackSpeed >= 0 ? this.currentTime >= totalDuration : this.currentTime <= 0;
+ }
+ const isAnimationFinished = this.holdTime === null && (this.state === "finished" || this.state === "running" && done);
+ if (isAnimationFinished && type !== inertia) {
+ state.value = getFinalKeyframe(keyframes2, this.options, finalKeyframe, this.speed);
+ }
+ if (onUpdate) {
+ onUpdate(state.value);
+ }
+ if (isAnimationFinished) {
+ this.finish();
+ }
+ return state;
+ }
+ /**
+ * Allows the returned animation to be awaited or promise-chained. Currently
+ * resolves when the animation finishes at all but in a future update could/should
+ * reject if its cancels.
+ */
+ then(resolve, reject) {
+ return this.finished.then(resolve, reject);
+ }
+ get duration() {
+ return /* @__PURE__ */ millisecondsToSeconds(this.calculatedDuration);
+ }
+ get iterationDuration() {
+ const { delay: delay2 = 0 } = this.options || {};
+ return this.duration + /* @__PURE__ */ millisecondsToSeconds(delay2);
+ }
+ get time() {
+ return /* @__PURE__ */ millisecondsToSeconds(this.currentTime);
+ }
+ set time(newTime) {
+ newTime = /* @__PURE__ */ secondsToMilliseconds(newTime);
+ this.currentTime = newTime;
+ if (this.startTime === null || this.holdTime !== null || this.playbackSpeed === 0) {
+ this.holdTime = newTime;
+ } else if (this.driver) {
+ this.startTime = this.driver.now() - newTime / this.playbackSpeed;
+ }
+ if (this.driver) {
+ this.driver.start(false);
+ } else {
+ this.startTime = 0;
+ this.state = "paused";
+ this.holdTime = newTime;
+ this.tick(newTime);
+ }
+ }
+ /**
+ * Returns the generator's velocity at the current time in units/second.
+ * Uses the analytical derivative when available (springs), avoiding
+ * the MotionValue's frame-dependent velocity estimation.
+ */
+ getGeneratorVelocity() {
+ const t = this.currentTime;
+ if (t <= 0)
+ return this.options.velocity || 0;
+ if (this.generator.velocity) {
+ return this.generator.velocity(t);
+ }
+ const current = this.generator.next(t).value;
+ return getGeneratorVelocity((s) => this.generator.next(s).value, t, current);
+ }
+ get speed() {
+ return this.playbackSpeed;
+ }
+ set speed(newSpeed) {
+ const hasChanged = this.playbackSpeed !== newSpeed;
+ if (hasChanged && this.driver) {
+ this.updateTime(time.now());
+ }
+ this.playbackSpeed = newSpeed;
+ if (hasChanged && this.driver) {
+ this.time = /* @__PURE__ */ millisecondsToSeconds(this.currentTime);
+ }
+ }
+ play() {
+ if (this.isStopped)
+ return;
+ const { driver = frameloopDriver, startTime } = this.options;
+ if (!this.driver) {
+ this.driver = driver((timestamp) => this.tick(timestamp));
+ }
+ this.options.onPlay?.();
+ const now2 = this.driver.now();
+ if (this.state === "finished") {
+ this.updateFinished();
+ this.startTime = now2;
+ } else if (this.holdTime !== null) {
+ this.startTime = now2 - this.holdTime;
+ } else if (!this.startTime) {
+ this.startTime = startTime ?? now2;
+ }
+ if (this.state === "finished" && this.speed < 0) {
+ this.startTime += this.calculatedDuration;
+ }
+ this.holdTime = null;
+ this.state = "running";
+ this.driver.start();
+ }
+ pause() {
+ this.state = "paused";
+ this.updateTime(time.now());
+ this.holdTime = this.currentTime;
+ }
+ complete() {
+ if (this.state !== "running") {
+ this.play();
+ }
+ this.state = "finished";
+ this.holdTime = null;
+ }
+ finish() {
+ this.notifyFinished();
+ this.teardown();
+ this.state = "finished";
+ this.options.onComplete?.();
+ }
+ cancel() {
+ this.holdTime = null;
+ this.startTime = 0;
+ this.tick(0);
+ this.teardown();
+ this.options.onCancel?.();
+ }
+ teardown() {
+ this.state = "idle";
+ this.stopDriver();
+ this.startTime = this.holdTime = null;
+ }
+ stopDriver() {
+ if (!this.driver)
+ return;
+ this.driver.stop();
+ this.driver = void 0;
+ }
+ sample(sampleTime) {
+ this.startTime = 0;
+ return this.tick(sampleTime, true);
+ }
+ attachTimeline(timeline) {
+ if (this.options.allowFlatten) {
+ this.options.type = "keyframes";
+ this.options.ease = "linear";
+ this.initAnimation();
+ }
+ this.driver?.stop();
+ return timeline.observe(this);
+ }
+}
+function fillWildcards(keyframes2) {
+ for (let i = 1; i < keyframes2.length; i++) {
+ keyframes2[i] ?? (keyframes2[i] = keyframes2[i - 1]);
+ }
+}
+const radToDeg = (rad) => rad * 180 / Math.PI;
+const rotate = (v) => {
+ const angle = radToDeg(Math.atan2(v[1], v[0]));
+ return rebaseAngle(angle);
+};
+const matrix2dParsers = {
+ x: 4,
+ y: 5,
+ translateX: 4,
+ translateY: 5,
+ scaleX: 0,
+ scaleY: 3,
+ scale: (v) => (Math.abs(v[0]) + Math.abs(v[3])) / 2,
+ rotate,
+ rotateZ: rotate,
+ skewX: (v) => radToDeg(Math.atan(v[1])),
+ skewY: (v) => radToDeg(Math.atan(v[2])),
+ skew: (v) => (Math.abs(v[1]) + Math.abs(v[2])) / 2
+};
+const rebaseAngle = (angle) => {
+ angle = angle % 360;
+ if (angle < 0)
+ angle += 360;
+ return angle;
+};
+const rotateZ = rotate;
+const scaleX = (v) => Math.sqrt(v[0] * v[0] + v[1] * v[1]);
+const scaleY = (v) => Math.sqrt(v[4] * v[4] + v[5] * v[5]);
+const matrix3dParsers = {
+ x: 12,
+ y: 13,
+ z: 14,
+ translateX: 12,
+ translateY: 13,
+ translateZ: 14,
+ scaleX,
+ scaleY,
+ scale: (v) => (scaleX(v) + scaleY(v)) / 2,
+ rotateX: (v) => rebaseAngle(radToDeg(Math.atan2(v[6], v[5]))),
+ rotateY: (v) => rebaseAngle(radToDeg(Math.atan2(-v[2], v[0]))),
+ rotateZ,
+ rotate: rotateZ,
+ skewX: (v) => radToDeg(Math.atan(v[4])),
+ skewY: (v) => radToDeg(Math.atan(v[1])),
+ skew: (v) => (Math.abs(v[1]) + Math.abs(v[4])) / 2
+};
+function defaultTransformValue(name) {
+ return name.includes("scale") ? 1 : 0;
+}
+function parseValueFromTransform(transform, name) {
+ if (!transform || transform === "none") {
+ return defaultTransformValue(name);
+ }
+ const matrix3dMatch = transform.match(/^matrix3d\(([-\d.e\s,]+)\)$/u);
+ let parsers;
+ let match;
+ if (matrix3dMatch) {
+ parsers = matrix3dParsers;
+ match = matrix3dMatch;
+ } else {
+ const matrix2dMatch = transform.match(/^matrix\(([-\d.e\s,]+)\)$/u);
+ parsers = matrix2dParsers;
+ match = matrix2dMatch;
+ }
+ if (!match) {
+ return defaultTransformValue(name);
+ }
+ const valueParser = parsers[name];
+ const values = match[1].split(",").map(convertTransformToNumber);
+ return typeof valueParser === "function" ? valueParser(values) : values[valueParser];
+}
+const readTransformValue = (instance, name) => {
+ const { transform = "none" } = getComputedStyle(instance);
+ return parseValueFromTransform(transform, name);
+};
+function convertTransformToNumber(value) {
+ return parseFloat(value.trim());
+}
+const transformPropOrder = [
+ "transformPerspective",
+ "x",
+ "y",
+ "z",
+ "translateX",
+ "translateY",
+ "translateZ",
+ "scale",
+ "scaleX",
+ "scaleY",
+ "rotate",
+ "rotateX",
+ "rotateY",
+ "rotateZ",
+ "skew",
+ "skewX",
+ "skewY"
+];
+const transformProps = /* @__PURE__ */ (() => new Set(transformPropOrder))();
+const isNumOrPxType = (v) => v === number || v === px;
+const transformKeys = /* @__PURE__ */ new Set(["x", "y", "z"]);
+const nonTranslationalTransformKeys = transformPropOrder.filter((key) => !transformKeys.has(key));
+function removeNonTranslationalTransform(visualElement) {
+ const removedTransforms = [];
+ nonTranslationalTransformKeys.forEach((key) => {
+ const value = visualElement.getValue(key);
+ if (value !== void 0) {
+ removedTransforms.push([key, value.get()]);
+ value.set(key.startsWith("scale") ? 1 : 0);
+ }
+ });
+ return removedTransforms;
+}
+const positionalValues = {
+ // Dimensions
+ width: ({ x }, { paddingLeft = "0", paddingRight = "0", boxSizing }) => {
+ const width = x.max - x.min;
+ return boxSizing === "border-box" ? width : width - parseFloat(paddingLeft) - parseFloat(paddingRight);
+ },
+ height: ({ y }, { paddingTop = "0", paddingBottom = "0", boxSizing }) => {
+ const height = y.max - y.min;
+ return boxSizing === "border-box" ? height : height - parseFloat(paddingTop) - parseFloat(paddingBottom);
+ },
+ top: (_bbox, { top }) => parseFloat(top),
+ left: (_bbox, { left }) => parseFloat(left),
+ bottom: ({ y }, { top }) => parseFloat(top) + (y.max - y.min),
+ right: ({ x }, { left }) => parseFloat(left) + (x.max - x.min),
+ // Transform
+ x: (_bbox, { transform }) => parseValueFromTransform(transform, "x"),
+ y: (_bbox, { transform }) => parseValueFromTransform(transform, "y")
+};
+positionalValues.translateX = positionalValues.x;
+positionalValues.translateY = positionalValues.y;
+const toResolve = /* @__PURE__ */ new Set();
+let isScheduled = false;
+let anyNeedsMeasurement = false;
+let isForced = false;
+function measureAllKeyframes() {
+ if (anyNeedsMeasurement) {
+ const resolversToMeasure = Array.from(toResolve).filter((resolver) => resolver.needsMeasurement);
+ const elementsToMeasure = new Set(resolversToMeasure.map((resolver) => resolver.element));
+ const transformsToRestore = /* @__PURE__ */ new Map();
+ elementsToMeasure.forEach((element) => {
+ const removedTransforms = removeNonTranslationalTransform(element);
+ if (!removedTransforms.length)
+ return;
+ transformsToRestore.set(element, removedTransforms);
+ element.render();
+ });
+ resolversToMeasure.forEach((resolver) => resolver.measureInitialState());
+ elementsToMeasure.forEach((element) => {
+ element.render();
+ const restore = transformsToRestore.get(element);
+ if (restore) {
+ restore.forEach(([key, value]) => {
+ element.getValue(key)?.set(value);
+ });
+ }
+ });
+ resolversToMeasure.forEach((resolver) => resolver.measureEndState());
+ resolversToMeasure.forEach((resolver) => {
+ if (resolver.suspendedScrollY !== void 0) {
+ window.scrollTo(0, resolver.suspendedScrollY);
+ }
+ });
+ }
+ anyNeedsMeasurement = false;
+ isScheduled = false;
+ toResolve.forEach((resolver) => resolver.complete(isForced));
+ toResolve.clear();
+}
+function readAllKeyframes() {
+ toResolve.forEach((resolver) => {
+ resolver.readKeyframes();
+ if (resolver.needsMeasurement) {
+ anyNeedsMeasurement = true;
+ }
+ });
+}
+function flushKeyframeResolvers() {
+ isForced = true;
+ readAllKeyframes();
+ measureAllKeyframes();
+ isForced = false;
+}
+class KeyframeResolver {
+ constructor(unresolvedKeyframes, onComplete, name, motionValue2, element, isAsync = false) {
+ this.state = "pending";
+ this.isAsync = false;
+ this.needsMeasurement = false;
+ this.unresolvedKeyframes = [...unresolvedKeyframes];
+ this.onComplete = onComplete;
+ this.name = name;
+ this.motionValue = motionValue2;
+ this.element = element;
+ this.isAsync = isAsync;
+ }
+ scheduleResolve() {
+ this.state = "scheduled";
+ if (this.isAsync) {
+ toResolve.add(this);
+ if (!isScheduled) {
+ isScheduled = true;
+ frame.read(readAllKeyframes);
+ frame.resolveKeyframes(measureAllKeyframes);
+ }
+ } else {
+ this.readKeyframes();
+ this.complete();
+ }
+ }
+ readKeyframes() {
+ const { unresolvedKeyframes, name, element, motionValue: motionValue2 } = this;
+ if (unresolvedKeyframes[0] === null) {
+ const currentValue = motionValue2?.get();
+ const finalKeyframe = unresolvedKeyframes[unresolvedKeyframes.length - 1];
+ if (currentValue !== void 0) {
+ unresolvedKeyframes[0] = currentValue;
+ } else if (element && name) {
+ const valueAsRead = element.readValue(name, finalKeyframe);
+ if (valueAsRead !== void 0 && valueAsRead !== null) {
+ unresolvedKeyframes[0] = valueAsRead;
+ }
+ }
+ if (unresolvedKeyframes[0] === void 0) {
+ unresolvedKeyframes[0] = finalKeyframe;
+ }
+ if (motionValue2 && currentValue === void 0) {
+ motionValue2.set(unresolvedKeyframes[0]);
+ }
+ }
+ fillWildcards(unresolvedKeyframes);
+ }
+ setFinalKeyframe() {
+ }
+ measureInitialState() {
+ }
+ renderEndStyles() {
+ }
+ measureEndState() {
+ }
+ complete(isForcedComplete = false) {
+ this.state = "complete";
+ this.onComplete(this.unresolvedKeyframes, this.finalKeyframe, isForcedComplete);
+ toResolve.delete(this);
+ }
+ cancel() {
+ if (this.state === "scheduled") {
+ toResolve.delete(this);
+ this.state = "pending";
+ }
+ }
+ resume() {
+ if (this.state === "pending")
+ this.scheduleResolve();
+ }
+}
+const isCSSVar = (name) => name.startsWith("--");
+function setStyle(element, name, value) {
+ isCSSVar(name) ? element.style.setProperty(name, value) : element.style[name] = value;
+}
+const supportsFlags = {};
+function memoSupports(callback, supportsFlag) {
+ const memoized = /* @__PURE__ */ memo(callback);
+ return () => supportsFlags[supportsFlag] ?? memoized();
+}
+const supportsScrollTimeline = /* @__PURE__ */ memoSupports(() => window.ScrollTimeline !== void 0, "scrollTimeline");
+const supportsLinearEasing = /* @__PURE__ */ memoSupports(() => {
+ try {
+ document.createElement("div").animate({ opacity: 0 }, { easing: "linear(0, 1)" });
+ } catch (e) {
+ return false;
+ }
+ return true;
+}, "linearEasing");
+const cubicBezierAsString = ([a, b, c, d]) => `cubic-bezier(${a}, ${b}, ${c}, ${d})`;
+const supportedWaapiEasing = {
+ linear: "linear",
+ ease: "ease",
+ easeIn: "ease-in",
+ easeOut: "ease-out",
+ easeInOut: "ease-in-out",
+ circIn: /* @__PURE__ */ cubicBezierAsString([0, 0.65, 0.55, 1]),
+ circOut: /* @__PURE__ */ cubicBezierAsString([0.55, 0, 1, 0.45]),
+ backIn: /* @__PURE__ */ cubicBezierAsString([0.31, 0.01, 0.66, -0.59]),
+ backOut: /* @__PURE__ */ cubicBezierAsString([0.33, 1.53, 0.69, 0.99])
+};
+function mapEasingToNativeEasing(easing, duration) {
+ if (!easing) {
+ return void 0;
+ } else if (typeof easing === "function") {
+ return supportsLinearEasing() ? generateLinearEasing(easing, duration) : "ease-out";
+ } else if (isBezierDefinition(easing)) {
+ return cubicBezierAsString(easing);
+ } else if (Array.isArray(easing)) {
+ return easing.map((segmentEasing) => mapEasingToNativeEasing(segmentEasing, duration) || supportedWaapiEasing.easeOut);
+ } else {
+ return supportedWaapiEasing[easing];
+ }
+}
+function startWaapiAnimation(element, valueName, keyframes2, { delay: delay2 = 0, duration = 300, repeat = 0, repeatType = "loop", ease: ease2 = "easeOut", times } = {}, pseudoElement = void 0) {
+ const keyframeOptions = {
+ [valueName]: keyframes2
+ };
+ if (times)
+ keyframeOptions.offset = times;
+ const easing = mapEasingToNativeEasing(ease2, duration);
+ if (Array.isArray(easing))
+ keyframeOptions.easing = easing;
+ const options = {
+ delay: delay2,
+ duration,
+ easing: !Array.isArray(easing) ? easing : "linear",
+ fill: "both",
+ iterations: repeat + 1,
+ direction: repeatType === "reverse" ? "alternate" : "normal"
+ };
+ if (pseudoElement)
+ options.pseudoElement = pseudoElement;
+ const animation = element.animate(keyframeOptions, options);
+ return animation;
+}
+function isGenerator(type) {
+ return typeof type === "function" && "applyToOptions" in type;
+}
+function applyGeneratorOptions({ type, ...options }) {
+ if (isGenerator(type) && supportsLinearEasing()) {
+ return type.applyToOptions(options);
+ } else {
+ options.duration ?? (options.duration = 300);
+ options.ease ?? (options.ease = "easeOut");
+ }
+ return options;
+}
+class NativeAnimation extends WithPromise {
+ constructor(options) {
+ super();
+ this.finishedTime = null;
+ this.isStopped = false;
+ this.manualStartTime = null;
+ if (!options)
+ return;
+ const { element, name, keyframes: keyframes2, pseudoElement, allowFlatten = false, finalKeyframe, onComplete } = options;
+ this.isPseudoElement = Boolean(pseudoElement);
+ this.allowFlatten = allowFlatten;
+ this.options = options;
+ invariant(typeof options.type !== "string", `Mini animate() doesn't support "type" as a string.`, "mini-spring");
+ const transition = applyGeneratorOptions(options);
+ this.animation = startWaapiAnimation(element, name, keyframes2, transition, pseudoElement);
+ if (transition.autoplay === false) {
+ this.animation.pause();
+ }
+ this.animation.onfinish = () => {
+ this.finishedTime = this.time;
+ if (!pseudoElement) {
+ const keyframe = getFinalKeyframe(keyframes2, this.options, finalKeyframe, this.speed);
+ if (this.updateMotionValue) {
+ this.updateMotionValue(keyframe);
+ }
+ setStyle(element, name, keyframe);
+ this.animation.cancel();
+ }
+ onComplete?.();
+ this.notifyFinished();
+ };
+ }
+ play() {
+ if (this.isStopped)
+ return;
+ this.manualStartTime = null;
+ this.animation.play();
+ if (this.state === "finished") {
+ this.updateFinished();
+ }
+ }
+ pause() {
+ this.animation.pause();
+ }
+ complete() {
+ this.animation.finish?.();
+ }
+ cancel() {
+ try {
+ this.animation.cancel();
+ } catch (e) {
+ }
+ }
+ stop() {
+ if (this.isStopped)
+ return;
+ this.isStopped = true;
+ const { state } = this;
+ if (state === "idle" || state === "finished") {
+ return;
+ }
+ if (this.updateMotionValue) {
+ this.updateMotionValue();
+ } else {
+ this.commitStyles();
+ }
+ if (!this.isPseudoElement)
+ this.cancel();
+ }
+ /**
+ * WAAPI doesn't natively have any interruption capabilities.
+ *
+ * In this method, we commit styles back to the DOM before cancelling
+ * the animation.
+ *
+ * This is designed to be overridden by NativeAnimationExtended, which
+ * will create a renderless JS animation and sample it twice to calculate
+ * its current value, "previous" value, and therefore allow
+ * Motion to also correctly calculate velocity for any subsequent animation
+ * while deferring the commit until the next animation frame.
+ */
+ commitStyles() {
+ const element = this.options?.element;
+ if (!this.isPseudoElement && element?.isConnected) {
+ this.animation.commitStyles?.();
+ }
+ }
+ get duration() {
+ const duration = this.animation.effect?.getComputedTiming?.().duration || 0;
+ return /* @__PURE__ */ millisecondsToSeconds(Number(duration));
+ }
+ get iterationDuration() {
+ const { delay: delay2 = 0 } = this.options || {};
+ return this.duration + /* @__PURE__ */ millisecondsToSeconds(delay2);
+ }
+ get time() {
+ return /* @__PURE__ */ millisecondsToSeconds(Number(this.animation.currentTime) || 0);
+ }
+ set time(newTime) {
+ const wasFinished = this.finishedTime !== null;
+ this.manualStartTime = null;
+ this.finishedTime = null;
+ this.animation.currentTime = /* @__PURE__ */ secondsToMilliseconds(newTime);
+ if (wasFinished) {
+ this.animation.pause();
+ }
+ }
+ /**
+ * The playback speed of the animation.
+ * 1 = normal speed, 2 = double speed, 0.5 = half speed.
+ */
+ get speed() {
+ return this.animation.playbackRate;
+ }
+ set speed(newSpeed) {
+ if (newSpeed < 0)
+ this.finishedTime = null;
+ this.animation.playbackRate = newSpeed;
+ }
+ get state() {
+ return this.finishedTime !== null ? "finished" : this.animation.playState;
+ }
+ get startTime() {
+ return this.manualStartTime ?? Number(this.animation.startTime);
+ }
+ set startTime(newStartTime) {
+ this.manualStartTime = this.animation.startTime = newStartTime;
+ }
+ /**
+ * Attaches a timeline to the animation, for instance the `ScrollTimeline`.
+ */
+ attachTimeline({ timeline, rangeStart, rangeEnd, observe }) {
+ if (this.allowFlatten) {
+ this.animation.effect?.updateTiming({ easing: "linear" });
+ }
+ this.animation.onfinish = null;
+ if (timeline && supportsScrollTimeline()) {
+ this.animation.timeline = timeline;
+ if (rangeStart)
+ this.animation.rangeStart = rangeStart;
+ if (rangeEnd)
+ this.animation.rangeEnd = rangeEnd;
+ return noop;
+ } else {
+ return observe(this);
+ }
+ }
+}
+const unsupportedEasingFunctions = {
+ anticipate,
+ backInOut,
+ circInOut
+};
+function isUnsupportedEase(key) {
+ return key in unsupportedEasingFunctions;
+}
+function replaceStringEasing(transition) {
+ if (typeof transition.ease === "string" && isUnsupportedEase(transition.ease)) {
+ transition.ease = unsupportedEasingFunctions[transition.ease];
+ }
+}
+const sampleDelta = 10;
+class NativeAnimationExtended extends NativeAnimation {
+ constructor(options) {
+ replaceStringEasing(options);
+ replaceTransitionType(options);
+ super(options);
+ if (options.startTime !== void 0 && options.autoplay !== false) {
+ this.startTime = options.startTime;
+ }
+ this.options = options;
+ }
+ /**
+ * WAAPI doesn't natively have any interruption capabilities.
+ *
+ * Rather than read committed styles back out of the DOM, we can
+ * create a renderless JS animation and sample it twice to calculate
+ * its current value, "previous" value, and therefore allow
+ * Motion to calculate velocity for any subsequent animation.
+ */
+ updateMotionValue(value) {
+ const { motionValue: motionValue2, onUpdate, onComplete, element, ...options } = this.options;
+ if (!motionValue2)
+ return;
+ if (value !== void 0) {
+ motionValue2.set(value);
+ return;
+ }
+ const sampleAnimation = new JSAnimation({
+ ...options,
+ autoplay: false
+ });
+ const sampleTime = Math.max(sampleDelta, time.now() - this.startTime);
+ const delta = clamp(0, sampleDelta, sampleTime - sampleDelta);
+ const current = sampleAnimation.sample(sampleTime).value;
+ const { name } = this.options;
+ if (element && name)
+ setStyle(element, name, current);
+ motionValue2.setWithVelocity(sampleAnimation.sample(Math.max(0, sampleTime - delta)).value, current, delta);
+ sampleAnimation.stop();
+ }
+}
+const isAnimatable = (value, name) => {
+ if (name === "zIndex")
+ return false;
+ if (typeof value === "number" || Array.isArray(value))
+ return true;
+ if (typeof value === "string" && // It's animatable if we have a string
+ (complex.test(value) || value === "0") && // And it contains numbers and/or colors
+ !value.startsWith("url(")) {
+ return true;
+ }
+ return false;
+};
+function hasKeyframesChanged(keyframes2) {
+ const current = keyframes2[0];
+ if (keyframes2.length === 1)
+ return true;
+ for (let i = 0; i < keyframes2.length; i++) {
+ if (keyframes2[i] !== current)
+ return true;
+ }
+}
+function canAnimate(keyframes2, name, type, velocity) {
+ const originKeyframe = keyframes2[0];
+ if (originKeyframe === null) {
+ return false;
+ }
+ if (name === "display" || name === "visibility")
+ return true;
+ const targetKeyframe = keyframes2[keyframes2.length - 1];
+ const isOriginAnimatable = isAnimatable(originKeyframe, name);
+ const isTargetAnimatable = isAnimatable(targetKeyframe, name);
+ warning(isOriginAnimatable === isTargetAnimatable, `You are trying to animate ${name} from "${originKeyframe}" to "${targetKeyframe}". "${isOriginAnimatable ? targetKeyframe : originKeyframe}" is not an animatable value.`, "value-not-animatable");
+ if (!isOriginAnimatable || !isTargetAnimatable) {
+ return false;
+ }
+ return hasKeyframesChanged(keyframes2) || (type === "spring" || isGenerator(type)) && velocity;
+}
+function makeAnimationInstant(options) {
+ options.duration = 0;
+ options.type = "keyframes";
+}
+const acceleratedValues = /* @__PURE__ */ new Set([
+ "opacity",
+ "clipPath",
+ "filter",
+ "transform"
+ // TODO: Can be accelerated but currently disabled until https://issues.chromium.org/issues/41491098 is resolved
+ // or until we implement support for linear() easing.
+ // "background-color"
+]);
+const browserColorFunctions = /^(?:oklch|oklab|lab|lch|color|color-mix|light-dark)\(/;
+function hasBrowserOnlyColors(keyframes2) {
+ for (let i = 0; i < keyframes2.length; i++) {
+ if (typeof keyframes2[i] === "string" && browserColorFunctions.test(keyframes2[i])) {
+ return true;
+ }
+ }
+ return false;
+}
+const colorProperties = /* @__PURE__ */ new Set([
+ "color",
+ "backgroundColor",
+ "outlineColor",
+ "fill",
+ "stroke",
+ "borderColor",
+ "borderTopColor",
+ "borderRightColor",
+ "borderBottomColor",
+ "borderLeftColor"
+]);
+const supportsWaapi = /* @__PURE__ */ memo(() => Object.hasOwnProperty.call(Element.prototype, "animate"));
+function supportsBrowserAnimation(options) {
+ const { motionValue: motionValue2, name, repeatDelay, repeatType, damping, type, keyframes: keyframes2 } = options;
+ const subject = motionValue2?.owner?.current;
+ if (!(subject instanceof HTMLElement)) {
+ return false;
+ }
+ const { onUpdate, transformTemplate } = motionValue2.owner.getProps();
+ return supportsWaapi() && name && /**
+ * Force WAAPI for color properties with browser-only color formats
+ * (oklch, oklab, lab, lch, etc.) that the JS animation path can't parse.
+ */
+ (acceleratedValues.has(name) || colorProperties.has(name) && hasBrowserOnlyColors(keyframes2)) && (name !== "transform" || !transformTemplate) && /**
+ * If we're outputting values to onUpdate then we can't use WAAPI as there's
+ * no way to read the value from WAAPI every frame.
+ */
+ !onUpdate && !repeatDelay && repeatType !== "mirror" && damping !== 0 && type !== "inertia";
+}
+const MAX_RESOLVE_DELAY = 40;
+class AsyncMotionValueAnimation extends WithPromise {
+ constructor({ autoplay = true, delay: delay2 = 0, type = "keyframes", repeat = 0, repeatDelay = 0, repeatType = "loop", keyframes: keyframes2, name, motionValue: motionValue2, element, ...options }) {
+ super();
+ this.stop = () => {
+ if (this._animation) {
+ this._animation.stop();
+ this.stopTimeline?.();
+ }
+ this.keyframeResolver?.cancel();
+ };
+ this.createdAt = time.now();
+ const optionsWithDefaults = {
+ autoplay,
+ delay: delay2,
+ type,
+ repeat,
+ repeatDelay,
+ repeatType,
+ name,
+ motionValue: motionValue2,
+ element,
+ ...options
+ };
+ const KeyframeResolver$1 = element?.KeyframeResolver || KeyframeResolver;
+ this.keyframeResolver = new KeyframeResolver$1(keyframes2, (resolvedKeyframes, finalKeyframe, forced) => this.onKeyframesResolved(resolvedKeyframes, finalKeyframe, optionsWithDefaults, !forced), name, motionValue2, element);
+ this.keyframeResolver?.scheduleResolve();
+ }
+ onKeyframesResolved(keyframes2, finalKeyframe, options, sync) {
+ this.keyframeResolver = void 0;
+ const { name, type, velocity, delay: delay2, isHandoff, onUpdate } = options;
+ this.resolvedAt = time.now();
+ let canAnimateValue = true;
+ if (!canAnimate(keyframes2, name, type, velocity)) {
+ canAnimateValue = false;
+ if (MotionGlobalConfig.instantAnimations || !delay2) {
+ onUpdate?.(getFinalKeyframe(keyframes2, options, finalKeyframe));
+ }
+ keyframes2[0] = keyframes2[keyframes2.length - 1];
+ makeAnimationInstant(options);
+ options.repeat = 0;
+ }
+ const startTime = sync ? !this.resolvedAt ? this.createdAt : this.resolvedAt - this.createdAt > MAX_RESOLVE_DELAY ? this.resolvedAt : this.createdAt : void 0;
+ const resolvedOptions = {
+ startTime,
+ finalKeyframe,
+ ...options,
+ keyframes: keyframes2
+ };
+ const useWaapi = canAnimateValue && !isHandoff && supportsBrowserAnimation(resolvedOptions);
+ const element = resolvedOptions.motionValue?.owner?.current;
+ let animation;
+ if (useWaapi) {
+ try {
+ animation = new NativeAnimationExtended({
+ ...resolvedOptions,
+ element
+ });
+ } catch {
+ animation = new JSAnimation(resolvedOptions);
+ }
+ } else {
+ animation = new JSAnimation(resolvedOptions);
+ }
+ animation.finished.then(() => {
+ this.notifyFinished();
+ }).catch(noop);
+ if (this.pendingTimeline) {
+ this.stopTimeline = animation.attachTimeline(this.pendingTimeline);
+ this.pendingTimeline = void 0;
+ }
+ this._animation = animation;
+ }
+ get finished() {
+ if (!this._animation) {
+ return this._finished;
+ } else {
+ return this.animation.finished;
+ }
+ }
+ then(onResolve, _onReject) {
+ return this.finished.finally(onResolve).then(() => {
+ });
+ }
+ get animation() {
+ if (!this._animation) {
+ this.keyframeResolver?.resume();
+ flushKeyframeResolvers();
+ }
+ return this._animation;
+ }
+ get duration() {
+ return this.animation.duration;
+ }
+ get iterationDuration() {
+ return this.animation.iterationDuration;
+ }
+ get time() {
+ return this.animation.time;
+ }
+ set time(newTime) {
+ this.animation.time = newTime;
+ }
+ get speed() {
+ return this.animation.speed;
+ }
+ get state() {
+ return this.animation.state;
+ }
+ set speed(newSpeed) {
+ this.animation.speed = newSpeed;
+ }
+ get startTime() {
+ return this.animation.startTime;
+ }
+ attachTimeline(timeline) {
+ if (this._animation) {
+ this.stopTimeline = this.animation.attachTimeline(timeline);
+ } else {
+ this.pendingTimeline = timeline;
+ }
+ return () => this.stop();
+ }
+ play() {
+ this.animation.play();
+ }
+ pause() {
+ this.animation.pause();
+ }
+ complete() {
+ this.animation.complete();
+ }
+ cancel() {
+ if (this._animation) {
+ this.animation.cancel();
+ }
+ this.keyframeResolver?.cancel();
+ }
+}
+function calcChildStagger(children, child, delayChildren, staggerChildren = 0, staggerDirection = 1) {
+ const index = Array.from(children).sort((a, b) => a.sortNodePosition(b)).indexOf(child);
+ const numChildren = children.size;
+ const maxStaggerDuration = (numChildren - 1) * staggerChildren;
+ const delayIsFunction = typeof delayChildren === "function";
+ return delayIsFunction ? delayChildren(index, numChildren) : staggerDirection === 1 ? index * staggerChildren : maxStaggerDuration - index * staggerChildren;
+}
+const splitCSSVariableRegex = (
+ // eslint-disable-next-line redos-detector/no-unsafe-regex -- false positive, as it can match a lot of words
+ /^var\(--(?:([\w-]+)|([\w-]+), ?([a-zA-Z\d ()%#.,-]+))\)/u
+);
+function parseCSSVariable(current) {
+ const match = splitCSSVariableRegex.exec(current);
+ if (!match)
+ return [,];
+ const [, token1, token2, fallback] = match;
+ return [`--${token1 ?? token2}`, fallback];
+}
+const maxDepth = 4;
+function getVariableValue(current, element, depth = 1) {
+ invariant(depth <= maxDepth, `Max CSS variable fallback depth detected in property "${current}". This may indicate a circular fallback dependency.`, "max-css-var-depth");
+ const [token, fallback] = parseCSSVariable(current);
+ if (!token)
+ return;
+ const resolved = window.getComputedStyle(element).getPropertyValue(token);
+ if (resolved) {
+ const trimmed = resolved.trim();
+ return isNumericalString(trimmed) ? parseFloat(trimmed) : trimmed;
+ }
+ return isCSSVariableToken(fallback) ? getVariableValue(fallback, element, depth + 1) : fallback;
+}
+const underDampedSpring = {
+ type: "spring",
+ stiffness: 500,
+ damping: 25,
+ restSpeed: 10
+};
+const criticallyDampedSpring = (target) => ({
+ type: "spring",
+ stiffness: 550,
+ damping: target === 0 ? 2 * Math.sqrt(550) : 30,
+ restSpeed: 10
+});
+const keyframesTransition = {
+ type: "keyframes",
+ duration: 0.8
+};
+const ease = {
+ type: "keyframes",
+ ease: [0.25, 0.1, 0.35, 1],
+ duration: 0.3
+};
+const getDefaultTransition = (valueKey, { keyframes: keyframes2 }) => {
+ if (keyframes2.length > 2) {
+ return keyframesTransition;
+ } else if (transformProps.has(valueKey)) {
+ return valueKey.startsWith("scale") ? criticallyDampedSpring(keyframes2[1]) : underDampedSpring;
+ }
+ return ease;
+};
+function resolveTransition(transition, parentTransition) {
+ if (transition?.inherit && parentTransition) {
+ const { inherit: _, ...rest } = transition;
+ return { ...parentTransition, ...rest };
+ }
+ return transition;
+}
+function getValueTransition(transition, key) {
+ const valueTransition = transition?.[key] ?? transition?.["default"] ?? transition;
+ if (valueTransition !== transition) {
+ return resolveTransition(valueTransition, transition);
+ }
+ return valueTransition;
+}
+const orchestrationKeys = /* @__PURE__ */ new Set([
+ "when",
+ "delay",
+ "delayChildren",
+ "staggerChildren",
+ "staggerDirection",
+ "repeat",
+ "repeatType",
+ "repeatDelay",
+ "from",
+ "elapsed"
+]);
+function isTransitionDefined(transition) {
+ for (const key in transition) {
+ if (!orchestrationKeys.has(key))
+ return true;
+ }
+ return false;
+}
+const animateMotionValue = (name, value, target, transition = {}, element, isHandoff) => (onComplete) => {
+ const valueTransition = getValueTransition(transition, name) || {};
+ const delay2 = valueTransition.delay || transition.delay || 0;
+ let { elapsed = 0 } = transition;
+ elapsed = elapsed - /* @__PURE__ */ secondsToMilliseconds(delay2);
+ const options = {
+ keyframes: Array.isArray(target) ? target : [null, target],
+ ease: "easeOut",
+ velocity: value.getVelocity(),
+ ...valueTransition,
+ delay: -elapsed,
+ onUpdate: (v) => {
+ value.set(v);
+ valueTransition.onUpdate && valueTransition.onUpdate(v);
+ },
+ onComplete: () => {
+ onComplete();
+ valueTransition.onComplete && valueTransition.onComplete();
+ },
+ name,
+ motionValue: value,
+ element: isHandoff ? void 0 : element
+ };
+ if (!isTransitionDefined(valueTransition)) {
+ Object.assign(options, getDefaultTransition(name, options));
+ }
+ options.duration && (options.duration = /* @__PURE__ */ secondsToMilliseconds(options.duration));
+ options.repeatDelay && (options.repeatDelay = /* @__PURE__ */ secondsToMilliseconds(options.repeatDelay));
+ if (options.from !== void 0) {
+ options.keyframes[0] = options.from;
+ }
+ let shouldSkip = false;
+ if (options.type === false || options.duration === 0 && !options.repeatDelay) {
+ makeAnimationInstant(options);
+ if (options.delay === 0) {
+ shouldSkip = true;
+ }
+ }
+ if (MotionGlobalConfig.instantAnimations || MotionGlobalConfig.skipAnimations || element?.shouldSkipAnimations) {
+ shouldSkip = true;
+ makeAnimationInstant(options);
+ options.delay = 0;
+ }
+ options.allowFlatten = !valueTransition.type && !valueTransition.ease;
+ if (shouldSkip && !isHandoff && value.get() !== void 0) {
+ const finalKeyframe = getFinalKeyframe(options.keyframes, valueTransition);
+ if (finalKeyframe !== void 0) {
+ frame.update(() => {
+ options.onUpdate(finalKeyframe);
+ options.onComplete();
+ });
+ return;
+ }
+ }
+ return valueTransition.isSync ? new JSAnimation(options) : new AsyncMotionValueAnimation(options);
+};
+function getValueState(visualElement) {
+ const state = [{}, {}];
+ visualElement?.values.forEach((value, key) => {
+ state[0][key] = value.get();
+ state[1][key] = value.getVelocity();
+ });
+ return state;
+}
+function resolveVariantFromProps(props, definition, custom, visualElement) {
+ if (typeof definition === "function") {
+ const [current, velocity] = getValueState(visualElement);
+ definition = definition(custom !== void 0 ? custom : props.custom, current, velocity);
+ }
+ if (typeof definition === "string") {
+ definition = props.variants && props.variants[definition];
+ }
+ if (typeof definition === "function") {
+ const [current, velocity] = getValueState(visualElement);
+ definition = definition(custom !== void 0 ? custom : props.custom, current, velocity);
+ }
+ return definition;
+}
+function resolveVariant(visualElement, definition, custom) {
+ const props = visualElement.getProps();
+ return resolveVariantFromProps(props, definition, custom !== void 0 ? custom : props.custom, visualElement);
+}
+const positionalKeys = /* @__PURE__ */ new Set([
+ "width",
+ "height",
+ "top",
+ "left",
+ "right",
+ "bottom",
+ ...transformPropOrder
+]);
+const MAX_VELOCITY_DELTA = 30;
+const isFloat = (value) => {
+ return !isNaN(parseFloat(value));
+};
+class MotionValue {
+ /**
+ * @param init - The initiating value
+ * @param config - Optional configuration options
+ *
+ * - `transformer`: A function to transform incoming values with.
+ */
+ constructor(init, options = {}) {
+ this.canTrackVelocity = null;
+ this.events = {};
+ this.updateAndNotify = (v) => {
+ const currentTime = time.now();
+ if (this.updatedAt !== currentTime) {
+ this.setPrevFrameValue();
+ }
+ this.prev = this.current;
+ this.setCurrent(v);
+ if (this.current !== this.prev) {
+ this.events.change?.notify(this.current);
+ if (this.dependents) {
+ for (const dependent of this.dependents) {
+ dependent.dirty();
+ }
+ }
+ }
+ };
+ this.hasAnimated = false;
+ this.setCurrent(init);
+ this.owner = options.owner;
+ }
+ setCurrent(current) {
+ this.current = current;
+ this.updatedAt = time.now();
+ if (this.canTrackVelocity === null && current !== void 0) {
+ this.canTrackVelocity = isFloat(this.current);
+ }
+ }
+ setPrevFrameValue(prevFrameValue = this.current) {
+ this.prevFrameValue = prevFrameValue;
+ this.prevUpdatedAt = this.updatedAt;
+ }
+ /**
+ * Adds a function that will be notified when the `MotionValue` is updated.
+ *
+ * It returns a function that, when called, will cancel the subscription.
+ *
+ * When calling `onChange` inside a React component, it should be wrapped with the
+ * `useEffect` hook. As it returns an unsubscribe function, this should be returned
+ * from the `useEffect` function to ensure you don't add duplicate subscribers..
+ *
+ * ```jsx
+ * export const MyComponent = () => {
+ * const x = useMotionValue(0)
+ * const y = useMotionValue(0)
+ * const opacity = useMotionValue(1)
+ *
+ * useEffect(() => {
+ * function updateOpacity() {
+ * const maxXY = Math.max(x.get(), y.get())
+ * const newOpacity = transform(maxXY, [0, 100], [1, 0])
+ * opacity.set(newOpacity)
+ * }
+ *
+ * const unsubscribeX = x.on("change", updateOpacity)
+ * const unsubscribeY = y.on("change", updateOpacity)
+ *
+ * return () => {
+ * unsubscribeX()
+ * unsubscribeY()
+ * }
+ * }, [])
+ *
+ * return
+ * }
+ * ```
+ *
+ * @param subscriber - A function that receives the latest value.
+ * @returns A function that, when called, will cancel this subscription.
+ *
+ * @deprecated
+ */
+ onChange(subscription) {
+ if (process.env.NODE_ENV !== "production") {
+ warnOnce(false, `value.onChange(callback) is deprecated. Switch to value.on("change", callback).`);
+ }
+ return this.on("change", subscription);
+ }
+ on(eventName, callback) {
+ if (!this.events[eventName]) {
+ this.events[eventName] = new SubscriptionManager();
+ }
+ const unsubscribe = this.events[eventName].add(callback);
+ if (eventName === "change") {
+ return () => {
+ unsubscribe();
+ frame.read(() => {
+ if (!this.events.change.getSize()) {
+ this.stop();
+ }
+ });
+ };
+ }
+ return unsubscribe;
+ }
+ clearListeners() {
+ for (const eventManagers in this.events) {
+ this.events[eventManagers].clear();
+ }
+ }
+ /**
+ * Attaches a passive effect to the `MotionValue`.
+ */
+ attach(passiveEffect, stopPassiveEffect) {
+ this.passiveEffect = passiveEffect;
+ this.stopPassiveEffect = stopPassiveEffect;
+ }
+ /**
+ * Sets the state of the `MotionValue`.
+ *
+ * @remarks
+ *
+ * ```jsx
+ * const x = useMotionValue(0)
+ * x.set(10)
+ * ```
+ *
+ * @param latest - Latest value to set.
+ * @param render - Whether to notify render subscribers. Defaults to `true`
+ *
+ * @public
+ */
+ set(v) {
+ if (!this.passiveEffect) {
+ this.updateAndNotify(v);
+ } else {
+ this.passiveEffect(v, this.updateAndNotify);
+ }
+ }
+ setWithVelocity(prev, current, delta) {
+ this.set(current);
+ this.prev = void 0;
+ this.prevFrameValue = prev;
+ this.prevUpdatedAt = this.updatedAt - delta;
+ }
+ /**
+ * Set the state of the `MotionValue`, stopping any active animations,
+ * effects, and resets velocity to `0`.
+ */
+ jump(v, endAnimation = true) {
+ this.updateAndNotify(v);
+ this.prev = v;
+ this.prevUpdatedAt = this.prevFrameValue = void 0;
+ endAnimation && this.stop();
+ if (this.stopPassiveEffect)
+ this.stopPassiveEffect();
+ }
+ dirty() {
+ this.events.change?.notify(this.current);
+ }
+ addDependent(dependent) {
+ if (!this.dependents) {
+ this.dependents = /* @__PURE__ */ new Set();
+ }
+ this.dependents.add(dependent);
+ }
+ removeDependent(dependent) {
+ if (this.dependents) {
+ this.dependents.delete(dependent);
+ }
+ }
+ /**
+ * Returns the latest state of `MotionValue`
+ *
+ * @returns - The latest state of `MotionValue`
+ *
+ * @public
+ */
+ get() {
+ return this.current;
+ }
+ /**
+ * @public
+ */
+ getPrevious() {
+ return this.prev;
+ }
+ /**
+ * Returns the latest velocity of `MotionValue`
+ *
+ * @returns - The latest velocity of `MotionValue`. Returns `0` if the state is non-numerical.
+ *
+ * @public
+ */
+ getVelocity() {
+ const currentTime = time.now();
+ if (!this.canTrackVelocity || this.prevFrameValue === void 0 || currentTime - this.updatedAt > MAX_VELOCITY_DELTA) {
+ return 0;
+ }
+ const delta = Math.min(this.updatedAt - this.prevUpdatedAt, MAX_VELOCITY_DELTA);
+ return velocityPerSecond(parseFloat(this.current) - parseFloat(this.prevFrameValue), delta);
+ }
+ /**
+ * Registers a new animation to control this `MotionValue`. Only one
+ * animation can drive a `MotionValue` at one time.
+ *
+ * ```jsx
+ * value.start()
+ * ```
+ *
+ * @param animation - A function that starts the provided animation
+ */
+ start(startAnimation) {
+ this.stop();
+ return new Promise((resolve) => {
+ this.hasAnimated = true;
+ this.animation = startAnimation(resolve);
+ if (this.events.animationStart) {
+ this.events.animationStart.notify();
+ }
+ }).then(() => {
+ if (this.events.animationComplete) {
+ this.events.animationComplete.notify();
+ }
+ this.clearAnimation();
+ });
+ }
+ /**
+ * Stop the currently active animation.
+ *
+ * @public
+ */
+ stop() {
+ if (this.animation) {
+ this.animation.stop();
+ if (this.events.animationCancel) {
+ this.events.animationCancel.notify();
+ }
+ }
+ this.clearAnimation();
+ }
+ /**
+ * Returns `true` if this value is currently animating.
+ *
+ * @public
+ */
+ isAnimating() {
+ return !!this.animation;
+ }
+ clearAnimation() {
+ delete this.animation;
+ }
+ /**
+ * Destroy and clean up subscribers to this `MotionValue`.
+ *
+ * The `MotionValue` hooks like `useMotionValue` and `useTransform` automatically
+ * handle the lifecycle of the returned `MotionValue`, so this method is only necessary if you've manually
+ * created a `MotionValue` via the `motionValue` function.
+ *
+ * @public
+ */
+ destroy() {
+ this.dependents?.clear();
+ this.events.destroy?.notify();
+ this.clearListeners();
+ this.stop();
+ if (this.stopPassiveEffect) {
+ this.stopPassiveEffect();
+ }
+ }
+}
+function motionValue(init, options) {
+ return new MotionValue(init, options);
+}
+const isKeyframesTarget = (v) => {
+ return Array.isArray(v);
+};
+function setMotionValue(visualElement, key, value) {
+ if (visualElement.hasValue(key)) {
+ visualElement.getValue(key).set(value);
+ } else {
+ visualElement.addValue(key, motionValue(value));
+ }
+}
+function resolveFinalValueInKeyframes(v) {
+ return isKeyframesTarget(v) ? v[v.length - 1] || 0 : v;
+}
+function setTarget(visualElement, definition) {
+ const resolved = resolveVariant(visualElement, definition);
+ let { transitionEnd = {}, transition = {}, ...target } = resolved || {};
+ target = { ...target, ...transitionEnd };
+ for (const key in target) {
+ const value = resolveFinalValueInKeyframes(target[key]);
+ setMotionValue(visualElement, key, value);
+ }
+}
+const isMotionValue = (value) => Boolean(value && value.getVelocity);
+function isWillChangeMotionValue(value) {
+ return Boolean(isMotionValue(value) && value.add);
+}
+function addValueToWillChange(visualElement, key) {
+ const willChange = visualElement.getValue("willChange");
+ if (isWillChangeMotionValue(willChange)) {
+ return willChange.add(key);
+ } else if (!willChange && MotionGlobalConfig.WillChange) {
+ const newWillChange = new MotionGlobalConfig.WillChange("auto");
+ visualElement.addValue("willChange", newWillChange);
+ newWillChange.add(key);
+ }
+}
+function camelToDash(str) {
+ return str.replace(/([A-Z])/g, (match) => `-${match.toLowerCase()}`);
+}
+const optimizedAppearDataId = "framerAppearId";
+const optimizedAppearDataAttribute = "data-" + camelToDash(optimizedAppearDataId);
+function getOptimisedAppearId(visualElement) {
+ return visualElement.props[optimizedAppearDataAttribute];
+}
+function shouldBlockAnimation({ protectedKeys, needsAnimating }, key) {
+ const shouldBlock = protectedKeys.hasOwnProperty(key) && needsAnimating[key] !== true;
+ needsAnimating[key] = false;
+ return shouldBlock;
+}
+function animateTarget(visualElement, targetAndTransition, { delay: delay2 = 0, transitionOverride, type } = {}) {
+ let { transition, transitionEnd, ...target } = targetAndTransition;
+ const defaultTransition = visualElement.getDefaultTransition();
+ transition = transition ? resolveTransition(transition, defaultTransition) : defaultTransition;
+ const reduceMotion = transition?.reduceMotion;
+ if (transitionOverride)
+ transition = transitionOverride;
+ const animations2 = [];
+ const animationTypeState = type && visualElement.animationState && visualElement.animationState.getState()[type];
+ for (const key in target) {
+ const value = visualElement.getValue(key, visualElement.latestValues[key] ?? null);
+ const valueTarget = target[key];
+ if (valueTarget === void 0 || animationTypeState && shouldBlockAnimation(animationTypeState, key)) {
+ continue;
+ }
+ const valueTransition = {
+ delay: delay2,
+ ...getValueTransition(transition || {}, key)
+ };
+ const currentValue = value.get();
+ if (currentValue !== void 0 && !value.isAnimating() && !Array.isArray(valueTarget) && valueTarget === currentValue && !valueTransition.velocity) {
+ frame.update(() => value.set(valueTarget));
+ continue;
+ }
+ let isHandoff = false;
+ if (window.MotionHandoffAnimation) {
+ const appearId = getOptimisedAppearId(visualElement);
+ if (appearId) {
+ const startTime = window.MotionHandoffAnimation(appearId, key, frame);
+ if (startTime !== null) {
+ valueTransition.startTime = startTime;
+ isHandoff = true;
+ }
+ }
+ }
+ addValueToWillChange(visualElement, key);
+ const shouldReduceMotion = reduceMotion ?? visualElement.shouldReduceMotion;
+ value.start(animateMotionValue(key, value, valueTarget, shouldReduceMotion && positionalKeys.has(key) ? { type: false } : valueTransition, visualElement, isHandoff));
+ const animation = value.animation;
+ if (animation) {
+ animations2.push(animation);
+ }
+ }
+ if (transitionEnd) {
+ const applyTransitionEnd = () => frame.update(() => {
+ transitionEnd && setTarget(visualElement, transitionEnd);
+ });
+ if (animations2.length) {
+ Promise.all(animations2).then(applyTransitionEnd);
+ } else {
+ applyTransitionEnd();
+ }
+ }
+ return animations2;
+}
+function animateVariant(visualElement, variant, options = {}) {
+ const resolved = resolveVariant(visualElement, variant, options.type === "exit" ? visualElement.presenceContext?.custom : void 0);
+ let { transition = visualElement.getDefaultTransition() || {} } = resolved || {};
+ if (options.transitionOverride) {
+ transition = options.transitionOverride;
+ }
+ const getAnimation = resolved ? () => Promise.all(animateTarget(visualElement, resolved, options)) : () => Promise.resolve();
+ const getChildAnimations = visualElement.variantChildren && visualElement.variantChildren.size ? (forwardDelay = 0) => {
+ const { delayChildren = 0, staggerChildren, staggerDirection } = transition;
+ return animateChildren(visualElement, variant, forwardDelay, delayChildren, staggerChildren, staggerDirection, options);
+ } : () => Promise.resolve();
+ const { when } = transition;
+ if (when) {
+ const [first, last] = when === "beforeChildren" ? [getAnimation, getChildAnimations] : [getChildAnimations, getAnimation];
+ return first().then(() => last());
+ } else {
+ return Promise.all([getAnimation(), getChildAnimations(options.delay)]);
+ }
+}
+function animateChildren(visualElement, variant, delay2 = 0, delayChildren = 0, staggerChildren = 0, staggerDirection = 1, options) {
+ const animations2 = [];
+ for (const child of visualElement.variantChildren) {
+ child.notify("AnimationStart", variant);
+ animations2.push(animateVariant(child, variant, {
+ ...options,
+ delay: delay2 + (typeof delayChildren === "function" ? 0 : delayChildren) + calcChildStagger(visualElement.variantChildren, child, delayChildren, staggerChildren, staggerDirection)
+ }).then(() => child.notify("AnimationComplete", variant)));
+ }
+ return Promise.all(animations2);
+}
+function animateVisualElement(visualElement, definition, options = {}) {
+ visualElement.notify("AnimationStart", definition);
+ let animation;
+ if (Array.isArray(definition)) {
+ const animations2 = definition.map((variant) => animateVariant(visualElement, variant, options));
+ animation = Promise.all(animations2);
+ } else if (typeof definition === "string") {
+ animation = animateVariant(visualElement, definition, options);
+ } else {
+ const resolvedDefinition = typeof definition === "function" ? resolveVariant(visualElement, definition, options.custom) : definition;
+ animation = Promise.all(animateTarget(visualElement, resolvedDefinition, options));
+ }
+ return animation.then(() => {
+ visualElement.notify("AnimationComplete", definition);
+ });
+}
+const auto = {
+ test: (v) => v === "auto",
+ parse: (v) => v
+};
+const testValueType = (v) => (type) => type.test(v);
+const dimensionValueTypes = [number, px, percent, degrees, vw, vh, auto];
+const findDimensionValueType = (v) => dimensionValueTypes.find(testValueType(v));
+function isNone(value) {
+ if (typeof value === "number") {
+ return value === 0;
+ } else if (value !== null) {
+ return value === "none" || value === "0" || isZeroValueString(value);
+ } else {
+ return true;
+ }
+}
+const maxDefaults = /* @__PURE__ */ new Set(["brightness", "contrast", "saturate", "opacity"]);
+function applyDefaultFilter(v) {
+ const [name, value] = v.slice(0, -1).split("(");
+ if (name === "drop-shadow")
+ return v;
+ const [number2] = value.match(floatRegex) || [];
+ if (!number2)
+ return v;
+ const unit = value.replace(number2, "");
+ let defaultValue = maxDefaults.has(name) ? 1 : 0;
+ if (number2 !== value)
+ defaultValue *= 100;
+ return name + "(" + defaultValue + unit + ")";
+}
+const functionRegex = /\b([a-z-]*)\(.*?\)/gu;
+const filter = {
+ ...complex,
+ getAnimatableNone: (v) => {
+ const functions = v.match(functionRegex);
+ return functions ? functions.map(applyDefaultFilter).join(" ") : v;
+ }
+};
+const mask = {
+ ...complex,
+ getAnimatableNone: (v) => {
+ const parsed = complex.parse(v);
+ const transformer = complex.createTransformer(v);
+ return transformer(parsed.map((v2) => typeof v2 === "number" ? 0 : typeof v2 === "object" ? { ...v2, alpha: 1 } : v2));
+ }
+};
+const int = {
+ ...number,
+ transform: Math.round
+};
+const transformValueTypes = {
+ rotate: degrees,
+ rotateX: degrees,
+ rotateY: degrees,
+ rotateZ: degrees,
+ scale,
+ scaleX: scale,
+ scaleY: scale,
+ scaleZ: scale,
+ skew: degrees,
+ skewX: degrees,
+ skewY: degrees,
+ distance: px,
+ translateX: px,
+ translateY: px,
+ translateZ: px,
+ x: px,
+ y: px,
+ z: px,
+ perspective: px,
+ transformPerspective: px,
+ opacity: alpha,
+ originX: progressPercentage,
+ originY: progressPercentage,
+ originZ: px
+};
+const numberValueTypes = {
+ // Border props
+ borderWidth: px,
+ borderTopWidth: px,
+ borderRightWidth: px,
+ borderBottomWidth: px,
+ borderLeftWidth: px,
+ borderRadius: px,
+ borderTopLeftRadius: px,
+ borderTopRightRadius: px,
+ borderBottomRightRadius: px,
+ borderBottomLeftRadius: px,
+ // Positioning props
+ width: px,
+ maxWidth: px,
+ height: px,
+ maxHeight: px,
+ top: px,
+ right: px,
+ bottom: px,
+ left: px,
+ inset: px,
+ insetBlock: px,
+ insetBlockStart: px,
+ insetBlockEnd: px,
+ insetInline: px,
+ insetInlineStart: px,
+ insetInlineEnd: px,
+ // Spacing props
+ padding: px,
+ paddingTop: px,
+ paddingRight: px,
+ paddingBottom: px,
+ paddingLeft: px,
+ paddingBlock: px,
+ paddingBlockStart: px,
+ paddingBlockEnd: px,
+ paddingInline: px,
+ paddingInlineStart: px,
+ paddingInlineEnd: px,
+ margin: px,
+ marginTop: px,
+ marginRight: px,
+ marginBottom: px,
+ marginLeft: px,
+ marginBlock: px,
+ marginBlockStart: px,
+ marginBlockEnd: px,
+ marginInline: px,
+ marginInlineStart: px,
+ marginInlineEnd: px,
+ // Typography
+ fontSize: px,
+ // Misc
+ backgroundPositionX: px,
+ backgroundPositionY: px,
+ ...transformValueTypes,
+ zIndex: int,
+ // SVG
+ fillOpacity: alpha,
+ strokeOpacity: alpha,
+ numOctaves: int
+};
+const defaultValueTypes = {
+ ...numberValueTypes,
+ // Color props
+ color,
+ backgroundColor: color,
+ outlineColor: color,
+ fill: color,
+ stroke: color,
+ // Border props
+ borderColor: color,
+ borderTopColor: color,
+ borderRightColor: color,
+ borderBottomColor: color,
+ borderLeftColor: color,
+ filter,
+ WebkitFilter: filter,
+ mask,
+ WebkitMask: mask
+};
+const getDefaultValueType = (key) => defaultValueTypes[key];
+const customTypes = /* @__PURE__ */ new Set([filter, mask]);
+function getAnimatableNone(key, value) {
+ let defaultValueType = getDefaultValueType(key);
+ if (!customTypes.has(defaultValueType))
+ defaultValueType = complex;
+ return defaultValueType.getAnimatableNone ? defaultValueType.getAnimatableNone(value) : void 0;
+}
+const invalidTemplates = /* @__PURE__ */ new Set(["auto", "none", "0"]);
+function makeNoneKeyframesAnimatable(unresolvedKeyframes, noneKeyframeIndexes, name) {
+ let i = 0;
+ let animatableTemplate = void 0;
+ while (i < unresolvedKeyframes.length && !animatableTemplate) {
+ const keyframe = unresolvedKeyframes[i];
+ if (typeof keyframe === "string" && !invalidTemplates.has(keyframe) && analyseComplexValue(keyframe).values.length) {
+ animatableTemplate = unresolvedKeyframes[i];
+ }
+ i++;
+ }
+ if (animatableTemplate && name) {
+ for (const noneIndex of noneKeyframeIndexes) {
+ unresolvedKeyframes[noneIndex] = getAnimatableNone(name, animatableTemplate);
+ }
+ }
+}
+class DOMKeyframesResolver extends KeyframeResolver {
+ constructor(unresolvedKeyframes, onComplete, name, motionValue2, element) {
+ super(unresolvedKeyframes, onComplete, name, motionValue2, element, true);
+ }
+ readKeyframes() {
+ const { unresolvedKeyframes, element, name } = this;
+ if (!element || !element.current)
+ return;
+ super.readKeyframes();
+ for (let i = 0; i < unresolvedKeyframes.length; i++) {
+ let keyframe = unresolvedKeyframes[i];
+ if (typeof keyframe === "string") {
+ keyframe = keyframe.trim();
+ if (isCSSVariableToken(keyframe)) {
+ const resolved = getVariableValue(keyframe, element.current);
+ if (resolved !== void 0) {
+ unresolvedKeyframes[i] = resolved;
+ }
+ if (i === unresolvedKeyframes.length - 1) {
+ this.finalKeyframe = keyframe;
+ }
+ }
+ }
+ }
+ this.resolveNoneKeyframes();
+ if (!positionalKeys.has(name) || unresolvedKeyframes.length !== 2) {
+ return;
+ }
+ const [origin, target] = unresolvedKeyframes;
+ const originType = findDimensionValueType(origin);
+ const targetType = findDimensionValueType(target);
+ const originHasVar = containsCSSVariable(origin);
+ const targetHasVar = containsCSSVariable(target);
+ if (originHasVar !== targetHasVar && positionalValues[name]) {
+ this.needsMeasurement = true;
+ return;
+ }
+ if (originType === targetType)
+ return;
+ if (isNumOrPxType(originType) && isNumOrPxType(targetType)) {
+ for (let i = 0; i < unresolvedKeyframes.length; i++) {
+ const value = unresolvedKeyframes[i];
+ if (typeof value === "string") {
+ unresolvedKeyframes[i] = parseFloat(value);
+ }
+ }
+ } else if (positionalValues[name]) {
+ this.needsMeasurement = true;
+ }
+ }
+ resolveNoneKeyframes() {
+ const { unresolvedKeyframes, name } = this;
+ const noneKeyframeIndexes = [];
+ for (let i = 0; i < unresolvedKeyframes.length; i++) {
+ if (unresolvedKeyframes[i] === null || isNone(unresolvedKeyframes[i])) {
+ noneKeyframeIndexes.push(i);
+ }
+ }
+ if (noneKeyframeIndexes.length) {
+ makeNoneKeyframesAnimatable(unresolvedKeyframes, noneKeyframeIndexes, name);
+ }
+ }
+ measureInitialState() {
+ const { element, unresolvedKeyframes, name } = this;
+ if (!element || !element.current)
+ return;
+ if (name === "height") {
+ this.suspendedScrollY = window.pageYOffset;
+ }
+ this.measuredOrigin = positionalValues[name](element.measureViewportBox(), window.getComputedStyle(element.current));
+ unresolvedKeyframes[0] = this.measuredOrigin;
+ const measureKeyframe = unresolvedKeyframes[unresolvedKeyframes.length - 1];
+ if (measureKeyframe !== void 0) {
+ element.getValue(name, measureKeyframe).jump(measureKeyframe, false);
+ }
+ }
+ measureEndState() {
+ const { element, name, unresolvedKeyframes } = this;
+ if (!element || !element.current)
+ return;
+ const value = element.getValue(name);
+ value && value.jump(this.measuredOrigin, false);
+ const finalKeyframeIndex = unresolvedKeyframes.length - 1;
+ const finalKeyframe = unresolvedKeyframes[finalKeyframeIndex];
+ unresolvedKeyframes[finalKeyframeIndex] = positionalValues[name](element.measureViewportBox(), window.getComputedStyle(element.current));
+ if (finalKeyframe !== null && this.finalKeyframe === void 0) {
+ this.finalKeyframe = finalKeyframe;
+ }
+ if (this.removedTransforms?.length) {
+ this.removedTransforms.forEach(([unsetTransformName, unsetTransformValue]) => {
+ element.getValue(unsetTransformName).set(unsetTransformValue);
+ });
+ }
+ this.resolveNoneKeyframes();
+ }
+}
+function resolveElements(elementOrSelector, scope, selectorCache) {
+ if (elementOrSelector == null) {
+ return [];
+ }
+ if (elementOrSelector instanceof EventTarget) {
+ return [elementOrSelector];
+ } else if (typeof elementOrSelector === "string") {
+ let root = document;
+ const elements = selectorCache?.[elementOrSelector] ?? root.querySelectorAll(elementOrSelector);
+ return elements ? Array.from(elements) : [];
+ }
+ return Array.from(elementOrSelector).filter((element) => element != null);
+}
+const getValueAsType = (value, type) => {
+ return type && typeof value === "number" ? type.transform(value) : value;
+};
+function isHTMLElement(element) {
+ return isObject(element) && "offsetHeight" in element && !("ownerSVGElement" in element);
+}
+const { schedule: microtask } = /* @__PURE__ */ createRenderBatcher(queueMicrotask, false);
+const isDragging = {
+ x: false,
+ y: false
+};
+function isDragActive() {
+ return isDragging.x || isDragging.y;
+}
+function setDragLock(axis) {
+ if (axis === "x" || axis === "y") {
+ if (isDragging[axis]) {
+ return null;
+ } else {
+ isDragging[axis] = true;
+ return () => {
+ isDragging[axis] = false;
+ };
+ }
+ } else {
+ if (isDragging.x || isDragging.y) {
+ return null;
+ } else {
+ isDragging.x = isDragging.y = true;
+ return () => {
+ isDragging.x = isDragging.y = false;
+ };
+ }
+ }
+}
+function setupGesture(elementOrSelector, options) {
+ const elements = resolveElements(elementOrSelector);
+ const gestureAbortController = new AbortController();
+ const eventOptions = {
+ passive: true,
+ ...options,
+ signal: gestureAbortController.signal
+ };
+ const cancel = () => gestureAbortController.abort();
+ return [elements, eventOptions, cancel];
+}
+function isValidHover(event) {
+ return !(event.pointerType === "touch" || isDragActive());
+}
+function hover(elementOrSelector, onHoverStart, options = {}) {
+ const [elements, eventOptions, cancel] = setupGesture(elementOrSelector, options);
+ elements.forEach((element) => {
+ let isPressed = false;
+ let deferredHoverEnd = false;
+ let hoverEndCallback;
+ const removePointerLeave = () => {
+ element.removeEventListener("pointerleave", onPointerLeave);
+ };
+ const endHover = (event) => {
+ if (hoverEndCallback) {
+ hoverEndCallback(event);
+ hoverEndCallback = void 0;
+ }
+ removePointerLeave();
+ };
+ const onPointerUp = (event) => {
+ isPressed = false;
+ window.removeEventListener("pointerup", onPointerUp);
+ window.removeEventListener("pointercancel", onPointerUp);
+ if (deferredHoverEnd) {
+ deferredHoverEnd = false;
+ endHover(event);
+ }
+ };
+ const onPointerDown = () => {
+ isPressed = true;
+ window.addEventListener("pointerup", onPointerUp, eventOptions);
+ window.addEventListener("pointercancel", onPointerUp, eventOptions);
+ };
+ const onPointerLeave = (leaveEvent) => {
+ if (leaveEvent.pointerType === "touch")
+ return;
+ if (isPressed) {
+ deferredHoverEnd = true;
+ return;
+ }
+ endHover(leaveEvent);
+ };
+ const onPointerEnter = (enterEvent) => {
+ if (!isValidHover(enterEvent))
+ return;
+ deferredHoverEnd = false;
+ const onHoverEnd = onHoverStart(element, enterEvent);
+ if (typeof onHoverEnd !== "function")
+ return;
+ hoverEndCallback = onHoverEnd;
+ element.addEventListener("pointerleave", onPointerLeave, eventOptions);
+ };
+ element.addEventListener("pointerenter", onPointerEnter, eventOptions);
+ element.addEventListener("pointerdown", onPointerDown, eventOptions);
+ });
+ return cancel;
+}
+const isNodeOrChild = (parent, child) => {
+ if (!child) {
+ return false;
+ } else if (parent === child) {
+ return true;
+ } else {
+ return isNodeOrChild(parent, child.parentElement);
+ }
+};
+const isPrimaryPointer = (event) => {
+ if (event.pointerType === "mouse") {
+ return typeof event.button !== "number" || event.button <= 0;
+ } else {
+ return event.isPrimary !== false;
+ }
+};
+const keyboardAccessibleElements = /* @__PURE__ */ new Set([
+ "BUTTON",
+ "INPUT",
+ "SELECT",
+ "TEXTAREA",
+ "A"
+]);
+function isElementKeyboardAccessible(element) {
+ return keyboardAccessibleElements.has(element.tagName) || element.isContentEditable === true;
+}
+const textInputElements = /* @__PURE__ */ new Set(["INPUT", "SELECT", "TEXTAREA"]);
+function isElementTextInput(element) {
+ return textInputElements.has(element.tagName) || element.isContentEditable === true;
+}
+const isPressing = /* @__PURE__ */ new WeakSet();
+function filterEvents(callback) {
+ return (event) => {
+ if (event.key !== "Enter")
+ return;
+ callback(event);
+ };
+}
+function firePointerEvent(target, type) {
+ target.dispatchEvent(new PointerEvent("pointer" + type, { isPrimary: true, bubbles: true }));
+}
+const enableKeyboardPress = (focusEvent, eventOptions) => {
+ const element = focusEvent.currentTarget;
+ if (!element)
+ return;
+ const handleKeydown = filterEvents(() => {
+ if (isPressing.has(element))
+ return;
+ firePointerEvent(element, "down");
+ const handleKeyup = filterEvents(() => {
+ firePointerEvent(element, "up");
+ });
+ const handleBlur = () => firePointerEvent(element, "cancel");
+ element.addEventListener("keyup", handleKeyup, eventOptions);
+ element.addEventListener("blur", handleBlur, eventOptions);
+ });
+ element.addEventListener("keydown", handleKeydown, eventOptions);
+ element.addEventListener("blur", () => element.removeEventListener("keydown", handleKeydown), eventOptions);
+};
+function isValidPressEvent(event) {
+ return isPrimaryPointer(event) && !isDragActive();
+}
+const claimedPointerDownEvents = /* @__PURE__ */ new WeakSet();
+function press(targetOrSelector, onPressStart, options = {}) {
+ const [targets, eventOptions, cancelEvents] = setupGesture(targetOrSelector, options);
+ const startPress = (startEvent) => {
+ const target = startEvent.currentTarget;
+ if (!isValidPressEvent(startEvent))
+ return;
+ if (claimedPointerDownEvents.has(startEvent))
+ return;
+ isPressing.add(target);
+ if (options.stopPropagation) {
+ claimedPointerDownEvents.add(startEvent);
+ }
+ const onPressEnd = onPressStart(target, startEvent);
+ const onPointerEnd = (endEvent, success) => {
+ window.removeEventListener("pointerup", onPointerUp);
+ window.removeEventListener("pointercancel", onPointerCancel);
+ if (isPressing.has(target)) {
+ isPressing.delete(target);
+ }
+ if (!isValidPressEvent(endEvent)) {
+ return;
+ }
+ if (typeof onPressEnd === "function") {
+ onPressEnd(endEvent, { success });
+ }
+ };
+ const onPointerUp = (upEvent) => {
+ onPointerEnd(upEvent, target === window || target === document || options.useGlobalTarget || isNodeOrChild(target, upEvent.target));
+ };
+ const onPointerCancel = (cancelEvent) => {
+ onPointerEnd(cancelEvent, false);
+ };
+ window.addEventListener("pointerup", onPointerUp, eventOptions);
+ window.addEventListener("pointercancel", onPointerCancel, eventOptions);
+ };
+ targets.forEach((target) => {
+ const pointerDownTarget = options.useGlobalTarget ? window : target;
+ pointerDownTarget.addEventListener("pointerdown", startPress, eventOptions);
+ if (isHTMLElement(target)) {
+ target.addEventListener("focus", (event) => enableKeyboardPress(event, eventOptions));
+ if (!isElementKeyboardAccessible(target) && !target.hasAttribute("tabindex")) {
+ target.tabIndex = 0;
+ }
+ }
+ });
+ return cancelEvents;
+}
+function isSVGElement(element) {
+ return isObject(element) && "ownerSVGElement" in element;
+}
+const resizeHandlers = /* @__PURE__ */ new WeakMap();
+let observer;
+const getSize = (borderBoxAxis, svgAxis, htmlAxis) => (target, borderBoxSize) => {
+ if (borderBoxSize && borderBoxSize[0]) {
+ return borderBoxSize[0][borderBoxAxis + "Size"];
+ } else if (isSVGElement(target) && "getBBox" in target) {
+ return target.getBBox()[svgAxis];
+ } else {
+ return target[htmlAxis];
+ }
+};
+const getWidth = /* @__PURE__ */ getSize("inline", "width", "offsetWidth");
+const getHeight = /* @__PURE__ */ getSize("block", "height", "offsetHeight");
+function notifyTarget({ target, borderBoxSize }) {
+ resizeHandlers.get(target)?.forEach((handler) => {
+ handler(target, {
+ get width() {
+ return getWidth(target, borderBoxSize);
+ },
+ get height() {
+ return getHeight(target, borderBoxSize);
+ }
+ });
+ });
+}
+function notifyAll(entries) {
+ entries.forEach(notifyTarget);
+}
+function createResizeObserver() {
+ if (typeof ResizeObserver === "undefined")
+ return;
+ observer = new ResizeObserver(notifyAll);
+}
+function resizeElement(target, handler) {
+ if (!observer)
+ createResizeObserver();
+ const elements = resolveElements(target);
+ elements.forEach((element) => {
+ let elementHandlers = resizeHandlers.get(element);
+ if (!elementHandlers) {
+ elementHandlers = /* @__PURE__ */ new Set();
+ resizeHandlers.set(element, elementHandlers);
+ }
+ elementHandlers.add(handler);
+ observer?.observe(element);
+ });
+ return () => {
+ elements.forEach((element) => {
+ const elementHandlers = resizeHandlers.get(element);
+ elementHandlers?.delete(handler);
+ if (!elementHandlers?.size) {
+ observer?.unobserve(element);
+ }
+ });
+ };
+}
+const windowCallbacks = /* @__PURE__ */ new Set();
+let windowResizeHandler;
+function createWindowResizeHandler() {
+ windowResizeHandler = () => {
+ const info = {
+ get width() {
+ return window.innerWidth;
+ },
+ get height() {
+ return window.innerHeight;
+ }
+ };
+ windowCallbacks.forEach((callback) => callback(info));
+ };
+ window.addEventListener("resize", windowResizeHandler);
+}
+function resizeWindow(callback) {
+ windowCallbacks.add(callback);
+ if (!windowResizeHandler)
+ createWindowResizeHandler();
+ return () => {
+ windowCallbacks.delete(callback);
+ if (!windowCallbacks.size && typeof windowResizeHandler === "function") {
+ window.removeEventListener("resize", windowResizeHandler);
+ windowResizeHandler = void 0;
+ }
+ };
+}
+function resize(a, b) {
+ return typeof a === "function" ? resizeWindow(a) : resizeElement(a, b);
+}
+function isSVGSVGElement(element) {
+ return isSVGElement(element) && element.tagName === "svg";
+}
+const valueTypes = [...dimensionValueTypes, color, complex];
+const findValueType = (v) => valueTypes.find(testValueType(v));
+const createAxisDelta = () => ({
+ translate: 0,
+ scale: 1,
+ origin: 0,
+ originPoint: 0
+});
+const createDelta = () => ({
+ x: createAxisDelta(),
+ y: createAxisDelta()
+});
+const createAxis = () => ({ min: 0, max: 0 });
+const createBox = () => ({
+ x: createAxis(),
+ y: createAxis()
+});
+const visualElementStore = /* @__PURE__ */ new WeakMap();
+function isAnimationControls(v) {
+ return v !== null && typeof v === "object" && typeof v.start === "function";
+}
+function isVariantLabel(v) {
+ return typeof v === "string" || Array.isArray(v);
+}
+const variantPriorityOrder = [
+ "animate",
+ "whileInView",
+ "whileFocus",
+ "whileHover",
+ "whileTap",
+ "whileDrag",
+ "exit"
+];
+const variantProps = ["initial", ...variantPriorityOrder];
+function isControllingVariants(props) {
+ return isAnimationControls(props.animate) || variantProps.some((name) => isVariantLabel(props[name]));
+}
+function isVariantNode(props) {
+ return Boolean(isControllingVariants(props) || props.variants);
+}
+function updateMotionValuesFromProps(element, next, prev) {
+ for (const key in next) {
+ const nextValue = next[key];
+ const prevValue = prev[key];
+ if (isMotionValue(nextValue)) {
+ element.addValue(key, nextValue);
+ } else if (isMotionValue(prevValue)) {
+ element.addValue(key, motionValue(nextValue, { owner: element }));
+ } else if (prevValue !== nextValue) {
+ if (element.hasValue(key)) {
+ const existingValue = element.getValue(key);
+ if (existingValue.liveStyle === true) {
+ existingValue.jump(nextValue);
+ } else if (!existingValue.hasAnimated) {
+ existingValue.set(nextValue);
+ }
+ } else {
+ const latestValue = element.getStaticValue(key);
+ element.addValue(key, motionValue(latestValue !== void 0 ? latestValue : nextValue, { owner: element }));
+ }
+ }
+ }
+ for (const key in prev) {
+ if (next[key] === void 0)
+ element.removeValue(key);
+ }
+ return next;
+}
+const prefersReducedMotion = { current: null };
+const hasReducedMotionListener = { current: false };
+const isBrowser = typeof window !== "undefined";
+function initPrefersReducedMotion() {
+ hasReducedMotionListener.current = true;
+ if (!isBrowser)
+ return;
+ if (window.matchMedia) {
+ const motionMediaQuery = window.matchMedia("(prefers-reduced-motion)");
+ const setReducedMotionPreferences = () => prefersReducedMotion.current = motionMediaQuery.matches;
+ motionMediaQuery.addEventListener("change", setReducedMotionPreferences);
+ setReducedMotionPreferences();
+ } else {
+ prefersReducedMotion.current = false;
+ }
+}
+const propEventHandlers = [
+ "AnimationStart",
+ "AnimationComplete",
+ "Update",
+ "BeforeLayoutMeasure",
+ "LayoutMeasure",
+ "LayoutAnimationStart",
+ "LayoutAnimationComplete"
+];
+let featureDefinitions = {};
+function setFeatureDefinitions(definitions) {
+ featureDefinitions = definitions;
+}
+function getFeatureDefinitions() {
+ return featureDefinitions;
+}
+class VisualElement {
+ /**
+ * This method takes React props and returns found MotionValues. For example, HTML
+ * MotionValues will be found within the style prop, whereas for Three.js within attribute arrays.
+ *
+ * This isn't an abstract method as it needs calling in the constructor, but it is
+ * intended to be one.
+ */
+ scrapeMotionValuesFromProps(_props, _prevProps, _visualElement) {
+ return {};
+ }
+ constructor({ parent, props, presenceContext, reducedMotionConfig, skipAnimations, blockInitialAnimation, visualState }, options = {}) {
+ this.current = null;
+ this.children = /* @__PURE__ */ new Set();
+ this.isVariantNode = false;
+ this.isControllingVariants = false;
+ this.shouldReduceMotion = null;
+ this.shouldSkipAnimations = false;
+ this.values = /* @__PURE__ */ new Map();
+ this.KeyframeResolver = KeyframeResolver;
+ this.features = {};
+ this.valueSubscriptions = /* @__PURE__ */ new Map();
+ this.prevMotionValues = {};
+ this.hasBeenMounted = false;
+ this.events = {};
+ this.propEventSubscriptions = {};
+ this.notifyUpdate = () => this.notify("Update", this.latestValues);
+ this.render = () => {
+ if (!this.current)
+ return;
+ this.triggerBuild();
+ this.renderInstance(this.current, this.renderState, this.props.style, this.projection);
+ };
+ this.renderScheduledAt = 0;
+ this.scheduleRender = () => {
+ const now2 = time.now();
+ if (this.renderScheduledAt < now2) {
+ this.renderScheduledAt = now2;
+ frame.render(this.render, false, true);
+ }
+ };
+ const { latestValues, renderState } = visualState;
+ this.latestValues = latestValues;
+ this.baseTarget = { ...latestValues };
+ this.initialValues = props.initial ? { ...latestValues } : {};
+ this.renderState = renderState;
+ this.parent = parent;
+ this.props = props;
+ this.presenceContext = presenceContext;
+ this.depth = parent ? parent.depth + 1 : 0;
+ this.reducedMotionConfig = reducedMotionConfig;
+ this.skipAnimationsConfig = skipAnimations;
+ this.options = options;
+ this.blockInitialAnimation = Boolean(blockInitialAnimation);
+ this.isControllingVariants = isControllingVariants(props);
+ this.isVariantNode = isVariantNode(props);
+ if (this.isVariantNode) {
+ this.variantChildren = /* @__PURE__ */ new Set();
+ }
+ this.manuallyAnimateOnMount = Boolean(parent && parent.current);
+ const { willChange, ...initialMotionValues } = this.scrapeMotionValuesFromProps(props, {}, this);
+ for (const key in initialMotionValues) {
+ const value = initialMotionValues[key];
+ if (latestValues[key] !== void 0 && isMotionValue(value)) {
+ value.set(latestValues[key]);
+ }
+ }
+ }
+ mount(instance) {
+ if (this.hasBeenMounted) {
+ for (const key in this.initialValues) {
+ this.values.get(key)?.jump(this.initialValues[key]);
+ this.latestValues[key] = this.initialValues[key];
+ }
+ }
+ this.current = instance;
+ visualElementStore.set(instance, this);
+ if (this.projection && !this.projection.instance) {
+ this.projection.mount(instance);
+ }
+ if (this.parent && this.isVariantNode && !this.isControllingVariants) {
+ this.removeFromVariantTree = this.parent.addVariantChild(this);
+ }
+ this.values.forEach((value, key) => this.bindToMotionValue(key, value));
+ if (this.reducedMotionConfig === "never") {
+ this.shouldReduceMotion = false;
+ } else if (this.reducedMotionConfig === "always") {
+ this.shouldReduceMotion = true;
+ } else {
+ if (!hasReducedMotionListener.current) {
+ initPrefersReducedMotion();
+ }
+ this.shouldReduceMotion = prefersReducedMotion.current;
+ }
+ if (process.env.NODE_ENV !== "production") {
+ warnOnce(this.shouldReduceMotion !== true, "You have Reduced Motion enabled on your device. Animations may not appear as expected.", "reduced-motion-disabled");
+ }
+ this.shouldSkipAnimations = this.skipAnimationsConfig ?? false;
+ this.parent?.addChild(this);
+ this.update(this.props, this.presenceContext);
+ this.hasBeenMounted = true;
+ }
+ unmount() {
+ this.projection && this.projection.unmount();
+ cancelFrame(this.notifyUpdate);
+ cancelFrame(this.render);
+ this.valueSubscriptions.forEach((remove) => remove());
+ this.valueSubscriptions.clear();
+ this.removeFromVariantTree && this.removeFromVariantTree();
+ this.parent?.removeChild(this);
+ for (const key in this.events) {
+ this.events[key].clear();
+ }
+ for (const key in this.features) {
+ const feature = this.features[key];
+ if (feature) {
+ feature.unmount();
+ feature.isMounted = false;
+ }
+ }
+ this.current = null;
+ }
+ addChild(child) {
+ this.children.add(child);
+ this.enteringChildren ?? (this.enteringChildren = /* @__PURE__ */ new Set());
+ this.enteringChildren.add(child);
+ }
+ removeChild(child) {
+ this.children.delete(child);
+ this.enteringChildren && this.enteringChildren.delete(child);
+ }
+ bindToMotionValue(key, value) {
+ if (this.valueSubscriptions.has(key)) {
+ this.valueSubscriptions.get(key)();
+ }
+ if (value.accelerate && acceleratedValues.has(key) && this.current instanceof HTMLElement) {
+ const { factory, keyframes: keyframes2, times, ease: ease2, duration } = value.accelerate;
+ const animation = new NativeAnimation({
+ element: this.current,
+ name: key,
+ keyframes: keyframes2,
+ times,
+ ease: ease2,
+ duration: /* @__PURE__ */ secondsToMilliseconds(duration)
+ });
+ const cleanup = factory(animation);
+ this.valueSubscriptions.set(key, () => {
+ cleanup();
+ animation.cancel();
+ });
+ return;
+ }
+ const valueIsTransform = transformProps.has(key);
+ if (valueIsTransform && this.onBindTransform) {
+ this.onBindTransform();
+ }
+ const removeOnChange = value.on("change", (latestValue) => {
+ this.latestValues[key] = latestValue;
+ this.props.onUpdate && frame.preRender(this.notifyUpdate);
+ if (valueIsTransform && this.projection) {
+ this.projection.isTransformDirty = true;
+ }
+ this.scheduleRender();
+ });
+ let removeSyncCheck;
+ if (typeof window !== "undefined" && window.MotionCheckAppearSync) {
+ removeSyncCheck = window.MotionCheckAppearSync(this, key, value);
+ }
+ this.valueSubscriptions.set(key, () => {
+ removeOnChange();
+ if (removeSyncCheck)
+ removeSyncCheck();
+ if (value.owner)
+ value.stop();
+ });
+ }
+ sortNodePosition(other) {
+ if (!this.current || !this.sortInstanceNodePosition || this.type !== other.type) {
+ return 0;
+ }
+ return this.sortInstanceNodePosition(this.current, other.current);
+ }
+ updateFeatures() {
+ let key = "animation";
+ for (key in featureDefinitions) {
+ const featureDefinition = featureDefinitions[key];
+ if (!featureDefinition)
+ continue;
+ const { isEnabled, Feature: FeatureConstructor } = featureDefinition;
+ if (!this.features[key] && FeatureConstructor && isEnabled(this.props)) {
+ this.features[key] = new FeatureConstructor(this);
+ }
+ if (this.features[key]) {
+ const feature = this.features[key];
+ if (feature.isMounted) {
+ feature.update();
+ } else {
+ feature.mount();
+ feature.isMounted = true;
+ }
+ }
+ }
+ }
+ triggerBuild() {
+ this.build(this.renderState, this.latestValues, this.props);
+ }
+ /**
+ * Measure the current viewport box with or without transforms.
+ * Only measures axis-aligned boxes, rotate and skew must be manually
+ * removed with a re-render to work.
+ */
+ measureViewportBox() {
+ return this.current ? this.measureInstanceViewportBox(this.current, this.props) : createBox();
+ }
+ getStaticValue(key) {
+ return this.latestValues[key];
+ }
+ setStaticValue(key, value) {
+ this.latestValues[key] = value;
+ }
+ /**
+ * Update the provided props. Ensure any newly-added motion values are
+ * added to our map, old ones removed, and listeners updated.
+ */
+ update(props, presenceContext) {
+ if (props.transformTemplate || this.props.transformTemplate) {
+ this.scheduleRender();
+ }
+ this.prevProps = this.props;
+ this.props = props;
+ this.prevPresenceContext = this.presenceContext;
+ this.presenceContext = presenceContext;
+ for (let i = 0; i < propEventHandlers.length; i++) {
+ const key = propEventHandlers[i];
+ if (this.propEventSubscriptions[key]) {
+ this.propEventSubscriptions[key]();
+ delete this.propEventSubscriptions[key];
+ }
+ const listenerName = "on" + key;
+ const listener = props[listenerName];
+ if (listener) {
+ this.propEventSubscriptions[key] = this.on(key, listener);
+ }
+ }
+ this.prevMotionValues = updateMotionValuesFromProps(this, this.scrapeMotionValuesFromProps(props, this.prevProps || {}, this), this.prevMotionValues);
+ if (this.handleChildMotionValue) {
+ this.handleChildMotionValue();
+ }
+ }
+ getProps() {
+ return this.props;
+ }
+ /**
+ * Returns the variant definition with a given name.
+ */
+ getVariant(name) {
+ return this.props.variants ? this.props.variants[name] : void 0;
+ }
+ /**
+ * Returns the defined default transition on this component.
+ */
+ getDefaultTransition() {
+ return this.props.transition;
+ }
+ getTransformPagePoint() {
+ return this.props.transformPagePoint;
+ }
+ getClosestVariantNode() {
+ return this.isVariantNode ? this : this.parent ? this.parent.getClosestVariantNode() : void 0;
+ }
+ /**
+ * Add a child visual element to our set of children.
+ */
+ addVariantChild(child) {
+ const closestVariantNode = this.getClosestVariantNode();
+ if (closestVariantNode) {
+ closestVariantNode.variantChildren && closestVariantNode.variantChildren.add(child);
+ return () => closestVariantNode.variantChildren.delete(child);
+ }
+ }
+ /**
+ * Add a motion value and bind it to this visual element.
+ */
+ addValue(key, value) {
+ const existingValue = this.values.get(key);
+ if (value !== existingValue) {
+ if (existingValue)
+ this.removeValue(key);
+ this.bindToMotionValue(key, value);
+ this.values.set(key, value);
+ this.latestValues[key] = value.get();
+ }
+ }
+ /**
+ * Remove a motion value and unbind any active subscriptions.
+ */
+ removeValue(key) {
+ this.values.delete(key);
+ const unsubscribe = this.valueSubscriptions.get(key);
+ if (unsubscribe) {
+ unsubscribe();
+ this.valueSubscriptions.delete(key);
+ }
+ delete this.latestValues[key];
+ this.removeValueFromRenderState(key, this.renderState);
+ }
+ /**
+ * Check whether we have a motion value for this key
+ */
+ hasValue(key) {
+ return this.values.has(key);
+ }
+ getValue(key, defaultValue) {
+ if (this.props.values && this.props.values[key]) {
+ return this.props.values[key];
+ }
+ let value = this.values.get(key);
+ if (value === void 0 && defaultValue !== void 0) {
+ value = motionValue(defaultValue === null ? void 0 : defaultValue, { owner: this });
+ this.addValue(key, value);
+ }
+ return value;
+ }
+ /**
+ * If we're trying to animate to a previously unencountered value,
+ * we need to check for it in our state and as a last resort read it
+ * directly from the instance (which might have performance implications).
+ */
+ readValue(key, target) {
+ let value = this.latestValues[key] !== void 0 || !this.current ? this.latestValues[key] : this.getBaseTargetFromProps(this.props, key) ?? this.readValueFromInstance(this.current, key, this.options);
+ if (value !== void 0 && value !== null) {
+ if (typeof value === "string" && (isNumericalString(value) || isZeroValueString(value))) {
+ value = parseFloat(value);
+ } else if (!findValueType(value) && complex.test(target)) {
+ value = getAnimatableNone(key, target);
+ }
+ this.setBaseTarget(key, isMotionValue(value) ? value.get() : value);
+ }
+ return isMotionValue(value) ? value.get() : value;
+ }
+ /**
+ * Set the base target to later animate back to. This is currently
+ * only hydrated on creation and when we first read a value.
+ */
+ setBaseTarget(key, value) {
+ this.baseTarget[key] = value;
+ }
+ /**
+ * Find the base target for a value thats been removed from all animation
+ * props.
+ */
+ getBaseTarget(key) {
+ const { initial } = this.props;
+ let valueFromInitial;
+ if (typeof initial === "string" || typeof initial === "object") {
+ const variant = resolveVariantFromProps(this.props, initial, this.presenceContext?.custom);
+ if (variant) {
+ valueFromInitial = variant[key];
+ }
+ }
+ if (initial && valueFromInitial !== void 0) {
+ return valueFromInitial;
+ }
+ const target = this.getBaseTargetFromProps(this.props, key);
+ if (target !== void 0 && !isMotionValue(target))
+ return target;
+ return this.initialValues[key] !== void 0 && valueFromInitial === void 0 ? void 0 : this.baseTarget[key];
+ }
+ on(eventName, callback) {
+ if (!this.events[eventName]) {
+ this.events[eventName] = new SubscriptionManager();
+ }
+ return this.events[eventName].add(callback);
+ }
+ notify(eventName, ...args) {
+ if (this.events[eventName]) {
+ this.events[eventName].notify(...args);
+ }
+ }
+ scheduleRenderMicrotask() {
+ microtask.render(this.render);
+ }
+}
+class DOMVisualElement extends VisualElement {
+ constructor() {
+ super(...arguments);
+ this.KeyframeResolver = DOMKeyframesResolver;
+ }
+ sortInstanceNodePosition(a, b) {
+ return a.compareDocumentPosition(b) & 2 ? 1 : -1;
+ }
+ getBaseTargetFromProps(props, key) {
+ const style = props.style;
+ return style ? style[key] : void 0;
+ }
+ removeValueFromRenderState(key, { vars, style }) {
+ delete vars[key];
+ delete style[key];
+ }
+ handleChildMotionValue() {
+ if (this.childSubscription) {
+ this.childSubscription();
+ delete this.childSubscription;
+ }
+ const { children } = this.props;
+ if (isMotionValue(children)) {
+ this.childSubscription = children.on("change", (latest) => {
+ if (this.current) {
+ this.current.textContent = `${latest}`;
+ }
+ });
+ }
+ }
+}
+class Feature {
+ constructor(node) {
+ this.isMounted = false;
+ this.node = node;
+ }
+ update() {
+ }
+}
+function convertBoundingBoxToBox({ top, left, right, bottom }) {
+ return {
+ x: { min: left, max: right },
+ y: { min: top, max: bottom }
+ };
+}
+function convertBoxToBoundingBox({ x, y }) {
+ return { top: y.min, right: x.max, bottom: y.max, left: x.min };
+}
+function transformBoxPoints(point, transformPoint2) {
+ if (!transformPoint2)
+ return point;
+ const topLeft = transformPoint2({ x: point.left, y: point.top });
+ const bottomRight = transformPoint2({ x: point.right, y: point.bottom });
+ return {
+ top: topLeft.y,
+ left: topLeft.x,
+ bottom: bottomRight.y,
+ right: bottomRight.x
+ };
+}
+function isIdentityScale(scale2) {
+ return scale2 === void 0 || scale2 === 1;
+}
+function hasScale({ scale: scale2, scaleX: scaleX2, scaleY: scaleY2 }) {
+ return !isIdentityScale(scale2) || !isIdentityScale(scaleX2) || !isIdentityScale(scaleY2);
+}
+function hasTransform(values) {
+ return hasScale(values) || has2DTranslate(values) || values.z || values.rotate || values.rotateX || values.rotateY || values.skewX || values.skewY;
+}
+function has2DTranslate(values) {
+ return is2DTranslate(values.x) || is2DTranslate(values.y);
+}
+function is2DTranslate(value) {
+ return value && value !== "0%";
+}
+function scalePoint(point, scale2, originPoint) {
+ const distanceFromOrigin = point - originPoint;
+ const scaled = scale2 * distanceFromOrigin;
+ return originPoint + scaled;
+}
+function applyPointDelta(point, translate, scale2, originPoint, boxScale) {
+ if (boxScale !== void 0) {
+ point = scalePoint(point, boxScale, originPoint);
+ }
+ return scalePoint(point, scale2, originPoint) + translate;
+}
+function applyAxisDelta(axis, translate = 0, scale2 = 1, originPoint, boxScale) {
+ axis.min = applyPointDelta(axis.min, translate, scale2, originPoint, boxScale);
+ axis.max = applyPointDelta(axis.max, translate, scale2, originPoint, boxScale);
+}
+function applyBoxDelta(box, { x, y }) {
+ applyAxisDelta(box.x, x.translate, x.scale, x.originPoint);
+ applyAxisDelta(box.y, y.translate, y.scale, y.originPoint);
+}
+const TREE_SCALE_SNAP_MIN = 0.999999999999;
+const TREE_SCALE_SNAP_MAX = 1.0000000000001;
+function applyTreeDeltas(box, treeScale, treePath, isSharedTransition = false) {
+ const treeLength = treePath.length;
+ if (!treeLength)
+ return;
+ treeScale.x = treeScale.y = 1;
+ let node;
+ let delta;
+ for (let i = 0; i < treeLength; i++) {
+ node = treePath[i];
+ delta = node.projectionDelta;
+ const { visualElement } = node.options;
+ if (visualElement && visualElement.props.style && visualElement.props.style.display === "contents") {
+ continue;
+ }
+ if (isSharedTransition && node.options.layoutScroll && node.scroll && node !== node.root) {
+ translateAxis(box.x, -node.scroll.offset.x);
+ translateAxis(box.y, -node.scroll.offset.y);
+ }
+ if (delta) {
+ treeScale.x *= delta.x.scale;
+ treeScale.y *= delta.y.scale;
+ applyBoxDelta(box, delta);
+ }
+ if (isSharedTransition && hasTransform(node.latestValues)) {
+ transformBox(box, node.latestValues, node.layout?.layoutBox);
+ }
+ }
+ if (treeScale.x < TREE_SCALE_SNAP_MAX && treeScale.x > TREE_SCALE_SNAP_MIN) {
+ treeScale.x = 1;
+ }
+ if (treeScale.y < TREE_SCALE_SNAP_MAX && treeScale.y > TREE_SCALE_SNAP_MIN) {
+ treeScale.y = 1;
+ }
+}
+function translateAxis(axis, distance2) {
+ axis.min += distance2;
+ axis.max += distance2;
+}
+function transformAxis(axis, axisTranslate, axisScale, boxScale, axisOrigin = 0.5) {
+ const originPoint = mixNumber$1(axis.min, axis.max, axisOrigin);
+ applyAxisDelta(axis, axisTranslate, axisScale, originPoint, boxScale);
+}
+function resolveAxisTranslate(value, axis) {
+ if (typeof value === "string") {
+ return parseFloat(value) / 100 * (axis.max - axis.min);
+ }
+ return value;
+}
+function transformBox(box, transform, sourceBox) {
+ const resolveBox = sourceBox ?? box;
+ transformAxis(box.x, resolveAxisTranslate(transform.x, resolveBox.x), transform.scaleX, transform.scale, transform.originX);
+ transformAxis(box.y, resolveAxisTranslate(transform.y, resolveBox.y), transform.scaleY, transform.scale, transform.originY);
+}
+function measureViewportBox(instance, transformPoint2) {
+ return convertBoundingBoxToBox(transformBoxPoints(instance.getBoundingClientRect(), transformPoint2));
+}
+function measurePageBox(element, rootProjectionNode2, transformPagePoint) {
+ const viewportBox = measureViewportBox(element, transformPagePoint);
+ const { scroll } = rootProjectionNode2;
+ if (scroll) {
+ translateAxis(viewportBox.x, scroll.offset.x);
+ translateAxis(viewportBox.y, scroll.offset.y);
+ }
+ return viewportBox;
+}
+const translateAlias = {
+ x: "translateX",
+ y: "translateY",
+ z: "translateZ",
+ transformPerspective: "perspective"
+};
+const numTransforms = transformPropOrder.length;
+function buildTransform(latestValues, transform, transformTemplate) {
+ let transformString = "";
+ let transformIsDefault = true;
+ for (let i = 0; i < numTransforms; i++) {
+ const key = transformPropOrder[i];
+ const value = latestValues[key];
+ if (value === void 0)
+ continue;
+ let valueIsDefault = true;
+ if (typeof value === "number") {
+ valueIsDefault = value === (key.startsWith("scale") ? 1 : 0);
+ } else {
+ const parsed = parseFloat(value);
+ valueIsDefault = key.startsWith("scale") ? parsed === 1 : parsed === 0;
+ }
+ if (!valueIsDefault || transformTemplate) {
+ const valueAsType = getValueAsType(value, numberValueTypes[key]);
+ if (!valueIsDefault) {
+ transformIsDefault = false;
+ const transformName = translateAlias[key] || key;
+ transformString += `${transformName}(${valueAsType}) `;
+ }
+ if (transformTemplate) {
+ transform[key] = valueAsType;
+ }
+ }
+ }
+ transformString = transformString.trim();
+ if (transformTemplate) {
+ transformString = transformTemplate(transform, transformIsDefault ? "" : transformString);
+ } else if (transformIsDefault) {
+ transformString = "none";
+ }
+ return transformString;
+}
+function buildHTMLStyles(state, latestValues, transformTemplate) {
+ const { style, vars, transformOrigin } = state;
+ let hasTransform2 = false;
+ let hasTransformOrigin = false;
+ for (const key in latestValues) {
+ const value = latestValues[key];
+ if (transformProps.has(key)) {
+ hasTransform2 = true;
+ continue;
+ } else if (isCSSVariableName(key)) {
+ vars[key] = value;
+ continue;
+ } else {
+ const valueAsType = getValueAsType(value, numberValueTypes[key]);
+ if (key.startsWith("origin")) {
+ hasTransformOrigin = true;
+ transformOrigin[key] = valueAsType;
+ } else {
+ style[key] = valueAsType;
+ }
+ }
+ }
+ if (!latestValues.transform) {
+ if (hasTransform2 || transformTemplate) {
+ style.transform = buildTransform(latestValues, state.transform, transformTemplate);
+ } else if (style.transform) {
+ style.transform = "none";
+ }
+ }
+ if (hasTransformOrigin) {
+ const { originX = "50%", originY = "50%", originZ = 0 } = transformOrigin;
+ style.transformOrigin = `${originX} ${originY} ${originZ}`;
+ }
+}
+function renderHTML(element, { style, vars }, styleProp, projection) {
+ const elementStyle = element.style;
+ let key;
+ for (key in style) {
+ elementStyle[key] = style[key];
+ }
+ projection?.applyProjectionStyles(elementStyle, styleProp);
+ for (key in vars) {
+ elementStyle.setProperty(key, vars[key]);
+ }
+}
+function pixelsToPercent(pixels, axis) {
+ if (axis.max === axis.min)
+ return 0;
+ return pixels / (axis.max - axis.min) * 100;
+}
+const correctBorderRadius = {
+ correct: (latest, node) => {
+ if (!node.target)
+ return latest;
+ if (typeof latest === "string") {
+ if (px.test(latest)) {
+ latest = parseFloat(latest);
+ } else {
+ return latest;
+ }
+ }
+ const x = pixelsToPercent(latest, node.target.x);
+ const y = pixelsToPercent(latest, node.target.y);
+ return `${x}% ${y}%`;
+ }
+};
+const correctBoxShadow = {
+ correct: (latest, { treeScale, projectionDelta }) => {
+ const original = latest;
+ const shadow = complex.parse(latest);
+ if (shadow.length > 5)
+ return original;
+ const template = complex.createTransformer(latest);
+ const offset = typeof shadow[0] !== "number" ? 1 : 0;
+ const xScale = projectionDelta.x.scale * treeScale.x;
+ const yScale = projectionDelta.y.scale * treeScale.y;
+ shadow[0 + offset] /= xScale;
+ shadow[1 + offset] /= yScale;
+ const averageScale = mixNumber$1(xScale, yScale, 0.5);
+ if (typeof shadow[2 + offset] === "number")
+ shadow[2 + offset] /= averageScale;
+ if (typeof shadow[3 + offset] === "number")
+ shadow[3 + offset] /= averageScale;
+ return template(shadow);
+ }
+};
+const scaleCorrectors = {
+ borderRadius: {
+ ...correctBorderRadius,
+ applyTo: [
+ "borderTopLeftRadius",
+ "borderTopRightRadius",
+ "borderBottomLeftRadius",
+ "borderBottomRightRadius"
+ ]
+ },
+ borderTopLeftRadius: correctBorderRadius,
+ borderTopRightRadius: correctBorderRadius,
+ borderBottomLeftRadius: correctBorderRadius,
+ borderBottomRightRadius: correctBorderRadius,
+ boxShadow: correctBoxShadow
+};
+function isForcedMotionValue(key, { layout: layout2, layoutId }) {
+ return transformProps.has(key) || key.startsWith("origin") || (layout2 || layoutId !== void 0) && (!!scaleCorrectors[key] || key === "opacity");
+}
+function scrapeMotionValuesFromProps$1(props, prevProps, visualElement) {
+ const style = props.style;
+ const prevStyle = prevProps?.style;
+ const newValues = {};
+ if (!style)
+ return newValues;
+ for (const key in style) {
+ if (isMotionValue(style[key]) || prevStyle && isMotionValue(prevStyle[key]) || isForcedMotionValue(key, props) || visualElement?.getValue(key)?.liveStyle !== void 0) {
+ newValues[key] = style[key];
+ }
+ }
+ return newValues;
+}
+function getComputedStyle$1(element) {
+ return window.getComputedStyle(element);
+}
+class HTMLVisualElement extends DOMVisualElement {
+ constructor() {
+ super(...arguments);
+ this.type = "html";
+ this.renderInstance = renderHTML;
+ }
+ readValueFromInstance(instance, key) {
+ if (transformProps.has(key)) {
+ return this.projection?.isProjecting ? defaultTransformValue(key) : readTransformValue(instance, key);
+ } else {
+ const computedStyle = getComputedStyle$1(instance);
+ const value = (isCSSVariableName(key) ? computedStyle.getPropertyValue(key) : computedStyle[key]) || 0;
+ return typeof value === "string" ? value.trim() : value;
+ }
+ }
+ measureInstanceViewportBox(instance, { transformPagePoint }) {
+ return measureViewportBox(instance, transformPagePoint);
+ }
+ build(renderState, latestValues, props) {
+ buildHTMLStyles(renderState, latestValues, props.transformTemplate);
+ }
+ scrapeMotionValuesFromProps(props, prevProps, visualElement) {
+ return scrapeMotionValuesFromProps$1(props, prevProps, visualElement);
+ }
+}
+const dashKeys = {
+ offset: "stroke-dashoffset",
+ array: "stroke-dasharray"
+};
+const camelKeys = {
+ offset: "strokeDashoffset",
+ array: "strokeDasharray"
+};
+function buildSVGPath(attrs, length, spacing = 1, offset = 0, useDashCase = true) {
+ attrs.pathLength = 1;
+ const keys = useDashCase ? dashKeys : camelKeys;
+ attrs[keys.offset] = `${-offset}`;
+ attrs[keys.array] = `${length} ${spacing}`;
+}
+const cssMotionPathProperties = [
+ "offsetDistance",
+ "offsetPath",
+ "offsetRotate",
+ "offsetAnchor"
+];
+function buildSVGAttrs(state, {
+ attrX,
+ attrY,
+ attrScale,
+ pathLength,
+ pathSpacing = 1,
+ pathOffset = 0,
+ // This is object creation, which we try to avoid per-frame.
+ ...latest
+}, isSVGTag2, transformTemplate, styleProp) {
+ buildHTMLStyles(state, latest, transformTemplate);
+ if (isSVGTag2) {
+ if (state.style.viewBox) {
+ state.attrs.viewBox = state.style.viewBox;
+ }
+ return;
+ }
+ state.attrs = state.style;
+ state.style = {};
+ const { attrs, style } = state;
+ if (attrs.transform) {
+ style.transform = attrs.transform;
+ delete attrs.transform;
+ }
+ if (style.transform || attrs.transformOrigin) {
+ style.transformOrigin = attrs.transformOrigin ?? "50% 50%";
+ delete attrs.transformOrigin;
+ }
+ if (style.transform) {
+ style.transformBox = styleProp?.transformBox ?? "fill-box";
+ delete attrs.transformBox;
+ }
+ for (const key of cssMotionPathProperties) {
+ if (attrs[key] !== void 0) {
+ style[key] = attrs[key];
+ delete attrs[key];
+ }
+ }
+ if (attrX !== void 0)
+ attrs.x = attrX;
+ if (attrY !== void 0)
+ attrs.y = attrY;
+ if (attrScale !== void 0)
+ attrs.scale = attrScale;
+ if (pathLength !== void 0) {
+ buildSVGPath(attrs, pathLength, pathSpacing, pathOffset, false);
+ }
+}
+const camelCaseAttributes = /* @__PURE__ */ new Set([
+ "baseFrequency",
+ "diffuseConstant",
+ "kernelMatrix",
+ "kernelUnitLength",
+ "keySplines",
+ "keyTimes",
+ "limitingConeAngle",
+ "markerHeight",
+ "markerWidth",
+ "numOctaves",
+ "targetX",
+ "targetY",
+ "surfaceScale",
+ "specularConstant",
+ "specularExponent",
+ "stdDeviation",
+ "tableValues",
+ "viewBox",
+ "gradientTransform",
+ "pathLength",
+ "startOffset",
+ "textLength",
+ "lengthAdjust"
+]);
+const isSVGTag = (tag) => typeof tag === "string" && tag.toLowerCase() === "svg";
+function renderSVG(element, renderState, _styleProp, projection) {
+ renderHTML(element, renderState, void 0, projection);
+ for (const key in renderState.attrs) {
+ element.setAttribute(!camelCaseAttributes.has(key) ? camelToDash(key) : key, renderState.attrs[key]);
+ }
+}
+function scrapeMotionValuesFromProps(props, prevProps, visualElement) {
+ const newValues = scrapeMotionValuesFromProps$1(props, prevProps, visualElement);
+ for (const key in props) {
+ if (isMotionValue(props[key]) || isMotionValue(prevProps[key])) {
+ const targetKey = transformPropOrder.indexOf(key) !== -1 ? "attr" + key.charAt(0).toUpperCase() + key.substring(1) : key;
+ newValues[targetKey] = props[key];
+ }
+ }
+ return newValues;
+}
+class SVGVisualElement extends DOMVisualElement {
+ constructor() {
+ super(...arguments);
+ this.type = "svg";
+ this.isSVGTag = false;
+ this.measureInstanceViewportBox = createBox;
+ }
+ getBaseTargetFromProps(props, key) {
+ return props[key];
+ }
+ readValueFromInstance(instance, key) {
+ if (transformProps.has(key)) {
+ const defaultType = getDefaultValueType(key);
+ return defaultType ? defaultType.default || 0 : 0;
+ }
+ key = !camelCaseAttributes.has(key) ? camelToDash(key) : key;
+ return instance.getAttribute(key);
+ }
+ scrapeMotionValuesFromProps(props, prevProps, visualElement) {
+ return scrapeMotionValuesFromProps(props, prevProps, visualElement);
+ }
+ build(renderState, latestValues, props) {
+ buildSVGAttrs(renderState, latestValues, this.isSVGTag, props.transformTemplate, props.style);
+ }
+ renderInstance(instance, renderState, styleProp, projection) {
+ renderSVG(instance, renderState, styleProp, projection);
+ }
+ mount(instance) {
+ this.isSVGTag = isSVGTag(instance.tagName);
+ super.mount(instance);
+ }
+}
+const numVariantProps = variantProps.length;
+function getVariantContext(visualElement) {
+ if (!visualElement)
+ return void 0;
+ if (!visualElement.isControllingVariants) {
+ const context2 = visualElement.parent ? getVariantContext(visualElement.parent) || {} : {};
+ if (visualElement.props.initial !== void 0) {
+ context2.initial = visualElement.props.initial;
+ }
+ return context2;
+ }
+ const context = {};
+ for (let i = 0; i < numVariantProps; i++) {
+ const name = variantProps[i];
+ const prop = visualElement.props[name];
+ if (isVariantLabel(prop) || prop === false) {
+ context[name] = prop;
+ }
+ }
+ return context;
+}
+function shallowCompare(next, prev) {
+ if (!Array.isArray(prev))
+ return false;
+ const prevLength = prev.length;
+ if (prevLength !== next.length)
+ return false;
+ for (let i = 0; i < prevLength; i++) {
+ if (prev[i] !== next[i])
+ return false;
+ }
+ return true;
+}
+const reversePriorityOrder = [...variantPriorityOrder].reverse();
+const numAnimationTypes = variantPriorityOrder.length;
+function createAnimateFunction(visualElement) {
+ return (animations2) => {
+ return Promise.all(animations2.map(({ animation, options }) => animateVisualElement(visualElement, animation, options)));
+ };
+}
+function createAnimationState(visualElement) {
+ let animate = createAnimateFunction(visualElement);
+ let state = createState();
+ let isInitialRender = true;
+ let wasReset = false;
+ const buildResolvedTypeValues = (type) => (acc, definition) => {
+ const resolved = resolveVariant(visualElement, definition, type === "exit" ? visualElement.presenceContext?.custom : void 0);
+ if (resolved) {
+ const { transition, transitionEnd, ...target } = resolved;
+ acc = { ...acc, ...target, ...transitionEnd };
+ }
+ return acc;
+ };
+ function setAnimateFunction(makeAnimator) {
+ animate = makeAnimator(visualElement);
+ }
+ function animateChanges(changedActiveType) {
+ const { props } = visualElement;
+ const context = getVariantContext(visualElement.parent) || {};
+ const animations2 = [];
+ const removedKeys = /* @__PURE__ */ new Set();
+ let encounteredKeys = {};
+ let removedVariantIndex = Infinity;
+ for (let i = 0; i < numAnimationTypes; i++) {
+ const type = reversePriorityOrder[i];
+ const typeState = state[type];
+ const prop = props[type] !== void 0 ? props[type] : context[type];
+ const propIsVariant = isVariantLabel(prop);
+ const activeDelta = type === changedActiveType ? typeState.isActive : null;
+ if (activeDelta === false)
+ removedVariantIndex = i;
+ let isInherited = prop === context[type] && prop !== props[type] && propIsVariant;
+ if (isInherited && (isInitialRender || wasReset) && visualElement.manuallyAnimateOnMount) {
+ isInherited = false;
+ }
+ typeState.protectedKeys = { ...encounteredKeys };
+ if (
+ // If it isn't active and hasn't *just* been set as inactive
+ !typeState.isActive && activeDelta === null || // If we didn't and don't have any defined prop for this animation type
+ !prop && !typeState.prevProp || // Or if the prop doesn't define an animation
+ isAnimationControls(prop) || typeof prop === "boolean"
+ ) {
+ continue;
+ }
+ if (type === "exit" && typeState.isActive && activeDelta !== true) {
+ if (typeState.prevResolvedValues) {
+ encounteredKeys = {
+ ...encounteredKeys,
+ ...typeState.prevResolvedValues
+ };
+ }
+ continue;
+ }
+ const variantDidChange = checkVariantsDidChange(typeState.prevProp, prop);
+ let shouldAnimateType = variantDidChange || // If we're making this variant active, we want to always make it active
+ type === changedActiveType && typeState.isActive && !isInherited && propIsVariant || // If we removed a higher-priority variant (i is in reverse order)
+ i > removedVariantIndex && propIsVariant;
+ let handledRemovedValues = false;
+ const definitionList = Array.isArray(prop) ? prop : [prop];
+ let resolvedValues = definitionList.reduce(buildResolvedTypeValues(type), {});
+ if (activeDelta === false)
+ resolvedValues = {};
+ const { prevResolvedValues = {} } = typeState;
+ const allKeys = {
+ ...prevResolvedValues,
+ ...resolvedValues
+ };
+ const markToAnimate = (key) => {
+ shouldAnimateType = true;
+ if (removedKeys.has(key)) {
+ handledRemovedValues = true;
+ removedKeys.delete(key);
+ }
+ typeState.needsAnimating[key] = true;
+ const motionValue2 = visualElement.getValue(key);
+ if (motionValue2)
+ motionValue2.liveStyle = false;
+ };
+ for (const key in allKeys) {
+ const next = resolvedValues[key];
+ const prev = prevResolvedValues[key];
+ if (encounteredKeys.hasOwnProperty(key))
+ continue;
+ let valueHasChanged = false;
+ if (isKeyframesTarget(next) && isKeyframesTarget(prev)) {
+ valueHasChanged = !shallowCompare(next, prev);
+ } else {
+ valueHasChanged = next !== prev;
+ }
+ if (valueHasChanged) {
+ if (next !== void 0 && next !== null) {
+ markToAnimate(key);
+ } else {
+ removedKeys.add(key);
+ }
+ } else if (next !== void 0 && removedKeys.has(key)) {
+ markToAnimate(key);
+ } else {
+ typeState.protectedKeys[key] = true;
+ }
+ }
+ typeState.prevProp = prop;
+ typeState.prevResolvedValues = resolvedValues;
+ if (typeState.isActive) {
+ encounteredKeys = { ...encounteredKeys, ...resolvedValues };
+ }
+ if ((isInitialRender || wasReset) && visualElement.blockInitialAnimation) {
+ shouldAnimateType = false;
+ }
+ const willAnimateViaParent = isInherited && variantDidChange;
+ const needsAnimating = !willAnimateViaParent || handledRemovedValues;
+ if (shouldAnimateType && needsAnimating) {
+ animations2.push(...definitionList.map((animation) => {
+ const options = { type };
+ if (typeof animation === "string" && (isInitialRender || wasReset) && !willAnimateViaParent && visualElement.manuallyAnimateOnMount && visualElement.parent) {
+ const { parent } = visualElement;
+ const parentVariant = resolveVariant(parent, animation);
+ if (parent.enteringChildren && parentVariant) {
+ const { delayChildren } = parentVariant.transition || {};
+ options.delay = calcChildStagger(parent.enteringChildren, visualElement, delayChildren);
+ }
+ }
+ return {
+ animation,
+ options
+ };
+ }));
+ }
+ }
+ if (removedKeys.size) {
+ const fallbackAnimation = {};
+ if (typeof props.initial !== "boolean") {
+ const initialTransition = resolveVariant(visualElement, Array.isArray(props.initial) ? props.initial[0] : props.initial);
+ if (initialTransition && initialTransition.transition) {
+ fallbackAnimation.transition = initialTransition.transition;
+ }
+ }
+ removedKeys.forEach((key) => {
+ const fallbackTarget = visualElement.getBaseTarget(key);
+ const motionValue2 = visualElement.getValue(key);
+ if (motionValue2)
+ motionValue2.liveStyle = true;
+ fallbackAnimation[key] = fallbackTarget ?? null;
+ });
+ animations2.push({ animation: fallbackAnimation });
+ }
+ let shouldAnimate = Boolean(animations2.length);
+ if (isInitialRender && (props.initial === false || props.initial === props.animate) && !visualElement.manuallyAnimateOnMount) {
+ shouldAnimate = false;
+ }
+ isInitialRender = false;
+ wasReset = false;
+ return shouldAnimate ? animate(animations2) : Promise.resolve();
+ }
+ function setActive(type, isActive) {
+ if (state[type].isActive === isActive)
+ return Promise.resolve();
+ visualElement.variantChildren?.forEach((child) => child.animationState?.setActive(type, isActive));
+ state[type].isActive = isActive;
+ const animations2 = animateChanges(type);
+ for (const key in state) {
+ state[key].protectedKeys = {};
+ }
+ return animations2;
+ }
+ return {
+ animateChanges,
+ setActive,
+ setAnimateFunction,
+ getState: () => state,
+ reset: () => {
+ state = createState();
+ wasReset = true;
+ }
+ };
+}
+function checkVariantsDidChange(prev, next) {
+ if (typeof next === "string") {
+ return next !== prev;
+ } else if (Array.isArray(next)) {
+ return !shallowCompare(next, prev);
+ }
+ return false;
+}
+function createTypeState(isActive = false) {
+ return {
+ isActive,
+ protectedKeys: {},
+ needsAnimating: {},
+ prevResolvedValues: {}
+ };
+}
+function createState() {
+ return {
+ animate: createTypeState(true),
+ whileInView: createTypeState(),
+ whileHover: createTypeState(),
+ whileTap: createTypeState(),
+ whileDrag: createTypeState(),
+ whileFocus: createTypeState(),
+ exit: createTypeState()
+ };
+}
+function copyAxisInto(axis, originAxis) {
+ axis.min = originAxis.min;
+ axis.max = originAxis.max;
+}
+function copyBoxInto(box, originBox) {
+ copyAxisInto(box.x, originBox.x);
+ copyAxisInto(box.y, originBox.y);
+}
+function copyAxisDeltaInto(delta, originDelta) {
+ delta.translate = originDelta.translate;
+ delta.scale = originDelta.scale;
+ delta.originPoint = originDelta.originPoint;
+ delta.origin = originDelta.origin;
+}
+const SCALE_PRECISION = 1e-4;
+const SCALE_MIN = 1 - SCALE_PRECISION;
+const SCALE_MAX = 1 + SCALE_PRECISION;
+const TRANSLATE_PRECISION = 0.01;
+const TRANSLATE_MIN = 0 - TRANSLATE_PRECISION;
+const TRANSLATE_MAX = 0 + TRANSLATE_PRECISION;
+function calcLength(axis) {
+ return axis.max - axis.min;
+}
+function isNear(value, target, maxDistance) {
+ return Math.abs(value - target) <= maxDistance;
+}
+function calcAxisDelta(delta, source, target, origin = 0.5) {
+ delta.origin = origin;
+ delta.originPoint = mixNumber$1(source.min, source.max, delta.origin);
+ delta.scale = calcLength(target) / calcLength(source);
+ delta.translate = mixNumber$1(target.min, target.max, delta.origin) - delta.originPoint;
+ if (delta.scale >= SCALE_MIN && delta.scale <= SCALE_MAX || isNaN(delta.scale)) {
+ delta.scale = 1;
+ }
+ if (delta.translate >= TRANSLATE_MIN && delta.translate <= TRANSLATE_MAX || isNaN(delta.translate)) {
+ delta.translate = 0;
+ }
+}
+function calcBoxDelta(delta, source, target, origin) {
+ calcAxisDelta(delta.x, source.x, target.x, origin ? origin.originX : void 0);
+ calcAxisDelta(delta.y, source.y, target.y, origin ? origin.originY : void 0);
+}
+function calcRelativeAxis(target, relative, parent, anchor = 0) {
+ const anchorPoint = anchor ? mixNumber$1(parent.min, parent.max, anchor) : parent.min;
+ target.min = anchorPoint + relative.min;
+ target.max = target.min + calcLength(relative);
+}
+function calcRelativeBox(target, relative, parent, anchor) {
+ calcRelativeAxis(target.x, relative.x, parent.x, anchor?.x);
+ calcRelativeAxis(target.y, relative.y, parent.y, anchor?.y);
+}
+function calcRelativeAxisPosition(target, layout2, parent, anchor = 0) {
+ const anchorPoint = anchor ? mixNumber$1(parent.min, parent.max, anchor) : parent.min;
+ target.min = layout2.min - anchorPoint;
+ target.max = target.min + calcLength(layout2);
+}
+function calcRelativePosition(target, layout2, parent, anchor) {
+ calcRelativeAxisPosition(target.x, layout2.x, parent.x, anchor?.x);
+ calcRelativeAxisPosition(target.y, layout2.y, parent.y, anchor?.y);
+}
+function removePointDelta(point, translate, scale2, originPoint, boxScale) {
+ point -= translate;
+ point = scalePoint(point, 1 / scale2, originPoint);
+ if (boxScale !== void 0) {
+ point = scalePoint(point, 1 / boxScale, originPoint);
+ }
+ return point;
+}
+function removeAxisDelta(axis, translate = 0, scale2 = 1, origin = 0.5, boxScale, originAxis = axis, sourceAxis = axis) {
+ if (percent.test(translate)) {
+ translate = parseFloat(translate);
+ const relativeProgress = mixNumber$1(sourceAxis.min, sourceAxis.max, translate / 100);
+ translate = relativeProgress - sourceAxis.min;
+ }
+ if (typeof translate !== "number")
+ return;
+ let originPoint = mixNumber$1(originAxis.min, originAxis.max, origin);
+ if (axis === originAxis)
+ originPoint -= translate;
+ axis.min = removePointDelta(axis.min, translate, scale2, originPoint, boxScale);
+ axis.max = removePointDelta(axis.max, translate, scale2, originPoint, boxScale);
+}
+function removeAxisTransforms(axis, transforms, [key, scaleKey, originKey], origin, sourceAxis) {
+ removeAxisDelta(axis, transforms[key], transforms[scaleKey], transforms[originKey], transforms.scale, origin, sourceAxis);
+}
+const xKeys = ["x", "scaleX", "originX"];
+const yKeys = ["y", "scaleY", "originY"];
+function removeBoxTransforms(box, transforms, originBox, sourceBox) {
+ removeAxisTransforms(box.x, transforms, xKeys, originBox ? originBox.x : void 0, sourceBox ? sourceBox.x : void 0);
+ removeAxisTransforms(box.y, transforms, yKeys, originBox ? originBox.y : void 0, sourceBox ? sourceBox.y : void 0);
+}
+function isAxisDeltaZero(delta) {
+ return delta.translate === 0 && delta.scale === 1;
+}
+function isDeltaZero(delta) {
+ return isAxisDeltaZero(delta.x) && isAxisDeltaZero(delta.y);
+}
+function axisEquals(a, b) {
+ return a.min === b.min && a.max === b.max;
+}
+function boxEquals(a, b) {
+ return axisEquals(a.x, b.x) && axisEquals(a.y, b.y);
+}
+function axisEqualsRounded(a, b) {
+ return Math.round(a.min) === Math.round(b.min) && Math.round(a.max) === Math.round(b.max);
+}
+function boxEqualsRounded(a, b) {
+ return axisEqualsRounded(a.x, b.x) && axisEqualsRounded(a.y, b.y);
+}
+function aspectRatio(box) {
+ return calcLength(box.x) / calcLength(box.y);
+}
+function axisDeltaEquals(a, b) {
+ return a.translate === b.translate && a.scale === b.scale && a.originPoint === b.originPoint;
+}
+function eachAxis(callback) {
+ return [callback("x"), callback("y")];
+}
+function buildProjectionTransform(delta, treeScale, latestTransform) {
+ let transform = "";
+ const xTranslate = delta.x.translate / treeScale.x;
+ const yTranslate = delta.y.translate / treeScale.y;
+ const zTranslate = latestTransform?.z || 0;
+ if (xTranslate || yTranslate || zTranslate) {
+ transform = `translate3d(${xTranslate}px, ${yTranslate}px, ${zTranslate}px) `;
+ }
+ if (treeScale.x !== 1 || treeScale.y !== 1) {
+ transform += `scale(${1 / treeScale.x}, ${1 / treeScale.y}) `;
+ }
+ if (latestTransform) {
+ const { transformPerspective, rotate: rotate2, rotateX, rotateY, skewX, skewY } = latestTransform;
+ if (transformPerspective)
+ transform = `perspective(${transformPerspective}px) ${transform}`;
+ if (rotate2)
+ transform += `rotate(${rotate2}deg) `;
+ if (rotateX)
+ transform += `rotateX(${rotateX}deg) `;
+ if (rotateY)
+ transform += `rotateY(${rotateY}deg) `;
+ if (skewX)
+ transform += `skewX(${skewX}deg) `;
+ if (skewY)
+ transform += `skewY(${skewY}deg) `;
+ }
+ const elementScaleX = delta.x.scale * treeScale.x;
+ const elementScaleY = delta.y.scale * treeScale.y;
+ if (elementScaleX !== 1 || elementScaleY !== 1) {
+ transform += `scale(${elementScaleX}, ${elementScaleY})`;
+ }
+ return transform || "none";
+}
+const borderLabels = [
+ "borderTopLeftRadius",
+ "borderTopRightRadius",
+ "borderBottomLeftRadius",
+ "borderBottomRightRadius"
+];
+const numBorders = borderLabels.length;
+const asNumber = (value) => typeof value === "string" ? parseFloat(value) : value;
+const isPx = (value) => typeof value === "number" || px.test(value);
+function mixValues(target, follow, lead, progress2, shouldCrossfadeOpacity, isOnlyMember) {
+ if (shouldCrossfadeOpacity) {
+ target.opacity = mixNumber$1(0, lead.opacity ?? 1, easeCrossfadeIn(progress2));
+ target.opacityExit = mixNumber$1(follow.opacity ?? 1, 0, easeCrossfadeOut(progress2));
+ } else if (isOnlyMember) {
+ target.opacity = mixNumber$1(follow.opacity ?? 1, lead.opacity ?? 1, progress2);
+ }
+ for (let i = 0; i < numBorders; i++) {
+ const borderLabel = borderLabels[i];
+ let followRadius = getRadius(follow, borderLabel);
+ let leadRadius = getRadius(lead, borderLabel);
+ if (followRadius === void 0 && leadRadius === void 0)
+ continue;
+ followRadius || (followRadius = 0);
+ leadRadius || (leadRadius = 0);
+ const canMix = followRadius === 0 || leadRadius === 0 || isPx(followRadius) === isPx(leadRadius);
+ if (canMix) {
+ target[borderLabel] = Math.max(mixNumber$1(asNumber(followRadius), asNumber(leadRadius), progress2), 0);
+ if (percent.test(leadRadius) || percent.test(followRadius)) {
+ target[borderLabel] += "%";
+ }
+ } else {
+ target[borderLabel] = leadRadius;
+ }
+ }
+ if (follow.rotate || lead.rotate) {
+ target.rotate = mixNumber$1(follow.rotate || 0, lead.rotate || 0, progress2);
+ }
+}
+function getRadius(values, radiusName) {
+ return values[radiusName] !== void 0 ? values[radiusName] : values.borderRadius;
+}
+const easeCrossfadeIn = /* @__PURE__ */ compress(0, 0.5, circOut);
+const easeCrossfadeOut = /* @__PURE__ */ compress(0.5, 0.95, noop);
+function compress(min, max, easing) {
+ return (p) => {
+ if (p < min)
+ return 0;
+ if (p > max)
+ return 1;
+ return easing(/* @__PURE__ */ progress(min, max, p));
+ };
+}
+function animateSingleValue(value, keyframes2, options) {
+ const motionValue$1 = isMotionValue(value) ? value : motionValue(value);
+ motionValue$1.start(animateMotionValue("", motionValue$1, keyframes2, options));
+ return motionValue$1.animation;
+}
+function addDomEvent(target, eventName, handler, options = { passive: true }) {
+ target.addEventListener(eventName, handler, options);
+ return () => target.removeEventListener(eventName, handler);
+}
+const compareByDepth = (a, b) => a.depth - b.depth;
+class FlatTree {
+ constructor() {
+ this.children = [];
+ this.isDirty = false;
+ }
+ add(child) {
+ addUniqueItem(this.children, child);
+ this.isDirty = true;
+ }
+ remove(child) {
+ removeItem(this.children, child);
+ this.isDirty = true;
+ }
+ forEach(callback) {
+ this.isDirty && this.children.sort(compareByDepth);
+ this.isDirty = false;
+ this.children.forEach(callback);
+ }
+}
+function delay(callback, timeout) {
+ const start = time.now();
+ const checkElapsed = ({ timestamp }) => {
+ const elapsed = timestamp - start;
+ if (elapsed >= timeout) {
+ cancelFrame(checkElapsed);
+ callback(elapsed - timeout);
+ }
+ };
+ frame.setup(checkElapsed, true);
+ return () => cancelFrame(checkElapsed);
+}
+function resolveMotionValue(value) {
+ return isMotionValue(value) ? value.get() : value;
+}
+class NodeStack {
+ constructor() {
+ this.members = [];
+ }
+ add(node) {
+ addUniqueItem(this.members, node);
+ for (let i = this.members.length - 1; i >= 0; i--) {
+ const member = this.members[i];
+ if (member === node || member === this.lead || member === this.prevLead)
+ continue;
+ const inst = member.instance;
+ if ((!inst || inst.isConnected === false) && !member.snapshot) {
+ removeItem(this.members, member);
+ member.unmount();
+ }
+ }
+ node.scheduleRender();
+ }
+ remove(node) {
+ removeItem(this.members, node);
+ if (node === this.prevLead)
+ this.prevLead = void 0;
+ if (node === this.lead) {
+ const prevLead = this.members[this.members.length - 1];
+ if (prevLead)
+ this.promote(prevLead);
+ }
+ }
+ relegate(node) {
+ for (let i = this.members.indexOf(node) - 1; i >= 0; i--) {
+ const member = this.members[i];
+ if (member.isPresent !== false && member.instance?.isConnected !== false) {
+ this.promote(member);
+ return true;
+ }
+ }
+ return false;
+ }
+ promote(node, preserveFollowOpacity) {
+ const prevLead = this.lead;
+ if (node === prevLead)
+ return;
+ this.prevLead = prevLead;
+ this.lead = node;
+ node.show();
+ if (prevLead) {
+ prevLead.updateSnapshot();
+ node.scheduleRender();
+ const { layoutDependency: prevDep } = prevLead.options;
+ const { layoutDependency: nextDep } = node.options;
+ if (prevDep === void 0 || prevDep !== nextDep) {
+ node.resumeFrom = prevLead;
+ if (preserveFollowOpacity)
+ prevLead.preserveOpacity = true;
+ if (prevLead.snapshot) {
+ node.snapshot = prevLead.snapshot;
+ node.snapshot.latestValues = prevLead.animationValues || prevLead.latestValues;
+ }
+ if (node.root?.isUpdating)
+ node.isLayoutDirty = true;
+ }
+ if (node.options.crossfade === false)
+ prevLead.hide();
+ }
+ }
+ exitAnimationComplete() {
+ this.members.forEach((member) => {
+ member.options.onExitComplete?.();
+ member.resumingFrom?.options.onExitComplete?.();
+ });
+ }
+ scheduleRender() {
+ this.members.forEach((member) => member.instance && member.scheduleRender(false));
+ }
+ removeLeadSnapshot() {
+ if (this.lead?.snapshot)
+ this.lead.snapshot = void 0;
+ }
+}
+const globalProjectionState = {
+ /**
+ * Global flag as to whether the tree has animated since the last time
+ * we resized the window
+ */
+ hasAnimatedSinceResize: true,
+ /**
+ * We set this to true once, on the first update. Any nodes added to the tree beyond that
+ * update will be given a `data-projection-id` attribute.
+ */
+ hasEverUpdated: false
+};
+const transformAxes = ["", "X", "Y", "Z"];
+const animationTarget = 1e3;
+let id$1 = 0;
+function resetDistortingTransform(key, visualElement, values, sharedAnimationValues) {
+ const { latestValues } = visualElement;
+ if (latestValues[key]) {
+ values[key] = latestValues[key];
+ visualElement.setStaticValue(key, 0);
+ if (sharedAnimationValues) {
+ sharedAnimationValues[key] = 0;
+ }
+ }
+}
+function cancelTreeOptimisedTransformAnimations(projectionNode) {
+ projectionNode.hasCheckedOptimisedAppear = true;
+ if (projectionNode.root === projectionNode)
+ return;
+ const { visualElement } = projectionNode.options;
+ if (!visualElement)
+ return;
+ const appearId = getOptimisedAppearId(visualElement);
+ if (window.MotionHasOptimisedAnimation(appearId, "transform")) {
+ const { layout: layout2, layoutId } = projectionNode.options;
+ window.MotionCancelOptimisedAnimation(appearId, "transform", frame, !(layout2 || layoutId));
+ }
+ const { parent } = projectionNode;
+ if (parent && !parent.hasCheckedOptimisedAppear) {
+ cancelTreeOptimisedTransformAnimations(parent);
+ }
+}
+function createProjectionNode$1({ attachResizeListener, defaultParent, measureScroll, checkIsScrollRoot, resetTransform }) {
+ return class ProjectionNode {
+ constructor(latestValues = {}, parent = defaultParent?.()) {
+ this.id = id$1++;
+ this.animationId = 0;
+ this.animationCommitId = 0;
+ this.children = /* @__PURE__ */ new Set();
+ this.options = {};
+ this.isTreeAnimating = false;
+ this.isAnimationBlocked = false;
+ this.isLayoutDirty = false;
+ this.isProjectionDirty = false;
+ this.isSharedProjectionDirty = false;
+ this.isTransformDirty = false;
+ this.updateManuallyBlocked = false;
+ this.updateBlockedByResize = false;
+ this.isUpdating = false;
+ this.isSVG = false;
+ this.needsReset = false;
+ this.shouldResetTransform = false;
+ this.hasCheckedOptimisedAppear = false;
+ this.treeScale = { x: 1, y: 1 };
+ this.eventHandlers = /* @__PURE__ */ new Map();
+ this.hasTreeAnimated = false;
+ this.layoutVersion = 0;
+ this.updateScheduled = false;
+ this.scheduleUpdate = () => this.update();
+ this.projectionUpdateScheduled = false;
+ this.checkUpdateFailed = () => {
+ if (this.isUpdating) {
+ this.isUpdating = false;
+ this.clearAllSnapshots();
+ }
+ };
+ this.updateProjection = () => {
+ this.projectionUpdateScheduled = false;
+ this.nodes.forEach(propagateDirtyNodes);
+ this.nodes.forEach(resolveTargetDelta);
+ this.nodes.forEach(calcProjection);
+ this.nodes.forEach(cleanDirtyNodes);
+ };
+ this.resolvedRelativeTargetAt = 0;
+ this.linkedParentVersion = 0;
+ this.hasProjected = false;
+ this.isVisible = true;
+ this.animationProgress = 0;
+ this.sharedNodes = /* @__PURE__ */ new Map();
+ this.latestValues = latestValues;
+ this.root = parent ? parent.root || parent : this;
+ this.path = parent ? [...parent.path, parent] : [];
+ this.parent = parent;
+ this.depth = parent ? parent.depth + 1 : 0;
+ for (let i = 0; i < this.path.length; i++) {
+ this.path[i].shouldResetTransform = true;
+ }
+ if (this.root === this)
+ this.nodes = new FlatTree();
+ }
+ addEventListener(name, handler) {
+ if (!this.eventHandlers.has(name)) {
+ this.eventHandlers.set(name, new SubscriptionManager());
+ }
+ return this.eventHandlers.get(name).add(handler);
+ }
+ notifyListeners(name, ...args) {
+ const subscriptionManager = this.eventHandlers.get(name);
+ subscriptionManager && subscriptionManager.notify(...args);
+ }
+ hasListeners(name) {
+ return this.eventHandlers.has(name);
+ }
+ /**
+ * Lifecycles
+ */
+ mount(instance) {
+ if (this.instance)
+ return;
+ this.isSVG = isSVGElement(instance) && !isSVGSVGElement(instance);
+ this.instance = instance;
+ const { layoutId, layout: layout2, visualElement } = this.options;
+ if (visualElement && !visualElement.current) {
+ visualElement.mount(instance);
+ }
+ this.root.nodes.add(this);
+ this.parent && this.parent.children.add(this);
+ if (this.root.hasTreeAnimated && (layout2 || layoutId)) {
+ this.isLayoutDirty = true;
+ }
+ if (attachResizeListener) {
+ let cancelDelay;
+ let innerWidth = 0;
+ const resizeUnblockUpdate = () => this.root.updateBlockedByResize = false;
+ frame.read(() => {
+ innerWidth = window.innerWidth;
+ });
+ attachResizeListener(instance, () => {
+ const newInnerWidth = window.innerWidth;
+ if (newInnerWidth === innerWidth)
+ return;
+ innerWidth = newInnerWidth;
+ this.root.updateBlockedByResize = true;
+ cancelDelay && cancelDelay();
+ cancelDelay = delay(resizeUnblockUpdate, 250);
+ if (globalProjectionState.hasAnimatedSinceResize) {
+ globalProjectionState.hasAnimatedSinceResize = false;
+ this.nodes.forEach(finishAnimation);
+ }
+ });
+ }
+ if (layoutId) {
+ this.root.registerSharedNode(layoutId, this);
+ }
+ if (this.options.animate !== false && visualElement && (layoutId || layout2)) {
+ this.addEventListener("didUpdate", ({ delta, hasLayoutChanged, hasRelativeLayoutChanged, layout: newLayout }) => {
+ if (this.isTreeAnimationBlocked()) {
+ this.target = void 0;
+ this.relativeTarget = void 0;
+ return;
+ }
+ const layoutTransition = this.options.transition || visualElement.getDefaultTransition() || defaultLayoutTransition;
+ const { onLayoutAnimationStart, onLayoutAnimationComplete } = visualElement.getProps();
+ const hasTargetChanged = !this.targetLayout || !boxEqualsRounded(this.targetLayout, newLayout);
+ const hasOnlyRelativeTargetChanged = !hasLayoutChanged && hasRelativeLayoutChanged;
+ if (this.options.layoutRoot || this.resumeFrom || hasOnlyRelativeTargetChanged || hasLayoutChanged && (hasTargetChanged || !this.currentAnimation)) {
+ if (this.resumeFrom) {
+ this.resumingFrom = this.resumeFrom;
+ this.resumingFrom.resumingFrom = void 0;
+ }
+ const animationOptions = {
+ ...getValueTransition(layoutTransition, "layout"),
+ onPlay: onLayoutAnimationStart,
+ onComplete: onLayoutAnimationComplete
+ };
+ if (visualElement.shouldReduceMotion || this.options.layoutRoot) {
+ animationOptions.delay = 0;
+ animationOptions.type = false;
+ }
+ this.startAnimation(animationOptions);
+ this.setAnimationOrigin(delta, hasOnlyRelativeTargetChanged);
+ } else {
+ if (!hasLayoutChanged) {
+ finishAnimation(this);
+ }
+ if (this.isLead() && this.options.onExitComplete) {
+ this.options.onExitComplete();
+ }
+ }
+ this.targetLayout = newLayout;
+ });
+ }
+ }
+ unmount() {
+ this.options.layoutId && this.willUpdate();
+ this.root.nodes.remove(this);
+ const stack = this.getStack();
+ stack && stack.remove(this);
+ this.parent && this.parent.children.delete(this);
+ this.instance = void 0;
+ this.eventHandlers.clear();
+ cancelFrame(this.updateProjection);
+ }
+ // only on the root
+ blockUpdate() {
+ this.updateManuallyBlocked = true;
+ }
+ unblockUpdate() {
+ this.updateManuallyBlocked = false;
+ }
+ isUpdateBlocked() {
+ return this.updateManuallyBlocked || this.updateBlockedByResize;
+ }
+ isTreeAnimationBlocked() {
+ return this.isAnimationBlocked || this.parent && this.parent.isTreeAnimationBlocked() || false;
+ }
+ // Note: currently only running on root node
+ startUpdate() {
+ if (this.isUpdateBlocked())
+ return;
+ this.isUpdating = true;
+ this.nodes && this.nodes.forEach(resetSkewAndRotation);
+ this.animationId++;
+ }
+ getTransformTemplate() {
+ const { visualElement } = this.options;
+ return visualElement && visualElement.getProps().transformTemplate;
+ }
+ willUpdate(shouldNotifyListeners = true) {
+ this.root.hasTreeAnimated = true;
+ if (this.root.isUpdateBlocked()) {
+ this.options.onExitComplete && this.options.onExitComplete();
+ return;
+ }
+ if (window.MotionCancelOptimisedAnimation && !this.hasCheckedOptimisedAppear) {
+ cancelTreeOptimisedTransformAnimations(this);
+ }
+ !this.root.isUpdating && this.root.startUpdate();
+ if (this.isLayoutDirty)
+ return;
+ this.isLayoutDirty = true;
+ for (let i = 0; i < this.path.length; i++) {
+ const node = this.path[i];
+ node.shouldResetTransform = true;
+ if (typeof node.latestValues.x === "string" || typeof node.latestValues.y === "string") {
+ node.isLayoutDirty = true;
+ }
+ node.updateScroll("snapshot");
+ if (node.options.layoutRoot) {
+ node.willUpdate(false);
+ }
+ }
+ const { layoutId, layout: layout2 } = this.options;
+ if (layoutId === void 0 && !layout2)
+ return;
+ const transformTemplate = this.getTransformTemplate();
+ this.prevTransformTemplateValue = transformTemplate ? transformTemplate(this.latestValues, "") : void 0;
+ this.updateSnapshot();
+ shouldNotifyListeners && this.notifyListeners("willUpdate");
+ }
+ update() {
+ this.updateScheduled = false;
+ const updateWasBlocked = this.isUpdateBlocked();
+ if (updateWasBlocked) {
+ const wasBlockedByResize = this.updateBlockedByResize;
+ this.unblockUpdate();
+ this.updateBlockedByResize = false;
+ this.clearAllSnapshots();
+ if (wasBlockedByResize) {
+ this.nodes.forEach(forceLayoutMeasure);
+ }
+ this.nodes.forEach(clearMeasurements);
+ return;
+ }
+ if (this.animationId <= this.animationCommitId) {
+ this.nodes.forEach(clearIsLayoutDirty);
+ return;
+ }
+ this.animationCommitId = this.animationId;
+ if (!this.isUpdating) {
+ this.nodes.forEach(clearIsLayoutDirty);
+ } else {
+ this.isUpdating = false;
+ this.nodes.forEach(ensureDraggedNodesSnapshotted);
+ this.nodes.forEach(resetTransformStyle);
+ this.nodes.forEach(updateLayout);
+ this.nodes.forEach(notifyLayoutUpdate);
+ }
+ this.clearAllSnapshots();
+ const now2 = time.now();
+ frameData.delta = clamp(0, 1e3 / 60, now2 - frameData.timestamp);
+ frameData.timestamp = now2;
+ frameData.isProcessing = true;
+ frameSteps.update.process(frameData);
+ frameSteps.preRender.process(frameData);
+ frameSteps.render.process(frameData);
+ frameData.isProcessing = false;
+ }
+ didUpdate() {
+ if (!this.updateScheduled) {
+ this.updateScheduled = true;
+ microtask.read(this.scheduleUpdate);
+ }
+ }
+ clearAllSnapshots() {
+ this.nodes.forEach(clearSnapshot);
+ this.sharedNodes.forEach(removeLeadSnapshots);
+ }
+ scheduleUpdateProjection() {
+ if (!this.projectionUpdateScheduled) {
+ this.projectionUpdateScheduled = true;
+ frame.preRender(this.updateProjection, false, true);
+ }
+ }
+ scheduleCheckAfterUnmount() {
+ frame.postRender(() => {
+ if (this.isLayoutDirty) {
+ this.root.didUpdate();
+ } else {
+ this.root.checkUpdateFailed();
+ }
+ });
+ }
+ /**
+ * Update measurements
+ */
+ updateSnapshot() {
+ if (this.snapshot || !this.instance)
+ return;
+ this.snapshot = this.measure();
+ if (this.snapshot && !calcLength(this.snapshot.measuredBox.x) && !calcLength(this.snapshot.measuredBox.y)) {
+ this.snapshot = void 0;
+ }
+ }
+ updateLayout() {
+ if (!this.instance)
+ return;
+ this.updateScroll();
+ if (!(this.options.alwaysMeasureLayout && this.isLead()) && !this.isLayoutDirty) {
+ return;
+ }
+ if (this.resumeFrom && !this.resumeFrom.instance) {
+ for (let i = 0; i < this.path.length; i++) {
+ const node = this.path[i];
+ node.updateScroll();
+ }
+ }
+ const prevLayout = this.layout;
+ this.layout = this.measure(false);
+ this.layoutVersion++;
+ if (!this.layoutCorrected)
+ this.layoutCorrected = createBox();
+ this.isLayoutDirty = false;
+ this.projectionDelta = void 0;
+ this.notifyListeners("measure", this.layout.layoutBox);
+ const { visualElement } = this.options;
+ visualElement && visualElement.notify("LayoutMeasure", this.layout.layoutBox, prevLayout ? prevLayout.layoutBox : void 0);
+ }
+ updateScroll(phase = "measure") {
+ let needsMeasurement = Boolean(this.options.layoutScroll && this.instance);
+ if (this.scroll && this.scroll.animationId === this.root.animationId && this.scroll.phase === phase) {
+ needsMeasurement = false;
+ }
+ if (needsMeasurement && this.instance) {
+ const isRoot = checkIsScrollRoot(this.instance);
+ this.scroll = {
+ animationId: this.root.animationId,
+ phase,
+ isRoot,
+ offset: measureScroll(this.instance),
+ wasRoot: this.scroll ? this.scroll.isRoot : isRoot
+ };
+ }
+ }
+ resetTransform() {
+ if (!resetTransform)
+ return;
+ const isResetRequested = this.isLayoutDirty || this.shouldResetTransform || this.options.alwaysMeasureLayout;
+ const hasProjection = this.projectionDelta && !isDeltaZero(this.projectionDelta);
+ const transformTemplate = this.getTransformTemplate();
+ const transformTemplateValue = transformTemplate ? transformTemplate(this.latestValues, "") : void 0;
+ const transformTemplateHasChanged = transformTemplateValue !== this.prevTransformTemplateValue;
+ if (isResetRequested && this.instance && (hasProjection || hasTransform(this.latestValues) || transformTemplateHasChanged)) {
+ resetTransform(this.instance, transformTemplateValue);
+ this.shouldResetTransform = false;
+ this.scheduleRender();
+ }
+ }
+ measure(removeTransform = true) {
+ const pageBox = this.measurePageBox();
+ let layoutBox = this.removeElementScroll(pageBox);
+ if (removeTransform) {
+ layoutBox = this.removeTransform(layoutBox);
+ }
+ roundBox(layoutBox);
+ return {
+ animationId: this.root.animationId,
+ measuredBox: pageBox,
+ layoutBox,
+ latestValues: {},
+ source: this.id
+ };
+ }
+ measurePageBox() {
+ const { visualElement } = this.options;
+ if (!visualElement)
+ return createBox();
+ const box = visualElement.measureViewportBox();
+ const wasInScrollRoot = this.scroll?.wasRoot || this.path.some(checkNodeWasScrollRoot);
+ if (!wasInScrollRoot) {
+ const { scroll } = this.root;
+ if (scroll) {
+ translateAxis(box.x, scroll.offset.x);
+ translateAxis(box.y, scroll.offset.y);
+ }
+ }
+ return box;
+ }
+ removeElementScroll(box) {
+ const boxWithoutScroll = createBox();
+ copyBoxInto(boxWithoutScroll, box);
+ if (this.scroll?.wasRoot) {
+ return boxWithoutScroll;
+ }
+ for (let i = 0; i < this.path.length; i++) {
+ const node = this.path[i];
+ const { scroll, options } = node;
+ if (node !== this.root && scroll && options.layoutScroll) {
+ if (scroll.wasRoot) {
+ copyBoxInto(boxWithoutScroll, box);
+ }
+ translateAxis(boxWithoutScroll.x, scroll.offset.x);
+ translateAxis(boxWithoutScroll.y, scroll.offset.y);
+ }
+ }
+ return boxWithoutScroll;
+ }
+ applyTransform(box, transformOnly = false, output) {
+ const withTransforms = output || createBox();
+ copyBoxInto(withTransforms, box);
+ for (let i = 0; i < this.path.length; i++) {
+ const node = this.path[i];
+ if (!transformOnly && node.options.layoutScroll && node.scroll && node !== node.root) {
+ translateAxis(withTransforms.x, -node.scroll.offset.x);
+ translateAxis(withTransforms.y, -node.scroll.offset.y);
+ }
+ if (!hasTransform(node.latestValues))
+ continue;
+ transformBox(withTransforms, node.latestValues, node.layout?.layoutBox);
+ }
+ if (hasTransform(this.latestValues)) {
+ transformBox(withTransforms, this.latestValues, this.layout?.layoutBox);
+ }
+ return withTransforms;
+ }
+ removeTransform(box) {
+ const boxWithoutTransform = createBox();
+ copyBoxInto(boxWithoutTransform, box);
+ for (let i = 0; i < this.path.length; i++) {
+ const node = this.path[i];
+ if (!hasTransform(node.latestValues))
+ continue;
+ let sourceBox;
+ if (node.instance) {
+ hasScale(node.latestValues) && node.updateSnapshot();
+ sourceBox = createBox();
+ copyBoxInto(sourceBox, node.measurePageBox());
+ }
+ removeBoxTransforms(boxWithoutTransform, node.latestValues, node.snapshot?.layoutBox, sourceBox);
+ }
+ if (hasTransform(this.latestValues)) {
+ removeBoxTransforms(boxWithoutTransform, this.latestValues);
+ }
+ return boxWithoutTransform;
+ }
+ setTargetDelta(delta) {
+ this.targetDelta = delta;
+ this.root.scheduleUpdateProjection();
+ this.isProjectionDirty = true;
+ }
+ setOptions(options) {
+ this.options = {
+ ...this.options,
+ ...options,
+ crossfade: options.crossfade !== void 0 ? options.crossfade : true
+ };
+ }
+ clearMeasurements() {
+ this.scroll = void 0;
+ this.layout = void 0;
+ this.snapshot = void 0;
+ this.prevTransformTemplateValue = void 0;
+ this.targetDelta = void 0;
+ this.target = void 0;
+ this.isLayoutDirty = false;
+ }
+ forceRelativeParentToResolveTarget() {
+ if (!this.relativeParent)
+ return;
+ if (this.relativeParent.resolvedRelativeTargetAt !== frameData.timestamp) {
+ this.relativeParent.resolveTargetDelta(true);
+ }
+ }
+ resolveTargetDelta(forceRecalculation = false) {
+ const lead = this.getLead();
+ this.isProjectionDirty || (this.isProjectionDirty = lead.isProjectionDirty);
+ this.isTransformDirty || (this.isTransformDirty = lead.isTransformDirty);
+ this.isSharedProjectionDirty || (this.isSharedProjectionDirty = lead.isSharedProjectionDirty);
+ const isShared = Boolean(this.resumingFrom) || this !== lead;
+ const canSkip = !(forceRecalculation || isShared && this.isSharedProjectionDirty || this.isProjectionDirty || this.parent?.isProjectionDirty || this.attemptToResolveRelativeTarget || this.root.updateBlockedByResize);
+ if (canSkip)
+ return;
+ const { layout: layout2, layoutId } = this.options;
+ if (!this.layout || !(layout2 || layoutId))
+ return;
+ this.resolvedRelativeTargetAt = frameData.timestamp;
+ const relativeParent = this.getClosestProjectingParent();
+ if (relativeParent && this.linkedParentVersion !== relativeParent.layoutVersion && !relativeParent.options.layoutRoot) {
+ this.removeRelativeTarget();
+ }
+ if (!this.targetDelta && !this.relativeTarget) {
+ if (this.options.layoutAnchor !== false && relativeParent && relativeParent.layout) {
+ this.createRelativeTarget(relativeParent, this.layout.layoutBox, relativeParent.layout.layoutBox);
+ } else {
+ this.removeRelativeTarget();
+ }
+ }
+ if (!this.relativeTarget && !this.targetDelta)
+ return;
+ if (!this.target) {
+ this.target = createBox();
+ this.targetWithTransforms = createBox();
+ }
+ if (this.relativeTarget && this.relativeTargetOrigin && this.relativeParent && this.relativeParent.target) {
+ this.forceRelativeParentToResolveTarget();
+ calcRelativeBox(this.target, this.relativeTarget, this.relativeParent.target, this.options.layoutAnchor || void 0);
+ } else if (this.targetDelta) {
+ if (Boolean(this.resumingFrom)) {
+ this.applyTransform(this.layout.layoutBox, false, this.target);
+ } else {
+ copyBoxInto(this.target, this.layout.layoutBox);
+ }
+ applyBoxDelta(this.target, this.targetDelta);
+ } else {
+ copyBoxInto(this.target, this.layout.layoutBox);
+ }
+ if (this.attemptToResolveRelativeTarget) {
+ this.attemptToResolveRelativeTarget = false;
+ if (this.options.layoutAnchor !== false && relativeParent && Boolean(relativeParent.resumingFrom) === Boolean(this.resumingFrom) && !relativeParent.options.layoutScroll && relativeParent.target && this.animationProgress !== 1) {
+ this.createRelativeTarget(relativeParent, this.target, relativeParent.target);
+ } else {
+ this.relativeParent = this.relativeTarget = void 0;
+ }
+ }
+ }
+ getClosestProjectingParent() {
+ if (!this.parent || hasScale(this.parent.latestValues) || has2DTranslate(this.parent.latestValues)) {
+ return void 0;
+ }
+ if (this.parent.isProjecting()) {
+ return this.parent;
+ } else {
+ return this.parent.getClosestProjectingParent();
+ }
+ }
+ isProjecting() {
+ return Boolean((this.relativeTarget || this.targetDelta || this.options.layoutRoot) && this.layout);
+ }
+ createRelativeTarget(relativeParent, layout2, parentLayout) {
+ this.relativeParent = relativeParent;
+ this.linkedParentVersion = relativeParent.layoutVersion;
+ this.forceRelativeParentToResolveTarget();
+ this.relativeTarget = createBox();
+ this.relativeTargetOrigin = createBox();
+ calcRelativePosition(this.relativeTargetOrigin, layout2, parentLayout, this.options.layoutAnchor || void 0);
+ copyBoxInto(this.relativeTarget, this.relativeTargetOrigin);
+ }
+ removeRelativeTarget() {
+ this.relativeParent = this.relativeTarget = void 0;
+ }
+ calcProjection() {
+ const lead = this.getLead();
+ const isShared = Boolean(this.resumingFrom) || this !== lead;
+ let canSkip = true;
+ if (this.isProjectionDirty || this.parent?.isProjectionDirty) {
+ canSkip = false;
+ }
+ if (isShared && (this.isSharedProjectionDirty || this.isTransformDirty)) {
+ canSkip = false;
+ }
+ if (this.resolvedRelativeTargetAt === frameData.timestamp) {
+ canSkip = false;
+ }
+ if (canSkip)
+ return;
+ const { layout: layout2, layoutId } = this.options;
+ this.isTreeAnimating = Boolean(this.parent && this.parent.isTreeAnimating || this.currentAnimation || this.pendingAnimation);
+ if (!this.isTreeAnimating) {
+ this.targetDelta = this.relativeTarget = void 0;
+ }
+ if (!this.layout || !(layout2 || layoutId))
+ return;
+ copyBoxInto(this.layoutCorrected, this.layout.layoutBox);
+ const prevTreeScaleX = this.treeScale.x;
+ const prevTreeScaleY = this.treeScale.y;
+ applyTreeDeltas(this.layoutCorrected, this.treeScale, this.path, isShared);
+ if (lead.layout && !lead.target && (this.treeScale.x !== 1 || this.treeScale.y !== 1)) {
+ lead.target = lead.layout.layoutBox;
+ lead.targetWithTransforms = createBox();
+ }
+ const { target } = lead;
+ if (!target) {
+ if (this.prevProjectionDelta) {
+ this.createProjectionDeltas();
+ this.scheduleRender();
+ }
+ return;
+ }
+ if (!this.projectionDelta || !this.prevProjectionDelta) {
+ this.createProjectionDeltas();
+ } else {
+ copyAxisDeltaInto(this.prevProjectionDelta.x, this.projectionDelta.x);
+ copyAxisDeltaInto(this.prevProjectionDelta.y, this.projectionDelta.y);
+ }
+ calcBoxDelta(this.projectionDelta, this.layoutCorrected, target, this.latestValues);
+ if (this.treeScale.x !== prevTreeScaleX || this.treeScale.y !== prevTreeScaleY || !axisDeltaEquals(this.projectionDelta.x, this.prevProjectionDelta.x) || !axisDeltaEquals(this.projectionDelta.y, this.prevProjectionDelta.y)) {
+ this.hasProjected = true;
+ this.scheduleRender();
+ this.notifyListeners("projectionUpdate", target);
+ }
+ }
+ hide() {
+ this.isVisible = false;
+ }
+ show() {
+ this.isVisible = true;
+ }
+ scheduleRender(notifyAll2 = true) {
+ this.options.visualElement?.scheduleRender();
+ if (notifyAll2) {
+ const stack = this.getStack();
+ stack && stack.scheduleRender();
+ }
+ if (this.resumingFrom && !this.resumingFrom.instance) {
+ this.resumingFrom = void 0;
+ }
+ }
+ createProjectionDeltas() {
+ this.prevProjectionDelta = createDelta();
+ this.projectionDelta = createDelta();
+ this.projectionDeltaWithTransform = createDelta();
+ }
+ setAnimationOrigin(delta, hasOnlyRelativeTargetChanged = false) {
+ const snapshot = this.snapshot;
+ const snapshotLatestValues = snapshot ? snapshot.latestValues : {};
+ const mixedValues = { ...this.latestValues };
+ const targetDelta = createDelta();
+ if (!this.relativeParent || !this.relativeParent.options.layoutRoot) {
+ this.relativeTarget = this.relativeTargetOrigin = void 0;
+ }
+ this.attemptToResolveRelativeTarget = !hasOnlyRelativeTargetChanged;
+ const relativeLayout = createBox();
+ const snapshotSource = snapshot ? snapshot.source : void 0;
+ const layoutSource = this.layout ? this.layout.source : void 0;
+ const isSharedLayoutAnimation = snapshotSource !== layoutSource;
+ const stack = this.getStack();
+ const isOnlyMember = !stack || stack.members.length <= 1;
+ const shouldCrossfadeOpacity = Boolean(isSharedLayoutAnimation && !isOnlyMember && this.options.crossfade === true && !this.path.some(hasOpacityCrossfade));
+ this.animationProgress = 0;
+ let prevRelativeTarget;
+ this.mixTargetDelta = (latest) => {
+ const progress2 = latest / 1e3;
+ mixAxisDelta(targetDelta.x, delta.x, progress2);
+ mixAxisDelta(targetDelta.y, delta.y, progress2);
+ this.setTargetDelta(targetDelta);
+ if (this.relativeTarget && this.relativeTargetOrigin && this.layout && this.relativeParent && this.relativeParent.layout) {
+ calcRelativePosition(relativeLayout, this.layout.layoutBox, this.relativeParent.layout.layoutBox, this.options.layoutAnchor || void 0);
+ mixBox(this.relativeTarget, this.relativeTargetOrigin, relativeLayout, progress2);
+ if (prevRelativeTarget && boxEquals(this.relativeTarget, prevRelativeTarget)) {
+ this.isProjectionDirty = false;
+ }
+ if (!prevRelativeTarget)
+ prevRelativeTarget = createBox();
+ copyBoxInto(prevRelativeTarget, this.relativeTarget);
+ }
+ if (isSharedLayoutAnimation) {
+ this.animationValues = mixedValues;
+ mixValues(mixedValues, snapshotLatestValues, this.latestValues, progress2, shouldCrossfadeOpacity, isOnlyMember);
+ }
+ this.root.scheduleUpdateProjection();
+ this.scheduleRender();
+ this.animationProgress = progress2;
+ };
+ this.mixTargetDelta(this.options.layoutRoot ? 1e3 : 0);
+ }
+ startAnimation(options) {
+ this.notifyListeners("animationStart");
+ this.currentAnimation?.stop();
+ this.resumingFrom?.currentAnimation?.stop();
+ if (this.pendingAnimation) {
+ cancelFrame(this.pendingAnimation);
+ this.pendingAnimation = void 0;
+ }
+ this.pendingAnimation = frame.update(() => {
+ globalProjectionState.hasAnimatedSinceResize = true;
+ this.motionValue || (this.motionValue = motionValue(0));
+ this.motionValue.jump(0, false);
+ this.currentAnimation = animateSingleValue(this.motionValue, [0, 1e3], {
+ ...options,
+ velocity: 0,
+ isSync: true,
+ onUpdate: (latest) => {
+ this.mixTargetDelta(latest);
+ options.onUpdate && options.onUpdate(latest);
+ },
+ onStop: () => {
+ },
+ onComplete: () => {
+ options.onComplete && options.onComplete();
+ this.completeAnimation();
+ }
+ });
+ if (this.resumingFrom) {
+ this.resumingFrom.currentAnimation = this.currentAnimation;
+ }
+ this.pendingAnimation = void 0;
+ });
+ }
+ completeAnimation() {
+ if (this.resumingFrom) {
+ this.resumingFrom.currentAnimation = void 0;
+ this.resumingFrom.preserveOpacity = void 0;
+ }
+ const stack = this.getStack();
+ stack && stack.exitAnimationComplete();
+ this.resumingFrom = this.currentAnimation = this.animationValues = void 0;
+ this.notifyListeners("animationComplete");
+ }
+ finishAnimation() {
+ if (this.currentAnimation) {
+ this.mixTargetDelta && this.mixTargetDelta(animationTarget);
+ this.currentAnimation.stop();
+ }
+ this.completeAnimation();
+ }
+ applyTransformsToTarget() {
+ const lead = this.getLead();
+ let { targetWithTransforms, target, layout: layout2, latestValues } = lead;
+ if (!targetWithTransforms || !target || !layout2)
+ return;
+ if (this !== lead && this.layout && layout2 && shouldAnimatePositionOnly(this.options.animationType, this.layout.layoutBox, layout2.layoutBox)) {
+ target = this.target || createBox();
+ const xLength = calcLength(this.layout.layoutBox.x);
+ target.x.min = lead.target.x.min;
+ target.x.max = target.x.min + xLength;
+ const yLength = calcLength(this.layout.layoutBox.y);
+ target.y.min = lead.target.y.min;
+ target.y.max = target.y.min + yLength;
+ }
+ copyBoxInto(targetWithTransforms, target);
+ transformBox(targetWithTransforms, latestValues);
+ calcBoxDelta(this.projectionDeltaWithTransform, this.layoutCorrected, targetWithTransforms, latestValues);
+ }
+ registerSharedNode(layoutId, node) {
+ if (!this.sharedNodes.has(layoutId)) {
+ this.sharedNodes.set(layoutId, new NodeStack());
+ }
+ const stack = this.sharedNodes.get(layoutId);
+ stack.add(node);
+ const config = node.options.initialPromotionConfig;
+ node.promote({
+ transition: config ? config.transition : void 0,
+ preserveFollowOpacity: config && config.shouldPreserveFollowOpacity ? config.shouldPreserveFollowOpacity(node) : void 0
+ });
+ }
+ isLead() {
+ const stack = this.getStack();
+ return stack ? stack.lead === this : true;
+ }
+ getLead() {
+ const { layoutId } = this.options;
+ return layoutId ? this.getStack()?.lead || this : this;
+ }
+ getPrevLead() {
+ const { layoutId } = this.options;
+ return layoutId ? this.getStack()?.prevLead : void 0;
+ }
+ getStack() {
+ const { layoutId } = this.options;
+ if (layoutId)
+ return this.root.sharedNodes.get(layoutId);
+ }
+ promote({ needsReset, transition, preserveFollowOpacity } = {}) {
+ const stack = this.getStack();
+ if (stack)
+ stack.promote(this, preserveFollowOpacity);
+ if (needsReset) {
+ this.projectionDelta = void 0;
+ this.needsReset = true;
+ }
+ if (transition)
+ this.setOptions({ transition });
+ }
+ relegate() {
+ const stack = this.getStack();
+ if (stack) {
+ return stack.relegate(this);
+ } else {
+ return false;
+ }
+ }
+ resetSkewAndRotation() {
+ const { visualElement } = this.options;
+ if (!visualElement)
+ return;
+ let hasDistortingTransform = false;
+ const { latestValues } = visualElement;
+ if (latestValues.z || latestValues.rotate || latestValues.rotateX || latestValues.rotateY || latestValues.rotateZ || latestValues.skewX || latestValues.skewY) {
+ hasDistortingTransform = true;
+ }
+ if (!hasDistortingTransform)
+ return;
+ const resetValues = {};
+ if (latestValues.z) {
+ resetDistortingTransform("z", visualElement, resetValues, this.animationValues);
+ }
+ for (let i = 0; i < transformAxes.length; i++) {
+ resetDistortingTransform(`rotate${transformAxes[i]}`, visualElement, resetValues, this.animationValues);
+ resetDistortingTransform(`skew${transformAxes[i]}`, visualElement, resetValues, this.animationValues);
+ }
+ visualElement.render();
+ for (const key in resetValues) {
+ visualElement.setStaticValue(key, resetValues[key]);
+ if (this.animationValues) {
+ this.animationValues[key] = resetValues[key];
+ }
+ }
+ visualElement.scheduleRender();
+ }
+ applyProjectionStyles(targetStyle, styleProp) {
+ if (!this.instance || this.isSVG)
+ return;
+ if (!this.isVisible) {
+ targetStyle.visibility = "hidden";
+ return;
+ }
+ const transformTemplate = this.getTransformTemplate();
+ if (this.needsReset) {
+ this.needsReset = false;
+ targetStyle.visibility = "";
+ targetStyle.opacity = "";
+ targetStyle.pointerEvents = resolveMotionValue(styleProp?.pointerEvents) || "";
+ targetStyle.transform = transformTemplate ? transformTemplate(this.latestValues, "") : "none";
+ return;
+ }
+ const lead = this.getLead();
+ if (!this.projectionDelta || !this.layout || !lead.target) {
+ if (this.options.layoutId) {
+ targetStyle.opacity = this.latestValues.opacity !== void 0 ? this.latestValues.opacity : 1;
+ targetStyle.pointerEvents = resolveMotionValue(styleProp?.pointerEvents) || "";
+ }
+ if (this.hasProjected && !hasTransform(this.latestValues)) {
+ targetStyle.transform = transformTemplate ? transformTemplate({}, "") : "none";
+ this.hasProjected = false;
+ }
+ return;
+ }
+ targetStyle.visibility = "";
+ const valuesToRender = lead.animationValues || lead.latestValues;
+ this.applyTransformsToTarget();
+ let transform = buildProjectionTransform(this.projectionDeltaWithTransform, this.treeScale, valuesToRender);
+ if (transformTemplate) {
+ transform = transformTemplate(valuesToRender, transform);
+ }
+ targetStyle.transform = transform;
+ const { x, y } = this.projectionDelta;
+ targetStyle.transformOrigin = `${x.origin * 100}% ${y.origin * 100}% 0`;
+ if (lead.animationValues) {
+ targetStyle.opacity = lead === this ? valuesToRender.opacity ?? this.latestValues.opacity ?? 1 : this.preserveOpacity ? this.latestValues.opacity : valuesToRender.opacityExit;
+ } else {
+ targetStyle.opacity = lead === this ? valuesToRender.opacity !== void 0 ? valuesToRender.opacity : "" : valuesToRender.opacityExit !== void 0 ? valuesToRender.opacityExit : 0;
+ }
+ for (const key in scaleCorrectors) {
+ if (valuesToRender[key] === void 0)
+ continue;
+ const { correct, applyTo, isCSSVariable } = scaleCorrectors[key];
+ const corrected = transform === "none" ? valuesToRender[key] : correct(valuesToRender[key], lead);
+ if (applyTo) {
+ const num = applyTo.length;
+ for (let i = 0; i < num; i++) {
+ targetStyle[applyTo[i]] = corrected;
+ }
+ } else {
+ if (isCSSVariable) {
+ this.options.visualElement.renderState.vars[key] = corrected;
+ } else {
+ targetStyle[key] = corrected;
+ }
+ }
+ }
+ if (this.options.layoutId) {
+ targetStyle.pointerEvents = lead === this ? resolveMotionValue(styleProp?.pointerEvents) || "" : "none";
+ }
+ }
+ clearSnapshot() {
+ this.resumeFrom = this.snapshot = void 0;
+ }
+ // Only run on root
+ resetTree() {
+ this.root.nodes.forEach((node) => node.currentAnimation?.stop());
+ this.root.nodes.forEach(clearMeasurements);
+ this.root.sharedNodes.clear();
+ }
+ };
+}
+function updateLayout(node) {
+ node.updateLayout();
+}
+function notifyLayoutUpdate(node) {
+ const snapshot = node.resumeFrom?.snapshot || node.snapshot;
+ if (node.isLead() && node.layout && snapshot && node.hasListeners("didUpdate")) {
+ const { layoutBox: layout2, measuredBox: measuredLayout } = node.layout;
+ const { animationType } = node.options;
+ const isShared = snapshot.source !== node.layout.source;
+ if (animationType === "size") {
+ eachAxis((axis) => {
+ const axisSnapshot = isShared ? snapshot.measuredBox[axis] : snapshot.layoutBox[axis];
+ const length = calcLength(axisSnapshot);
+ axisSnapshot.min = layout2[axis].min;
+ axisSnapshot.max = axisSnapshot.min + length;
+ });
+ } else if (animationType === "x" || animationType === "y") {
+ const snapAxis = animationType === "x" ? "y" : "x";
+ copyAxisInto(isShared ? snapshot.measuredBox[snapAxis] : snapshot.layoutBox[snapAxis], layout2[snapAxis]);
+ } else if (shouldAnimatePositionOnly(animationType, snapshot.layoutBox, layout2)) {
+ eachAxis((axis) => {
+ const axisSnapshot = isShared ? snapshot.measuredBox[axis] : snapshot.layoutBox[axis];
+ const length = calcLength(layout2[axis]);
+ axisSnapshot.max = axisSnapshot.min + length;
+ if (node.relativeTarget && !node.currentAnimation) {
+ node.isProjectionDirty = true;
+ node.relativeTarget[axis].max = node.relativeTarget[axis].min + length;
+ }
+ });
+ }
+ const layoutDelta = createDelta();
+ calcBoxDelta(layoutDelta, layout2, snapshot.layoutBox);
+ const visualDelta = createDelta();
+ if (isShared) {
+ calcBoxDelta(visualDelta, node.applyTransform(measuredLayout, true), snapshot.measuredBox);
+ } else {
+ calcBoxDelta(visualDelta, layout2, snapshot.layoutBox);
+ }
+ const hasLayoutChanged = !isDeltaZero(layoutDelta);
+ let hasRelativeLayoutChanged = false;
+ if (!node.resumeFrom) {
+ const relativeParent = node.getClosestProjectingParent();
+ if (relativeParent && !relativeParent.resumeFrom) {
+ const { snapshot: parentSnapshot, layout: parentLayout } = relativeParent;
+ if (parentSnapshot && parentLayout) {
+ const anchor = node.options.layoutAnchor || void 0;
+ const relativeSnapshot = createBox();
+ calcRelativePosition(relativeSnapshot, snapshot.layoutBox, parentSnapshot.layoutBox, anchor);
+ const relativeLayout = createBox();
+ calcRelativePosition(relativeLayout, layout2, parentLayout.layoutBox, anchor);
+ if (!boxEqualsRounded(relativeSnapshot, relativeLayout)) {
+ hasRelativeLayoutChanged = true;
+ }
+ if (relativeParent.options.layoutRoot) {
+ node.relativeTarget = relativeLayout;
+ node.relativeTargetOrigin = relativeSnapshot;
+ node.relativeParent = relativeParent;
+ }
+ }
+ }
+ }
+ node.notifyListeners("didUpdate", {
+ layout: layout2,
+ snapshot,
+ delta: visualDelta,
+ layoutDelta,
+ hasLayoutChanged,
+ hasRelativeLayoutChanged
+ });
+ } else if (node.isLead()) {
+ const { onExitComplete } = node.options;
+ onExitComplete && onExitComplete();
+ }
+ node.options.transition = void 0;
+}
+function propagateDirtyNodes(node) {
+ if (!node.parent)
+ return;
+ if (!node.isProjecting()) {
+ node.isProjectionDirty = node.parent.isProjectionDirty;
+ }
+ node.isSharedProjectionDirty || (node.isSharedProjectionDirty = Boolean(node.isProjectionDirty || node.parent.isProjectionDirty || node.parent.isSharedProjectionDirty));
+ node.isTransformDirty || (node.isTransformDirty = node.parent.isTransformDirty);
+}
+function cleanDirtyNodes(node) {
+ node.isProjectionDirty = node.isSharedProjectionDirty = node.isTransformDirty = false;
+}
+function clearSnapshot(node) {
+ node.clearSnapshot();
+}
+function clearMeasurements(node) {
+ node.clearMeasurements();
+}
+function forceLayoutMeasure(node) {
+ node.isLayoutDirty = true;
+ node.updateLayout();
+}
+function clearIsLayoutDirty(node) {
+ node.isLayoutDirty = false;
+}
+function ensureDraggedNodesSnapshotted(node) {
+ if (node.isAnimationBlocked && node.layout && !node.isLayoutDirty) {
+ node.snapshot = node.layout;
+ node.isLayoutDirty = true;
+ }
+}
+function resetTransformStyle(node) {
+ const { visualElement } = node.options;
+ if (visualElement && visualElement.getProps().onBeforeLayoutMeasure) {
+ visualElement.notify("BeforeLayoutMeasure");
+ }
+ node.resetTransform();
+}
+function finishAnimation(node) {
+ node.finishAnimation();
+ node.targetDelta = node.relativeTarget = node.target = void 0;
+ node.isProjectionDirty = true;
+}
+function resolveTargetDelta(node) {
+ node.resolveTargetDelta();
+}
+function calcProjection(node) {
+ node.calcProjection();
+}
+function resetSkewAndRotation(node) {
+ node.resetSkewAndRotation();
+}
+function removeLeadSnapshots(stack) {
+ stack.removeLeadSnapshot();
+}
+function mixAxisDelta(output, delta, p) {
+ output.translate = mixNumber$1(delta.translate, 0, p);
+ output.scale = mixNumber$1(delta.scale, 1, p);
+ output.origin = delta.origin;
+ output.originPoint = delta.originPoint;
+}
+function mixAxis(output, from, to, p) {
+ output.min = mixNumber$1(from.min, to.min, p);
+ output.max = mixNumber$1(from.max, to.max, p);
+}
+function mixBox(output, from, to, p) {
+ mixAxis(output.x, from.x, to.x, p);
+ mixAxis(output.y, from.y, to.y, p);
+}
+function hasOpacityCrossfade(node) {
+ return node.animationValues && node.animationValues.opacityExit !== void 0;
+}
+const defaultLayoutTransition = {
+ duration: 0.45,
+ ease: [0.4, 0, 0.1, 1]
+};
+const userAgentContains = (string) => typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().includes(string);
+const roundPoint = userAgentContains("applewebkit/") && !userAgentContains("chrome/") ? Math.round : noop;
+function roundAxis(axis) {
+ axis.min = roundPoint(axis.min);
+ axis.max = roundPoint(axis.max);
+}
+function roundBox(box) {
+ roundAxis(box.x);
+ roundAxis(box.y);
+}
+function shouldAnimatePositionOnly(animationType, snapshot, layout2) {
+ return animationType === "position" || animationType === "preserve-aspect" && !isNear(aspectRatio(snapshot), aspectRatio(layout2), 0.2);
+}
+function checkNodeWasScrollRoot(node) {
+ return node !== node.root && node.scroll?.wasRoot;
+}
+const DocumentProjectionNode = createProjectionNode$1({
+ attachResizeListener: (ref, notify) => addDomEvent(ref, "resize", notify),
+ measureScroll: () => ({
+ x: document.documentElement.scrollLeft || document.body?.scrollLeft || 0,
+ y: document.documentElement.scrollTop || document.body?.scrollTop || 0
+ }),
+ checkIsScrollRoot: () => true
+});
+const rootProjectionNode = {
+ current: void 0
+};
+const HTMLProjectionNode = createProjectionNode$1({
+ measureScroll: (instance) => ({
+ x: instance.scrollLeft,
+ y: instance.scrollTop
+ }),
+ defaultParent: () => {
+ if (!rootProjectionNode.current) {
+ const documentNode = new DocumentProjectionNode({});
+ documentNode.mount(window);
+ documentNode.setOptions({ layoutScroll: true });
+ rootProjectionNode.current = documentNode;
+ }
+ return rootProjectionNode.current;
+ },
+ resetTransform: (instance, value) => {
+ instance.style.transform = value !== void 0 ? value : "none";
+ },
+ checkIsScrollRoot: (instance) => Boolean(window.getComputedStyle(instance).position === "fixed")
+});
+const MotionConfigContext = reactExports.createContext({
+ transformPagePoint: (p) => p,
+ isStatic: false,
+ reducedMotion: "never"
+});
+function setRef(ref, value) {
+ if (typeof ref === "function") {
+ return ref(value);
+ } else if (ref !== null && ref !== void 0) {
+ ref.current = value;
+ }
+}
+function composeRefs(...refs) {
+ return (node) => {
+ let hasCleanup = false;
+ const cleanups = refs.map((ref) => {
+ const cleanup = setRef(ref, node);
+ if (!hasCleanup && typeof cleanup === "function") {
+ hasCleanup = true;
+ }
+ return cleanup;
+ });
+ if (hasCleanup) {
+ return () => {
+ for (let i = 0; i < cleanups.length; i++) {
+ const cleanup = cleanups[i];
+ if (typeof cleanup === "function") {
+ cleanup();
+ } else {
+ setRef(refs[i], null);
+ }
+ }
+ };
+ }
+ };
+}
+function useComposedRefs(...refs) {
+ return reactExports.useCallback(composeRefs(...refs), refs);
+}
+class PopChildMeasure extends reactExports.Component {
+ getSnapshotBeforeUpdate(prevProps) {
+ const element = this.props.childRef.current;
+ if (isHTMLElement(element) && prevProps.isPresent && !this.props.isPresent && this.props.pop !== false) {
+ const parent = element.offsetParent;
+ const parentWidth = isHTMLElement(parent) ? parent.offsetWidth || 0 : 0;
+ const parentHeight = isHTMLElement(parent) ? parent.offsetHeight || 0 : 0;
+ const computedStyle = getComputedStyle(element);
+ const size = this.props.sizeRef.current;
+ size.height = parseFloat(computedStyle.height);
+ size.width = parseFloat(computedStyle.width);
+ size.top = element.offsetTop;
+ size.left = element.offsetLeft;
+ size.right = parentWidth - size.width - size.left;
+ size.bottom = parentHeight - size.height - size.top;
+ }
+ return null;
+ }
+ /**
+ * Required with getSnapshotBeforeUpdate to stop React complaining.
+ */
+ componentDidUpdate() {
+ }
+ render() {
+ return this.props.children;
+ }
+}
+function PopChild({ children, isPresent, anchorX, anchorY, root, pop }) {
+ const id2 = reactExports.useId();
+ const ref = reactExports.useRef(null);
+ const size = reactExports.useRef({
+ width: 0,
+ height: 0,
+ top: 0,
+ left: 0,
+ right: 0,
+ bottom: 0
+ });
+ const { nonce } = reactExports.useContext(MotionConfigContext);
+ const childRef = children.props?.ref ?? children?.ref;
+ const composedRef = useComposedRefs(ref, childRef);
+ reactExports.useInsertionEffect(() => {
+ const { width, height, top, left, right, bottom } = size.current;
+ if (isPresent || pop === false || !ref.current || !width || !height)
+ return;
+ const x = anchorX === "left" ? `left: ${left}` : `right: ${right}`;
+ const y = anchorY === "bottom" ? `bottom: ${bottom}` : `top: ${top}`;
+ ref.current.dataset.motionPopId = id2;
+ const style = document.createElement("style");
+ if (nonce)
+ style.nonce = nonce;
+ const parent = root ?? document.head;
+ parent.appendChild(style);
+ if (style.sheet) {
+ style.sheet.insertRule(`
+ [data-motion-pop-id="${id2}"] {
+ position: absolute !important;
+ width: ${width}px !important;
+ height: ${height}px !important;
+ ${x}px !important;
+ ${y}px !important;
+ }
+ `);
+ }
+ return () => {
+ ref.current?.removeAttribute("data-motion-pop-id");
+ if (parent.contains(style)) {
+ parent.removeChild(style);
+ }
+ };
+ }, [isPresent]);
+ return jsxRuntimeExports.jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, pop, children: pop === false ? children : reactExports.cloneElement(children, { ref: composedRef }) });
+}
+const PresenceChild = ({ children, initial, isPresent, onExitComplete, custom, presenceAffectsLayout, mode, anchorX, anchorY, root }) => {
+ const presenceChildren = useConstant(newChildrenMap);
+ const id2 = reactExports.useId();
+ let isReusedContext = true;
+ let context = reactExports.useMemo(() => {
+ isReusedContext = false;
+ return {
+ id: id2,
+ initial,
+ isPresent,
+ custom,
+ onExitComplete: (childId) => {
+ presenceChildren.set(childId, true);
+ for (const isComplete of presenceChildren.values()) {
+ if (!isComplete)
+ return;
+ }
+ onExitComplete && onExitComplete();
+ },
+ register: (childId) => {
+ presenceChildren.set(childId, false);
+ return () => presenceChildren.delete(childId);
+ }
+ };
+ }, [isPresent, presenceChildren, onExitComplete]);
+ if (presenceAffectsLayout && isReusedContext) {
+ context = { ...context };
+ }
+ reactExports.useMemo(() => {
+ presenceChildren.forEach((_, key) => presenceChildren.set(key, false));
+ }, [isPresent]);
+ reactExports.useEffect(() => {
+ !isPresent && !presenceChildren.size && onExitComplete && onExitComplete();
+ }, [isPresent]);
+ children = jsxRuntimeExports.jsx(PopChild, { pop: mode === "popLayout", isPresent, anchorX, anchorY, root, children });
+ return jsxRuntimeExports.jsx(PresenceContext.Provider, { value: context, children });
+};
+function newChildrenMap() {
+ return /* @__PURE__ */ new Map();
+}
+function usePresence(subscribe = true) {
+ const context = reactExports.useContext(PresenceContext);
+ if (context === null)
+ return [true, null];
+ const { isPresent, onExitComplete, register } = context;
+ const id2 = reactExports.useId();
+ reactExports.useEffect(() => {
+ if (subscribe) {
+ return register(id2);
+ }
+ }, [subscribe]);
+ const safeToRemove = reactExports.useCallback(() => subscribe && onExitComplete && onExitComplete(id2), [id2, onExitComplete, subscribe]);
+ return !isPresent && onExitComplete ? [false, safeToRemove] : [true];
+}
+const getChildKey = (child) => child.key || "";
+function onlyElements(children) {
+ const filtered = [];
+ reactExports.Children.forEach(children, (child) => {
+ if (reactExports.isValidElement(child))
+ filtered.push(child);
+ });
+ return filtered;
+}
+const AnimatePresence = ({ children, custom, initial = true, onExitComplete, presenceAffectsLayout = true, mode = "sync", propagate = false, anchorX = "left", anchorY = "top", root }) => {
+ const [isParentPresent, safeToRemove] = usePresence(propagate);
+ const presentChildren = reactExports.useMemo(() => onlyElements(children), [children]);
+ const presentKeys = propagate && !isParentPresent ? [] : presentChildren.map(getChildKey);
+ const isInitialRender = reactExports.useRef(true);
+ const pendingPresentChildren = reactExports.useRef(presentChildren);
+ const exitComplete = useConstant(() => /* @__PURE__ */ new Map());
+ const exitingComponents = reactExports.useRef(/* @__PURE__ */ new Set());
+ const [diffedChildren, setDiffedChildren] = reactExports.useState(presentChildren);
+ const [renderedChildren, setRenderedChildren] = reactExports.useState(presentChildren);
+ useIsomorphicLayoutEffect(() => {
+ isInitialRender.current = false;
+ pendingPresentChildren.current = presentChildren;
+ for (let i = 0; i < renderedChildren.length; i++) {
+ const key = getChildKey(renderedChildren[i]);
+ if (!presentKeys.includes(key)) {
+ if (exitComplete.get(key) !== true) {
+ exitComplete.set(key, false);
+ }
+ } else {
+ exitComplete.delete(key);
+ exitingComponents.current.delete(key);
+ }
+ }
+ }, [renderedChildren, presentKeys.length, presentKeys.join("-")]);
+ const exitingChildren = [];
+ if (presentChildren !== diffedChildren) {
+ let nextChildren = [...presentChildren];
+ for (let i = 0; i < renderedChildren.length; i++) {
+ const child = renderedChildren[i];
+ const key = getChildKey(child);
+ if (!presentKeys.includes(key)) {
+ nextChildren.splice(i, 0, child);
+ exitingChildren.push(child);
+ }
+ }
+ if (mode === "wait" && exitingChildren.length) {
+ nextChildren = exitingChildren;
+ }
+ setRenderedChildren(onlyElements(nextChildren));
+ setDiffedChildren(presentChildren);
+ return null;
+ }
+ if (process.env.NODE_ENV !== "production" && mode === "wait" && renderedChildren.length > 1) {
+ console.warn(`You're attempting to animate multiple children within AnimatePresence, but its mode is set to "wait". This will lead to odd visual behaviour.`);
+ }
+ const { forceRender } = reactExports.useContext(LayoutGroupContext);
+ return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: renderedChildren.map((child) => {
+ const key = getChildKey(child);
+ const isPresent = propagate && !isParentPresent ? false : presentChildren === renderedChildren || presentKeys.includes(key);
+ const onExit = () => {
+ if (exitingComponents.current.has(key)) {
+ return;
+ }
+ if (exitComplete.has(key)) {
+ exitingComponents.current.add(key);
+ exitComplete.set(key, true);
+ } else {
+ return;
+ }
+ let isEveryExitComplete = true;
+ exitComplete.forEach((isExitComplete) => {
+ if (!isExitComplete)
+ isEveryExitComplete = false;
+ });
+ if (isEveryExitComplete) {
+ forceRender?.();
+ setRenderedChildren(pendingPresentChildren.current);
+ propagate && safeToRemove?.();
+ onExitComplete && onExitComplete();
+ }
+ };
+ return jsxRuntimeExports.jsx(PresenceChild, { isPresent, initial: !isInitialRender.current || initial ? void 0 : false, custom, presenceAffectsLayout, mode, root, onExitComplete: isPresent ? void 0 : onExit, anchorX, anchorY, children: child }, key);
+ }) });
+};
+const LazyContext = reactExports.createContext({ strict: false });
+const featureProps = {
+ animation: [
+ "animate",
+ "variants",
+ "whileHover",
+ "whileTap",
+ "exit",
+ "whileInView",
+ "whileFocus",
+ "whileDrag"
+ ],
+ exit: ["exit"],
+ drag: ["drag", "dragControls"],
+ focus: ["whileFocus"],
+ hover: ["whileHover", "onHoverStart", "onHoverEnd"],
+ tap: ["whileTap", "onTap", "onTapStart", "onTapCancel"],
+ pan: ["onPan", "onPanStart", "onPanSessionStart", "onPanEnd"],
+ inView: ["whileInView", "onViewportEnter", "onViewportLeave"],
+ layout: ["layout", "layoutId"]
+};
+let isInitialized = false;
+function initFeatureDefinitions() {
+ if (isInitialized)
+ return;
+ const initialFeatureDefinitions = {};
+ for (const key in featureProps) {
+ initialFeatureDefinitions[key] = {
+ isEnabled: (props) => featureProps[key].some((name) => !!props[name])
+ };
+ }
+ setFeatureDefinitions(initialFeatureDefinitions);
+ isInitialized = true;
+}
+function getInitializedFeatureDefinitions() {
+ initFeatureDefinitions();
+ return getFeatureDefinitions();
+}
+function loadFeatures(features) {
+ const featureDefinitions2 = getInitializedFeatureDefinitions();
+ for (const key in features) {
+ featureDefinitions2[key] = {
+ ...featureDefinitions2[key],
+ ...features[key]
+ };
+ }
+ setFeatureDefinitions(featureDefinitions2);
+}
+const validMotionProps = /* @__PURE__ */ new Set([
+ "animate",
+ "exit",
+ "variants",
+ "initial",
+ "style",
+ "values",
+ "variants",
+ "transition",
+ "transformTemplate",
+ "custom",
+ "inherit",
+ "onBeforeLayoutMeasure",
+ "onAnimationStart",
+ "onAnimationComplete",
+ "onUpdate",
+ "onDragStart",
+ "onDrag",
+ "onDragEnd",
+ "onMeasureDragConstraints",
+ "onDirectionLock",
+ "onDragTransitionEnd",
+ "_dragX",
+ "_dragY",
+ "onHoverStart",
+ "onHoverEnd",
+ "onViewportEnter",
+ "onViewportLeave",
+ "globalTapTarget",
+ "propagate",
+ "ignoreStrict",
+ "viewport"
+]);
+function isValidMotionProp(key) {
+ return key.startsWith("while") || key.startsWith("drag") && key !== "draggable" || key.startsWith("layout") || key.startsWith("onTap") || key.startsWith("onPan") || key.startsWith("onLayout") || validMotionProps.has(key);
+}
+let shouldForward = (key) => !isValidMotionProp(key);
+function loadExternalIsValidProp(isValidProp) {
+ if (typeof isValidProp !== "function")
+ return;
+ shouldForward = (key) => key.startsWith("on") ? !isValidMotionProp(key) : isValidProp(key);
+}
+try {
+ const emotionPkg = "@emotion/is-prop-valid";
+ loadExternalIsValidProp(require(emotionPkg).default);
+} catch {
+}
+function filterProps(props, isDom, forwardMotionProps) {
+ const filteredProps = {};
+ for (const key in props) {
+ if (key === "values" && typeof props.values === "object")
+ continue;
+ if (isMotionValue(props[key]))
+ continue;
+ if (shouldForward(key) || forwardMotionProps === true && isValidMotionProp(key) || !isDom && !isValidMotionProp(key) || // If trying to use native HTML drag events, forward drag listeners
+ props["draggable"] && key.startsWith("onDrag")) {
+ filteredProps[key] = props[key];
+ }
+ }
+ return filteredProps;
+}
+const MotionContext = /* @__PURE__ */ reactExports.createContext({});
+function getCurrentTreeVariants(props, context) {
+ if (isControllingVariants(props)) {
+ const { initial, animate } = props;
+ return {
+ initial: initial === false || isVariantLabel(initial) ? initial : void 0,
+ animate: isVariantLabel(animate) ? animate : void 0
+ };
+ }
+ return props.inherit !== false ? context : {};
+}
+function useCreateMotionContext(props) {
+ const { initial, animate } = getCurrentTreeVariants(props, reactExports.useContext(MotionContext));
+ return reactExports.useMemo(() => ({ initial, animate }), [variantLabelsAsDependency(initial), variantLabelsAsDependency(animate)]);
+}
+function variantLabelsAsDependency(prop) {
+ return Array.isArray(prop) ? prop.join(" ") : prop;
+}
+const createHtmlRenderState = () => ({
+ style: {},
+ transform: {},
+ transformOrigin: {},
+ vars: {}
+});
+function copyRawValuesOnly(target, source, props) {
+ for (const key in source) {
+ if (!isMotionValue(source[key]) && !isForcedMotionValue(key, props)) {
+ target[key] = source[key];
+ }
+ }
+}
+function useInitialMotionValues({ transformTemplate }, visualState) {
+ return reactExports.useMemo(() => {
+ const state = createHtmlRenderState();
+ buildHTMLStyles(state, visualState, transformTemplate);
+ return Object.assign({}, state.vars, state.style);
+ }, [visualState]);
+}
+function useStyle(props, visualState) {
+ const styleProp = props.style || {};
+ const style = {};
+ copyRawValuesOnly(style, styleProp, props);
+ Object.assign(style, useInitialMotionValues(props, visualState));
+ return style;
+}
+function useHTMLProps(props, visualState) {
+ const htmlProps = {};
+ const style = useStyle(props, visualState);
+ if (props.drag && props.dragListener !== false) {
+ htmlProps.draggable = false;
+ style.userSelect = style.WebkitUserSelect = style.WebkitTouchCallout = "none";
+ style.touchAction = props.drag === true ? "none" : `pan-${props.drag === "x" ? "y" : "x"}`;
+ }
+ if (props.tabIndex === void 0 && (props.onTap || props.onTapStart || props.whileTap)) {
+ htmlProps.tabIndex = 0;
+ }
+ htmlProps.style = style;
+ return htmlProps;
+}
+const createSvgRenderState = () => ({
+ ...createHtmlRenderState(),
+ attrs: {}
+});
+function useSVGProps(props, visualState, _isStatic, Component) {
+ const visualProps = reactExports.useMemo(() => {
+ const state = createSvgRenderState();
+ buildSVGAttrs(state, visualState, isSVGTag(Component), props.transformTemplate, props.style);
+ return {
+ ...state.attrs,
+ style: { ...state.style }
+ };
+ }, [visualState]);
+ if (props.style) {
+ const rawStyles = {};
+ copyRawValuesOnly(rawStyles, props.style, props);
+ visualProps.style = { ...rawStyles, ...visualProps.style };
+ }
+ return visualProps;
+}
+const lowercaseSVGElements = [
+ "animate",
+ "circle",
+ "defs",
+ "desc",
+ "ellipse",
+ "g",
+ "image",
+ "line",
+ "filter",
+ "marker",
+ "mask",
+ "metadata",
+ "path",
+ "pattern",
+ "polygon",
+ "polyline",
+ "rect",
+ "stop",
+ "switch",
+ "symbol",
+ "svg",
+ "text",
+ "tspan",
+ "use",
+ "view"
+];
+function isSVGComponent(Component) {
+ if (
+ /**
+ * If it's not a string, it's a custom React component. Currently we only support
+ * HTML custom React components.
+ */
+ typeof Component !== "string" || /**
+ * If it contains a dash, the element is a custom HTML webcomponent.
+ */
+ Component.includes("-")
+ ) {
+ return false;
+ } else if (
+ /**
+ * If it's in our list of lowercase SVG tags, it's an SVG component
+ */
+ lowercaseSVGElements.indexOf(Component) > -1 || /**
+ * If it contains a capital letter, it's an SVG component
+ */
+ /[A-Z]/u.test(Component)
+ ) {
+ return true;
+ }
+ return false;
+}
+function useRender(Component, props, ref, { latestValues }, isStatic, forwardMotionProps = false, isSVG) {
+ const useVisualProps = isSVG ?? isSVGComponent(Component) ? useSVGProps : useHTMLProps;
+ const visualProps = useVisualProps(props, latestValues, isStatic, Component);
+ const filteredProps = filterProps(props, typeof Component === "string", forwardMotionProps);
+ const elementProps = Component !== reactExports.Fragment ? { ...filteredProps, ...visualProps, ref } : {};
+ const { children } = props;
+ const renderedChildren = reactExports.useMemo(() => isMotionValue(children) ? children.get() : children, [children]);
+ return reactExports.createElement(Component, {
+ ...elementProps,
+ children: renderedChildren
+ });
+}
+function makeState({ scrapeMotionValuesFromProps: scrapeMotionValuesFromProps2, createRenderState }, props, context, presenceContext) {
+ const state = {
+ latestValues: makeLatestValues(props, context, presenceContext, scrapeMotionValuesFromProps2),
+ renderState: createRenderState()
+ };
+ return state;
+}
+function makeLatestValues(props, context, presenceContext, scrapeMotionValues) {
+ const values = {};
+ const motionValues = scrapeMotionValues(props, {});
+ for (const key in motionValues) {
+ values[key] = resolveMotionValue(motionValues[key]);
+ }
+ let { initial, animate } = props;
+ const isControllingVariants$1 = isControllingVariants(props);
+ const isVariantNode$1 = isVariantNode(props);
+ if (context && isVariantNode$1 && !isControllingVariants$1 && props.inherit !== false) {
+ if (initial === void 0)
+ initial = context.initial;
+ if (animate === void 0)
+ animate = context.animate;
+ }
+ let isInitialAnimationBlocked = presenceContext ? presenceContext.initial === false : false;
+ isInitialAnimationBlocked = isInitialAnimationBlocked || initial === false;
+ const variantToSet = isInitialAnimationBlocked ? animate : initial;
+ if (variantToSet && typeof variantToSet !== "boolean" && !isAnimationControls(variantToSet)) {
+ const list = Array.isArray(variantToSet) ? variantToSet : [variantToSet];
+ for (let i = 0; i < list.length; i++) {
+ const resolved = resolveVariantFromProps(props, list[i]);
+ if (resolved) {
+ const { transitionEnd, transition, ...target } = resolved;
+ for (const key in target) {
+ let valueTarget = target[key];
+ if (Array.isArray(valueTarget)) {
+ const index = isInitialAnimationBlocked ? valueTarget.length - 1 : 0;
+ valueTarget = valueTarget[index];
+ }
+ if (valueTarget !== null) {
+ values[key] = valueTarget;
+ }
+ }
+ for (const key in transitionEnd) {
+ values[key] = transitionEnd[key];
+ }
+ }
+ }
+ }
+ return values;
+}
+const makeUseVisualState = (config) => (props, isStatic) => {
+ const context = reactExports.useContext(MotionContext);
+ const presenceContext = reactExports.useContext(PresenceContext);
+ const make = () => makeState(config, props, context, presenceContext);
+ return isStatic ? make() : useConstant(make);
+};
+const useHTMLVisualState = /* @__PURE__ */ makeUseVisualState({
+ scrapeMotionValuesFromProps: scrapeMotionValuesFromProps$1,
+ createRenderState: createHtmlRenderState
+});
+const useSVGVisualState = /* @__PURE__ */ makeUseVisualState({
+ scrapeMotionValuesFromProps,
+ createRenderState: createSvgRenderState
+});
+const motionComponentSymbol = /* @__PURE__ */ Symbol.for("motionComponentSymbol");
+function useMotionRef(visualState, visualElement, externalRef) {
+ const externalRefContainer = reactExports.useRef(externalRef);
+ reactExports.useInsertionEffect(() => {
+ externalRefContainer.current = externalRef;
+ });
+ const refCleanup = reactExports.useRef(null);
+ return reactExports.useCallback((instance) => {
+ if (instance) {
+ visualState.onMount?.(instance);
+ }
+ const ref = externalRefContainer.current;
+ if (typeof ref === "function") {
+ if (instance) {
+ const cleanup = ref(instance);
+ if (typeof cleanup === "function") {
+ refCleanup.current = cleanup;
+ }
+ } else if (refCleanup.current) {
+ refCleanup.current();
+ refCleanup.current = null;
+ } else {
+ ref(instance);
+ }
+ } else if (ref) {
+ ref.current = instance;
+ }
+ if (visualElement) {
+ instance ? visualElement.mount(instance) : visualElement.unmount();
+ }
+ }, [visualElement]);
+}
+const SwitchLayoutGroupContext = reactExports.createContext({});
+function isRefObject(ref) {
+ return ref && typeof ref === "object" && Object.prototype.hasOwnProperty.call(ref, "current");
+}
+function useVisualElement(Component, visualState, props, createVisualElement, ProjectionNodeConstructor, isSVG) {
+ const { visualElement: parent } = reactExports.useContext(MotionContext);
+ const lazyContext = reactExports.useContext(LazyContext);
+ const presenceContext = reactExports.useContext(PresenceContext);
+ const motionConfig = reactExports.useContext(MotionConfigContext);
+ const reducedMotionConfig = motionConfig.reducedMotion;
+ const skipAnimations = motionConfig.skipAnimations;
+ const visualElementRef = reactExports.useRef(null);
+ const hasMountedOnce = reactExports.useRef(false);
+ createVisualElement = createVisualElement || lazyContext.renderer;
+ if (!visualElementRef.current && createVisualElement) {
+ visualElementRef.current = createVisualElement(Component, {
+ visualState,
+ parent,
+ props,
+ presenceContext,
+ blockInitialAnimation: presenceContext ? presenceContext.initial === false : false,
+ reducedMotionConfig,
+ skipAnimations,
+ isSVG
+ });
+ if (hasMountedOnce.current && visualElementRef.current) {
+ visualElementRef.current.manuallyAnimateOnMount = true;
+ }
+ }
+ const visualElement = visualElementRef.current;
+ const initialLayoutGroupConfig = reactExports.useContext(SwitchLayoutGroupContext);
+ if (visualElement && !visualElement.projection && ProjectionNodeConstructor && (visualElement.type === "html" || visualElement.type === "svg")) {
+ createProjectionNode(visualElementRef.current, props, ProjectionNodeConstructor, initialLayoutGroupConfig);
+ }
+ const isMounted = reactExports.useRef(false);
+ reactExports.useInsertionEffect(() => {
+ if (visualElement && isMounted.current) {
+ visualElement.update(props, presenceContext);
+ }
+ });
+ const optimisedAppearId = props[optimizedAppearDataAttribute];
+ const wantsHandoff = reactExports.useRef(Boolean(optimisedAppearId) && typeof window !== "undefined" && !window.MotionHandoffIsComplete?.(optimisedAppearId) && window.MotionHasOptimisedAnimation?.(optimisedAppearId));
+ useIsomorphicLayoutEffect(() => {
+ hasMountedOnce.current = true;
+ if (!visualElement)
+ return;
+ isMounted.current = true;
+ window.MotionIsMounted = true;
+ visualElement.updateFeatures();
+ visualElement.scheduleRenderMicrotask();
+ if (wantsHandoff.current && visualElement.animationState) {
+ visualElement.animationState.animateChanges();
+ }
+ });
+ reactExports.useEffect(() => {
+ if (!visualElement)
+ return;
+ if (!wantsHandoff.current && visualElement.animationState) {
+ visualElement.animationState.animateChanges();
+ }
+ if (wantsHandoff.current) {
+ queueMicrotask(() => {
+ window.MotionHandoffMarkAsComplete?.(optimisedAppearId);
+ });
+ wantsHandoff.current = false;
+ }
+ visualElement.enteringChildren = void 0;
+ });
+ return visualElement;
+}
+function createProjectionNode(visualElement, props, ProjectionNodeConstructor, initialPromotionConfig) {
+ const { layoutId, layout: layout2, drag: drag2, dragConstraints, layoutScroll, layoutRoot, layoutAnchor, layoutCrossfade } = props;
+ visualElement.projection = new ProjectionNodeConstructor(visualElement.latestValues, props["data-framer-portal-id"] ? void 0 : getClosestProjectingNode(visualElement.parent));
+ visualElement.projection.setOptions({
+ layoutId,
+ layout: layout2,
+ alwaysMeasureLayout: Boolean(drag2) || dragConstraints && isRefObject(dragConstraints),
+ visualElement,
+ /**
+ * TODO: Update options in an effect. This could be tricky as it'll be too late
+ * to update by the time layout animations run.
+ * We also need to fix this safeToRemove by linking it up to the one returned by usePresence,
+ * ensuring it gets called if there's no potential layout animations.
+ *
+ */
+ animationType: typeof layout2 === "string" ? layout2 : "both",
+ initialPromotionConfig,
+ crossfade: layoutCrossfade,
+ layoutScroll,
+ layoutRoot,
+ layoutAnchor
+ });
+}
+function getClosestProjectingNode(visualElement) {
+ if (!visualElement)
+ return void 0;
+ return visualElement.options.allowProjection !== false ? visualElement.projection : getClosestProjectingNode(visualElement.parent);
+}
+function createMotionComponent(Component, { forwardMotionProps = false, type } = {}, preloadedFeatures, createVisualElement) {
+ preloadedFeatures && loadFeatures(preloadedFeatures);
+ const isSVG = type ? type === "svg" : isSVGComponent(Component);
+ const useVisualState = isSVG ? useSVGVisualState : useHTMLVisualState;
+ function MotionDOMComponent(props, externalRef) {
+ let MeasureLayout2;
+ const configAndProps = {
+ ...reactExports.useContext(MotionConfigContext),
+ ...props,
+ layoutId: useLayoutId(props)
+ };
+ const { isStatic } = configAndProps;
+ const context = useCreateMotionContext(props);
+ const visualState = useVisualState(props, isStatic);
+ if (!isStatic && typeof window !== "undefined") {
+ useStrictMode(configAndProps, preloadedFeatures);
+ const layoutProjection = getProjectionFunctionality(configAndProps);
+ MeasureLayout2 = layoutProjection.MeasureLayout;
+ context.visualElement = useVisualElement(Component, visualState, configAndProps, createVisualElement, layoutProjection.ProjectionNode, isSVG);
+ }
+ return jsxRuntimeExports.jsxs(MotionContext.Provider, { value: context, children: [MeasureLayout2 && context.visualElement ? jsxRuntimeExports.jsx(MeasureLayout2, { visualElement: context.visualElement, ...configAndProps }) : null, useRender(Component, props, useMotionRef(visualState, context.visualElement, externalRef), visualState, isStatic, forwardMotionProps, isSVG)] });
+ }
+ MotionDOMComponent.displayName = `motion.${typeof Component === "string" ? Component : `create(${Component.displayName ?? Component.name ?? ""})`}`;
+ const ForwardRefMotionComponent = reactExports.forwardRef(MotionDOMComponent);
+ ForwardRefMotionComponent[motionComponentSymbol] = Component;
+ return ForwardRefMotionComponent;
+}
+function useLayoutId({ layoutId }) {
+ const layoutGroupId = reactExports.useContext(LayoutGroupContext).id;
+ return layoutGroupId && layoutId !== void 0 ? layoutGroupId + "-" + layoutId : layoutId;
+}
+function useStrictMode(configAndProps, preloadedFeatures) {
+ const isStrict = reactExports.useContext(LazyContext).strict;
+ if (process.env.NODE_ENV !== "production" && preloadedFeatures && isStrict) {
+ const strictMessage = "You have rendered a `motion` component within a `LazyMotion` component. This will break tree shaking. Import and render a `m` component instead.";
+ configAndProps.ignoreStrict ? warning(false, strictMessage, "lazy-strict-mode") : invariant(false, strictMessage, "lazy-strict-mode");
+ }
+}
+function getProjectionFunctionality(props) {
+ const featureDefinitions2 = getInitializedFeatureDefinitions();
+ const { drag: drag2, layout: layout2 } = featureDefinitions2;
+ if (!drag2 && !layout2)
+ return {};
+ const combined = { ...drag2, ...layout2 };
+ return {
+ MeasureLayout: drag2?.isEnabled(props) || layout2?.isEnabled(props) ? combined.MeasureLayout : void 0,
+ ProjectionNode: combined.ProjectionNode
+ };
+}
+function createMotionProxy(preloadedFeatures, createVisualElement) {
+ if (typeof Proxy === "undefined") {
+ return createMotionComponent;
+ }
+ const componentCache = /* @__PURE__ */ new Map();
+ const factory = (Component, options) => {
+ return createMotionComponent(Component, options, preloadedFeatures, createVisualElement);
+ };
+ const deprecatedFactoryFunction = (Component, options) => {
+ if (process.env.NODE_ENV !== "production") {
+ warnOnce(false, "motion() is deprecated. Use motion.create() instead.");
+ }
+ return factory(Component, options);
+ };
+ return new Proxy(deprecatedFactoryFunction, {
+ /**
+ * Called when `motion` is referenced with a prop: `motion.div`, `motion.input` etc.
+ * The prop name is passed through as `key` and we can use that to generate a `motion`
+ * DOM component with that name.
+ */
+ get: (_target, key) => {
+ if (key === "create")
+ return factory;
+ if (!componentCache.has(key)) {
+ componentCache.set(key, createMotionComponent(key, void 0, preloadedFeatures, createVisualElement));
+ }
+ return componentCache.get(key);
+ }
+ });
+}
+const createDomVisualElement = (Component, options) => {
+ const isSVG = options.isSVG ?? isSVGComponent(Component);
+ return isSVG ? new SVGVisualElement(options) : new HTMLVisualElement(options, {
+ allowProjection: Component !== reactExports.Fragment
+ });
+};
+class AnimationFeature extends Feature {
+ /**
+ * We dynamically generate the AnimationState manager as it contains a reference
+ * to the underlying animation library. We only want to load that if we load this,
+ * so people can optionally code split it out using the `m` component.
+ */
+ constructor(node) {
+ super(node);
+ node.animationState || (node.animationState = createAnimationState(node));
+ }
+ updateAnimationControlsSubscription() {
+ const { animate } = this.node.getProps();
+ if (isAnimationControls(animate)) {
+ this.unmountControls = animate.subscribe(this.node);
+ }
+ }
+ /**
+ * Subscribe any provided AnimationControls to the component's VisualElement
+ */
+ mount() {
+ this.updateAnimationControlsSubscription();
+ }
+ update() {
+ const { animate } = this.node.getProps();
+ const { animate: prevAnimate } = this.node.prevProps || {};
+ if (animate !== prevAnimate) {
+ this.updateAnimationControlsSubscription();
+ }
+ }
+ unmount() {
+ this.node.animationState.reset();
+ this.unmountControls?.();
+ }
+}
+let id = 0;
+class ExitAnimationFeature extends Feature {
+ constructor() {
+ super(...arguments);
+ this.id = id++;
+ this.isExitComplete = false;
+ }
+ update() {
+ if (!this.node.presenceContext)
+ return;
+ const { isPresent, onExitComplete } = this.node.presenceContext;
+ const { isPresent: prevIsPresent } = this.node.prevPresenceContext || {};
+ if (!this.node.animationState || isPresent === prevIsPresent) {
+ return;
+ }
+ if (isPresent && prevIsPresent === false) {
+ if (this.isExitComplete) {
+ const { initial, custom } = this.node.getProps();
+ if (typeof initial === "string") {
+ const resolved = resolveVariant(this.node, initial, custom);
+ if (resolved) {
+ const { transition, transitionEnd, ...target } = resolved;
+ for (const key in target) {
+ this.node.getValue(key)?.jump(target[key]);
+ }
+ }
+ }
+ this.node.animationState.reset();
+ this.node.animationState.animateChanges();
+ } else {
+ this.node.animationState.setActive("exit", false);
+ }
+ this.isExitComplete = false;
+ return;
+ }
+ const exitAnimation = this.node.animationState.setActive("exit", !isPresent);
+ if (onExitComplete && !isPresent) {
+ exitAnimation.then(() => {
+ this.isExitComplete = true;
+ onExitComplete(this.id);
+ });
+ }
+ }
+ mount() {
+ const { register, onExitComplete } = this.node.presenceContext || {};
+ if (onExitComplete) {
+ onExitComplete(this.id);
+ }
+ if (register) {
+ this.unmount = register(this.id);
+ }
+ }
+ unmount() {
+ }
+}
+const animations = {
+ animation: {
+ Feature: AnimationFeature
+ },
+ exit: {
+ Feature: ExitAnimationFeature
+ }
+};
+function extractEventInfo(event) {
+ return {
+ point: {
+ x: event.pageX,
+ y: event.pageY
+ }
+ };
+}
+const addPointerInfo = (handler) => (event) => isPrimaryPointer(event) && handler(event, extractEventInfo(event));
+function addPointerEvent(target, eventName, handler, options) {
+ return addDomEvent(target, eventName, addPointerInfo(handler), options);
+}
+const getContextWindow = ({ current }) => {
+ return current ? current.ownerDocument.defaultView : null;
+};
+const distance = (a, b) => Math.abs(a - b);
+function distance2D(a, b) {
+ const xDelta = distance(a.x, b.x);
+ const yDelta = distance(a.y, b.y);
+ return Math.sqrt(xDelta ** 2 + yDelta ** 2);
+}
+const overflowStyles = /* @__PURE__ */ new Set(["auto", "scroll"]);
+class PanSession {
+ constructor(event, handlers, { transformPagePoint, contextWindow = window, dragSnapToOrigin = false, distanceThreshold = 3, element } = {}) {
+ this.startEvent = null;
+ this.lastMoveEvent = null;
+ this.lastMoveEventInfo = null;
+ this.lastRawMoveEventInfo = null;
+ this.handlers = {};
+ this.contextWindow = window;
+ this.scrollPositions = /* @__PURE__ */ new Map();
+ this.removeScrollListeners = null;
+ this.onElementScroll = (event2) => {
+ this.handleScroll(event2.target);
+ };
+ this.onWindowScroll = () => {
+ this.handleScroll(window);
+ };
+ this.updatePoint = () => {
+ if (!(this.lastMoveEvent && this.lastMoveEventInfo))
+ return;
+ if (this.lastRawMoveEventInfo) {
+ this.lastMoveEventInfo = transformPoint(this.lastRawMoveEventInfo, this.transformPagePoint);
+ }
+ const info2 = getPanInfo(this.lastMoveEventInfo, this.history);
+ const isPanStarted = this.startEvent !== null;
+ const isDistancePastThreshold = distance2D(info2.offset, { x: 0, y: 0 }) >= this.distanceThreshold;
+ if (!isPanStarted && !isDistancePastThreshold)
+ return;
+ const { point: point2 } = info2;
+ const { timestamp: timestamp2 } = frameData;
+ this.history.push({ ...point2, timestamp: timestamp2 });
+ const { onStart, onMove } = this.handlers;
+ if (!isPanStarted) {
+ onStart && onStart(this.lastMoveEvent, info2);
+ this.startEvent = this.lastMoveEvent;
+ }
+ onMove && onMove(this.lastMoveEvent, info2);
+ };
+ this.handlePointerMove = (event2, info2) => {
+ this.lastMoveEvent = event2;
+ this.lastRawMoveEventInfo = info2;
+ this.lastMoveEventInfo = transformPoint(info2, this.transformPagePoint);
+ frame.update(this.updatePoint, true);
+ };
+ this.handlePointerUp = (event2, info2) => {
+ this.end();
+ const { onEnd, onSessionEnd, resumeAnimation } = this.handlers;
+ if (this.dragSnapToOrigin || !this.startEvent) {
+ resumeAnimation && resumeAnimation();
+ }
+ if (!(this.lastMoveEvent && this.lastMoveEventInfo))
+ return;
+ const panInfo = getPanInfo(event2.type === "pointercancel" ? this.lastMoveEventInfo : transformPoint(info2, this.transformPagePoint), this.history);
+ if (this.startEvent && onEnd) {
+ onEnd(event2, panInfo);
+ }
+ onSessionEnd && onSessionEnd(event2, panInfo);
+ };
+ if (!isPrimaryPointer(event))
+ return;
+ this.dragSnapToOrigin = dragSnapToOrigin;
+ this.handlers = handlers;
+ this.transformPagePoint = transformPagePoint;
+ this.distanceThreshold = distanceThreshold;
+ this.contextWindow = contextWindow || window;
+ const info = extractEventInfo(event);
+ const initialInfo = transformPoint(info, this.transformPagePoint);
+ const { point } = initialInfo;
+ const { timestamp } = frameData;
+ this.history = [{ ...point, timestamp }];
+ const { onSessionStart } = handlers;
+ onSessionStart && onSessionStart(event, getPanInfo(initialInfo, this.history));
+ this.removeListeners = pipe(addPointerEvent(this.contextWindow, "pointermove", this.handlePointerMove), addPointerEvent(this.contextWindow, "pointerup", this.handlePointerUp), addPointerEvent(this.contextWindow, "pointercancel", this.handlePointerUp));
+ if (element) {
+ this.startScrollTracking(element);
+ }
+ }
+ /**
+ * Start tracking scroll on ancestors and window.
+ */
+ startScrollTracking(element) {
+ let current = element.parentElement;
+ while (current) {
+ const style = getComputedStyle(current);
+ if (overflowStyles.has(style.overflowX) || overflowStyles.has(style.overflowY)) {
+ this.scrollPositions.set(current, {
+ x: current.scrollLeft,
+ y: current.scrollTop
+ });
+ }
+ current = current.parentElement;
+ }
+ this.scrollPositions.set(window, {
+ x: window.scrollX,
+ y: window.scrollY
+ });
+ window.addEventListener("scroll", this.onElementScroll, {
+ capture: true
+ });
+ window.addEventListener("scroll", this.onWindowScroll);
+ this.removeScrollListeners = () => {
+ window.removeEventListener("scroll", this.onElementScroll, {
+ capture: true
+ });
+ window.removeEventListener("scroll", this.onWindowScroll);
+ };
+ }
+ /**
+ * Handle scroll compensation during drag.
+ *
+ * For element scroll: adjusts history origin since pageX/pageY doesn't change.
+ * For window scroll: adjusts lastMoveEventInfo since pageX/pageY would change.
+ */
+ handleScroll(target) {
+ const initial = this.scrollPositions.get(target);
+ if (!initial)
+ return;
+ const isWindow = target === window;
+ const current = isWindow ? { x: window.scrollX, y: window.scrollY } : {
+ x: target.scrollLeft,
+ y: target.scrollTop
+ };
+ const delta = { x: current.x - initial.x, y: current.y - initial.y };
+ if (delta.x === 0 && delta.y === 0)
+ return;
+ if (isWindow) {
+ if (this.lastMoveEventInfo) {
+ this.lastMoveEventInfo.point.x += delta.x;
+ this.lastMoveEventInfo.point.y += delta.y;
+ }
+ } else {
+ if (this.history.length > 0) {
+ this.history[0].x -= delta.x;
+ this.history[0].y -= delta.y;
+ }
+ }
+ this.scrollPositions.set(target, current);
+ frame.update(this.updatePoint, true);
+ }
+ updateHandlers(handlers) {
+ this.handlers = handlers;
+ }
+ end() {
+ this.removeListeners && this.removeListeners();
+ this.removeScrollListeners && this.removeScrollListeners();
+ this.scrollPositions.clear();
+ cancelFrame(this.updatePoint);
+ }
+}
+function transformPoint(info, transformPagePoint) {
+ return transformPagePoint ? { point: transformPagePoint(info.point) } : info;
+}
+function subtractPoint(a, b) {
+ return { x: a.x - b.x, y: a.y - b.y };
+}
+function getPanInfo({ point }, history) {
+ return {
+ point,
+ delta: subtractPoint(point, lastDevicePoint(history)),
+ offset: subtractPoint(point, startDevicePoint(history)),
+ velocity: getVelocity(history, 0.1)
+ };
+}
+function startDevicePoint(history) {
+ return history[0];
+}
+function lastDevicePoint(history) {
+ return history[history.length - 1];
+}
+function getVelocity(history, timeDelta) {
+ if (history.length < 2) {
+ return { x: 0, y: 0 };
+ }
+ let i = history.length - 1;
+ let timestampedPoint = null;
+ const lastPoint = lastDevicePoint(history);
+ while (i >= 0) {
+ timestampedPoint = history[i];
+ if (lastPoint.timestamp - timestampedPoint.timestamp > /* @__PURE__ */ secondsToMilliseconds(timeDelta)) {
+ break;
+ }
+ i--;
+ }
+ if (!timestampedPoint) {
+ return { x: 0, y: 0 };
+ }
+ if (timestampedPoint === history[0] && history.length > 2 && lastPoint.timestamp - timestampedPoint.timestamp > /* @__PURE__ */ secondsToMilliseconds(timeDelta) * 2) {
+ timestampedPoint = history[1];
+ }
+ const time2 = /* @__PURE__ */ millisecondsToSeconds(lastPoint.timestamp - timestampedPoint.timestamp);
+ if (time2 === 0) {
+ return { x: 0, y: 0 };
+ }
+ const currentVelocity = {
+ x: (lastPoint.x - timestampedPoint.x) / time2,
+ y: (lastPoint.y - timestampedPoint.y) / time2
+ };
+ if (currentVelocity.x === Infinity) {
+ currentVelocity.x = 0;
+ }
+ if (currentVelocity.y === Infinity) {
+ currentVelocity.y = 0;
+ }
+ return currentVelocity;
+}
+function applyConstraints(point, { min, max }, elastic) {
+ if (min !== void 0 && point < min) {
+ point = elastic ? mixNumber$1(min, point, elastic.min) : Math.max(point, min);
+ } else if (max !== void 0 && point > max) {
+ point = elastic ? mixNumber$1(max, point, elastic.max) : Math.min(point, max);
+ }
+ return point;
+}
+function calcRelativeAxisConstraints(axis, min, max) {
+ return {
+ min: min !== void 0 ? axis.min + min : void 0,
+ max: max !== void 0 ? axis.max + max - (axis.max - axis.min) : void 0
+ };
+}
+function calcRelativeConstraints(layoutBox, { top, left, bottom, right }) {
+ return {
+ x: calcRelativeAxisConstraints(layoutBox.x, left, right),
+ y: calcRelativeAxisConstraints(layoutBox.y, top, bottom)
+ };
+}
+function calcViewportAxisConstraints(layoutAxis, constraintsAxis) {
+ let min = constraintsAxis.min - layoutAxis.min;
+ let max = constraintsAxis.max - layoutAxis.max;
+ if (constraintsAxis.max - constraintsAxis.min < layoutAxis.max - layoutAxis.min) {
+ [min, max] = [max, min];
+ }
+ return { min, max };
+}
+function calcViewportConstraints(layoutBox, constraintsBox) {
+ return {
+ x: calcViewportAxisConstraints(layoutBox.x, constraintsBox.x),
+ y: calcViewportAxisConstraints(layoutBox.y, constraintsBox.y)
+ };
+}
+function calcOrigin(source, target) {
+ let origin = 0.5;
+ const sourceLength = calcLength(source);
+ const targetLength = calcLength(target);
+ if (targetLength > sourceLength) {
+ origin = /* @__PURE__ */ progress(target.min, target.max - sourceLength, source.min);
+ } else if (sourceLength > targetLength) {
+ origin = /* @__PURE__ */ progress(source.min, source.max - targetLength, target.min);
+ }
+ return clamp(0, 1, origin);
+}
+function rebaseAxisConstraints(layout2, constraints) {
+ const relativeConstraints = {};
+ if (constraints.min !== void 0) {
+ relativeConstraints.min = constraints.min - layout2.min;
+ }
+ if (constraints.max !== void 0) {
+ relativeConstraints.max = constraints.max - layout2.min;
+ }
+ return relativeConstraints;
+}
+const defaultElastic = 0.35;
+function resolveDragElastic(dragElastic = defaultElastic) {
+ if (dragElastic === false) {
+ dragElastic = 0;
+ } else if (dragElastic === true) {
+ dragElastic = defaultElastic;
+ }
+ return {
+ x: resolveAxisElastic(dragElastic, "left", "right"),
+ y: resolveAxisElastic(dragElastic, "top", "bottom")
+ };
+}
+function resolveAxisElastic(dragElastic, minLabel, maxLabel) {
+ return {
+ min: resolvePointElastic(dragElastic, minLabel),
+ max: resolvePointElastic(dragElastic, maxLabel)
+ };
+}
+function resolvePointElastic(dragElastic, label) {
+ return typeof dragElastic === "number" ? dragElastic : dragElastic[label] || 0;
+}
+const elementDragControls = /* @__PURE__ */ new WeakMap();
+class VisualElementDragControls {
+ constructor(visualElement) {
+ this.openDragLock = null;
+ this.isDragging = false;
+ this.currentDirection = null;
+ this.originPoint = { x: 0, y: 0 };
+ this.constraints = false;
+ this.hasMutatedConstraints = false;
+ this.elastic = createBox();
+ this.latestPointerEvent = null;
+ this.latestPanInfo = null;
+ this.visualElement = visualElement;
+ }
+ start(originEvent, { snapToCursor = false, distanceThreshold } = {}) {
+ const { presenceContext } = this.visualElement;
+ if (presenceContext && presenceContext.isPresent === false)
+ return;
+ const onSessionStart = (event) => {
+ if (snapToCursor) {
+ this.snapToCursor(extractEventInfo(event).point);
+ }
+ this.stopAnimation();
+ };
+ const onStart = (event, info) => {
+ const { drag: drag2, dragPropagation, onDragStart } = this.getProps();
+ if (drag2 && !dragPropagation) {
+ if (this.openDragLock)
+ this.openDragLock();
+ this.openDragLock = setDragLock(drag2);
+ if (!this.openDragLock)
+ return;
+ }
+ this.latestPointerEvent = event;
+ this.latestPanInfo = info;
+ this.isDragging = true;
+ this.currentDirection = null;
+ this.resolveConstraints();
+ if (this.visualElement.projection) {
+ this.visualElement.projection.isAnimationBlocked = true;
+ this.visualElement.projection.target = void 0;
+ }
+ eachAxis((axis) => {
+ let current = this.getAxisMotionValue(axis).get() || 0;
+ if (percent.test(current)) {
+ const { projection } = this.visualElement;
+ if (projection && projection.layout) {
+ const measuredAxis = projection.layout.layoutBox[axis];
+ if (measuredAxis) {
+ const length = calcLength(measuredAxis);
+ current = length * (parseFloat(current) / 100);
+ }
+ }
+ }
+ this.originPoint[axis] = current;
+ });
+ if (onDragStart) {
+ frame.update(() => onDragStart(event, info), false, true);
+ }
+ addValueToWillChange(this.visualElement, "transform");
+ const { animationState } = this.visualElement;
+ animationState && animationState.setActive("whileDrag", true);
+ };
+ const onMove = (event, info) => {
+ this.latestPointerEvent = event;
+ this.latestPanInfo = info;
+ const { dragPropagation, dragDirectionLock, onDirectionLock, onDrag } = this.getProps();
+ if (!dragPropagation && !this.openDragLock)
+ return;
+ const { offset } = info;
+ if (dragDirectionLock && this.currentDirection === null) {
+ this.currentDirection = getCurrentDirection(offset);
+ if (this.currentDirection !== null) {
+ onDirectionLock && onDirectionLock(this.currentDirection);
+ }
+ return;
+ }
+ this.updateAxis("x", info.point, offset);
+ this.updateAxis("y", info.point, offset);
+ this.visualElement.render();
+ if (onDrag) {
+ frame.update(() => onDrag(event, info), false, true);
+ }
+ };
+ const onSessionEnd = (event, info) => {
+ this.latestPointerEvent = event;
+ this.latestPanInfo = info;
+ this.stop(event, info);
+ this.latestPointerEvent = null;
+ this.latestPanInfo = null;
+ };
+ const resumeAnimation = () => {
+ const { dragSnapToOrigin: snap } = this.getProps();
+ if (snap || this.constraints) {
+ this.startAnimation({ x: 0, y: 0 });
+ }
+ };
+ const { dragSnapToOrigin } = this.getProps();
+ this.panSession = new PanSession(originEvent, {
+ onSessionStart,
+ onStart,
+ onMove,
+ onSessionEnd,
+ resumeAnimation
+ }, {
+ transformPagePoint: this.visualElement.getTransformPagePoint(),
+ dragSnapToOrigin,
+ distanceThreshold,
+ contextWindow: getContextWindow(this.visualElement),
+ element: this.visualElement.current
+ });
+ }
+ /**
+ * @internal
+ */
+ stop(event, panInfo) {
+ const finalEvent = event || this.latestPointerEvent;
+ const finalPanInfo = panInfo || this.latestPanInfo;
+ const isDragging2 = this.isDragging;
+ this.cancel();
+ if (!isDragging2 || !finalPanInfo || !finalEvent)
+ return;
+ const { velocity } = finalPanInfo;
+ this.startAnimation(velocity);
+ const { onDragEnd } = this.getProps();
+ if (onDragEnd) {
+ frame.postRender(() => onDragEnd(finalEvent, finalPanInfo));
+ }
+ }
+ /**
+ * @internal
+ */
+ cancel() {
+ this.isDragging = false;
+ const { projection, animationState } = this.visualElement;
+ if (projection) {
+ projection.isAnimationBlocked = false;
+ }
+ this.endPanSession();
+ const { dragPropagation } = this.getProps();
+ if (!dragPropagation && this.openDragLock) {
+ this.openDragLock();
+ this.openDragLock = null;
+ }
+ animationState && animationState.setActive("whileDrag", false);
+ }
+ /**
+ * Clean up the pan session without modifying other drag state.
+ * This is used during unmount to ensure event listeners are removed
+ * without affecting projection animations or drag locks.
+ * @internal
+ */
+ endPanSession() {
+ this.panSession && this.panSession.end();
+ this.panSession = void 0;
+ }
+ updateAxis(axis, _point, offset) {
+ const { drag: drag2 } = this.getProps();
+ if (!offset || !shouldDrag(axis, drag2, this.currentDirection))
+ return;
+ const axisValue = this.getAxisMotionValue(axis);
+ let next = this.originPoint[axis] + offset[axis];
+ if (this.constraints && this.constraints[axis]) {
+ next = applyConstraints(next, this.constraints[axis], this.elastic[axis]);
+ }
+ axisValue.set(next);
+ }
+ resolveConstraints() {
+ const { dragConstraints, dragElastic } = this.getProps();
+ const layout2 = this.visualElement.projection && !this.visualElement.projection.layout ? this.visualElement.projection.measure(false) : this.visualElement.projection?.layout;
+ const prevConstraints = this.constraints;
+ if (dragConstraints && isRefObject(dragConstraints)) {
+ if (!this.constraints) {
+ this.constraints = this.resolveRefConstraints();
+ }
+ } else {
+ if (dragConstraints && layout2) {
+ this.constraints = calcRelativeConstraints(layout2.layoutBox, dragConstraints);
+ } else {
+ this.constraints = false;
+ }
+ }
+ this.elastic = resolveDragElastic(dragElastic);
+ if (prevConstraints !== this.constraints && !isRefObject(dragConstraints) && layout2 && this.constraints && !this.hasMutatedConstraints) {
+ eachAxis((axis) => {
+ if (this.constraints !== false && this.getAxisMotionValue(axis)) {
+ this.constraints[axis] = rebaseAxisConstraints(layout2.layoutBox[axis], this.constraints[axis]);
+ }
+ });
+ }
+ }
+ resolveRefConstraints() {
+ const { dragConstraints: constraints, onMeasureDragConstraints } = this.getProps();
+ if (!constraints || !isRefObject(constraints))
+ return false;
+ const constraintsElement = constraints.current;
+ invariant(constraintsElement !== null, "If `dragConstraints` is set as a React ref, that ref must be passed to another component's `ref` prop.", "drag-constraints-ref");
+ const { projection } = this.visualElement;
+ if (!projection || !projection.layout)
+ return false;
+ const constraintsBox = measurePageBox(constraintsElement, projection.root, this.visualElement.getTransformPagePoint());
+ let measuredConstraints = calcViewportConstraints(projection.layout.layoutBox, constraintsBox);
+ if (onMeasureDragConstraints) {
+ const userConstraints = onMeasureDragConstraints(convertBoxToBoundingBox(measuredConstraints));
+ this.hasMutatedConstraints = !!userConstraints;
+ if (userConstraints) {
+ measuredConstraints = convertBoundingBoxToBox(userConstraints);
+ }
+ }
+ return measuredConstraints;
+ }
+ startAnimation(velocity) {
+ const { drag: drag2, dragMomentum, dragElastic, dragTransition, dragSnapToOrigin, onDragTransitionEnd } = this.getProps();
+ const constraints = this.constraints || {};
+ const momentumAnimations = eachAxis((axis) => {
+ if (!shouldDrag(axis, drag2, this.currentDirection)) {
+ return;
+ }
+ let transition = constraints && constraints[axis] || {};
+ if (dragSnapToOrigin === true || dragSnapToOrigin === axis)
+ transition = { min: 0, max: 0 };
+ const bounceStiffness = dragElastic ? 200 : 1e6;
+ const bounceDamping = dragElastic ? 40 : 1e7;
+ const inertia2 = {
+ type: "inertia",
+ velocity: dragMomentum ? velocity[axis] : 0,
+ bounceStiffness,
+ bounceDamping,
+ timeConstant: 750,
+ restDelta: 1,
+ restSpeed: 10,
+ ...dragTransition,
+ ...transition
+ };
+ return this.startAxisValueAnimation(axis, inertia2);
+ });
+ return Promise.all(momentumAnimations).then(onDragTransitionEnd);
+ }
+ startAxisValueAnimation(axis, transition) {
+ const axisValue = this.getAxisMotionValue(axis);
+ addValueToWillChange(this.visualElement, axis);
+ return axisValue.start(animateMotionValue(axis, axisValue, 0, transition, this.visualElement, false));
+ }
+ stopAnimation() {
+ eachAxis((axis) => this.getAxisMotionValue(axis).stop());
+ }
+ /**
+ * Drag works differently depending on which props are provided.
+ *
+ * - If _dragX and _dragY are provided, we output the gesture delta directly to those motion values.
+ * - Otherwise, we apply the delta to the x/y motion values.
+ */
+ getAxisMotionValue(axis) {
+ const dragKey = `_drag${axis.toUpperCase()}`;
+ const props = this.visualElement.getProps();
+ const externalMotionValue = props[dragKey];
+ return externalMotionValue ? externalMotionValue : this.visualElement.getValue(axis, (props.initial ? props.initial[axis] : void 0) || 0);
+ }
+ snapToCursor(point) {
+ eachAxis((axis) => {
+ const { drag: drag2 } = this.getProps();
+ if (!shouldDrag(axis, drag2, this.currentDirection))
+ return;
+ const { projection } = this.visualElement;
+ const axisValue = this.getAxisMotionValue(axis);
+ if (projection && projection.layout) {
+ const { min, max } = projection.layout.layoutBox[axis];
+ const current = axisValue.get() || 0;
+ axisValue.set(point[axis] - mixNumber$1(min, max, 0.5) + current);
+ }
+ });
+ }
+ /**
+ * When the viewport resizes we want to check if the measured constraints
+ * have changed and, if so, reposition the element within those new constraints
+ * relative to where it was before the resize.
+ */
+ scalePositionWithinConstraints() {
+ if (!this.visualElement.current)
+ return;
+ const { drag: drag2, dragConstraints } = this.getProps();
+ const { projection } = this.visualElement;
+ if (!isRefObject(dragConstraints) || !projection || !this.constraints)
+ return;
+ this.stopAnimation();
+ const boxProgress = { x: 0, y: 0 };
+ eachAxis((axis) => {
+ const axisValue = this.getAxisMotionValue(axis);
+ if (axisValue && this.constraints !== false) {
+ const latest = axisValue.get();
+ boxProgress[axis] = calcOrigin({ min: latest, max: latest }, this.constraints[axis]);
+ }
+ });
+ const { transformTemplate } = this.visualElement.getProps();
+ this.visualElement.current.style.transform = transformTemplate ? transformTemplate({}, "") : "none";
+ projection.root && projection.root.updateScroll();
+ projection.updateLayout();
+ this.constraints = false;
+ this.resolveConstraints();
+ eachAxis((axis) => {
+ if (!shouldDrag(axis, drag2, null))
+ return;
+ const axisValue = this.getAxisMotionValue(axis);
+ const { min, max } = this.constraints[axis];
+ axisValue.set(mixNumber$1(min, max, boxProgress[axis]));
+ });
+ this.visualElement.render();
+ }
+ addListeners() {
+ if (!this.visualElement.current)
+ return;
+ elementDragControls.set(this.visualElement, this);
+ const element = this.visualElement.current;
+ const stopPointerListener = addPointerEvent(element, "pointerdown", (event) => {
+ const { drag: drag2, dragListener = true } = this.getProps();
+ const target = event.target;
+ const isClickingTextInputChild = target !== element && isElementTextInput(target);
+ if (drag2 && dragListener && !isClickingTextInputChild) {
+ this.start(event);
+ }
+ });
+ let stopResizeObservers;
+ const measureDragConstraints = () => {
+ const { dragConstraints } = this.getProps();
+ if (isRefObject(dragConstraints) && dragConstraints.current) {
+ this.constraints = this.resolveRefConstraints();
+ if (!stopResizeObservers) {
+ stopResizeObservers = startResizeObservers(element, dragConstraints.current, () => this.scalePositionWithinConstraints());
+ }
+ }
+ };
+ const { projection } = this.visualElement;
+ const stopMeasureLayoutListener = projection.addEventListener("measure", measureDragConstraints);
+ if (projection && !projection.layout) {
+ projection.root && projection.root.updateScroll();
+ projection.updateLayout();
+ }
+ frame.read(measureDragConstraints);
+ const stopResizeListener = addDomEvent(window, "resize", () => this.scalePositionWithinConstraints());
+ const stopLayoutUpdateListener = projection.addEventListener("didUpdate", (({ delta, hasLayoutChanged }) => {
+ if (this.isDragging && hasLayoutChanged) {
+ eachAxis((axis) => {
+ const motionValue2 = this.getAxisMotionValue(axis);
+ if (!motionValue2)
+ return;
+ this.originPoint[axis] += delta[axis].translate;
+ motionValue2.set(motionValue2.get() + delta[axis].translate);
+ });
+ this.visualElement.render();
+ }
+ }));
+ return () => {
+ stopResizeListener();
+ stopPointerListener();
+ stopMeasureLayoutListener();
+ stopLayoutUpdateListener && stopLayoutUpdateListener();
+ stopResizeObservers && stopResizeObservers();
+ };
+ }
+ getProps() {
+ const props = this.visualElement.getProps();
+ const { drag: drag2 = false, dragDirectionLock = false, dragPropagation = false, dragConstraints = false, dragElastic = defaultElastic, dragMomentum = true } = props;
+ return {
+ ...props,
+ drag: drag2,
+ dragDirectionLock,
+ dragPropagation,
+ dragConstraints,
+ dragElastic,
+ dragMomentum
+ };
+ }
+}
+function skipFirstCall(callback) {
+ let isFirst = true;
+ return () => {
+ if (isFirst) {
+ isFirst = false;
+ return;
+ }
+ callback();
+ };
+}
+function startResizeObservers(element, constraintsElement, onResize) {
+ const stopElement = resize(element, skipFirstCall(onResize));
+ const stopContainer = resize(constraintsElement, skipFirstCall(onResize));
+ return () => {
+ stopElement();
+ stopContainer();
+ };
+}
+function shouldDrag(direction, drag2, currentDirection) {
+ return (drag2 === true || drag2 === direction) && (currentDirection === null || currentDirection === direction);
+}
+function getCurrentDirection(offset, lockThreshold = 10) {
+ let direction = null;
+ if (Math.abs(offset.y) > lockThreshold) {
+ direction = "y";
+ } else if (Math.abs(offset.x) > lockThreshold) {
+ direction = "x";
+ }
+ return direction;
+}
+class DragGesture extends Feature {
+ constructor(node) {
+ super(node);
+ this.removeGroupControls = noop;
+ this.removeListeners = noop;
+ this.controls = new VisualElementDragControls(node);
+ }
+ mount() {
+ const { dragControls } = this.node.getProps();
+ if (dragControls) {
+ this.removeGroupControls = dragControls.subscribe(this.controls);
+ }
+ this.removeListeners = this.controls.addListeners() || noop;
+ }
+ update() {
+ const { dragControls } = this.node.getProps();
+ const { dragControls: prevDragControls } = this.node.prevProps || {};
+ if (dragControls !== prevDragControls) {
+ this.removeGroupControls();
+ if (dragControls) {
+ this.removeGroupControls = dragControls.subscribe(this.controls);
+ }
+ }
+ }
+ unmount() {
+ this.removeGroupControls();
+ this.removeListeners();
+ if (!this.controls.isDragging) {
+ this.controls.endPanSession();
+ }
+ }
+}
+const asyncHandler = (handler) => (event, info) => {
+ if (handler) {
+ frame.update(() => handler(event, info), false, true);
+ }
+};
+class PanGesture extends Feature {
+ constructor() {
+ super(...arguments);
+ this.removePointerDownListener = noop;
+ }
+ onPointerDown(pointerDownEvent) {
+ this.session = new PanSession(pointerDownEvent, this.createPanHandlers(), {
+ transformPagePoint: this.node.getTransformPagePoint(),
+ contextWindow: getContextWindow(this.node)
+ });
+ }
+ createPanHandlers() {
+ const { onPanSessionStart, onPanStart, onPan, onPanEnd } = this.node.getProps();
+ return {
+ onSessionStart: asyncHandler(onPanSessionStart),
+ onStart: asyncHandler(onPanStart),
+ onMove: asyncHandler(onPan),
+ onEnd: (event, info) => {
+ delete this.session;
+ if (onPanEnd) {
+ frame.postRender(() => onPanEnd(event, info));
+ }
+ }
+ };
+ }
+ mount() {
+ this.removePointerDownListener = addPointerEvent(this.node.current, "pointerdown", (event) => this.onPointerDown(event));
+ }
+ update() {
+ this.session && this.session.updateHandlers(this.createPanHandlers());
+ }
+ unmount() {
+ this.removePointerDownListener();
+ this.session && this.session.end();
+ }
+}
+let hasTakenAnySnapshot = false;
+class MeasureLayoutWithContext extends reactExports.Component {
+ /**
+ * This only mounts projection nodes for components that
+ * need measuring, we might want to do it for all components
+ * in order to incorporate transforms
+ */
+ componentDidMount() {
+ const { visualElement, layoutGroup, switchLayoutGroup, layoutId } = this.props;
+ const { projection } = visualElement;
+ if (projection) {
+ if (layoutGroup.group)
+ layoutGroup.group.add(projection);
+ if (switchLayoutGroup && switchLayoutGroup.register && layoutId) {
+ switchLayoutGroup.register(projection);
+ }
+ if (hasTakenAnySnapshot) {
+ projection.root.didUpdate();
+ }
+ projection.addEventListener("animationComplete", () => {
+ this.safeToRemove();
+ });
+ projection.setOptions({
+ ...projection.options,
+ layoutDependency: this.props.layoutDependency,
+ onExitComplete: () => this.safeToRemove()
+ });
+ }
+ globalProjectionState.hasEverUpdated = true;
+ }
+ getSnapshotBeforeUpdate(prevProps) {
+ const { layoutDependency, visualElement, drag: drag2, isPresent } = this.props;
+ const { projection } = visualElement;
+ if (!projection)
+ return null;
+ projection.isPresent = isPresent;
+ if (prevProps.layoutDependency !== layoutDependency) {
+ projection.setOptions({
+ ...projection.options,
+ layoutDependency
+ });
+ }
+ hasTakenAnySnapshot = true;
+ if (drag2 || prevProps.layoutDependency !== layoutDependency || layoutDependency === void 0 || prevProps.isPresent !== isPresent) {
+ projection.willUpdate();
+ } else {
+ this.safeToRemove();
+ }
+ if (prevProps.isPresent !== isPresent) {
+ if (isPresent) {
+ projection.promote();
+ } else if (!projection.relegate()) {
+ frame.postRender(() => {
+ const stack = projection.getStack();
+ if (!stack || !stack.members.length) {
+ this.safeToRemove();
+ }
+ });
+ }
+ }
+ return null;
+ }
+ componentDidUpdate() {
+ const { visualElement, layoutAnchor } = this.props;
+ const { projection } = visualElement;
+ if (projection) {
+ projection.options.layoutAnchor = layoutAnchor;
+ projection.root.didUpdate();
+ microtask.postRender(() => {
+ if (!projection.currentAnimation && projection.isLead()) {
+ this.safeToRemove();
+ }
+ });
+ }
+ }
+ componentWillUnmount() {
+ const { visualElement, layoutGroup, switchLayoutGroup: promoteContext } = this.props;
+ const { projection } = visualElement;
+ hasTakenAnySnapshot = true;
+ if (projection) {
+ projection.scheduleCheckAfterUnmount();
+ if (layoutGroup && layoutGroup.group)
+ layoutGroup.group.remove(projection);
+ if (promoteContext && promoteContext.deregister)
+ promoteContext.deregister(projection);
+ }
+ }
+ safeToRemove() {
+ const { safeToRemove } = this.props;
+ safeToRemove && safeToRemove();
+ }
+ render() {
+ return null;
+ }
+}
+function MeasureLayout(props) {
+ const [isPresent, safeToRemove] = usePresence();
+ const layoutGroup = reactExports.useContext(LayoutGroupContext);
+ return jsxRuntimeExports.jsx(MeasureLayoutWithContext, { ...props, layoutGroup, switchLayoutGroup: reactExports.useContext(SwitchLayoutGroupContext), isPresent, safeToRemove });
+}
+const drag = {
+ pan: {
+ Feature: PanGesture
+ },
+ drag: {
+ Feature: DragGesture,
+ ProjectionNode: HTMLProjectionNode,
+ MeasureLayout
+ }
+};
+function handleHoverEvent(node, event, lifecycle) {
+ const { props } = node;
+ if (node.animationState && props.whileHover) {
+ node.animationState.setActive("whileHover", lifecycle === "Start");
+ }
+ const eventName = "onHover" + lifecycle;
+ const callback = props[eventName];
+ if (callback) {
+ frame.postRender(() => callback(event, extractEventInfo(event)));
+ }
+}
+class HoverGesture extends Feature {
+ mount() {
+ const { current } = this.node;
+ if (!current)
+ return;
+ this.unmount = hover(current, (_element, startEvent) => {
+ handleHoverEvent(this.node, startEvent, "Start");
+ return (endEvent) => handleHoverEvent(this.node, endEvent, "End");
+ });
+ }
+ unmount() {
+ }
+}
+class FocusGesture extends Feature {
+ constructor() {
+ super(...arguments);
+ this.isActive = false;
+ }
+ onFocus() {
+ let isFocusVisible = false;
+ try {
+ isFocusVisible = this.node.current.matches(":focus-visible");
+ } catch (e) {
+ isFocusVisible = true;
+ }
+ if (!isFocusVisible || !this.node.animationState)
+ return;
+ this.node.animationState.setActive("whileFocus", true);
+ this.isActive = true;
+ }
+ onBlur() {
+ if (!this.isActive || !this.node.animationState)
+ return;
+ this.node.animationState.setActive("whileFocus", false);
+ this.isActive = false;
+ }
+ mount() {
+ this.unmount = pipe(addDomEvent(this.node.current, "focus", () => this.onFocus()), addDomEvent(this.node.current, "blur", () => this.onBlur()));
+ }
+ unmount() {
+ }
+}
+function handlePressEvent(node, event, lifecycle) {
+ const { props } = node;
+ if (node.current instanceof HTMLButtonElement && node.current.disabled) {
+ return;
+ }
+ if (node.animationState && props.whileTap) {
+ node.animationState.setActive("whileTap", lifecycle === "Start");
+ }
+ const eventName = "onTap" + (lifecycle === "End" ? "" : lifecycle);
+ const callback = props[eventName];
+ if (callback) {
+ frame.postRender(() => callback(event, extractEventInfo(event)));
+ }
+}
+class PressGesture extends Feature {
+ mount() {
+ const { current } = this.node;
+ if (!current)
+ return;
+ const { globalTapTarget, propagate } = this.node.props;
+ this.unmount = press(current, (_element, startEvent) => {
+ handlePressEvent(this.node, startEvent, "Start");
+ return (endEvent, { success }) => handlePressEvent(this.node, endEvent, success ? "End" : "Cancel");
+ }, {
+ useGlobalTarget: globalTapTarget,
+ stopPropagation: propagate?.tap === false
+ });
+ }
+ unmount() {
+ }
+}
+const observerCallbacks = /* @__PURE__ */ new WeakMap();
+const observers = /* @__PURE__ */ new WeakMap();
+const fireObserverCallback = (entry) => {
+ const callback = observerCallbacks.get(entry.target);
+ callback && callback(entry);
+};
+const fireAllObserverCallbacks = (entries) => {
+ entries.forEach(fireObserverCallback);
+};
+function initIntersectionObserver({ root, ...options }) {
+ const lookupRoot = root || document;
+ if (!observers.has(lookupRoot)) {
+ observers.set(lookupRoot, {});
+ }
+ const rootObservers = observers.get(lookupRoot);
+ const key = JSON.stringify(options);
+ if (!rootObservers[key]) {
+ rootObservers[key] = new IntersectionObserver(fireAllObserverCallbacks, { root, ...options });
+ }
+ return rootObservers[key];
+}
+function observeIntersection(element, options, callback) {
+ const rootInteresectionObserver = initIntersectionObserver(options);
+ observerCallbacks.set(element, callback);
+ rootInteresectionObserver.observe(element);
+ return () => {
+ observerCallbacks.delete(element);
+ rootInteresectionObserver.unobserve(element);
+ };
+}
+const thresholdNames = {
+ some: 0,
+ all: 1
+};
+class InViewFeature extends Feature {
+ constructor() {
+ super(...arguments);
+ this.hasEnteredView = false;
+ this.isInView = false;
+ }
+ startObserver() {
+ this.stopObserver?.();
+ const { viewport = {} } = this.node.getProps();
+ const { root, margin: rootMargin, amount = "some", once } = viewport;
+ const options = {
+ root: root ? root.current : void 0,
+ rootMargin,
+ threshold: typeof amount === "number" ? amount : thresholdNames[amount]
+ };
+ const onIntersectionUpdate = (entry) => {
+ const { isIntersecting } = entry;
+ if (this.isInView === isIntersecting)
+ return;
+ this.isInView = isIntersecting;
+ if (once && !isIntersecting && this.hasEnteredView) {
+ return;
+ } else if (isIntersecting) {
+ this.hasEnteredView = true;
+ }
+ if (this.node.animationState) {
+ this.node.animationState.setActive("whileInView", isIntersecting);
+ }
+ const { onViewportEnter, onViewportLeave } = this.node.getProps();
+ const callback = isIntersecting ? onViewportEnter : onViewportLeave;
+ callback && callback(entry);
+ };
+ this.stopObserver = observeIntersection(this.node.current, options, onIntersectionUpdate);
+ }
+ mount() {
+ this.startObserver();
+ }
+ update() {
+ if (typeof IntersectionObserver === "undefined")
+ return;
+ const { props, prevProps } = this.node;
+ const hasOptionsChanged = ["amount", "margin", "root"].some(hasViewportOptionChanged(props, prevProps));
+ if (hasOptionsChanged) {
+ this.startObserver();
+ }
+ }
+ unmount() {
+ this.stopObserver?.();
+ this.hasEnteredView = false;
+ this.isInView = false;
+ }
+}
+function hasViewportOptionChanged({ viewport = {} }, { viewport: prevViewport = {} } = {}) {
+ return (name) => viewport[name] !== prevViewport[name];
+}
+const gestureAnimations = {
+ inView: {
+ Feature: InViewFeature
+ },
+ tap: {
+ Feature: PressGesture
+ },
+ focus: {
+ Feature: FocusGesture
+ },
+ hover: {
+ Feature: HoverGesture
+ }
+};
+const layout = {
+ layout: {
+ ProjectionNode: HTMLProjectionNode,
+ MeasureLayout
+ }
+};
+const featureBundle = {
+ ...animations,
+ ...gestureAnimations,
+ ...drag,
+ ...layout
+};
+const motion = /* @__PURE__ */ createMotionProxy(featureBundle, createDomVisualElement);
+function useReducedMotion() {
+ !hasReducedMotionListener.current && initPrefersReducedMotion();
+ const [shouldReduceMotion] = reactExports.useState(prefersReducedMotion.current);
+ if (process.env.NODE_ENV !== "production") {
+ warnOnce(shouldReduceMotion !== true, "You have Reduced Motion enabled on your device. Animations may not appear as expected.", "reduced-motion-disabled");
+ }
+ return shouldReduceMotion;
+}
+export {
+ AnimatePresence as A,
+ motion as m,
+ useReducedMotion as u
+};
diff --git a/bootstrap/ssr/assets/vendor-realtime-cgmg5qQY.js b/bootstrap/ssr/assets/vendor-realtime-cgmg5qQY.js
new file mode 100644
index 00000000..015a0ffe
--- /dev/null
+++ b/bootstrap/ssr/assets/vendor-realtime-cgmg5qQY.js
@@ -0,0 +1,9704 @@
+import require$$0 from "util";
+import stream from "stream";
+import require$$4 from "https";
+import require$$5 from "url";
+import require$$6 from "fs";
+import require$$1 from "crypto";
+import require$$4$2 from "assert";
+import require$$1$1 from "buffer";
+import require$$2 from "child_process";
+import require$$4$1 from "events";
+import require$$8 from "net";
+import require$$10 from "tls";
+import { c as commonjsGlobal, g as getDefaultExportFromCjs } from "./vendor-tiptap-DSw66HfW.js";
+import require$$3 from "http";
+class u {
+ constructor() {
+ this.notificationCreatedEvent = ".Illuminate\\Notifications\\Events\\BroadcastNotificationCreated";
+ }
+ /**
+ * Listen for a whisper event on the channel instance.
+ */
+ listenForWhisper(e, t) {
+ return this.listen(".client-" + e, t);
+ }
+ /**
+ * Listen for an event on the channel instance.
+ */
+ notification(e) {
+ return this.listen(this.notificationCreatedEvent, e);
+ }
+ /**
+ * Stop listening for notification events on the channel instance.
+ */
+ stopListeningForNotification(e) {
+ return this.stopListening(this.notificationCreatedEvent, e);
+ }
+ /**
+ * Stop listening for a whisper event on the channel instance.
+ */
+ stopListeningForWhisper(e, t) {
+ return this.stopListening(".client-" + e, t);
+ }
+}
+class d {
+ /**
+ * Create a new class instance.
+ */
+ constructor(e) {
+ this.namespace = e;
+ }
+ /**
+ * Format the given event name.
+ */
+ format(e) {
+ return [".", "\\"].includes(e.charAt(0)) ? e.substring(1) : (this.namespace && (e = this.namespace + "." + e), e.replace(/\./g, "\\"));
+ }
+ /**
+ * Set the event namespace.
+ */
+ setNamespace(e) {
+ this.namespace = e;
+ }
+}
+function g(s) {
+ try {
+ return Reflect.construct(String, [], s), true;
+ } catch {
+ return false;
+ }
+}
+class l extends u {
+ /**
+ * Create a new class instance.
+ */
+ constructor(e, t, n) {
+ super(), this.name = t, this.pusher = e, this.options = n, this.eventFormatter = new d(this.options.namespace), this.subscribe();
+ }
+ /**
+ * Subscribe to a Pusher channel.
+ */
+ subscribe() {
+ this.subscription = this.pusher.subscribe(this.name);
+ }
+ /**
+ * Unsubscribe from a Pusher channel.
+ */
+ unsubscribe() {
+ this.pusher.unsubscribe(this.name);
+ }
+ /**
+ * Listen for an event on the channel instance.
+ */
+ listen(e, t) {
+ return this.on(this.eventFormatter.format(e), t), this;
+ }
+ /**
+ * Listen for all events on the channel instance.
+ */
+ listenToAll(e) {
+ return this.subscription.bind_global((t, n) => {
+ if (t.startsWith("pusher:"))
+ return;
+ let i = String(this.options.namespace ?? "").replace(
+ /\./g,
+ "\\"
+ ), a = t.startsWith(i) ? t.substring(i.length + 1) : "." + t;
+ e(a, n);
+ }), this;
+ }
+ /**
+ * Stop listening for an event on the channel instance.
+ */
+ stopListening(e, t) {
+ return t ? this.subscription.unbind(
+ this.eventFormatter.format(e),
+ t
+ ) : this.subscription.unbind(this.eventFormatter.format(e)), this;
+ }
+ /**
+ * Stop listening for all events on the channel instance.
+ */
+ stopListeningToAll(e) {
+ return e ? this.subscription.unbind_global(e) : this.subscription.unbind_global(), this;
+ }
+ /**
+ * Register a callback to be called anytime a subscription succeeds.
+ */
+ subscribed(e) {
+ return this.on("pusher:subscription_succeeded", () => {
+ e();
+ }), this;
+ }
+ /**
+ * Register a callback to be called anytime a subscription error occurs.
+ */
+ error(e) {
+ return this.on("pusher:subscription_error", (t) => {
+ e(t);
+ }), this;
+ }
+ /**
+ * Bind a channel to an event.
+ */
+ on(e, t) {
+ return this.subscription.bind(e, t), this;
+ }
+}
+class f extends l {
+ /**
+ * Send a whisper event to other clients in the channel.
+ */
+ whisper(e, t) {
+ return this.pusher.channels.channels[this.name].trigger(
+ `client-${e}`,
+ t
+ ), this;
+ }
+}
+class w extends l {
+ /**
+ * Send a whisper event to other clients in the channel.
+ */
+ whisper(e, t) {
+ return this.pusher.channels.channels[this.name].trigger(
+ `client-${e}`,
+ t
+ ), this;
+ }
+}
+class _ extends f {
+ /**
+ * Register a callback to be called anytime the member list changes.
+ */
+ here(e) {
+ return this.on("pusher:subscription_succeeded", (t) => {
+ e(Object.keys(t.members).map((n) => t.members[n]));
+ }), this;
+ }
+ /**
+ * Listen for someone joining the channel.
+ */
+ joining(e) {
+ return this.on("pusher:member_added", (t) => {
+ e(t.info);
+ }), this;
+ }
+ /**
+ * Send a whisper event to other clients in the channel.
+ */
+ whisper(e, t) {
+ return this.pusher.channels.channels[this.name].trigger(
+ `client-${e}`,
+ t
+ ), this;
+ }
+ /**
+ * Listen for someone leaving the channel.
+ */
+ leaving(e) {
+ return this.on("pusher:member_removed", (t) => {
+ e(t.info);
+ }), this;
+ }
+}
+class b extends u {
+ /**
+ * Create a new class instance.
+ */
+ constructor(e, t, n) {
+ super(), this.events = {}, this.listeners = {}, this.name = t, this.socket = e, this.options = n, this.eventFormatter = new d(this.options.namespace), this.subscribe();
+ }
+ /**
+ * Subscribe to a Socket.io channel.
+ */
+ subscribe() {
+ this.socket.emit("subscribe", {
+ channel: this.name,
+ auth: this.options.auth || {}
+ });
+ }
+ /**
+ * Unsubscribe from channel and ubind event callbacks.
+ */
+ unsubscribe() {
+ this.unbind(), this.socket.emit("unsubscribe", {
+ channel: this.name,
+ auth: this.options.auth || {}
+ });
+ }
+ /**
+ * Listen for an event on the channel instance.
+ */
+ listen(e, t) {
+ return this.on(this.eventFormatter.format(e), t), this;
+ }
+ /**
+ * Stop listening for an event on the channel instance.
+ */
+ stopListening(e, t) {
+ return this.unbindEvent(this.eventFormatter.format(e), t), this;
+ }
+ /**
+ * Register a callback to be called anytime a subscription succeeds.
+ */
+ subscribed(e) {
+ return this.on("connect", (t) => {
+ e(t);
+ }), this;
+ }
+ /**
+ * Register a callback to be called anytime an error occurs.
+ */
+ error(e) {
+ return this;
+ }
+ /**
+ * Bind the channel's socket to an event and store the callback.
+ */
+ on(e, t) {
+ return this.listeners[e] = this.listeners[e] || [], this.events[e] || (this.events[e] = (n, i) => {
+ this.name === n && this.listeners[e] && this.listeners[e].forEach((a) => a(i));
+ }, this.socket.on(e, this.events[e])), this.listeners[e].push(t), this;
+ }
+ /**
+ * Unbind the channel's socket from all stored event callbacks.
+ */
+ unbind() {
+ Object.keys(this.events).forEach((e) => {
+ this.unbindEvent(e);
+ });
+ }
+ /**
+ * Unbind the listeners for the given event.
+ */
+ unbindEvent(e, t) {
+ this.listeners[e] = this.listeners[e] || [], t && (this.listeners[e] = this.listeners[e].filter(
+ (n) => n !== t
+ )), (!t || this.listeners[e].length === 0) && (this.events[e] && (this.socket.removeListener(e, this.events[e]), delete this.events[e]), delete this.listeners[e]);
+ }
+}
+class v extends b {
+ /**
+ * Send a whisper event to other clients in the channel.
+ */
+ whisper(e, t) {
+ return this.socket.emit("client event", {
+ channel: this.name,
+ event: `client-${e}`,
+ data: t
+ }), this;
+ }
+}
+class C extends v {
+ /**
+ * Register a callback to be called anytime the member list changes.
+ */
+ here(e) {
+ return this.on("presence:subscribed", (t) => {
+ e(t.map((n) => n.user_info));
+ }), this;
+ }
+ /**
+ * Listen for someone joining the channel.
+ */
+ joining(e) {
+ return this.on(
+ "presence:joining",
+ (t) => e(t.user_info)
+ ), this;
+ }
+ /**
+ * Send a whisper event to other clients in the channel.
+ */
+ whisper(e, t) {
+ return this.socket.emit("client event", {
+ channel: this.name,
+ event: `client-${e}`,
+ data: t
+ }), this;
+ }
+ /**
+ * Listen for someone leaving the channel.
+ */
+ leaving(e) {
+ return this.on(
+ "presence:leaving",
+ (t) => e(t.user_info)
+ ), this;
+ }
+}
+class c extends u {
+ /**
+ * Subscribe to a channel.
+ */
+ subscribe() {
+ }
+ /**
+ * Unsubscribe from a channel.
+ */
+ unsubscribe() {
+ }
+ /**
+ * Listen for an event on the channel instance.
+ */
+ listen(e, t) {
+ return this;
+ }
+ /**
+ * Listen for all events on the channel instance.
+ */
+ listenToAll(e) {
+ return this;
+ }
+ /**
+ * Stop listening for an event on the channel instance.
+ */
+ stopListening(e, t) {
+ return this;
+ }
+ /**
+ * Register a callback to be called anytime a subscription succeeds.
+ */
+ subscribed(e) {
+ return this;
+ }
+ /**
+ * Register a callback to be called anytime an error occurs.
+ */
+ error(e) {
+ return this;
+ }
+ /**
+ * Bind a channel to an event.
+ */
+ on(e, t) {
+ return this;
+ }
+}
+class k extends c {
+ /**
+ * Send a whisper event to other clients in the channel.
+ */
+ whisper(e, t) {
+ return this;
+ }
+}
+class y extends c {
+ /**
+ * Send a whisper event to other clients in the channel.
+ */
+ whisper(e, t) {
+ return this;
+ }
+}
+class m extends k {
+ /**
+ * Register a callback to be called anytime the member list changes.
+ */
+ here(e) {
+ return this;
+ }
+ /**
+ * Listen for someone joining the channel.
+ */
+ joining(e) {
+ return this;
+ }
+ /**
+ * Send a whisper event to other clients in the channel.
+ */
+ whisper(e, t) {
+ return this;
+ }
+ /**
+ * Listen for someone leaving the channel.
+ */
+ leaving(e) {
+ return this;
+ }
+}
+const h = class h2 {
+ /**
+ * Create a new class instance.
+ */
+ constructor(e) {
+ this.setOptions(e), this.connect();
+ }
+ /**
+ * Merge the custom options with the defaults.
+ */
+ setOptions(e) {
+ this.options = {
+ ...h2._defaultOptions,
+ ...e,
+ broadcaster: e.broadcaster
+ };
+ let t = this.csrfToken();
+ t && (this.options.auth.headers["X-CSRF-TOKEN"] = t, this.options.userAuthentication.headers["X-CSRF-TOKEN"] = t), t = this.options.bearerToken, t && (this.options.auth.headers.Authorization = "Bearer " + t, this.options.userAuthentication.headers.Authorization = "Bearer " + t);
+ }
+ /**
+ * Extract the CSRF token from the page.
+ */
+ csrfToken() {
+ var e, t;
+ return typeof window < "u" && ((e = window.Laravel) != null && e.csrfToken) ? window.Laravel.csrfToken : this.options.csrfToken ? this.options.csrfToken : typeof document < "u" && typeof document.querySelector == "function" ? ((t = document.querySelector('meta[name="csrf-token"]')) == null ? void 0 : t.getAttribute("content")) ?? null : null;
+ }
+};
+h._defaultOptions = {
+ auth: {
+ headers: {}
+ },
+ authEndpoint: "/broadcasting/auth",
+ userAuthentication: {
+ endpoint: "/broadcasting/user-auth",
+ headers: {}
+ },
+ csrfToken: null,
+ bearerToken: null,
+ host: null,
+ key: null,
+ namespace: "App.Events"
+};
+let r = h;
+class o extends r {
+ constructor() {
+ super(...arguments), this.channels = {};
+ }
+ /**
+ * Create a fresh Pusher connection.
+ */
+ connect() {
+ if (typeof this.options.client < "u")
+ this.pusher = this.options.client;
+ else if (this.options.Pusher)
+ this.pusher = new this.options.Pusher(
+ this.options.key,
+ this.options
+ );
+ else if (typeof window < "u" && typeof window.Pusher < "u")
+ this.pusher = new window.Pusher(this.options.key, this.options);
+ else
+ throw new Error(
+ "Pusher client not found. Should be globally available or passed via options.client"
+ );
+ }
+ /**
+ * Sign in the user via Pusher user authentication (https://pusher.com/docs/channels/using_channels/user-authentication/).
+ */
+ signin() {
+ this.pusher.signin();
+ }
+ /**
+ * Listen for an event on a channel instance.
+ */
+ listen(e, t, n) {
+ return this.channel(e).listen(t, n);
+ }
+ /**
+ * Get a channel instance by name.
+ */
+ channel(e) {
+ return this.channels[e] || (this.channels[e] = new l(
+ this.pusher,
+ e,
+ this.options
+ )), this.channels[e];
+ }
+ /**
+ * Get a private channel instance by name.
+ */
+ privateChannel(e) {
+ return this.channels["private-" + e] || (this.channels["private-" + e] = new f(
+ this.pusher,
+ "private-" + e,
+ this.options
+ )), this.channels["private-" + e];
+ }
+ /**
+ * Get a private encrypted channel instance by name.
+ */
+ encryptedPrivateChannel(e) {
+ return this.channels["private-encrypted-" + e] || (this.channels["private-encrypted-" + e] = new w(
+ this.pusher,
+ "private-encrypted-" + e,
+ this.options
+ )), this.channels["private-encrypted-" + e];
+ }
+ /**
+ * Get a presence channel instance by name.
+ */
+ presenceChannel(e) {
+ return this.channels["presence-" + e] || (this.channels["presence-" + e] = new _(
+ this.pusher,
+ "presence-" + e,
+ this.options
+ )), this.channels["presence-" + e];
+ }
+ /**
+ * Leave the given channel, as well as its private and presence variants.
+ */
+ leave(e) {
+ [
+ e,
+ "private-" + e,
+ "private-encrypted-" + e,
+ "presence-" + e
+ ].forEach((n) => {
+ this.leaveChannel(n);
+ });
+ }
+ /**
+ * Leave the given channel.
+ */
+ leaveChannel(e) {
+ this.channels[e] && (this.channels[e].unsubscribe(), delete this.channels[e]);
+ }
+ /**
+ * Get the socket ID for the connection.
+ */
+ socketId() {
+ return this.pusher.connection.socket_id;
+ }
+ /**
+ * Get the current connection status.
+ */
+ connectionStatus() {
+ const e = this.pusher.connection.state;
+ switch (e) {
+ case "connected":
+ case "connecting":
+ return e;
+ case "failed":
+ case "unavailable":
+ return "failed";
+ default:
+ return "disconnected";
+ }
+ }
+ /**
+ * Subscribe to connection status changes.
+ */
+ onConnectionChange(e) {
+ const t = () => {
+ e(this.connectionStatus());
+ }, n = ["state_change", "connected", "disconnected"];
+ return n.forEach((i) => {
+ this.pusher.connection.bind(i, t);
+ }), () => {
+ n.forEach((i) => {
+ this.pusher.connection.unbind(i, t);
+ });
+ };
+ }
+ /**
+ * Disconnect Pusher connection.
+ */
+ disconnect() {
+ this.pusher.disconnect();
+ }
+}
+class S extends r {
+ constructor() {
+ super(...arguments), this.channels = {};
+ }
+ /**
+ * Create a fresh Socket.io connection.
+ */
+ connect() {
+ let e = this.getSocketIO();
+ this.socket = e(
+ this.options.host ?? void 0,
+ this.options
+ ), this.socket.io.on("reconnect", () => {
+ Object.values(this.channels).forEach((t) => {
+ t.subscribe();
+ });
+ });
+ }
+ /**
+ * Get socket.io module from global scope or options.
+ */
+ getSocketIO() {
+ if (typeof this.options.client < "u")
+ return this.options.client;
+ if (typeof window < "u" && typeof window.io < "u")
+ return window.io;
+ throw new Error(
+ "Socket.io client not found. Should be globally available or passed via options.client"
+ );
+ }
+ /**
+ * Listen for an event on a channel instance.
+ */
+ listen(e, t, n) {
+ return this.channel(e).listen(t, n);
+ }
+ /**
+ * Get a channel instance by name.
+ */
+ channel(e) {
+ return this.channels[e] || (this.channels[e] = new b(
+ this.socket,
+ e,
+ this.options
+ )), this.channels[e];
+ }
+ /**
+ * Get a private channel instance by name.
+ */
+ privateChannel(e) {
+ return this.channels["private-" + e] || (this.channels["private-" + e] = new v(
+ this.socket,
+ "private-" + e,
+ this.options
+ )), this.channels["private-" + e];
+ }
+ /**
+ * Get a presence channel instance by name.
+ */
+ presenceChannel(e) {
+ return this.channels["presence-" + e] || (this.channels["presence-" + e] = new C(
+ this.socket,
+ "presence-" + e,
+ this.options
+ )), this.channels["presence-" + e];
+ }
+ /**
+ * Leave the given channel, as well as its private and presence variants.
+ */
+ leave(e) {
+ [e, "private-" + e, "presence-" + e].forEach((n) => {
+ this.leaveChannel(n);
+ });
+ }
+ /**
+ * Leave the given channel.
+ */
+ leaveChannel(e) {
+ this.channels[e] && (this.channels[e].unsubscribe(), delete this.channels[e]);
+ }
+ /**
+ * Get the socket ID for the connection.
+ */
+ socketId() {
+ return this.socket.id;
+ }
+ /**
+ * Get the current connection status.
+ */
+ connectionStatus() {
+ return this.socket.connected ? "connected" : this.socket.io._reconnecting ? "reconnecting" : this.socket.id !== void 0 ? "disconnected" : "connecting";
+ }
+ /**
+ * Subscribe to connection status changes.
+ */
+ onConnectionChange(e) {
+ const t = () => {
+ e(this.connectionStatus());
+ }, n = [
+ "connect",
+ "disconnect",
+ "connect_error",
+ "reconnect_attempt",
+ "reconnect",
+ "reconnect_error",
+ "reconnect_failed"
+ ];
+ return n.forEach((i) => {
+ this.socket.on(i, t);
+ }), () => {
+ n.forEach((i) => {
+ this.socket.off(i, t);
+ });
+ };
+ }
+ /**
+ * Disconnect Socketio connection.
+ */
+ disconnect() {
+ this.socket.disconnect();
+ }
+}
+class p extends r {
+ constructor() {
+ super(...arguments), this.channels = {};
+ }
+ /**
+ * Create a fresh connection.
+ */
+ connect() {
+ }
+ /**
+ * Listen for an event on a channel instance.
+ */
+ listen(e, t, n) {
+ return new c();
+ }
+ /**
+ * Get a channel instance by name.
+ */
+ channel(e) {
+ return new c();
+ }
+ /**
+ * Get a private channel instance by name.
+ */
+ privateChannel(e) {
+ return new k();
+ }
+ /**
+ * Get a private encrypted channel instance by name.
+ */
+ encryptedPrivateChannel(e) {
+ return new y();
+ }
+ /**
+ * Get a presence channel instance by name.
+ */
+ presenceChannel(e) {
+ return new m();
+ }
+ /**
+ * Leave the given channel, as well as its private and presence variants.
+ */
+ leave(e) {
+ }
+ /**
+ * Leave the given channel.
+ */
+ leaveChannel(e) {
+ }
+ /**
+ * Get the socket ID for the connection.
+ */
+ socketId() {
+ return "fake-socket-id";
+ }
+ /**
+ * Get the current connection status.
+ */
+ connectionStatus() {
+ return "connected";
+ }
+ /**
+ * Subscribe to connection status changes.
+ */
+ onConnectionChange(e) {
+ return () => {
+ };
+ }
+ /**
+ * Disconnect the connection.
+ */
+ disconnect() {
+ }
+}
+class E {
+ /**
+ * Create a new class instance.
+ */
+ constructor(e) {
+ this.options = e, this.connect(), this.options.withoutInterceptors || this.registerInterceptors();
+ }
+ /**
+ * Get a channel instance by name.
+ */
+ channel(e) {
+ return this.connector.channel(e);
+ }
+ /**
+ * Create a new connection.
+ */
+ connect() {
+ if (this.options.broadcaster === "reverb")
+ this.connector = new o({
+ ...this.options,
+ cluster: ""
+ });
+ else if (this.options.broadcaster === "pusher")
+ this.connector = new o(this.options);
+ else if (this.options.broadcaster === "ably")
+ this.connector = new o({
+ ...this.options,
+ cluster: "",
+ broadcaster: "pusher"
+ });
+ else if (this.options.broadcaster === "socket.io")
+ this.connector = new S(this.options);
+ else if (this.options.broadcaster === "null")
+ this.connector = new p(this.options);
+ else if (typeof this.options.broadcaster == "function" && g(this.options.broadcaster))
+ this.connector = new this.options.broadcaster(this.options);
+ else
+ throw new Error(
+ `Broadcaster ${typeof this.options.broadcaster} ${String(this.options.broadcaster)} is not supported.`
+ );
+ }
+ /**
+ * Disconnect from the Echo server.
+ */
+ disconnect() {
+ this.connector.disconnect();
+ }
+ /**
+ * Get a presence channel instance by name.
+ */
+ join(e) {
+ return this.connector.presenceChannel(e);
+ }
+ /**
+ * Leave the given channel, as well as its private and presence variants.
+ */
+ leave(e) {
+ this.connector.leave(e);
+ }
+ /**
+ * Leave the given channel.
+ */
+ leaveChannel(e) {
+ this.connector.leaveChannel(e);
+ }
+ /**
+ * Leave all channels.
+ */
+ leaveAllChannels() {
+ for (const e in this.connector.channels)
+ this.leaveChannel(e);
+ }
+ /**
+ * Listen for an event on a channel instance.
+ */
+ listen(e, t, n) {
+ return this.connector.listen(e, t, n);
+ }
+ /**
+ * Get a private channel instance by name.
+ */
+ private(e) {
+ return this.connector.privateChannel(e);
+ }
+ /**
+ * Get a private encrypted channel instance by name.
+ */
+ encryptedPrivate(e) {
+ if (this.connectorSupportsEncryptedPrivateChannels(this.connector))
+ return this.connector.encryptedPrivateChannel(e);
+ throw new Error(
+ `Broadcaster ${typeof this.options.broadcaster} ${String(
+ this.options.broadcaster
+ )} does not support encrypted private channels.`
+ );
+ }
+ connectorSupportsEncryptedPrivateChannels(e) {
+ return e instanceof o || e instanceof p;
+ }
+ /**
+ * Get the Socket ID for the connection.
+ */
+ socketId() {
+ return this.connector.socketId();
+ }
+ /**
+ * Get the current connection status.
+ */
+ connectionStatus() {
+ return this.connector.connectionStatus();
+ }
+ /**
+ * Register 3rd party request interceptors. These are used to automatically
+ * send a connections socket id to a Laravel app with a X-Socket-Id header.
+ */
+ registerInterceptors() {
+ typeof Vue < "u" && (Vue != null && Vue.http) && this.registerVueRequestInterceptor(), typeof axios == "function" && this.registerAxiosRequestInterceptor(), typeof jQuery == "function" && this.registerjQueryAjaxSetup(), typeof Turbo == "object" && this.registerTurboRequestInterceptor();
+ }
+ /**
+ * Register a Vue HTTP interceptor to add the X-Socket-ID header.
+ */
+ registerVueRequestInterceptor() {
+ Vue.http.interceptors.push(
+ (e, t) => {
+ this.socketId() && e.headers.set("X-Socket-ID", this.socketId()), t();
+ }
+ );
+ }
+ /**
+ * Register an Axios HTTP interceptor to add the X-Socket-ID header.
+ */
+ registerAxiosRequestInterceptor() {
+ axios.interceptors.request.use(
+ (e) => (this.socketId() && (e.headers["X-Socket-Id"] = this.socketId()), e)
+ );
+ }
+ /**
+ * Register jQuery AjaxPrefilter to add the X-Socket-ID header.
+ */
+ registerjQueryAjaxSetup() {
+ typeof jQuery.ajax < "u" && jQuery.ajaxPrefilter(
+ (e, t, n) => {
+ this.socketId() && n.setRequestHeader("X-Socket-Id", this.socketId());
+ }
+ );
+ }
+ /**
+ * Register the Turbo Request interceptor to add the X-Socket-ID header.
+ */
+ registerTurboRequestInterceptor() {
+ document.addEventListener(
+ "turbo:before-fetch-request",
+ (e) => {
+ e.detail.fetchOptions.headers["X-Socket-Id"] = this.socketId();
+ }
+ );
+ }
+}
+var pusher = { exports: {} };
+var hasRequiredPusher;
+function requirePusher() {
+ if (hasRequiredPusher) return pusher.exports;
+ hasRequiredPusher = 1;
+ (function(module) {
+ (() => {
+ var __webpack_modules__ = {
+ /***/
+ 594(__unused_webpack_module, exports$1) {
+ var __extends = this && this.__extends || /* @__PURE__ */ (function() {
+ var extendStatics = function(d2, b2) {
+ extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d3, b3) {
+ d3.__proto__ = b3;
+ } || function(d3, b3) {
+ for (var p2 in b3) if (b3.hasOwnProperty(p2)) d3[p2] = b3[p2];
+ };
+ return extendStatics(d2, b2);
+ };
+ return function(d2, b2) {
+ extendStatics(d2, b2);
+ function __() {
+ this.constructor = d2;
+ }
+ d2.prototype = b2 === null ? Object.create(b2) : (__.prototype = b2.prototype, new __());
+ };
+ })();
+ Object.defineProperty(exports$1, "__esModule", { value: true });
+ var INVALID_BYTE = 256;
+ var Coder = (
+ /** @class */
+ (function() {
+ function Coder2(_paddingCharacter) {
+ if (_paddingCharacter === void 0) {
+ _paddingCharacter = "=";
+ }
+ this._paddingCharacter = _paddingCharacter;
+ }
+ Coder2.prototype.encodedLength = function(length) {
+ if (!this._paddingCharacter) {
+ return (length * 8 + 5) / 6 | 0;
+ }
+ return (length + 2) / 3 * 4 | 0;
+ };
+ Coder2.prototype.encode = function(data) {
+ var out = "";
+ var i = 0;
+ for (; i < data.length - 2; i += 3) {
+ var c2 = data[i] << 16 | data[i + 1] << 8 | data[i + 2];
+ out += this._encodeByte(c2 >>> 3 * 6 & 63);
+ out += this._encodeByte(c2 >>> 2 * 6 & 63);
+ out += this._encodeByte(c2 >>> 1 * 6 & 63);
+ out += this._encodeByte(c2 >>> 0 * 6 & 63);
+ }
+ var left = data.length - i;
+ if (left > 0) {
+ var c2 = data[i] << 16 | (left === 2 ? data[i + 1] << 8 : 0);
+ out += this._encodeByte(c2 >>> 3 * 6 & 63);
+ out += this._encodeByte(c2 >>> 2 * 6 & 63);
+ if (left === 2) {
+ out += this._encodeByte(c2 >>> 1 * 6 & 63);
+ } else {
+ out += this._paddingCharacter || "";
+ }
+ out += this._paddingCharacter || "";
+ }
+ return out;
+ };
+ Coder2.prototype.maxDecodedLength = function(length) {
+ if (!this._paddingCharacter) {
+ return (length * 6 + 7) / 8 | 0;
+ }
+ return length / 4 * 3 | 0;
+ };
+ Coder2.prototype.decodedLength = function(s) {
+ return this.maxDecodedLength(s.length - this._getPaddingLength(s));
+ };
+ Coder2.prototype.decode = function(s) {
+ if (s.length === 0) {
+ return new Uint8Array(0);
+ }
+ var paddingLength = this._getPaddingLength(s);
+ var length = s.length - paddingLength;
+ var out = new Uint8Array(this.maxDecodedLength(length));
+ var op = 0;
+ var i = 0;
+ var haveBad = 0;
+ var v0 = 0, v1 = 0, v2 = 0, v3 = 0;
+ for (; i < length - 4; i += 4) {
+ v0 = this._decodeChar(s.charCodeAt(i + 0));
+ v1 = this._decodeChar(s.charCodeAt(i + 1));
+ v2 = this._decodeChar(s.charCodeAt(i + 2));
+ v3 = this._decodeChar(s.charCodeAt(i + 3));
+ out[op++] = v0 << 2 | v1 >>> 4;
+ out[op++] = v1 << 4 | v2 >>> 2;
+ out[op++] = v2 << 6 | v3;
+ haveBad |= v0 & INVALID_BYTE;
+ haveBad |= v1 & INVALID_BYTE;
+ haveBad |= v2 & INVALID_BYTE;
+ haveBad |= v3 & INVALID_BYTE;
+ }
+ if (i < length - 1) {
+ v0 = this._decodeChar(s.charCodeAt(i));
+ v1 = this._decodeChar(s.charCodeAt(i + 1));
+ out[op++] = v0 << 2 | v1 >>> 4;
+ haveBad |= v0 & INVALID_BYTE;
+ haveBad |= v1 & INVALID_BYTE;
+ }
+ if (i < length - 2) {
+ v2 = this._decodeChar(s.charCodeAt(i + 2));
+ out[op++] = v1 << 4 | v2 >>> 2;
+ haveBad |= v2 & INVALID_BYTE;
+ }
+ if (i < length - 3) {
+ v3 = this._decodeChar(s.charCodeAt(i + 3));
+ out[op++] = v2 << 6 | v3;
+ haveBad |= v3 & INVALID_BYTE;
+ }
+ if (haveBad !== 0) {
+ throw new Error("Base64Coder: incorrect characters for decoding");
+ }
+ return out;
+ };
+ Coder2.prototype._encodeByte = function(b2) {
+ var result = b2;
+ result += 65;
+ result += 25 - b2 >>> 8 & 0 - 65 - 26 + 97;
+ result += 51 - b2 >>> 8 & 26 - 97 - 52 + 48;
+ result += 61 - b2 >>> 8 & 52 - 48 - 62 + 43;
+ result += 62 - b2 >>> 8 & 62 - 43 - 63 + 47;
+ return String.fromCharCode(result);
+ };
+ Coder2.prototype._decodeChar = function(c2) {
+ var result = INVALID_BYTE;
+ result += (42 - c2 & c2 - 44) >>> 8 & -INVALID_BYTE + c2 - 43 + 62;
+ result += (46 - c2 & c2 - 48) >>> 8 & -INVALID_BYTE + c2 - 47 + 63;
+ result += (47 - c2 & c2 - 58) >>> 8 & -INVALID_BYTE + c2 - 48 + 52;
+ result += (64 - c2 & c2 - 91) >>> 8 & -INVALID_BYTE + c2 - 65 + 0;
+ result += (96 - c2 & c2 - 123) >>> 8 & -INVALID_BYTE + c2 - 97 + 26;
+ return result;
+ };
+ Coder2.prototype._getPaddingLength = function(s) {
+ var paddingLength = 0;
+ if (this._paddingCharacter) {
+ for (var i = s.length - 1; i >= 0; i--) {
+ if (s[i] !== this._paddingCharacter) {
+ break;
+ }
+ paddingLength++;
+ }
+ if (s.length < 4 || paddingLength > 2) {
+ throw new Error("Base64Coder: incorrect padding");
+ }
+ }
+ return paddingLength;
+ };
+ return Coder2;
+ })()
+ );
+ exports$1.Coder = Coder;
+ var stdCoder = new Coder();
+ function encode(data) {
+ return stdCoder.encode(data);
+ }
+ exports$1.encode = encode;
+ function decode(s) {
+ return stdCoder.decode(s);
+ }
+ exports$1.decode = decode;
+ var URLSafeCoder = (
+ /** @class */
+ (function(_super) {
+ __extends(URLSafeCoder2, _super);
+ function URLSafeCoder2() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ URLSafeCoder2.prototype._encodeByte = function(b2) {
+ var result = b2;
+ result += 65;
+ result += 25 - b2 >>> 8 & 0 - 65 - 26 + 97;
+ result += 51 - b2 >>> 8 & 26 - 97 - 52 + 48;
+ result += 61 - b2 >>> 8 & 52 - 48 - 62 + 45;
+ result += 62 - b2 >>> 8 & 62 - 45 - 63 + 95;
+ return String.fromCharCode(result);
+ };
+ URLSafeCoder2.prototype._decodeChar = function(c2) {
+ var result = INVALID_BYTE;
+ result += (44 - c2 & c2 - 46) >>> 8 & -INVALID_BYTE + c2 - 45 + 62;
+ result += (94 - c2 & c2 - 96) >>> 8 & -INVALID_BYTE + c2 - 95 + 63;
+ result += (47 - c2 & c2 - 58) >>> 8 & -INVALID_BYTE + c2 - 48 + 52;
+ result += (64 - c2 & c2 - 91) >>> 8 & -INVALID_BYTE + c2 - 65 + 0;
+ result += (96 - c2 & c2 - 123) >>> 8 & -INVALID_BYTE + c2 - 97 + 26;
+ return result;
+ };
+ return URLSafeCoder2;
+ })(Coder)
+ );
+ exports$1.URLSafeCoder = URLSafeCoder;
+ var urlSafeCoder = new URLSafeCoder();
+ function encodeURLSafe(data) {
+ return urlSafeCoder.encode(data);
+ }
+ exports$1.encodeURLSafe = encodeURLSafe;
+ function decodeURLSafe(s) {
+ return urlSafeCoder.decode(s);
+ }
+ exports$1.decodeURLSafe = decodeURLSafe;
+ exports$1.encodedLength = function(length) {
+ return stdCoder.encodedLength(length);
+ };
+ exports$1.maxDecodedLength = function(length) {
+ return stdCoder.maxDecodedLength(length);
+ };
+ exports$1.decodedLength = function(s) {
+ return stdCoder.decodedLength(s);
+ };
+ },
+ /***/
+ 978(__unused_webpack_module, exports$1) {
+ var INVALID_UTF8 = "utf8: invalid source encoding";
+ function decode(arr) {
+ var chars = [];
+ for (var i = 0; i < arr.length; i++) {
+ var b2 = arr[i];
+ if (b2 & 128) {
+ var min = void 0;
+ if (b2 < 224) {
+ if (i >= arr.length) {
+ throw new Error(INVALID_UTF8);
+ }
+ var n1 = arr[++i];
+ if ((n1 & 192) !== 128) {
+ throw new Error(INVALID_UTF8);
+ }
+ b2 = (b2 & 31) << 6 | n1 & 63;
+ min = 128;
+ } else if (b2 < 240) {
+ if (i >= arr.length - 1) {
+ throw new Error(INVALID_UTF8);
+ }
+ var n1 = arr[++i];
+ var n2 = arr[++i];
+ if ((n1 & 192) !== 128 || (n2 & 192) !== 128) {
+ throw new Error(INVALID_UTF8);
+ }
+ b2 = (b2 & 15) << 12 | (n1 & 63) << 6 | n2 & 63;
+ min = 2048;
+ } else if (b2 < 248) {
+ if (i >= arr.length - 2) {
+ throw new Error(INVALID_UTF8);
+ }
+ var n1 = arr[++i];
+ var n2 = arr[++i];
+ var n3 = arr[++i];
+ if ((n1 & 192) !== 128 || (n2 & 192) !== 128 || (n3 & 192) !== 128) {
+ throw new Error(INVALID_UTF8);
+ }
+ b2 = (b2 & 15) << 18 | (n1 & 63) << 12 | (n2 & 63) << 6 | n3 & 63;
+ min = 65536;
+ } else {
+ throw new Error(INVALID_UTF8);
+ }
+ if (b2 < min || b2 >= 55296 && b2 <= 57343) {
+ throw new Error(INVALID_UTF8);
+ }
+ if (b2 >= 65536) {
+ if (b2 > 1114111) {
+ throw new Error(INVALID_UTF8);
+ }
+ b2 -= 65536;
+ chars.push(String.fromCharCode(55296 | b2 >> 10));
+ b2 = 56320 | b2 & 1023;
+ }
+ }
+ chars.push(String.fromCharCode(b2));
+ }
+ return chars.join("");
+ }
+ exports$1.D4 = decode;
+ },
+ /***/
+ 945(module2, __unused_webpack_exports, __webpack_require__2) {
+ var Stream = __webpack_require__2(203).Stream, util = __webpack_require__2(23), driver = __webpack_require__2(41), Headers = __webpack_require__2(160), API = __webpack_require__2(720), EventTarget = __webpack_require__2(667), Event = __webpack_require__2(859);
+ var EventSource = function(request, response, options) {
+ this.writable = true;
+ options = options || {};
+ this._stream = response.socket;
+ this._ping = options.ping || this.DEFAULT_PING;
+ this._retry = options.retry || this.DEFAULT_RETRY;
+ var scheme = driver.isSecureRequest(request) ? "https:" : "http:";
+ this.url = scheme + "//" + request.headers.host + request.url;
+ this.lastEventId = request.headers["last-event-id"] || "";
+ this.readyState = API.CONNECTING;
+ var headers = new Headers(), self2 = this;
+ if (options.headers) {
+ for (var key2 in options.headers) headers.set(key2, options.headers[key2]);
+ }
+ if (!this._stream || !this._stream.writable) return;
+ process.nextTick(function() {
+ self2._open();
+ });
+ this._stream.setTimeout(0);
+ this._stream.setNoDelay(true);
+ var handshake = "HTTP/1.1 200 OK\r\nContent-Type: text/event-stream\r\nCache-Control: no-cache, no-store\r\nConnection: close\r\n" + headers.toString() + "\r\nretry: " + Math.floor(this._retry * 1e3) + "\r\n\r\n";
+ this._write(handshake);
+ this._stream.on("drain", function() {
+ self2.emit("drain");
+ });
+ if (this._ping)
+ this._pingTimer = setInterval(function() {
+ self2.ping();
+ }, this._ping * 1e3);
+ ["error", "end"].forEach(function(event) {
+ self2._stream.on(event, function() {
+ self2.close();
+ });
+ });
+ };
+ util.inherits(EventSource, Stream);
+ EventSource.isEventSource = function(request) {
+ if (request.method !== "GET") return false;
+ var accept = (request.headers.accept || "").split(/\s*,\s*/);
+ return accept.indexOf("text/event-stream") >= 0;
+ };
+ var instance = {
+ DEFAULT_PING: 10,
+ DEFAULT_RETRY: 5,
+ _write: function(chunk) {
+ if (!this.writable) return false;
+ try {
+ return this._stream.write(chunk, "utf8");
+ } catch (e) {
+ return false;
+ }
+ },
+ _open: function() {
+ if (this.readyState !== API.CONNECTING) return;
+ this.readyState = API.OPEN;
+ var event = new Event("open");
+ event.initEvent("open", false, false);
+ this.dispatchEvent(event);
+ },
+ write: function(message) {
+ return this.send(message);
+ },
+ end: function(message) {
+ if (message !== void 0) this.write(message);
+ this.close();
+ },
+ send: function(message, options) {
+ if (this.readyState > API.OPEN) return false;
+ message = String(message).replace(/(\r\n|\r|\n)/g, "$1data: ");
+ options = options || {};
+ var frame = "";
+ if (options.event) frame += "event: " + options.event + "\r\n";
+ if (options.id) frame += "id: " + options.id + "\r\n";
+ frame += "data: " + message + "\r\n\r\n";
+ return this._write(frame);
+ },
+ ping: function() {
+ return this._write(":\r\n\r\n");
+ },
+ close: function() {
+ if (this.readyState > API.OPEN) return false;
+ this.readyState = API.CLOSED;
+ this.writable = false;
+ if (this._pingTimer) clearInterval(this._pingTimer);
+ if (this._stream) this._stream.end();
+ var event = new Event("close");
+ event.initEvent("close", false, false);
+ this.dispatchEvent(event);
+ return true;
+ }
+ };
+ for (var method in instance) EventSource.prototype[method] = instance[method];
+ for (var key in EventTarget) EventSource.prototype[key] = EventTarget[key];
+ module2.exports = EventSource;
+ },
+ /***/
+ 555(module2, __unused_webpack_exports, __webpack_require__2) {
+ var util = __webpack_require__2(23), driver = __webpack_require__2(41), API = __webpack_require__2(720);
+ var WebSocket = function(request, socket, body, protocols, options) {
+ options = options || {};
+ this._stream = socket;
+ this._driver = driver.http(request, { maxLength: options.maxLength, protocols });
+ var self2 = this;
+ if (!this._stream || !this._stream.writable) return;
+ if (!this._stream.readable) return this._stream.end();
+ var catchup = function() {
+ self2._stream.removeListener("data", catchup);
+ };
+ this._stream.on("data", catchup);
+ API.call(this, options);
+ process.nextTick(function() {
+ self2._driver.start();
+ self2._driver.io.write(body);
+ });
+ };
+ util.inherits(WebSocket, API);
+ WebSocket.isWebSocket = function(request) {
+ return driver.isWebSocket(request);
+ };
+ WebSocket.validateOptions = function(options, validKeys) {
+ driver.validateOptions(options, validKeys);
+ };
+ WebSocket.WebSocket = WebSocket;
+ WebSocket.Client = __webpack_require__2(333);
+ WebSocket.EventSource = __webpack_require__2(945);
+ module2.exports = WebSocket;
+ },
+ /***/
+ 720(module2, __unused_webpack_exports, __webpack_require__2) {
+ var Stream = __webpack_require__2(203).Stream, util = __webpack_require__2(23), driver = __webpack_require__2(41), EventTarget = __webpack_require__2(667), Event = __webpack_require__2(859);
+ var API = function(options) {
+ options = options || {};
+ driver.validateOptions(options, ["headers", "extensions", "maxLength", "ping", "proxy", "tls", "ca"]);
+ this.readable = this.writable = true;
+ var headers = options.headers;
+ if (headers) {
+ for (var name in headers) this._driver.setHeader(name, headers[name]);
+ }
+ var extensions = options.extensions;
+ if (extensions) {
+ [].concat(extensions).forEach(this._driver.addExtension, this._driver);
+ }
+ this._ping = options.ping;
+ this._pingId = 0;
+ this.readyState = API.CONNECTING;
+ this.bufferedAmount = 0;
+ this.protocol = "";
+ this.url = this._driver.url;
+ this.version = this._driver.version;
+ var self2 = this;
+ this._driver.on("open", function(e) {
+ self2._open();
+ });
+ this._driver.on("message", function(e) {
+ self2._receiveMessage(e.data);
+ });
+ this._driver.on("close", function(e) {
+ self2._beginClose(e.reason, e.code);
+ });
+ this._driver.on("error", function(error) {
+ self2._emitError(error.message);
+ });
+ this.on("error", function() {
+ });
+ this._driver.messages.on("drain", function() {
+ self2.emit("drain");
+ });
+ if (this._ping)
+ this._pingTimer = setInterval(function() {
+ self2._pingId += 1;
+ self2.ping(self2._pingId.toString());
+ }, this._ping * 1e3);
+ this._configureStream();
+ if (!this._proxy) {
+ this._stream.pipe(this._driver.io);
+ this._driver.io.pipe(this._stream);
+ }
+ };
+ util.inherits(API, Stream);
+ API.CONNECTING = 0;
+ API.OPEN = 1;
+ API.CLOSING = 2;
+ API.CLOSED = 3;
+ API.CLOSE_TIMEOUT = 3e4;
+ var instance = {
+ write: function(data) {
+ return this.send(data);
+ },
+ end: function(data) {
+ if (data !== void 0) this.send(data);
+ this.close();
+ },
+ pause: function() {
+ return this._driver.messages.pause();
+ },
+ resume: function() {
+ return this._driver.messages.resume();
+ },
+ send: function(data) {
+ if (this.readyState > API.OPEN) return false;
+ if (!(data instanceof Buffer)) data = String(data);
+ return this._driver.messages.write(data);
+ },
+ ping: function(message, callback) {
+ if (this.readyState > API.OPEN) return false;
+ return this._driver.ping(message, callback);
+ },
+ close: function(code, reason) {
+ if (code === void 0) code = 1e3;
+ if (reason === void 0) reason = "";
+ if (code !== 1e3 && (code < 3e3 || code > 4999))
+ throw new Error("Failed to execute 'close' on WebSocket: The code must be either 1000, or between 3000 and 4999. " + code + " is neither.");
+ if (this.readyState !== API.CLOSED) this.readyState = API.CLOSING;
+ var self2 = this;
+ this._closeTimer = setTimeout(function() {
+ self2._beginClose("", 1006);
+ }, API.CLOSE_TIMEOUT);
+ this._driver.close(reason, code);
+ },
+ _configureStream: function() {
+ var self2 = this;
+ this._stream.setTimeout(0);
+ this._stream.setNoDelay(true);
+ ["close", "end"].forEach(function(event) {
+ this._stream.on(event, function() {
+ self2._finalizeClose();
+ });
+ }, this);
+ this._stream.on("error", function(error) {
+ self2._emitError("Network error: " + self2.url + ": " + error.message);
+ self2._finalizeClose();
+ });
+ },
+ _open: function() {
+ if (this.readyState !== API.CONNECTING) return;
+ this.readyState = API.OPEN;
+ this.protocol = this._driver.protocol || "";
+ var event = new Event("open");
+ event.initEvent("open", false, false);
+ this.dispatchEvent(event);
+ },
+ _receiveMessage: function(data) {
+ if (this.readyState > API.OPEN) return false;
+ if (this.readable) this.emit("data", data);
+ var event = new Event("message", { data });
+ event.initEvent("message", false, false);
+ this.dispatchEvent(event);
+ },
+ _emitError: function(message) {
+ if (this.readyState >= API.CLOSING) return;
+ var event = new Event("error", { message });
+ event.initEvent("error", false, false);
+ this.dispatchEvent(event);
+ },
+ _beginClose: function(reason, code) {
+ if (this.readyState === API.CLOSED) return;
+ this.readyState = API.CLOSING;
+ this._closeParams = [reason, code];
+ if (this._stream) {
+ this._stream.destroy();
+ if (!this._stream.readable) this._finalizeClose();
+ }
+ },
+ _finalizeClose: function() {
+ if (this.readyState === API.CLOSED) return;
+ this.readyState = API.CLOSED;
+ if (this._closeTimer) clearTimeout(this._closeTimer);
+ if (this._pingTimer) clearInterval(this._pingTimer);
+ if (this._stream) this._stream.end();
+ if (this.readable) this.emit("end");
+ this.readable = this.writable = false;
+ var reason = this._closeParams ? this._closeParams[0] : "", code = this._closeParams ? this._closeParams[1] : 1006;
+ var event = new Event("close", { code, reason });
+ event.initEvent("close", false, false);
+ this.dispatchEvent(event);
+ }
+ };
+ for (var method in instance) API.prototype[method] = instance[method];
+ for (var key in EventTarget) API.prototype[key] = EventTarget[key];
+ module2.exports = API;
+ },
+ /***/
+ 859(module2) {
+ var Event = function(eventType, options) {
+ this.type = eventType;
+ for (var key in options)
+ this[key] = options[key];
+ };
+ Event.prototype.initEvent = function(eventType, canBubble, cancelable) {
+ this.type = eventType;
+ this.bubbles = canBubble;
+ this.cancelable = cancelable;
+ };
+ Event.prototype.stopPropagation = function() {
+ };
+ Event.prototype.preventDefault = function() {
+ };
+ Event.CAPTURING_PHASE = 1;
+ Event.AT_TARGET = 2;
+ Event.BUBBLING_PHASE = 3;
+ module2.exports = Event;
+ },
+ /***/
+ 667(module2, __unused_webpack_exports, __webpack_require__2) {
+ var Event = __webpack_require__2(859);
+ var EventTarget = {
+ onopen: null,
+ onmessage: null,
+ onerror: null,
+ onclose: null,
+ addEventListener: function(eventType, listener, useCapture) {
+ this.on(eventType, listener);
+ },
+ removeEventListener: function(eventType, listener, useCapture) {
+ this.removeListener(eventType, listener);
+ },
+ dispatchEvent: function(event) {
+ event.target = event.currentTarget = this;
+ event.eventPhase = Event.AT_TARGET;
+ if (this["on" + event.type])
+ this["on" + event.type](event);
+ this.emit(event.type, event);
+ }
+ };
+ module2.exports = EventTarget;
+ },
+ /***/
+ 333(module2, __unused_webpack_exports, __webpack_require__2) {
+ var util = __webpack_require__2(23), net = __webpack_require__2(278), tls = __webpack_require__2(756), url = __webpack_require__2(16), driver = __webpack_require__2(41), API = __webpack_require__2(720);
+ __webpack_require__2(859);
+ var DEFAULT_PORTS = { "http:": 80, "https:": 443, "ws:": 80, "wss:": 443 }, SECURE_PROTOCOLS = ["https:", "wss:"];
+ var Client = function(_url, protocols, options) {
+ options = options || {};
+ this.url = _url;
+ this._driver = driver.client(this.url, { maxLength: options.maxLength, protocols });
+ ["open", "error"].forEach(function(event) {
+ this._driver.on(event, function() {
+ self2.headers = self2._driver.headers;
+ self2.statusCode = self2._driver.statusCode;
+ });
+ }, this);
+ var proxy = options.proxy || {}, endpoint = url.parse(proxy.origin || this.url), port = endpoint.port || DEFAULT_PORTS[endpoint.protocol], secure = SECURE_PROTOCOLS.indexOf(endpoint.protocol) >= 0, onConnect = function() {
+ self2._onConnect();
+ }, netOptions = options.net || {}, originTLS = options.tls || {}, socketTLS = proxy.origin ? proxy.tls || {} : originTLS, self2 = this;
+ netOptions.host = socketTLS.host = endpoint.hostname;
+ netOptions.port = socketTLS.port = port;
+ originTLS.ca = originTLS.ca || options.ca;
+ socketTLS.servername = socketTLS.servername || endpoint.hostname;
+ this._stream = secure ? tls.connect(socketTLS, onConnect) : net.connect(netOptions, onConnect);
+ if (proxy.origin) this._configureProxy(proxy, originTLS);
+ API.call(this, options);
+ };
+ util.inherits(Client, API);
+ Client.prototype._onConnect = function() {
+ var worker = this._proxy || this._driver;
+ worker.start();
+ };
+ Client.prototype._configureProxy = function(proxy, originTLS) {
+ var uri = url.parse(this.url), secure = SECURE_PROTOCOLS.indexOf(uri.protocol) >= 0, self2 = this, name;
+ this._proxy = this._driver.proxy(proxy.origin);
+ if (proxy.headers) {
+ for (name in proxy.headers) this._proxy.setHeader(name, proxy.headers[name]);
+ }
+ this._proxy.pipe(this._stream, { end: false });
+ this._stream.pipe(this._proxy);
+ this._proxy.on("connect", function() {
+ if (secure) {
+ var options = { socket: self2._stream, servername: uri.hostname };
+ for (name in originTLS) options[name] = originTLS[name];
+ self2._stream = tls.connect(options);
+ self2._configureStream();
+ }
+ self2._driver.io.pipe(self2._stream);
+ self2._stream.pipe(self2._driver.io);
+ self2._driver.start();
+ });
+ this._proxy.on("error", function(error) {
+ self2._driver.emit("error", error);
+ });
+ };
+ module2.exports = Client;
+ },
+ /***/
+ 895(__unused_webpack_module, exports$1, __webpack_require__2) {
+ var assert = __webpack_require__2(613);
+ exports$1.e = HTTPParser;
+ function HTTPParser(type) {
+ assert.ok(type === HTTPParser.REQUEST || type === HTTPParser.RESPONSE || type === void 0);
+ if (type === void 0) ;
+ else {
+ this.initialize(type);
+ }
+ this.maxHeaderSize = HTTPParser.maxHeaderSize;
+ }
+ HTTPParser.prototype.initialize = function(type, async_resource) {
+ assert.ok(type === HTTPParser.REQUEST || type === HTTPParser.RESPONSE);
+ this.type = type;
+ this.state = type + "_LINE";
+ this.info = {
+ headers: [],
+ upgrade: false
+ };
+ this.trailers = [];
+ this.line = "";
+ this.isChunked = false;
+ this.connection = "";
+ this.headerSize = 0;
+ this.body_bytes = null;
+ this.isUserCall = false;
+ this.hadError = false;
+ };
+ HTTPParser.encoding = "ascii";
+ HTTPParser.maxHeaderSize = 80 * 1024;
+ HTTPParser.REQUEST = "REQUEST";
+ HTTPParser.RESPONSE = "RESPONSE";
+ var kOnHeaders = HTTPParser.kOnHeaders = 1;
+ var kOnHeadersComplete = HTTPParser.kOnHeadersComplete = 2;
+ var kOnBody = HTTPParser.kOnBody = 3;
+ var kOnMessageComplete = HTTPParser.kOnMessageComplete = 4;
+ HTTPParser.prototype[kOnHeaders] = HTTPParser.prototype[kOnHeadersComplete] = HTTPParser.prototype[kOnBody] = HTTPParser.prototype[kOnMessageComplete] = function() {
+ };
+ var compatMode0_12 = true;
+ Object.defineProperty(HTTPParser, "kOnExecute", {
+ get: function() {
+ compatMode0_12 = false;
+ return 99;
+ }
+ });
+ var methods = HTTPParser.methods = [
+ "DELETE",
+ "GET",
+ "HEAD",
+ "POST",
+ "PUT",
+ "CONNECT",
+ "OPTIONS",
+ "TRACE",
+ "COPY",
+ "LOCK",
+ "MKCOL",
+ "MOVE",
+ "PROPFIND",
+ "PROPPATCH",
+ "SEARCH",
+ "UNLOCK",
+ "BIND",
+ "REBIND",
+ "UNBIND",
+ "ACL",
+ "REPORT",
+ "MKACTIVITY",
+ "CHECKOUT",
+ "MERGE",
+ "M-SEARCH",
+ "NOTIFY",
+ "SUBSCRIBE",
+ "UNSUBSCRIBE",
+ "PATCH",
+ "PURGE",
+ "MKCALENDAR",
+ "LINK",
+ "UNLINK",
+ "SOURCE"
+ ];
+ var method_connect = methods.indexOf("CONNECT");
+ HTTPParser.prototype.reinitialize = HTTPParser;
+ HTTPParser.prototype.close = HTTPParser.prototype.pause = HTTPParser.prototype.resume = HTTPParser.prototype.free = function() {
+ };
+ HTTPParser.prototype._compatMode0_11 = false;
+ HTTPParser.prototype.getAsyncId = function() {
+ return 0;
+ };
+ var headerState = {
+ REQUEST_LINE: true,
+ RESPONSE_LINE: true,
+ HEADER: true
+ };
+ HTTPParser.prototype.execute = function(chunk, start, length) {
+ if (!(this instanceof HTTPParser)) {
+ throw new TypeError("not a HTTPParser");
+ }
+ start = start || 0;
+ length = typeof length === "number" ? length : chunk.length;
+ this.chunk = chunk;
+ this.offset = start;
+ var end = this.end = start + length;
+ try {
+ while (this.offset < end) {
+ if (this[this.state]()) {
+ break;
+ }
+ }
+ } catch (err) {
+ if (this.isUserCall) {
+ throw err;
+ }
+ this.hadError = true;
+ return err;
+ }
+ this.chunk = null;
+ length = this.offset - start;
+ if (headerState[this.state]) {
+ this.headerSize += length;
+ if (this.headerSize > (this.maxHeaderSize || HTTPParser.maxHeaderSize)) {
+ return new Error("max header size exceeded");
+ }
+ }
+ return length;
+ };
+ var stateFinishAllowed = {
+ REQUEST_LINE: true,
+ RESPONSE_LINE: true,
+ BODY_RAW: true
+ };
+ HTTPParser.prototype.finish = function() {
+ if (this.hadError) {
+ return;
+ }
+ if (!stateFinishAllowed[this.state]) {
+ return new Error("invalid state for EOF");
+ }
+ if (this.state === "BODY_RAW") {
+ this.userCall()(this[kOnMessageComplete]());
+ }
+ };
+ HTTPParser.prototype.consume = HTTPParser.prototype.unconsume = HTTPParser.prototype.getCurrentBuffer = function() {
+ };
+ HTTPParser.prototype.userCall = function() {
+ this.isUserCall = true;
+ var self2 = this;
+ return function(ret) {
+ self2.isUserCall = false;
+ return ret;
+ };
+ };
+ HTTPParser.prototype.nextRequest = function() {
+ this.userCall()(this[kOnMessageComplete]());
+ this.reinitialize(this.type);
+ };
+ HTTPParser.prototype.consumeLine = function() {
+ var end = this.end, chunk = this.chunk;
+ for (var i = this.offset; i < end; i++) {
+ if (chunk[i] === 10) {
+ var line = this.line + chunk.toString(HTTPParser.encoding, this.offset, i);
+ if (line.charAt(line.length - 1) === "\r") {
+ line = line.substr(0, line.length - 1);
+ }
+ this.line = "";
+ this.offset = i + 1;
+ return line;
+ }
+ }
+ this.line += chunk.toString(HTTPParser.encoding, this.offset, this.end);
+ this.offset = this.end;
+ };
+ var headerExp = /^([^: \t]+):[ \t]*((?:.*[^ \t])|)/;
+ var headerContinueExp = /^[ \t]+(.*[^ \t])/;
+ HTTPParser.prototype.parseHeader = function(line, headers) {
+ if (line.indexOf("\r") !== -1) {
+ throw parseErrorCode("HPE_LF_EXPECTED");
+ }
+ var match = headerExp.exec(line);
+ var k2 = match && match[1];
+ if (k2) {
+ headers.push(k2);
+ headers.push(match[2]);
+ } else {
+ var matchContinue = headerContinueExp.exec(line);
+ if (matchContinue && headers.length) {
+ if (headers[headers.length - 1]) {
+ headers[headers.length - 1] += " ";
+ }
+ headers[headers.length - 1] += matchContinue[1];
+ }
+ }
+ };
+ var requestExp = /^([A-Z-]+) ([^ ]+) HTTP\/(\d)\.(\d)$/;
+ HTTPParser.prototype.REQUEST_LINE = function() {
+ var line = this.consumeLine();
+ if (!line) {
+ return;
+ }
+ var match = requestExp.exec(line);
+ if (match === null) {
+ throw parseErrorCode("HPE_INVALID_CONSTANT");
+ }
+ this.info.method = this._compatMode0_11 ? match[1] : methods.indexOf(match[1]);
+ if (this.info.method === -1) {
+ throw new Error("invalid request method");
+ }
+ this.info.url = match[2];
+ this.info.versionMajor = +match[3];
+ this.info.versionMinor = +match[4];
+ this.body_bytes = 0;
+ this.state = "HEADER";
+ };
+ var responseExp = /^HTTP\/(\d)\.(\d) (\d{3}) ?(.*)$/;
+ HTTPParser.prototype.RESPONSE_LINE = function() {
+ var line = this.consumeLine();
+ if (!line) {
+ return;
+ }
+ var match = responseExp.exec(line);
+ if (match === null) {
+ throw parseErrorCode("HPE_INVALID_CONSTANT");
+ }
+ this.info.versionMajor = +match[1];
+ this.info.versionMinor = +match[2];
+ var statusCode = this.info.statusCode = +match[3];
+ this.info.statusMessage = match[4];
+ if ((statusCode / 100 | 0) === 1 || statusCode === 204 || statusCode === 304) {
+ this.body_bytes = 0;
+ }
+ this.state = "HEADER";
+ };
+ HTTPParser.prototype.shouldKeepAlive = function() {
+ if (this.info.versionMajor > 0 && this.info.versionMinor > 0) {
+ if (this.connection.indexOf("close") !== -1) {
+ return false;
+ }
+ } else if (this.connection.indexOf("keep-alive") === -1) {
+ return false;
+ }
+ if (this.body_bytes !== null || this.isChunked) {
+ return true;
+ }
+ return false;
+ };
+ HTTPParser.prototype.HEADER = function() {
+ var line = this.consumeLine();
+ if (line === void 0) {
+ return;
+ }
+ var info = this.info;
+ if (line) {
+ this.parseHeader(line, info.headers);
+ } else {
+ var headers = info.headers;
+ var hasContentLength = false;
+ var currentContentLengthValue;
+ var hasUpgradeHeader = false;
+ for (var i = 0; i < headers.length; i += 2) {
+ switch (headers[i].toLowerCase()) {
+ case "transfer-encoding":
+ this.isChunked = headers[i + 1].toLowerCase() === "chunked";
+ break;
+ case "content-length":
+ currentContentLengthValue = +headers[i + 1];
+ if (hasContentLength) {
+ if (currentContentLengthValue !== this.body_bytes) {
+ throw parseErrorCode("HPE_UNEXPECTED_CONTENT_LENGTH");
+ }
+ } else {
+ hasContentLength = true;
+ this.body_bytes = currentContentLengthValue;
+ }
+ break;
+ case "connection":
+ this.connection += headers[i + 1].toLowerCase();
+ break;
+ case "upgrade":
+ hasUpgradeHeader = true;
+ break;
+ }
+ }
+ if (this.isChunked && hasContentLength) {
+ hasContentLength = false;
+ this.body_bytes = null;
+ }
+ if (hasUpgradeHeader && this.connection.indexOf("upgrade") != -1) {
+ info.upgrade = this.type === HTTPParser.REQUEST || info.statusCode === 101;
+ } else {
+ info.upgrade = info.method === method_connect;
+ }
+ if (this.isChunked && info.upgrade) {
+ this.isChunked = false;
+ }
+ info.shouldKeepAlive = this.shouldKeepAlive();
+ var skipBody;
+ if (compatMode0_12) {
+ skipBody = this.userCall()(this[kOnHeadersComplete](info));
+ } else {
+ skipBody = this.userCall()(this[kOnHeadersComplete](
+ info.versionMajor,
+ info.versionMinor,
+ info.headers,
+ info.method,
+ info.url,
+ info.statusCode,
+ info.statusMessage,
+ info.upgrade,
+ info.shouldKeepAlive
+ ));
+ }
+ if (skipBody === 2) {
+ this.nextRequest();
+ return true;
+ } else if (this.isChunked && !skipBody) {
+ this.state = "BODY_CHUNKHEAD";
+ } else if (skipBody || this.body_bytes === 0) {
+ this.nextRequest();
+ return info.upgrade;
+ } else if (this.body_bytes === null) {
+ this.state = "BODY_RAW";
+ } else {
+ this.state = "BODY_SIZED";
+ }
+ }
+ };
+ HTTPParser.prototype.BODY_CHUNKHEAD = function() {
+ var line = this.consumeLine();
+ if (line === void 0) {
+ return;
+ }
+ this.body_bytes = parseInt(line, 16);
+ if (!this.body_bytes) {
+ this.state = "BODY_CHUNKTRAILERS";
+ } else {
+ this.state = "BODY_CHUNK";
+ }
+ };
+ HTTPParser.prototype.BODY_CHUNK = function() {
+ var length = Math.min(this.end - this.offset, this.body_bytes);
+ this.userCall()(this[kOnBody](this.chunk, this.offset, length));
+ this.offset += length;
+ this.body_bytes -= length;
+ if (!this.body_bytes) {
+ this.state = "BODY_CHUNKEMPTYLINE";
+ }
+ };
+ HTTPParser.prototype.BODY_CHUNKEMPTYLINE = function() {
+ var line = this.consumeLine();
+ if (line === void 0) {
+ return;
+ }
+ assert.equal(line, "");
+ this.state = "BODY_CHUNKHEAD";
+ };
+ HTTPParser.prototype.BODY_CHUNKTRAILERS = function() {
+ var line = this.consumeLine();
+ if (line === void 0) {
+ return;
+ }
+ if (line) {
+ this.parseHeader(line, this.trailers);
+ } else {
+ if (this.trailers.length) {
+ this.userCall()(this[kOnHeaders](this.trailers, ""));
+ }
+ this.nextRequest();
+ }
+ };
+ HTTPParser.prototype.BODY_RAW = function() {
+ var length = this.end - this.offset;
+ this.userCall()(this[kOnBody](this.chunk, this.offset, length));
+ this.offset = this.end;
+ };
+ HTTPParser.prototype.BODY_SIZED = function() {
+ var length = Math.min(this.end - this.offset, this.body_bytes);
+ this.userCall()(this[kOnBody](this.chunk, this.offset, length));
+ this.offset += length;
+ this.body_bytes -= length;
+ if (!this.body_bytes) {
+ this.nextRequest();
+ }
+ };
+ ["Headers", "HeadersComplete", "Body", "MessageComplete"].forEach(function(name) {
+ var k2 = HTTPParser["kOn" + name];
+ Object.defineProperty(HTTPParser.prototype, "on" + name, {
+ get: function() {
+ return this[k2];
+ },
+ set: function(to) {
+ this._compatMode0_11 = true;
+ method_connect = "CONNECT";
+ return this[k2] = to;
+ }
+ });
+ });
+ function parseErrorCode(code) {
+ var err = new Error("Parse Error");
+ err.code = code;
+ return err;
+ }
+ },
+ /***/
+ 891(module2, exports$1, __webpack_require__2) {
+ var buffer = __webpack_require__2(181);
+ var Buffer2 = buffer.Buffer;
+ function copyProps(src, dst) {
+ for (var key in src) {
+ dst[key] = src[key];
+ }
+ }
+ if (Buffer2.from && Buffer2.alloc && Buffer2.allocUnsafe && Buffer2.allocUnsafeSlow) {
+ module2.exports = buffer;
+ } else {
+ copyProps(buffer, exports$1);
+ exports$1.Buffer = SafeBuffer;
+ }
+ function SafeBuffer(arg, encodingOrOffset, length) {
+ return Buffer2(arg, encodingOrOffset, length);
+ }
+ copyProps(Buffer2, SafeBuffer);
+ SafeBuffer.from = function(arg, encodingOrOffset, length) {
+ if (typeof arg === "number") {
+ throw new TypeError("Argument must not be a number");
+ }
+ return Buffer2(arg, encodingOrOffset, length);
+ };
+ SafeBuffer.alloc = function(size, fill, encoding) {
+ if (typeof size !== "number") {
+ throw new TypeError("Argument must be a number");
+ }
+ var buf = Buffer2(size);
+ if (fill !== void 0) {
+ if (typeof encoding === "string") {
+ buf.fill(fill, encoding);
+ } else {
+ buf.fill(fill);
+ }
+ } else {
+ buf.fill(0);
+ }
+ return buf;
+ };
+ SafeBuffer.allocUnsafe = function(size) {
+ if (typeof size !== "number") {
+ throw new TypeError("Argument must be a number");
+ }
+ return Buffer2(size);
+ };
+ SafeBuffer.allocUnsafeSlow = function(size) {
+ if (typeof size !== "number") {
+ throw new TypeError("Argument must be a number");
+ }
+ return buffer.SlowBuffer(size);
+ };
+ },
+ /***/
+ 601(module2, __unused_webpack_exports, __webpack_require__2) {
+ (function(nacl) {
+ var gf = function(init) {
+ var i, r2 = new Float64Array(16);
+ if (init) for (i = 0; i < init.length; i++) r2[i] = init[i];
+ return r2;
+ };
+ var randombytes = function() {
+ throw new Error("no PRNG");
+ };
+ var _0 = new Uint8Array(16);
+ var _9 = new Uint8Array(32);
+ _9[0] = 9;
+ var gf0 = gf(), gf1 = gf([1]), _121665 = gf([56129, 1]), D = gf([30883, 4953, 19914, 30187, 55467, 16705, 2637, 112, 59544, 30585, 16505, 36039, 65139, 11119, 27886, 20995]), D2 = gf([61785, 9906, 39828, 60374, 45398, 33411, 5274, 224, 53552, 61171, 33010, 6542, 64743, 22239, 55772, 9222]), X = gf([54554, 36645, 11616, 51542, 42930, 38181, 51040, 26924, 56412, 64982, 57905, 49316, 21502, 52590, 14035, 8553]), Y = gf([26200, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214]), I = gf([41136, 18958, 6951, 50414, 58488, 44335, 6150, 12099, 55207, 15867, 153, 11085, 57099, 20417, 9344, 11139]);
+ function ts64(x, i, h3, l2) {
+ x[i] = h3 >> 24 & 255;
+ x[i + 1] = h3 >> 16 & 255;
+ x[i + 2] = h3 >> 8 & 255;
+ x[i + 3] = h3 & 255;
+ x[i + 4] = l2 >> 24 & 255;
+ x[i + 5] = l2 >> 16 & 255;
+ x[i + 6] = l2 >> 8 & 255;
+ x[i + 7] = l2 & 255;
+ }
+ function vn(x, xi, y2, yi, n) {
+ var i, d2 = 0;
+ for (i = 0; i < n; i++) d2 |= x[xi + i] ^ y2[yi + i];
+ return (1 & d2 - 1 >>> 8) - 1;
+ }
+ function crypto_verify_16(x, xi, y2, yi) {
+ return vn(x, xi, y2, yi, 16);
+ }
+ function crypto_verify_32(x, xi, y2, yi) {
+ return vn(x, xi, y2, yi, 32);
+ }
+ function core_salsa20(o2, p2, k2, c2) {
+ var j0 = c2[0] & 255 | (c2[1] & 255) << 8 | (c2[2] & 255) << 16 | (c2[3] & 255) << 24, j1 = k2[0] & 255 | (k2[1] & 255) << 8 | (k2[2] & 255) << 16 | (k2[3] & 255) << 24, j2 = k2[4] & 255 | (k2[5] & 255) << 8 | (k2[6] & 255) << 16 | (k2[7] & 255) << 24, j3 = k2[8] & 255 | (k2[9] & 255) << 8 | (k2[10] & 255) << 16 | (k2[11] & 255) << 24, j4 = k2[12] & 255 | (k2[13] & 255) << 8 | (k2[14] & 255) << 16 | (k2[15] & 255) << 24, j5 = c2[4] & 255 | (c2[5] & 255) << 8 | (c2[6] & 255) << 16 | (c2[7] & 255) << 24, j6 = p2[0] & 255 | (p2[1] & 255) << 8 | (p2[2] & 255) << 16 | (p2[3] & 255) << 24, j7 = p2[4] & 255 | (p2[5] & 255) << 8 | (p2[6] & 255) << 16 | (p2[7] & 255) << 24, j8 = p2[8] & 255 | (p2[9] & 255) << 8 | (p2[10] & 255) << 16 | (p2[11] & 255) << 24, j9 = p2[12] & 255 | (p2[13] & 255) << 8 | (p2[14] & 255) << 16 | (p2[15] & 255) << 24, j10 = c2[8] & 255 | (c2[9] & 255) << 8 | (c2[10] & 255) << 16 | (c2[11] & 255) << 24, j11 = k2[16] & 255 | (k2[17] & 255) << 8 | (k2[18] & 255) << 16 | (k2[19] & 255) << 24, j12 = k2[20] & 255 | (k2[21] & 255) << 8 | (k2[22] & 255) << 16 | (k2[23] & 255) << 24, j13 = k2[24] & 255 | (k2[25] & 255) << 8 | (k2[26] & 255) << 16 | (k2[27] & 255) << 24, j14 = k2[28] & 255 | (k2[29] & 255) << 8 | (k2[30] & 255) << 16 | (k2[31] & 255) << 24, j15 = c2[12] & 255 | (c2[13] & 255) << 8 | (c2[14] & 255) << 16 | (c2[15] & 255) << 24;
+ var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, x15 = j15, u2;
+ for (var i = 0; i < 20; i += 2) {
+ u2 = x0 + x12 | 0;
+ x4 ^= u2 << 7 | u2 >>> 32 - 7;
+ u2 = x4 + x0 | 0;
+ x8 ^= u2 << 9 | u2 >>> 32 - 9;
+ u2 = x8 + x4 | 0;
+ x12 ^= u2 << 13 | u2 >>> 32 - 13;
+ u2 = x12 + x8 | 0;
+ x0 ^= u2 << 18 | u2 >>> 32 - 18;
+ u2 = x5 + x1 | 0;
+ x9 ^= u2 << 7 | u2 >>> 32 - 7;
+ u2 = x9 + x5 | 0;
+ x13 ^= u2 << 9 | u2 >>> 32 - 9;
+ u2 = x13 + x9 | 0;
+ x1 ^= u2 << 13 | u2 >>> 32 - 13;
+ u2 = x1 + x13 | 0;
+ x5 ^= u2 << 18 | u2 >>> 32 - 18;
+ u2 = x10 + x6 | 0;
+ x14 ^= u2 << 7 | u2 >>> 32 - 7;
+ u2 = x14 + x10 | 0;
+ x2 ^= u2 << 9 | u2 >>> 32 - 9;
+ u2 = x2 + x14 | 0;
+ x6 ^= u2 << 13 | u2 >>> 32 - 13;
+ u2 = x6 + x2 | 0;
+ x10 ^= u2 << 18 | u2 >>> 32 - 18;
+ u2 = x15 + x11 | 0;
+ x3 ^= u2 << 7 | u2 >>> 32 - 7;
+ u2 = x3 + x15 | 0;
+ x7 ^= u2 << 9 | u2 >>> 32 - 9;
+ u2 = x7 + x3 | 0;
+ x11 ^= u2 << 13 | u2 >>> 32 - 13;
+ u2 = x11 + x7 | 0;
+ x15 ^= u2 << 18 | u2 >>> 32 - 18;
+ u2 = x0 + x3 | 0;
+ x1 ^= u2 << 7 | u2 >>> 32 - 7;
+ u2 = x1 + x0 | 0;
+ x2 ^= u2 << 9 | u2 >>> 32 - 9;
+ u2 = x2 + x1 | 0;
+ x3 ^= u2 << 13 | u2 >>> 32 - 13;
+ u2 = x3 + x2 | 0;
+ x0 ^= u2 << 18 | u2 >>> 32 - 18;
+ u2 = x5 + x4 | 0;
+ x6 ^= u2 << 7 | u2 >>> 32 - 7;
+ u2 = x6 + x5 | 0;
+ x7 ^= u2 << 9 | u2 >>> 32 - 9;
+ u2 = x7 + x6 | 0;
+ x4 ^= u2 << 13 | u2 >>> 32 - 13;
+ u2 = x4 + x7 | 0;
+ x5 ^= u2 << 18 | u2 >>> 32 - 18;
+ u2 = x10 + x9 | 0;
+ x11 ^= u2 << 7 | u2 >>> 32 - 7;
+ u2 = x11 + x10 | 0;
+ x8 ^= u2 << 9 | u2 >>> 32 - 9;
+ u2 = x8 + x11 | 0;
+ x9 ^= u2 << 13 | u2 >>> 32 - 13;
+ u2 = x9 + x8 | 0;
+ x10 ^= u2 << 18 | u2 >>> 32 - 18;
+ u2 = x15 + x14 | 0;
+ x12 ^= u2 << 7 | u2 >>> 32 - 7;
+ u2 = x12 + x15 | 0;
+ x13 ^= u2 << 9 | u2 >>> 32 - 9;
+ u2 = x13 + x12 | 0;
+ x14 ^= u2 << 13 | u2 >>> 32 - 13;
+ u2 = x14 + x13 | 0;
+ x15 ^= u2 << 18 | u2 >>> 32 - 18;
+ }
+ x0 = x0 + j0 | 0;
+ x1 = x1 + j1 | 0;
+ x2 = x2 + j2 | 0;
+ x3 = x3 + j3 | 0;
+ x4 = x4 + j4 | 0;
+ x5 = x5 + j5 | 0;
+ x6 = x6 + j6 | 0;
+ x7 = x7 + j7 | 0;
+ x8 = x8 + j8 | 0;
+ x9 = x9 + j9 | 0;
+ x10 = x10 + j10 | 0;
+ x11 = x11 + j11 | 0;
+ x12 = x12 + j12 | 0;
+ x13 = x13 + j13 | 0;
+ x14 = x14 + j14 | 0;
+ x15 = x15 + j15 | 0;
+ o2[0] = x0 >>> 0 & 255;
+ o2[1] = x0 >>> 8 & 255;
+ o2[2] = x0 >>> 16 & 255;
+ o2[3] = x0 >>> 24 & 255;
+ o2[4] = x1 >>> 0 & 255;
+ o2[5] = x1 >>> 8 & 255;
+ o2[6] = x1 >>> 16 & 255;
+ o2[7] = x1 >>> 24 & 255;
+ o2[8] = x2 >>> 0 & 255;
+ o2[9] = x2 >>> 8 & 255;
+ o2[10] = x2 >>> 16 & 255;
+ o2[11] = x2 >>> 24 & 255;
+ o2[12] = x3 >>> 0 & 255;
+ o2[13] = x3 >>> 8 & 255;
+ o2[14] = x3 >>> 16 & 255;
+ o2[15] = x3 >>> 24 & 255;
+ o2[16] = x4 >>> 0 & 255;
+ o2[17] = x4 >>> 8 & 255;
+ o2[18] = x4 >>> 16 & 255;
+ o2[19] = x4 >>> 24 & 255;
+ o2[20] = x5 >>> 0 & 255;
+ o2[21] = x5 >>> 8 & 255;
+ o2[22] = x5 >>> 16 & 255;
+ o2[23] = x5 >>> 24 & 255;
+ o2[24] = x6 >>> 0 & 255;
+ o2[25] = x6 >>> 8 & 255;
+ o2[26] = x6 >>> 16 & 255;
+ o2[27] = x6 >>> 24 & 255;
+ o2[28] = x7 >>> 0 & 255;
+ o2[29] = x7 >>> 8 & 255;
+ o2[30] = x7 >>> 16 & 255;
+ o2[31] = x7 >>> 24 & 255;
+ o2[32] = x8 >>> 0 & 255;
+ o2[33] = x8 >>> 8 & 255;
+ o2[34] = x8 >>> 16 & 255;
+ o2[35] = x8 >>> 24 & 255;
+ o2[36] = x9 >>> 0 & 255;
+ o2[37] = x9 >>> 8 & 255;
+ o2[38] = x9 >>> 16 & 255;
+ o2[39] = x9 >>> 24 & 255;
+ o2[40] = x10 >>> 0 & 255;
+ o2[41] = x10 >>> 8 & 255;
+ o2[42] = x10 >>> 16 & 255;
+ o2[43] = x10 >>> 24 & 255;
+ o2[44] = x11 >>> 0 & 255;
+ o2[45] = x11 >>> 8 & 255;
+ o2[46] = x11 >>> 16 & 255;
+ o2[47] = x11 >>> 24 & 255;
+ o2[48] = x12 >>> 0 & 255;
+ o2[49] = x12 >>> 8 & 255;
+ o2[50] = x12 >>> 16 & 255;
+ o2[51] = x12 >>> 24 & 255;
+ o2[52] = x13 >>> 0 & 255;
+ o2[53] = x13 >>> 8 & 255;
+ o2[54] = x13 >>> 16 & 255;
+ o2[55] = x13 >>> 24 & 255;
+ o2[56] = x14 >>> 0 & 255;
+ o2[57] = x14 >>> 8 & 255;
+ o2[58] = x14 >>> 16 & 255;
+ o2[59] = x14 >>> 24 & 255;
+ o2[60] = x15 >>> 0 & 255;
+ o2[61] = x15 >>> 8 & 255;
+ o2[62] = x15 >>> 16 & 255;
+ o2[63] = x15 >>> 24 & 255;
+ }
+ function core_hsalsa20(o2, p2, k2, c2) {
+ var j0 = c2[0] & 255 | (c2[1] & 255) << 8 | (c2[2] & 255) << 16 | (c2[3] & 255) << 24, j1 = k2[0] & 255 | (k2[1] & 255) << 8 | (k2[2] & 255) << 16 | (k2[3] & 255) << 24, j2 = k2[4] & 255 | (k2[5] & 255) << 8 | (k2[6] & 255) << 16 | (k2[7] & 255) << 24, j3 = k2[8] & 255 | (k2[9] & 255) << 8 | (k2[10] & 255) << 16 | (k2[11] & 255) << 24, j4 = k2[12] & 255 | (k2[13] & 255) << 8 | (k2[14] & 255) << 16 | (k2[15] & 255) << 24, j5 = c2[4] & 255 | (c2[5] & 255) << 8 | (c2[6] & 255) << 16 | (c2[7] & 255) << 24, j6 = p2[0] & 255 | (p2[1] & 255) << 8 | (p2[2] & 255) << 16 | (p2[3] & 255) << 24, j7 = p2[4] & 255 | (p2[5] & 255) << 8 | (p2[6] & 255) << 16 | (p2[7] & 255) << 24, j8 = p2[8] & 255 | (p2[9] & 255) << 8 | (p2[10] & 255) << 16 | (p2[11] & 255) << 24, j9 = p2[12] & 255 | (p2[13] & 255) << 8 | (p2[14] & 255) << 16 | (p2[15] & 255) << 24, j10 = c2[8] & 255 | (c2[9] & 255) << 8 | (c2[10] & 255) << 16 | (c2[11] & 255) << 24, j11 = k2[16] & 255 | (k2[17] & 255) << 8 | (k2[18] & 255) << 16 | (k2[19] & 255) << 24, j12 = k2[20] & 255 | (k2[21] & 255) << 8 | (k2[22] & 255) << 16 | (k2[23] & 255) << 24, j13 = k2[24] & 255 | (k2[25] & 255) << 8 | (k2[26] & 255) << 16 | (k2[27] & 255) << 24, j14 = k2[28] & 255 | (k2[29] & 255) << 8 | (k2[30] & 255) << 16 | (k2[31] & 255) << 24, j15 = c2[12] & 255 | (c2[13] & 255) << 8 | (c2[14] & 255) << 16 | (c2[15] & 255) << 24;
+ var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, x15 = j15, u2;
+ for (var i = 0; i < 20; i += 2) {
+ u2 = x0 + x12 | 0;
+ x4 ^= u2 << 7 | u2 >>> 32 - 7;
+ u2 = x4 + x0 | 0;
+ x8 ^= u2 << 9 | u2 >>> 32 - 9;
+ u2 = x8 + x4 | 0;
+ x12 ^= u2 << 13 | u2 >>> 32 - 13;
+ u2 = x12 + x8 | 0;
+ x0 ^= u2 << 18 | u2 >>> 32 - 18;
+ u2 = x5 + x1 | 0;
+ x9 ^= u2 << 7 | u2 >>> 32 - 7;
+ u2 = x9 + x5 | 0;
+ x13 ^= u2 << 9 | u2 >>> 32 - 9;
+ u2 = x13 + x9 | 0;
+ x1 ^= u2 << 13 | u2 >>> 32 - 13;
+ u2 = x1 + x13 | 0;
+ x5 ^= u2 << 18 | u2 >>> 32 - 18;
+ u2 = x10 + x6 | 0;
+ x14 ^= u2 << 7 | u2 >>> 32 - 7;
+ u2 = x14 + x10 | 0;
+ x2 ^= u2 << 9 | u2 >>> 32 - 9;
+ u2 = x2 + x14 | 0;
+ x6 ^= u2 << 13 | u2 >>> 32 - 13;
+ u2 = x6 + x2 | 0;
+ x10 ^= u2 << 18 | u2 >>> 32 - 18;
+ u2 = x15 + x11 | 0;
+ x3 ^= u2 << 7 | u2 >>> 32 - 7;
+ u2 = x3 + x15 | 0;
+ x7 ^= u2 << 9 | u2 >>> 32 - 9;
+ u2 = x7 + x3 | 0;
+ x11 ^= u2 << 13 | u2 >>> 32 - 13;
+ u2 = x11 + x7 | 0;
+ x15 ^= u2 << 18 | u2 >>> 32 - 18;
+ u2 = x0 + x3 | 0;
+ x1 ^= u2 << 7 | u2 >>> 32 - 7;
+ u2 = x1 + x0 | 0;
+ x2 ^= u2 << 9 | u2 >>> 32 - 9;
+ u2 = x2 + x1 | 0;
+ x3 ^= u2 << 13 | u2 >>> 32 - 13;
+ u2 = x3 + x2 | 0;
+ x0 ^= u2 << 18 | u2 >>> 32 - 18;
+ u2 = x5 + x4 | 0;
+ x6 ^= u2 << 7 | u2 >>> 32 - 7;
+ u2 = x6 + x5 | 0;
+ x7 ^= u2 << 9 | u2 >>> 32 - 9;
+ u2 = x7 + x6 | 0;
+ x4 ^= u2 << 13 | u2 >>> 32 - 13;
+ u2 = x4 + x7 | 0;
+ x5 ^= u2 << 18 | u2 >>> 32 - 18;
+ u2 = x10 + x9 | 0;
+ x11 ^= u2 << 7 | u2 >>> 32 - 7;
+ u2 = x11 + x10 | 0;
+ x8 ^= u2 << 9 | u2 >>> 32 - 9;
+ u2 = x8 + x11 | 0;
+ x9 ^= u2 << 13 | u2 >>> 32 - 13;
+ u2 = x9 + x8 | 0;
+ x10 ^= u2 << 18 | u2 >>> 32 - 18;
+ u2 = x15 + x14 | 0;
+ x12 ^= u2 << 7 | u2 >>> 32 - 7;
+ u2 = x12 + x15 | 0;
+ x13 ^= u2 << 9 | u2 >>> 32 - 9;
+ u2 = x13 + x12 | 0;
+ x14 ^= u2 << 13 | u2 >>> 32 - 13;
+ u2 = x14 + x13 | 0;
+ x15 ^= u2 << 18 | u2 >>> 32 - 18;
+ }
+ o2[0] = x0 >>> 0 & 255;
+ o2[1] = x0 >>> 8 & 255;
+ o2[2] = x0 >>> 16 & 255;
+ o2[3] = x0 >>> 24 & 255;
+ o2[4] = x5 >>> 0 & 255;
+ o2[5] = x5 >>> 8 & 255;
+ o2[6] = x5 >>> 16 & 255;
+ o2[7] = x5 >>> 24 & 255;
+ o2[8] = x10 >>> 0 & 255;
+ o2[9] = x10 >>> 8 & 255;
+ o2[10] = x10 >>> 16 & 255;
+ o2[11] = x10 >>> 24 & 255;
+ o2[12] = x15 >>> 0 & 255;
+ o2[13] = x15 >>> 8 & 255;
+ o2[14] = x15 >>> 16 & 255;
+ o2[15] = x15 >>> 24 & 255;
+ o2[16] = x6 >>> 0 & 255;
+ o2[17] = x6 >>> 8 & 255;
+ o2[18] = x6 >>> 16 & 255;
+ o2[19] = x6 >>> 24 & 255;
+ o2[20] = x7 >>> 0 & 255;
+ o2[21] = x7 >>> 8 & 255;
+ o2[22] = x7 >>> 16 & 255;
+ o2[23] = x7 >>> 24 & 255;
+ o2[24] = x8 >>> 0 & 255;
+ o2[25] = x8 >>> 8 & 255;
+ o2[26] = x8 >>> 16 & 255;
+ o2[27] = x8 >>> 24 & 255;
+ o2[28] = x9 >>> 0 & 255;
+ o2[29] = x9 >>> 8 & 255;
+ o2[30] = x9 >>> 16 & 255;
+ o2[31] = x9 >>> 24 & 255;
+ }
+ function crypto_core_salsa20(out, inp, k2, c2) {
+ core_salsa20(out, inp, k2, c2);
+ }
+ function crypto_core_hsalsa20(out, inp, k2, c2) {
+ core_hsalsa20(out, inp, k2, c2);
+ }
+ var sigma = new Uint8Array([101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107]);
+ function crypto_stream_salsa20_xor(c2, cpos, m2, mpos, b2, n, k2) {
+ var z = new Uint8Array(16), x = new Uint8Array(64);
+ var u2, i;
+ for (i = 0; i < 16; i++) z[i] = 0;
+ for (i = 0; i < 8; i++) z[i] = n[i];
+ while (b2 >= 64) {
+ crypto_core_salsa20(x, z, k2, sigma);
+ for (i = 0; i < 64; i++) c2[cpos + i] = m2[mpos + i] ^ x[i];
+ u2 = 1;
+ for (i = 8; i < 16; i++) {
+ u2 = u2 + (z[i] & 255) | 0;
+ z[i] = u2 & 255;
+ u2 >>>= 8;
+ }
+ b2 -= 64;
+ cpos += 64;
+ mpos += 64;
+ }
+ if (b2 > 0) {
+ crypto_core_salsa20(x, z, k2, sigma);
+ for (i = 0; i < b2; i++) c2[cpos + i] = m2[mpos + i] ^ x[i];
+ }
+ return 0;
+ }
+ function crypto_stream_salsa20(c2, cpos, b2, n, k2) {
+ var z = new Uint8Array(16), x = new Uint8Array(64);
+ var u2, i;
+ for (i = 0; i < 16; i++) z[i] = 0;
+ for (i = 0; i < 8; i++) z[i] = n[i];
+ while (b2 >= 64) {
+ crypto_core_salsa20(x, z, k2, sigma);
+ for (i = 0; i < 64; i++) c2[cpos + i] = x[i];
+ u2 = 1;
+ for (i = 8; i < 16; i++) {
+ u2 = u2 + (z[i] & 255) | 0;
+ z[i] = u2 & 255;
+ u2 >>>= 8;
+ }
+ b2 -= 64;
+ cpos += 64;
+ }
+ if (b2 > 0) {
+ crypto_core_salsa20(x, z, k2, sigma);
+ for (i = 0; i < b2; i++) c2[cpos + i] = x[i];
+ }
+ return 0;
+ }
+ function crypto_stream(c2, cpos, d2, n, k2) {
+ var s = new Uint8Array(32);
+ crypto_core_hsalsa20(s, n, k2, sigma);
+ var sn = new Uint8Array(8);
+ for (var i = 0; i < 8; i++) sn[i] = n[i + 16];
+ return crypto_stream_salsa20(c2, cpos, d2, sn, s);
+ }
+ function crypto_stream_xor(c2, cpos, m2, mpos, d2, n, k2) {
+ var s = new Uint8Array(32);
+ crypto_core_hsalsa20(s, n, k2, sigma);
+ var sn = new Uint8Array(8);
+ for (var i = 0; i < 8; i++) sn[i] = n[i + 16];
+ return crypto_stream_salsa20_xor(c2, cpos, m2, mpos, d2, sn, s);
+ }
+ var poly1305 = function(key) {
+ this.buffer = new Uint8Array(16);
+ this.r = new Uint16Array(10);
+ this.h = new Uint16Array(10);
+ this.pad = new Uint16Array(8);
+ this.leftover = 0;
+ this.fin = 0;
+ var t0, t1, t2, t3, t4, t5, t6, t7;
+ t0 = key[0] & 255 | (key[1] & 255) << 8;
+ this.r[0] = t0 & 8191;
+ t1 = key[2] & 255 | (key[3] & 255) << 8;
+ this.r[1] = (t0 >>> 13 | t1 << 3) & 8191;
+ t2 = key[4] & 255 | (key[5] & 255) << 8;
+ this.r[2] = (t1 >>> 10 | t2 << 6) & 7939;
+ t3 = key[6] & 255 | (key[7] & 255) << 8;
+ this.r[3] = (t2 >>> 7 | t3 << 9) & 8191;
+ t4 = key[8] & 255 | (key[9] & 255) << 8;
+ this.r[4] = (t3 >>> 4 | t4 << 12) & 255;
+ this.r[5] = t4 >>> 1 & 8190;
+ t5 = key[10] & 255 | (key[11] & 255) << 8;
+ this.r[6] = (t4 >>> 14 | t5 << 2) & 8191;
+ t6 = key[12] & 255 | (key[13] & 255) << 8;
+ this.r[7] = (t5 >>> 11 | t6 << 5) & 8065;
+ t7 = key[14] & 255 | (key[15] & 255) << 8;
+ this.r[8] = (t6 >>> 8 | t7 << 8) & 8191;
+ this.r[9] = t7 >>> 5 & 127;
+ this.pad[0] = key[16] & 255 | (key[17] & 255) << 8;
+ this.pad[1] = key[18] & 255 | (key[19] & 255) << 8;
+ this.pad[2] = key[20] & 255 | (key[21] & 255) << 8;
+ this.pad[3] = key[22] & 255 | (key[23] & 255) << 8;
+ this.pad[4] = key[24] & 255 | (key[25] & 255) << 8;
+ this.pad[5] = key[26] & 255 | (key[27] & 255) << 8;
+ this.pad[6] = key[28] & 255 | (key[29] & 255) << 8;
+ this.pad[7] = key[30] & 255 | (key[31] & 255) << 8;
+ };
+ poly1305.prototype.blocks = function(m2, mpos, bytes) {
+ var hibit = this.fin ? 0 : 1 << 11;
+ var t0, t1, t2, t3, t4, t5, t6, t7, c2;
+ var d0, d1, d2, d3, d4, d5, d6, d7, d8, d9;
+ var h0 = this.h[0], h1 = this.h[1], h22 = this.h[2], h3 = this.h[3], h4 = this.h[4], h5 = this.h[5], h6 = this.h[6], h7 = this.h[7], h8 = this.h[8], h9 = this.h[9];
+ var r0 = this.r[0], r1 = this.r[1], r2 = this.r[2], r3 = this.r[3], r4 = this.r[4], r5 = this.r[5], r6 = this.r[6], r7 = this.r[7], r8 = this.r[8], r9 = this.r[9];
+ while (bytes >= 16) {
+ t0 = m2[mpos + 0] & 255 | (m2[mpos + 1] & 255) << 8;
+ h0 += t0 & 8191;
+ t1 = m2[mpos + 2] & 255 | (m2[mpos + 3] & 255) << 8;
+ h1 += (t0 >>> 13 | t1 << 3) & 8191;
+ t2 = m2[mpos + 4] & 255 | (m2[mpos + 5] & 255) << 8;
+ h22 += (t1 >>> 10 | t2 << 6) & 8191;
+ t3 = m2[mpos + 6] & 255 | (m2[mpos + 7] & 255) << 8;
+ h3 += (t2 >>> 7 | t3 << 9) & 8191;
+ t4 = m2[mpos + 8] & 255 | (m2[mpos + 9] & 255) << 8;
+ h4 += (t3 >>> 4 | t4 << 12) & 8191;
+ h5 += t4 >>> 1 & 8191;
+ t5 = m2[mpos + 10] & 255 | (m2[mpos + 11] & 255) << 8;
+ h6 += (t4 >>> 14 | t5 << 2) & 8191;
+ t6 = m2[mpos + 12] & 255 | (m2[mpos + 13] & 255) << 8;
+ h7 += (t5 >>> 11 | t6 << 5) & 8191;
+ t7 = m2[mpos + 14] & 255 | (m2[mpos + 15] & 255) << 8;
+ h8 += (t6 >>> 8 | t7 << 8) & 8191;
+ h9 += t7 >>> 5 | hibit;
+ c2 = 0;
+ d0 = c2;
+ d0 += h0 * r0;
+ d0 += h1 * (5 * r9);
+ d0 += h22 * (5 * r8);
+ d0 += h3 * (5 * r7);
+ d0 += h4 * (5 * r6);
+ c2 = d0 >>> 13;
+ d0 &= 8191;
+ d0 += h5 * (5 * r5);
+ d0 += h6 * (5 * r4);
+ d0 += h7 * (5 * r3);
+ d0 += h8 * (5 * r2);
+ d0 += h9 * (5 * r1);
+ c2 += d0 >>> 13;
+ d0 &= 8191;
+ d1 = c2;
+ d1 += h0 * r1;
+ d1 += h1 * r0;
+ d1 += h22 * (5 * r9);
+ d1 += h3 * (5 * r8);
+ d1 += h4 * (5 * r7);
+ c2 = d1 >>> 13;
+ d1 &= 8191;
+ d1 += h5 * (5 * r6);
+ d1 += h6 * (5 * r5);
+ d1 += h7 * (5 * r4);
+ d1 += h8 * (5 * r3);
+ d1 += h9 * (5 * r2);
+ c2 += d1 >>> 13;
+ d1 &= 8191;
+ d2 = c2;
+ d2 += h0 * r2;
+ d2 += h1 * r1;
+ d2 += h22 * r0;
+ d2 += h3 * (5 * r9);
+ d2 += h4 * (5 * r8);
+ c2 = d2 >>> 13;
+ d2 &= 8191;
+ d2 += h5 * (5 * r7);
+ d2 += h6 * (5 * r6);
+ d2 += h7 * (5 * r5);
+ d2 += h8 * (5 * r4);
+ d2 += h9 * (5 * r3);
+ c2 += d2 >>> 13;
+ d2 &= 8191;
+ d3 = c2;
+ d3 += h0 * r3;
+ d3 += h1 * r2;
+ d3 += h22 * r1;
+ d3 += h3 * r0;
+ d3 += h4 * (5 * r9);
+ c2 = d3 >>> 13;
+ d3 &= 8191;
+ d3 += h5 * (5 * r8);
+ d3 += h6 * (5 * r7);
+ d3 += h7 * (5 * r6);
+ d3 += h8 * (5 * r5);
+ d3 += h9 * (5 * r4);
+ c2 += d3 >>> 13;
+ d3 &= 8191;
+ d4 = c2;
+ d4 += h0 * r4;
+ d4 += h1 * r3;
+ d4 += h22 * r2;
+ d4 += h3 * r1;
+ d4 += h4 * r0;
+ c2 = d4 >>> 13;
+ d4 &= 8191;
+ d4 += h5 * (5 * r9);
+ d4 += h6 * (5 * r8);
+ d4 += h7 * (5 * r7);
+ d4 += h8 * (5 * r6);
+ d4 += h9 * (5 * r5);
+ c2 += d4 >>> 13;
+ d4 &= 8191;
+ d5 = c2;
+ d5 += h0 * r5;
+ d5 += h1 * r4;
+ d5 += h22 * r3;
+ d5 += h3 * r2;
+ d5 += h4 * r1;
+ c2 = d5 >>> 13;
+ d5 &= 8191;
+ d5 += h5 * r0;
+ d5 += h6 * (5 * r9);
+ d5 += h7 * (5 * r8);
+ d5 += h8 * (5 * r7);
+ d5 += h9 * (5 * r6);
+ c2 += d5 >>> 13;
+ d5 &= 8191;
+ d6 = c2;
+ d6 += h0 * r6;
+ d6 += h1 * r5;
+ d6 += h22 * r4;
+ d6 += h3 * r3;
+ d6 += h4 * r2;
+ c2 = d6 >>> 13;
+ d6 &= 8191;
+ d6 += h5 * r1;
+ d6 += h6 * r0;
+ d6 += h7 * (5 * r9);
+ d6 += h8 * (5 * r8);
+ d6 += h9 * (5 * r7);
+ c2 += d6 >>> 13;
+ d6 &= 8191;
+ d7 = c2;
+ d7 += h0 * r7;
+ d7 += h1 * r6;
+ d7 += h22 * r5;
+ d7 += h3 * r4;
+ d7 += h4 * r3;
+ c2 = d7 >>> 13;
+ d7 &= 8191;
+ d7 += h5 * r2;
+ d7 += h6 * r1;
+ d7 += h7 * r0;
+ d7 += h8 * (5 * r9);
+ d7 += h9 * (5 * r8);
+ c2 += d7 >>> 13;
+ d7 &= 8191;
+ d8 = c2;
+ d8 += h0 * r8;
+ d8 += h1 * r7;
+ d8 += h22 * r6;
+ d8 += h3 * r5;
+ d8 += h4 * r4;
+ c2 = d8 >>> 13;
+ d8 &= 8191;
+ d8 += h5 * r3;
+ d8 += h6 * r2;
+ d8 += h7 * r1;
+ d8 += h8 * r0;
+ d8 += h9 * (5 * r9);
+ c2 += d8 >>> 13;
+ d8 &= 8191;
+ d9 = c2;
+ d9 += h0 * r9;
+ d9 += h1 * r8;
+ d9 += h22 * r7;
+ d9 += h3 * r6;
+ d9 += h4 * r5;
+ c2 = d9 >>> 13;
+ d9 &= 8191;
+ d9 += h5 * r4;
+ d9 += h6 * r3;
+ d9 += h7 * r2;
+ d9 += h8 * r1;
+ d9 += h9 * r0;
+ c2 += d9 >>> 13;
+ d9 &= 8191;
+ c2 = (c2 << 2) + c2 | 0;
+ c2 = c2 + d0 | 0;
+ d0 = c2 & 8191;
+ c2 = c2 >>> 13;
+ d1 += c2;
+ h0 = d0;
+ h1 = d1;
+ h22 = d2;
+ h3 = d3;
+ h4 = d4;
+ h5 = d5;
+ h6 = d6;
+ h7 = d7;
+ h8 = d8;
+ h9 = d9;
+ mpos += 16;
+ bytes -= 16;
+ }
+ this.h[0] = h0;
+ this.h[1] = h1;
+ this.h[2] = h22;
+ this.h[3] = h3;
+ this.h[4] = h4;
+ this.h[5] = h5;
+ this.h[6] = h6;
+ this.h[7] = h7;
+ this.h[8] = h8;
+ this.h[9] = h9;
+ };
+ poly1305.prototype.finish = function(mac, macpos) {
+ var g2 = new Uint16Array(10);
+ var c2, mask, f2, i;
+ if (this.leftover) {
+ i = this.leftover;
+ this.buffer[i++] = 1;
+ for (; i < 16; i++) this.buffer[i] = 0;
+ this.fin = 1;
+ this.blocks(this.buffer, 0, 16);
+ }
+ c2 = this.h[1] >>> 13;
+ this.h[1] &= 8191;
+ for (i = 2; i < 10; i++) {
+ this.h[i] += c2;
+ c2 = this.h[i] >>> 13;
+ this.h[i] &= 8191;
+ }
+ this.h[0] += c2 * 5;
+ c2 = this.h[0] >>> 13;
+ this.h[0] &= 8191;
+ this.h[1] += c2;
+ c2 = this.h[1] >>> 13;
+ this.h[1] &= 8191;
+ this.h[2] += c2;
+ g2[0] = this.h[0] + 5;
+ c2 = g2[0] >>> 13;
+ g2[0] &= 8191;
+ for (i = 1; i < 10; i++) {
+ g2[i] = this.h[i] + c2;
+ c2 = g2[i] >>> 13;
+ g2[i] &= 8191;
+ }
+ g2[9] -= 1 << 13;
+ mask = (c2 ^ 1) - 1;
+ for (i = 0; i < 10; i++) g2[i] &= mask;
+ mask = ~mask;
+ for (i = 0; i < 10; i++) this.h[i] = this.h[i] & mask | g2[i];
+ this.h[0] = (this.h[0] | this.h[1] << 13) & 65535;
+ this.h[1] = (this.h[1] >>> 3 | this.h[2] << 10) & 65535;
+ this.h[2] = (this.h[2] >>> 6 | this.h[3] << 7) & 65535;
+ this.h[3] = (this.h[3] >>> 9 | this.h[4] << 4) & 65535;
+ this.h[4] = (this.h[4] >>> 12 | this.h[5] << 1 | this.h[6] << 14) & 65535;
+ this.h[5] = (this.h[6] >>> 2 | this.h[7] << 11) & 65535;
+ this.h[6] = (this.h[7] >>> 5 | this.h[8] << 8) & 65535;
+ this.h[7] = (this.h[8] >>> 8 | this.h[9] << 5) & 65535;
+ f2 = this.h[0] + this.pad[0];
+ this.h[0] = f2 & 65535;
+ for (i = 1; i < 8; i++) {
+ f2 = (this.h[i] + this.pad[i] | 0) + (f2 >>> 16) | 0;
+ this.h[i] = f2 & 65535;
+ }
+ mac[macpos + 0] = this.h[0] >>> 0 & 255;
+ mac[macpos + 1] = this.h[0] >>> 8 & 255;
+ mac[macpos + 2] = this.h[1] >>> 0 & 255;
+ mac[macpos + 3] = this.h[1] >>> 8 & 255;
+ mac[macpos + 4] = this.h[2] >>> 0 & 255;
+ mac[macpos + 5] = this.h[2] >>> 8 & 255;
+ mac[macpos + 6] = this.h[3] >>> 0 & 255;
+ mac[macpos + 7] = this.h[3] >>> 8 & 255;
+ mac[macpos + 8] = this.h[4] >>> 0 & 255;
+ mac[macpos + 9] = this.h[4] >>> 8 & 255;
+ mac[macpos + 10] = this.h[5] >>> 0 & 255;
+ mac[macpos + 11] = this.h[5] >>> 8 & 255;
+ mac[macpos + 12] = this.h[6] >>> 0 & 255;
+ mac[macpos + 13] = this.h[6] >>> 8 & 255;
+ mac[macpos + 14] = this.h[7] >>> 0 & 255;
+ mac[macpos + 15] = this.h[7] >>> 8 & 255;
+ };
+ poly1305.prototype.update = function(m2, mpos, bytes) {
+ var i, want;
+ if (this.leftover) {
+ want = 16 - this.leftover;
+ if (want > bytes)
+ want = bytes;
+ for (i = 0; i < want; i++)
+ this.buffer[this.leftover + i] = m2[mpos + i];
+ bytes -= want;
+ mpos += want;
+ this.leftover += want;
+ if (this.leftover < 16)
+ return;
+ this.blocks(this.buffer, 0, 16);
+ this.leftover = 0;
+ }
+ if (bytes >= 16) {
+ want = bytes - bytes % 16;
+ this.blocks(m2, mpos, want);
+ mpos += want;
+ bytes -= want;
+ }
+ if (bytes) {
+ for (i = 0; i < bytes; i++)
+ this.buffer[this.leftover + i] = m2[mpos + i];
+ this.leftover += bytes;
+ }
+ };
+ function crypto_onetimeauth(out, outpos, m2, mpos, n, k2) {
+ var s = new poly1305(k2);
+ s.update(m2, mpos, n);
+ s.finish(out, outpos);
+ return 0;
+ }
+ function crypto_onetimeauth_verify(h3, hpos, m2, mpos, n, k2) {
+ var x = new Uint8Array(16);
+ crypto_onetimeauth(x, 0, m2, mpos, n, k2);
+ return crypto_verify_16(h3, hpos, x, 0);
+ }
+ function crypto_secretbox(c2, m2, d2, n, k2) {
+ var i;
+ if (d2 < 32) return -1;
+ crypto_stream_xor(c2, 0, m2, 0, d2, n, k2);
+ crypto_onetimeauth(c2, 16, c2, 32, d2 - 32, c2);
+ for (i = 0; i < 16; i++) c2[i] = 0;
+ return 0;
+ }
+ function crypto_secretbox_open(m2, c2, d2, n, k2) {
+ var i;
+ var x = new Uint8Array(32);
+ if (d2 < 32) return -1;
+ crypto_stream(x, 0, 32, n, k2);
+ if (crypto_onetimeauth_verify(c2, 16, c2, 32, d2 - 32, x) !== 0) return -1;
+ crypto_stream_xor(m2, 0, c2, 0, d2, n, k2);
+ for (i = 0; i < 32; i++) m2[i] = 0;
+ return 0;
+ }
+ function set25519(r2, a) {
+ var i;
+ for (i = 0; i < 16; i++) r2[i] = a[i] | 0;
+ }
+ function car25519(o2) {
+ var i, v2, c2 = 1;
+ for (i = 0; i < 16; i++) {
+ v2 = o2[i] + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ o2[i] = v2 - c2 * 65536;
+ }
+ o2[0] += c2 - 1 + 37 * (c2 - 1);
+ }
+ function sel25519(p2, q, b2) {
+ var t, c2 = ~(b2 - 1);
+ for (var i = 0; i < 16; i++) {
+ t = c2 & (p2[i] ^ q[i]);
+ p2[i] ^= t;
+ q[i] ^= t;
+ }
+ }
+ function pack25519(o2, n) {
+ var i, j, b2;
+ var m2 = gf(), t = gf();
+ for (i = 0; i < 16; i++) t[i] = n[i];
+ car25519(t);
+ car25519(t);
+ car25519(t);
+ for (j = 0; j < 2; j++) {
+ m2[0] = t[0] - 65517;
+ for (i = 1; i < 15; i++) {
+ m2[i] = t[i] - 65535 - (m2[i - 1] >> 16 & 1);
+ m2[i - 1] &= 65535;
+ }
+ m2[15] = t[15] - 32767 - (m2[14] >> 16 & 1);
+ b2 = m2[15] >> 16 & 1;
+ m2[14] &= 65535;
+ sel25519(t, m2, 1 - b2);
+ }
+ for (i = 0; i < 16; i++) {
+ o2[2 * i] = t[i] & 255;
+ o2[2 * i + 1] = t[i] >> 8;
+ }
+ }
+ function neq25519(a, b2) {
+ var c2 = new Uint8Array(32), d2 = new Uint8Array(32);
+ pack25519(c2, a);
+ pack25519(d2, b2);
+ return crypto_verify_32(c2, 0, d2, 0);
+ }
+ function par25519(a) {
+ var d2 = new Uint8Array(32);
+ pack25519(d2, a);
+ return d2[0] & 1;
+ }
+ function unpack25519(o2, n) {
+ var i;
+ for (i = 0; i < 16; i++) o2[i] = n[2 * i] + (n[2 * i + 1] << 8);
+ o2[15] &= 32767;
+ }
+ function A(o2, a, b2) {
+ for (var i = 0; i < 16; i++) o2[i] = a[i] + b2[i];
+ }
+ function Z(o2, a, b2) {
+ for (var i = 0; i < 16; i++) o2[i] = a[i] - b2[i];
+ }
+ function M(o2, a, b2) {
+ var v2, c2, t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0, t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0, t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0, t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0, b0 = b2[0], b1 = b2[1], b22 = b2[2], b3 = b2[3], b4 = b2[4], b5 = b2[5], b6 = b2[6], b7 = b2[7], b8 = b2[8], b9 = b2[9], b10 = b2[10], b11 = b2[11], b12 = b2[12], b13 = b2[13], b14 = b2[14], b15 = b2[15];
+ v2 = a[0];
+ t0 += v2 * b0;
+ t1 += v2 * b1;
+ t2 += v2 * b22;
+ t3 += v2 * b3;
+ t4 += v2 * b4;
+ t5 += v2 * b5;
+ t6 += v2 * b6;
+ t7 += v2 * b7;
+ t8 += v2 * b8;
+ t9 += v2 * b9;
+ t10 += v2 * b10;
+ t11 += v2 * b11;
+ t12 += v2 * b12;
+ t13 += v2 * b13;
+ t14 += v2 * b14;
+ t15 += v2 * b15;
+ v2 = a[1];
+ t1 += v2 * b0;
+ t2 += v2 * b1;
+ t3 += v2 * b22;
+ t4 += v2 * b3;
+ t5 += v2 * b4;
+ t6 += v2 * b5;
+ t7 += v2 * b6;
+ t8 += v2 * b7;
+ t9 += v2 * b8;
+ t10 += v2 * b9;
+ t11 += v2 * b10;
+ t12 += v2 * b11;
+ t13 += v2 * b12;
+ t14 += v2 * b13;
+ t15 += v2 * b14;
+ t16 += v2 * b15;
+ v2 = a[2];
+ t2 += v2 * b0;
+ t3 += v2 * b1;
+ t4 += v2 * b22;
+ t5 += v2 * b3;
+ t6 += v2 * b4;
+ t7 += v2 * b5;
+ t8 += v2 * b6;
+ t9 += v2 * b7;
+ t10 += v2 * b8;
+ t11 += v2 * b9;
+ t12 += v2 * b10;
+ t13 += v2 * b11;
+ t14 += v2 * b12;
+ t15 += v2 * b13;
+ t16 += v2 * b14;
+ t17 += v2 * b15;
+ v2 = a[3];
+ t3 += v2 * b0;
+ t4 += v2 * b1;
+ t5 += v2 * b22;
+ t6 += v2 * b3;
+ t7 += v2 * b4;
+ t8 += v2 * b5;
+ t9 += v2 * b6;
+ t10 += v2 * b7;
+ t11 += v2 * b8;
+ t12 += v2 * b9;
+ t13 += v2 * b10;
+ t14 += v2 * b11;
+ t15 += v2 * b12;
+ t16 += v2 * b13;
+ t17 += v2 * b14;
+ t18 += v2 * b15;
+ v2 = a[4];
+ t4 += v2 * b0;
+ t5 += v2 * b1;
+ t6 += v2 * b22;
+ t7 += v2 * b3;
+ t8 += v2 * b4;
+ t9 += v2 * b5;
+ t10 += v2 * b6;
+ t11 += v2 * b7;
+ t12 += v2 * b8;
+ t13 += v2 * b9;
+ t14 += v2 * b10;
+ t15 += v2 * b11;
+ t16 += v2 * b12;
+ t17 += v2 * b13;
+ t18 += v2 * b14;
+ t19 += v2 * b15;
+ v2 = a[5];
+ t5 += v2 * b0;
+ t6 += v2 * b1;
+ t7 += v2 * b22;
+ t8 += v2 * b3;
+ t9 += v2 * b4;
+ t10 += v2 * b5;
+ t11 += v2 * b6;
+ t12 += v2 * b7;
+ t13 += v2 * b8;
+ t14 += v2 * b9;
+ t15 += v2 * b10;
+ t16 += v2 * b11;
+ t17 += v2 * b12;
+ t18 += v2 * b13;
+ t19 += v2 * b14;
+ t20 += v2 * b15;
+ v2 = a[6];
+ t6 += v2 * b0;
+ t7 += v2 * b1;
+ t8 += v2 * b22;
+ t9 += v2 * b3;
+ t10 += v2 * b4;
+ t11 += v2 * b5;
+ t12 += v2 * b6;
+ t13 += v2 * b7;
+ t14 += v2 * b8;
+ t15 += v2 * b9;
+ t16 += v2 * b10;
+ t17 += v2 * b11;
+ t18 += v2 * b12;
+ t19 += v2 * b13;
+ t20 += v2 * b14;
+ t21 += v2 * b15;
+ v2 = a[7];
+ t7 += v2 * b0;
+ t8 += v2 * b1;
+ t9 += v2 * b22;
+ t10 += v2 * b3;
+ t11 += v2 * b4;
+ t12 += v2 * b5;
+ t13 += v2 * b6;
+ t14 += v2 * b7;
+ t15 += v2 * b8;
+ t16 += v2 * b9;
+ t17 += v2 * b10;
+ t18 += v2 * b11;
+ t19 += v2 * b12;
+ t20 += v2 * b13;
+ t21 += v2 * b14;
+ t22 += v2 * b15;
+ v2 = a[8];
+ t8 += v2 * b0;
+ t9 += v2 * b1;
+ t10 += v2 * b22;
+ t11 += v2 * b3;
+ t12 += v2 * b4;
+ t13 += v2 * b5;
+ t14 += v2 * b6;
+ t15 += v2 * b7;
+ t16 += v2 * b8;
+ t17 += v2 * b9;
+ t18 += v2 * b10;
+ t19 += v2 * b11;
+ t20 += v2 * b12;
+ t21 += v2 * b13;
+ t22 += v2 * b14;
+ t23 += v2 * b15;
+ v2 = a[9];
+ t9 += v2 * b0;
+ t10 += v2 * b1;
+ t11 += v2 * b22;
+ t12 += v2 * b3;
+ t13 += v2 * b4;
+ t14 += v2 * b5;
+ t15 += v2 * b6;
+ t16 += v2 * b7;
+ t17 += v2 * b8;
+ t18 += v2 * b9;
+ t19 += v2 * b10;
+ t20 += v2 * b11;
+ t21 += v2 * b12;
+ t22 += v2 * b13;
+ t23 += v2 * b14;
+ t24 += v2 * b15;
+ v2 = a[10];
+ t10 += v2 * b0;
+ t11 += v2 * b1;
+ t12 += v2 * b22;
+ t13 += v2 * b3;
+ t14 += v2 * b4;
+ t15 += v2 * b5;
+ t16 += v2 * b6;
+ t17 += v2 * b7;
+ t18 += v2 * b8;
+ t19 += v2 * b9;
+ t20 += v2 * b10;
+ t21 += v2 * b11;
+ t22 += v2 * b12;
+ t23 += v2 * b13;
+ t24 += v2 * b14;
+ t25 += v2 * b15;
+ v2 = a[11];
+ t11 += v2 * b0;
+ t12 += v2 * b1;
+ t13 += v2 * b22;
+ t14 += v2 * b3;
+ t15 += v2 * b4;
+ t16 += v2 * b5;
+ t17 += v2 * b6;
+ t18 += v2 * b7;
+ t19 += v2 * b8;
+ t20 += v2 * b9;
+ t21 += v2 * b10;
+ t22 += v2 * b11;
+ t23 += v2 * b12;
+ t24 += v2 * b13;
+ t25 += v2 * b14;
+ t26 += v2 * b15;
+ v2 = a[12];
+ t12 += v2 * b0;
+ t13 += v2 * b1;
+ t14 += v2 * b22;
+ t15 += v2 * b3;
+ t16 += v2 * b4;
+ t17 += v2 * b5;
+ t18 += v2 * b6;
+ t19 += v2 * b7;
+ t20 += v2 * b8;
+ t21 += v2 * b9;
+ t22 += v2 * b10;
+ t23 += v2 * b11;
+ t24 += v2 * b12;
+ t25 += v2 * b13;
+ t26 += v2 * b14;
+ t27 += v2 * b15;
+ v2 = a[13];
+ t13 += v2 * b0;
+ t14 += v2 * b1;
+ t15 += v2 * b22;
+ t16 += v2 * b3;
+ t17 += v2 * b4;
+ t18 += v2 * b5;
+ t19 += v2 * b6;
+ t20 += v2 * b7;
+ t21 += v2 * b8;
+ t22 += v2 * b9;
+ t23 += v2 * b10;
+ t24 += v2 * b11;
+ t25 += v2 * b12;
+ t26 += v2 * b13;
+ t27 += v2 * b14;
+ t28 += v2 * b15;
+ v2 = a[14];
+ t14 += v2 * b0;
+ t15 += v2 * b1;
+ t16 += v2 * b22;
+ t17 += v2 * b3;
+ t18 += v2 * b4;
+ t19 += v2 * b5;
+ t20 += v2 * b6;
+ t21 += v2 * b7;
+ t22 += v2 * b8;
+ t23 += v2 * b9;
+ t24 += v2 * b10;
+ t25 += v2 * b11;
+ t26 += v2 * b12;
+ t27 += v2 * b13;
+ t28 += v2 * b14;
+ t29 += v2 * b15;
+ v2 = a[15];
+ t15 += v2 * b0;
+ t16 += v2 * b1;
+ t17 += v2 * b22;
+ t18 += v2 * b3;
+ t19 += v2 * b4;
+ t20 += v2 * b5;
+ t21 += v2 * b6;
+ t22 += v2 * b7;
+ t23 += v2 * b8;
+ t24 += v2 * b9;
+ t25 += v2 * b10;
+ t26 += v2 * b11;
+ t27 += v2 * b12;
+ t28 += v2 * b13;
+ t29 += v2 * b14;
+ t30 += v2 * b15;
+ t0 += 38 * t16;
+ t1 += 38 * t17;
+ t2 += 38 * t18;
+ t3 += 38 * t19;
+ t4 += 38 * t20;
+ t5 += 38 * t21;
+ t6 += 38 * t22;
+ t7 += 38 * t23;
+ t8 += 38 * t24;
+ t9 += 38 * t25;
+ t10 += 38 * t26;
+ t11 += 38 * t27;
+ t12 += 38 * t28;
+ t13 += 38 * t29;
+ t14 += 38 * t30;
+ c2 = 1;
+ v2 = t0 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t0 = v2 - c2 * 65536;
+ v2 = t1 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t1 = v2 - c2 * 65536;
+ v2 = t2 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t2 = v2 - c2 * 65536;
+ v2 = t3 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t3 = v2 - c2 * 65536;
+ v2 = t4 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t4 = v2 - c2 * 65536;
+ v2 = t5 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t5 = v2 - c2 * 65536;
+ v2 = t6 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t6 = v2 - c2 * 65536;
+ v2 = t7 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t7 = v2 - c2 * 65536;
+ v2 = t8 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t8 = v2 - c2 * 65536;
+ v2 = t9 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t9 = v2 - c2 * 65536;
+ v2 = t10 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t10 = v2 - c2 * 65536;
+ v2 = t11 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t11 = v2 - c2 * 65536;
+ v2 = t12 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t12 = v2 - c2 * 65536;
+ v2 = t13 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t13 = v2 - c2 * 65536;
+ v2 = t14 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t14 = v2 - c2 * 65536;
+ v2 = t15 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t15 = v2 - c2 * 65536;
+ t0 += c2 - 1 + 37 * (c2 - 1);
+ c2 = 1;
+ v2 = t0 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t0 = v2 - c2 * 65536;
+ v2 = t1 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t1 = v2 - c2 * 65536;
+ v2 = t2 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t2 = v2 - c2 * 65536;
+ v2 = t3 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t3 = v2 - c2 * 65536;
+ v2 = t4 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t4 = v2 - c2 * 65536;
+ v2 = t5 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t5 = v2 - c2 * 65536;
+ v2 = t6 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t6 = v2 - c2 * 65536;
+ v2 = t7 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t7 = v2 - c2 * 65536;
+ v2 = t8 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t8 = v2 - c2 * 65536;
+ v2 = t9 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t9 = v2 - c2 * 65536;
+ v2 = t10 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t10 = v2 - c2 * 65536;
+ v2 = t11 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t11 = v2 - c2 * 65536;
+ v2 = t12 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t12 = v2 - c2 * 65536;
+ v2 = t13 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t13 = v2 - c2 * 65536;
+ v2 = t14 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t14 = v2 - c2 * 65536;
+ v2 = t15 + c2 + 65535;
+ c2 = Math.floor(v2 / 65536);
+ t15 = v2 - c2 * 65536;
+ t0 += c2 - 1 + 37 * (c2 - 1);
+ o2[0] = t0;
+ o2[1] = t1;
+ o2[2] = t2;
+ o2[3] = t3;
+ o2[4] = t4;
+ o2[5] = t5;
+ o2[6] = t6;
+ o2[7] = t7;
+ o2[8] = t8;
+ o2[9] = t9;
+ o2[10] = t10;
+ o2[11] = t11;
+ o2[12] = t12;
+ o2[13] = t13;
+ o2[14] = t14;
+ o2[15] = t15;
+ }
+ function S2(o2, a) {
+ M(o2, a, a);
+ }
+ function inv25519(o2, i) {
+ var c2 = gf();
+ var a;
+ for (a = 0; a < 16; a++) c2[a] = i[a];
+ for (a = 253; a >= 0; a--) {
+ S2(c2, c2);
+ if (a !== 2 && a !== 4) M(c2, c2, i);
+ }
+ for (a = 0; a < 16; a++) o2[a] = c2[a];
+ }
+ function pow2523(o2, i) {
+ var c2 = gf();
+ var a;
+ for (a = 0; a < 16; a++) c2[a] = i[a];
+ for (a = 250; a >= 0; a--) {
+ S2(c2, c2);
+ if (a !== 1) M(c2, c2, i);
+ }
+ for (a = 0; a < 16; a++) o2[a] = c2[a];
+ }
+ function crypto_scalarmult(q, n, p2) {
+ var z = new Uint8Array(32);
+ var x = new Float64Array(80), r2, i;
+ var a = gf(), b2 = gf(), c2 = gf(), d2 = gf(), e = gf(), f2 = gf();
+ for (i = 0; i < 31; i++) z[i] = n[i];
+ z[31] = n[31] & 127 | 64;
+ z[0] &= 248;
+ unpack25519(x, p2);
+ for (i = 0; i < 16; i++) {
+ b2[i] = x[i];
+ d2[i] = a[i] = c2[i] = 0;
+ }
+ a[0] = d2[0] = 1;
+ for (i = 254; i >= 0; --i) {
+ r2 = z[i >>> 3] >>> (i & 7) & 1;
+ sel25519(a, b2, r2);
+ sel25519(c2, d2, r2);
+ A(e, a, c2);
+ Z(a, a, c2);
+ A(c2, b2, d2);
+ Z(b2, b2, d2);
+ S2(d2, e);
+ S2(f2, a);
+ M(a, c2, a);
+ M(c2, b2, e);
+ A(e, a, c2);
+ Z(a, a, c2);
+ S2(b2, a);
+ Z(c2, d2, f2);
+ M(a, c2, _121665);
+ A(a, a, d2);
+ M(c2, c2, a);
+ M(a, d2, f2);
+ M(d2, b2, x);
+ S2(b2, e);
+ sel25519(a, b2, r2);
+ sel25519(c2, d2, r2);
+ }
+ for (i = 0; i < 16; i++) {
+ x[i + 16] = a[i];
+ x[i + 32] = c2[i];
+ x[i + 48] = b2[i];
+ x[i + 64] = d2[i];
+ }
+ var x32 = x.subarray(32);
+ var x16 = x.subarray(16);
+ inv25519(x32, x32);
+ M(x16, x16, x32);
+ pack25519(q, x16);
+ return 0;
+ }
+ function crypto_scalarmult_base(q, n) {
+ return crypto_scalarmult(q, n, _9);
+ }
+ function crypto_box_keypair(y2, x) {
+ randombytes(x, 32);
+ return crypto_scalarmult_base(y2, x);
+ }
+ function crypto_box_beforenm(k2, y2, x) {
+ var s = new Uint8Array(32);
+ crypto_scalarmult(s, x, y2);
+ return crypto_core_hsalsa20(k2, _0, s, sigma);
+ }
+ var crypto_box_afternm = crypto_secretbox;
+ var crypto_box_open_afternm = crypto_secretbox_open;
+ function crypto_box(c2, m2, d2, n, y2, x) {
+ var k2 = new Uint8Array(32);
+ crypto_box_beforenm(k2, y2, x);
+ return crypto_box_afternm(c2, m2, d2, n, k2);
+ }
+ function crypto_box_open(m2, c2, d2, n, y2, x) {
+ var k2 = new Uint8Array(32);
+ crypto_box_beforenm(k2, y2, x);
+ return crypto_box_open_afternm(m2, c2, d2, n, k2);
+ }
+ var K = [
+ 1116352408,
+ 3609767458,
+ 1899447441,
+ 602891725,
+ 3049323471,
+ 3964484399,
+ 3921009573,
+ 2173295548,
+ 961987163,
+ 4081628472,
+ 1508970993,
+ 3053834265,
+ 2453635748,
+ 2937671579,
+ 2870763221,
+ 3664609560,
+ 3624381080,
+ 2734883394,
+ 310598401,
+ 1164996542,
+ 607225278,
+ 1323610764,
+ 1426881987,
+ 3590304994,
+ 1925078388,
+ 4068182383,
+ 2162078206,
+ 991336113,
+ 2614888103,
+ 633803317,
+ 3248222580,
+ 3479774868,
+ 3835390401,
+ 2666613458,
+ 4022224774,
+ 944711139,
+ 264347078,
+ 2341262773,
+ 604807628,
+ 2007800933,
+ 770255983,
+ 1495990901,
+ 1249150122,
+ 1856431235,
+ 1555081692,
+ 3175218132,
+ 1996064986,
+ 2198950837,
+ 2554220882,
+ 3999719339,
+ 2821834349,
+ 766784016,
+ 2952996808,
+ 2566594879,
+ 3210313671,
+ 3203337956,
+ 3336571891,
+ 1034457026,
+ 3584528711,
+ 2466948901,
+ 113926993,
+ 3758326383,
+ 338241895,
+ 168717936,
+ 666307205,
+ 1188179964,
+ 773529912,
+ 1546045734,
+ 1294757372,
+ 1522805485,
+ 1396182291,
+ 2643833823,
+ 1695183700,
+ 2343527390,
+ 1986661051,
+ 1014477480,
+ 2177026350,
+ 1206759142,
+ 2456956037,
+ 344077627,
+ 2730485921,
+ 1290863460,
+ 2820302411,
+ 3158454273,
+ 3259730800,
+ 3505952657,
+ 3345764771,
+ 106217008,
+ 3516065817,
+ 3606008344,
+ 3600352804,
+ 1432725776,
+ 4094571909,
+ 1467031594,
+ 275423344,
+ 851169720,
+ 430227734,
+ 3100823752,
+ 506948616,
+ 1363258195,
+ 659060556,
+ 3750685593,
+ 883997877,
+ 3785050280,
+ 958139571,
+ 3318307427,
+ 1322822218,
+ 3812723403,
+ 1537002063,
+ 2003034995,
+ 1747873779,
+ 3602036899,
+ 1955562222,
+ 1575990012,
+ 2024104815,
+ 1125592928,
+ 2227730452,
+ 2716904306,
+ 2361852424,
+ 442776044,
+ 2428436474,
+ 593698344,
+ 2756734187,
+ 3733110249,
+ 3204031479,
+ 2999351573,
+ 3329325298,
+ 3815920427,
+ 3391569614,
+ 3928383900,
+ 3515267271,
+ 566280711,
+ 3940187606,
+ 3454069534,
+ 4118630271,
+ 4000239992,
+ 116418474,
+ 1914138554,
+ 174292421,
+ 2731055270,
+ 289380356,
+ 3203993006,
+ 460393269,
+ 320620315,
+ 685471733,
+ 587496836,
+ 852142971,
+ 1086792851,
+ 1017036298,
+ 365543100,
+ 1126000580,
+ 2618297676,
+ 1288033470,
+ 3409855158,
+ 1501505948,
+ 4234509866,
+ 1607167915,
+ 987167468,
+ 1816402316,
+ 1246189591
+ ];
+ function crypto_hashblocks_hl(hh, hl, m2, n) {
+ var wh = new Int32Array(16), wl = new Int32Array(16), bh0, bh1, bh2, bh3, bh4, bh5, bh6, bh7, bl0, bl1, bl2, bl3, bl4, bl5, bl6, bl7, th, tl, i, j, h3, l2, a, b2, c2, d2;
+ var ah0 = hh[0], ah1 = hh[1], ah2 = hh[2], ah3 = hh[3], ah4 = hh[4], ah5 = hh[5], ah6 = hh[6], ah7 = hh[7], al0 = hl[0], al1 = hl[1], al2 = hl[2], al3 = hl[3], al4 = hl[4], al5 = hl[5], al6 = hl[6], al7 = hl[7];
+ var pos = 0;
+ while (n >= 128) {
+ for (i = 0; i < 16; i++) {
+ j = 8 * i + pos;
+ wh[i] = m2[j + 0] << 24 | m2[j + 1] << 16 | m2[j + 2] << 8 | m2[j + 3];
+ wl[i] = m2[j + 4] << 24 | m2[j + 5] << 16 | m2[j + 6] << 8 | m2[j + 7];
+ }
+ for (i = 0; i < 80; i++) {
+ bh0 = ah0;
+ bh1 = ah1;
+ bh2 = ah2;
+ bh3 = ah3;
+ bh4 = ah4;
+ bh5 = ah5;
+ bh6 = ah6;
+ bh7 = ah7;
+ bl0 = al0;
+ bl1 = al1;
+ bl2 = al2;
+ bl3 = al3;
+ bl4 = al4;
+ bl5 = al5;
+ bl6 = al6;
+ bl7 = al7;
+ h3 = ah7;
+ l2 = al7;
+ a = l2 & 65535;
+ b2 = l2 >>> 16;
+ c2 = h3 & 65535;
+ d2 = h3 >>> 16;
+ h3 = (ah4 >>> 14 | al4 << 32 - 14) ^ (ah4 >>> 18 | al4 << 32 - 18) ^ (al4 >>> 41 - 32 | ah4 << 32 - (41 - 32));
+ l2 = (al4 >>> 14 | ah4 << 32 - 14) ^ (al4 >>> 18 | ah4 << 32 - 18) ^ (ah4 >>> 41 - 32 | al4 << 32 - (41 - 32));
+ a += l2 & 65535;
+ b2 += l2 >>> 16;
+ c2 += h3 & 65535;
+ d2 += h3 >>> 16;
+ h3 = ah4 & ah5 ^ ~ah4 & ah6;
+ l2 = al4 & al5 ^ ~al4 & al6;
+ a += l2 & 65535;
+ b2 += l2 >>> 16;
+ c2 += h3 & 65535;
+ d2 += h3 >>> 16;
+ h3 = K[i * 2];
+ l2 = K[i * 2 + 1];
+ a += l2 & 65535;
+ b2 += l2 >>> 16;
+ c2 += h3 & 65535;
+ d2 += h3 >>> 16;
+ h3 = wh[i % 16];
+ l2 = wl[i % 16];
+ a += l2 & 65535;
+ b2 += l2 >>> 16;
+ c2 += h3 & 65535;
+ d2 += h3 >>> 16;
+ b2 += a >>> 16;
+ c2 += b2 >>> 16;
+ d2 += c2 >>> 16;
+ th = c2 & 65535 | d2 << 16;
+ tl = a & 65535 | b2 << 16;
+ h3 = th;
+ l2 = tl;
+ a = l2 & 65535;
+ b2 = l2 >>> 16;
+ c2 = h3 & 65535;
+ d2 = h3 >>> 16;
+ h3 = (ah0 >>> 28 | al0 << 32 - 28) ^ (al0 >>> 34 - 32 | ah0 << 32 - (34 - 32)) ^ (al0 >>> 39 - 32 | ah0 << 32 - (39 - 32));
+ l2 = (al0 >>> 28 | ah0 << 32 - 28) ^ (ah0 >>> 34 - 32 | al0 << 32 - (34 - 32)) ^ (ah0 >>> 39 - 32 | al0 << 32 - (39 - 32));
+ a += l2 & 65535;
+ b2 += l2 >>> 16;
+ c2 += h3 & 65535;
+ d2 += h3 >>> 16;
+ h3 = ah0 & ah1 ^ ah0 & ah2 ^ ah1 & ah2;
+ l2 = al0 & al1 ^ al0 & al2 ^ al1 & al2;
+ a += l2 & 65535;
+ b2 += l2 >>> 16;
+ c2 += h3 & 65535;
+ d2 += h3 >>> 16;
+ b2 += a >>> 16;
+ c2 += b2 >>> 16;
+ d2 += c2 >>> 16;
+ bh7 = c2 & 65535 | d2 << 16;
+ bl7 = a & 65535 | b2 << 16;
+ h3 = bh3;
+ l2 = bl3;
+ a = l2 & 65535;
+ b2 = l2 >>> 16;
+ c2 = h3 & 65535;
+ d2 = h3 >>> 16;
+ h3 = th;
+ l2 = tl;
+ a += l2 & 65535;
+ b2 += l2 >>> 16;
+ c2 += h3 & 65535;
+ d2 += h3 >>> 16;
+ b2 += a >>> 16;
+ c2 += b2 >>> 16;
+ d2 += c2 >>> 16;
+ bh3 = c2 & 65535 | d2 << 16;
+ bl3 = a & 65535 | b2 << 16;
+ ah1 = bh0;
+ ah2 = bh1;
+ ah3 = bh2;
+ ah4 = bh3;
+ ah5 = bh4;
+ ah6 = bh5;
+ ah7 = bh6;
+ ah0 = bh7;
+ al1 = bl0;
+ al2 = bl1;
+ al3 = bl2;
+ al4 = bl3;
+ al5 = bl4;
+ al6 = bl5;
+ al7 = bl6;
+ al0 = bl7;
+ if (i % 16 === 15) {
+ for (j = 0; j < 16; j++) {
+ h3 = wh[j];
+ l2 = wl[j];
+ a = l2 & 65535;
+ b2 = l2 >>> 16;
+ c2 = h3 & 65535;
+ d2 = h3 >>> 16;
+ h3 = wh[(j + 9) % 16];
+ l2 = wl[(j + 9) % 16];
+ a += l2 & 65535;
+ b2 += l2 >>> 16;
+ c2 += h3 & 65535;
+ d2 += h3 >>> 16;
+ th = wh[(j + 1) % 16];
+ tl = wl[(j + 1) % 16];
+ h3 = (th >>> 1 | tl << 32 - 1) ^ (th >>> 8 | tl << 32 - 8) ^ th >>> 7;
+ l2 = (tl >>> 1 | th << 32 - 1) ^ (tl >>> 8 | th << 32 - 8) ^ (tl >>> 7 | th << 32 - 7);
+ a += l2 & 65535;
+ b2 += l2 >>> 16;
+ c2 += h3 & 65535;
+ d2 += h3 >>> 16;
+ th = wh[(j + 14) % 16];
+ tl = wl[(j + 14) % 16];
+ h3 = (th >>> 19 | tl << 32 - 19) ^ (tl >>> 61 - 32 | th << 32 - (61 - 32)) ^ th >>> 6;
+ l2 = (tl >>> 19 | th << 32 - 19) ^ (th >>> 61 - 32 | tl << 32 - (61 - 32)) ^ (tl >>> 6 | th << 32 - 6);
+ a += l2 & 65535;
+ b2 += l2 >>> 16;
+ c2 += h3 & 65535;
+ d2 += h3 >>> 16;
+ b2 += a >>> 16;
+ c2 += b2 >>> 16;
+ d2 += c2 >>> 16;
+ wh[j] = c2 & 65535 | d2 << 16;
+ wl[j] = a & 65535 | b2 << 16;
+ }
+ }
+ }
+ h3 = ah0;
+ l2 = al0;
+ a = l2 & 65535;
+ b2 = l2 >>> 16;
+ c2 = h3 & 65535;
+ d2 = h3 >>> 16;
+ h3 = hh[0];
+ l2 = hl[0];
+ a += l2 & 65535;
+ b2 += l2 >>> 16;
+ c2 += h3 & 65535;
+ d2 += h3 >>> 16;
+ b2 += a >>> 16;
+ c2 += b2 >>> 16;
+ d2 += c2 >>> 16;
+ hh[0] = ah0 = c2 & 65535 | d2 << 16;
+ hl[0] = al0 = a & 65535 | b2 << 16;
+ h3 = ah1;
+ l2 = al1;
+ a = l2 & 65535;
+ b2 = l2 >>> 16;
+ c2 = h3 & 65535;
+ d2 = h3 >>> 16;
+ h3 = hh[1];
+ l2 = hl[1];
+ a += l2 & 65535;
+ b2 += l2 >>> 16;
+ c2 += h3 & 65535;
+ d2 += h3 >>> 16;
+ b2 += a >>> 16;
+ c2 += b2 >>> 16;
+ d2 += c2 >>> 16;
+ hh[1] = ah1 = c2 & 65535 | d2 << 16;
+ hl[1] = al1 = a & 65535 | b2 << 16;
+ h3 = ah2;
+ l2 = al2;
+ a = l2 & 65535;
+ b2 = l2 >>> 16;
+ c2 = h3 & 65535;
+ d2 = h3 >>> 16;
+ h3 = hh[2];
+ l2 = hl[2];
+ a += l2 & 65535;
+ b2 += l2 >>> 16;
+ c2 += h3 & 65535;
+ d2 += h3 >>> 16;
+ b2 += a >>> 16;
+ c2 += b2 >>> 16;
+ d2 += c2 >>> 16;
+ hh[2] = ah2 = c2 & 65535 | d2 << 16;
+ hl[2] = al2 = a & 65535 | b2 << 16;
+ h3 = ah3;
+ l2 = al3;
+ a = l2 & 65535;
+ b2 = l2 >>> 16;
+ c2 = h3 & 65535;
+ d2 = h3 >>> 16;
+ h3 = hh[3];
+ l2 = hl[3];
+ a += l2 & 65535;
+ b2 += l2 >>> 16;
+ c2 += h3 & 65535;
+ d2 += h3 >>> 16;
+ b2 += a >>> 16;
+ c2 += b2 >>> 16;
+ d2 += c2 >>> 16;
+ hh[3] = ah3 = c2 & 65535 | d2 << 16;
+ hl[3] = al3 = a & 65535 | b2 << 16;
+ h3 = ah4;
+ l2 = al4;
+ a = l2 & 65535;
+ b2 = l2 >>> 16;
+ c2 = h3 & 65535;
+ d2 = h3 >>> 16;
+ h3 = hh[4];
+ l2 = hl[4];
+ a += l2 & 65535;
+ b2 += l2 >>> 16;
+ c2 += h3 & 65535;
+ d2 += h3 >>> 16;
+ b2 += a >>> 16;
+ c2 += b2 >>> 16;
+ d2 += c2 >>> 16;
+ hh[4] = ah4 = c2 & 65535 | d2 << 16;
+ hl[4] = al4 = a & 65535 | b2 << 16;
+ h3 = ah5;
+ l2 = al5;
+ a = l2 & 65535;
+ b2 = l2 >>> 16;
+ c2 = h3 & 65535;
+ d2 = h3 >>> 16;
+ h3 = hh[5];
+ l2 = hl[5];
+ a += l2 & 65535;
+ b2 += l2 >>> 16;
+ c2 += h3 & 65535;
+ d2 += h3 >>> 16;
+ b2 += a >>> 16;
+ c2 += b2 >>> 16;
+ d2 += c2 >>> 16;
+ hh[5] = ah5 = c2 & 65535 | d2 << 16;
+ hl[5] = al5 = a & 65535 | b2 << 16;
+ h3 = ah6;
+ l2 = al6;
+ a = l2 & 65535;
+ b2 = l2 >>> 16;
+ c2 = h3 & 65535;
+ d2 = h3 >>> 16;
+ h3 = hh[6];
+ l2 = hl[6];
+ a += l2 & 65535;
+ b2 += l2 >>> 16;
+ c2 += h3 & 65535;
+ d2 += h3 >>> 16;
+ b2 += a >>> 16;
+ c2 += b2 >>> 16;
+ d2 += c2 >>> 16;
+ hh[6] = ah6 = c2 & 65535 | d2 << 16;
+ hl[6] = al6 = a & 65535 | b2 << 16;
+ h3 = ah7;
+ l2 = al7;
+ a = l2 & 65535;
+ b2 = l2 >>> 16;
+ c2 = h3 & 65535;
+ d2 = h3 >>> 16;
+ h3 = hh[7];
+ l2 = hl[7];
+ a += l2 & 65535;
+ b2 += l2 >>> 16;
+ c2 += h3 & 65535;
+ d2 += h3 >>> 16;
+ b2 += a >>> 16;
+ c2 += b2 >>> 16;
+ d2 += c2 >>> 16;
+ hh[7] = ah7 = c2 & 65535 | d2 << 16;
+ hl[7] = al7 = a & 65535 | b2 << 16;
+ pos += 128;
+ n -= 128;
+ }
+ return n;
+ }
+ function crypto_hash(out, m2, n) {
+ var hh = new Int32Array(8), hl = new Int32Array(8), x = new Uint8Array(256), i, b2 = n;
+ hh[0] = 1779033703;
+ hh[1] = 3144134277;
+ hh[2] = 1013904242;
+ hh[3] = 2773480762;
+ hh[4] = 1359893119;
+ hh[5] = 2600822924;
+ hh[6] = 528734635;
+ hh[7] = 1541459225;
+ hl[0] = 4089235720;
+ hl[1] = 2227873595;
+ hl[2] = 4271175723;
+ hl[3] = 1595750129;
+ hl[4] = 2917565137;
+ hl[5] = 725511199;
+ hl[6] = 4215389547;
+ hl[7] = 327033209;
+ crypto_hashblocks_hl(hh, hl, m2, n);
+ n %= 128;
+ for (i = 0; i < n; i++) x[i] = m2[b2 - n + i];
+ x[n] = 128;
+ n = 256 - 128 * (n < 112 ? 1 : 0);
+ x[n - 9] = 0;
+ ts64(x, n - 8, b2 / 536870912 | 0, b2 << 3);
+ crypto_hashblocks_hl(hh, hl, x, n);
+ for (i = 0; i < 8; i++) ts64(out, 8 * i, hh[i], hl[i]);
+ return 0;
+ }
+ function add(p2, q) {
+ var a = gf(), b2 = gf(), c2 = gf(), d2 = gf(), e = gf(), f2 = gf(), g2 = gf(), h3 = gf(), t = gf();
+ Z(a, p2[1], p2[0]);
+ Z(t, q[1], q[0]);
+ M(a, a, t);
+ A(b2, p2[0], p2[1]);
+ A(t, q[0], q[1]);
+ M(b2, b2, t);
+ M(c2, p2[3], q[3]);
+ M(c2, c2, D2);
+ M(d2, p2[2], q[2]);
+ A(d2, d2, d2);
+ Z(e, b2, a);
+ Z(f2, d2, c2);
+ A(g2, d2, c2);
+ A(h3, b2, a);
+ M(p2[0], e, f2);
+ M(p2[1], h3, g2);
+ M(p2[2], g2, f2);
+ M(p2[3], e, h3);
+ }
+ function cswap(p2, q, b2) {
+ var i;
+ for (i = 0; i < 4; i++) {
+ sel25519(p2[i], q[i], b2);
+ }
+ }
+ function pack(r2, p2) {
+ var tx = gf(), ty = gf(), zi = gf();
+ inv25519(zi, p2[2]);
+ M(tx, p2[0], zi);
+ M(ty, p2[1], zi);
+ pack25519(r2, ty);
+ r2[31] ^= par25519(tx) << 7;
+ }
+ function scalarmult(p2, q, s) {
+ var b2, i;
+ set25519(p2[0], gf0);
+ set25519(p2[1], gf1);
+ set25519(p2[2], gf1);
+ set25519(p2[3], gf0);
+ for (i = 255; i >= 0; --i) {
+ b2 = s[i / 8 | 0] >> (i & 7) & 1;
+ cswap(p2, q, b2);
+ add(q, p2);
+ add(p2, p2);
+ cswap(p2, q, b2);
+ }
+ }
+ function scalarbase(p2, s) {
+ var q = [gf(), gf(), gf(), gf()];
+ set25519(q[0], X);
+ set25519(q[1], Y);
+ set25519(q[2], gf1);
+ M(q[3], X, Y);
+ scalarmult(p2, q, s);
+ }
+ function crypto_sign_keypair(pk, sk, seeded) {
+ var d2 = new Uint8Array(64);
+ var p2 = [gf(), gf(), gf(), gf()];
+ var i;
+ if (!seeded) randombytes(sk, 32);
+ crypto_hash(d2, sk, 32);
+ d2[0] &= 248;
+ d2[31] &= 127;
+ d2[31] |= 64;
+ scalarbase(p2, d2);
+ pack(pk, p2);
+ for (i = 0; i < 32; i++) sk[i + 32] = pk[i];
+ return 0;
+ }
+ var L = new Float64Array([237, 211, 245, 92, 26, 99, 18, 88, 214, 156, 247, 162, 222, 249, 222, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16]);
+ function modL(r2, x) {
+ var carry, i, j, k2;
+ for (i = 63; i >= 32; --i) {
+ carry = 0;
+ for (j = i - 32, k2 = i - 12; j < k2; ++j) {
+ x[j] += carry - 16 * x[i] * L[j - (i - 32)];
+ carry = Math.floor((x[j] + 128) / 256);
+ x[j] -= carry * 256;
+ }
+ x[j] += carry;
+ x[i] = 0;
+ }
+ carry = 0;
+ for (j = 0; j < 32; j++) {
+ x[j] += carry - (x[31] >> 4) * L[j];
+ carry = x[j] >> 8;
+ x[j] &= 255;
+ }
+ for (j = 0; j < 32; j++) x[j] -= carry * L[j];
+ for (i = 0; i < 32; i++) {
+ x[i + 1] += x[i] >> 8;
+ r2[i] = x[i] & 255;
+ }
+ }
+ function reduce(r2) {
+ var x = new Float64Array(64), i;
+ for (i = 0; i < 64; i++) x[i] = r2[i];
+ for (i = 0; i < 64; i++) r2[i] = 0;
+ modL(r2, x);
+ }
+ function crypto_sign(sm, m2, n, sk) {
+ var d2 = new Uint8Array(64), h3 = new Uint8Array(64), r2 = new Uint8Array(64);
+ var i, j, x = new Float64Array(64);
+ var p2 = [gf(), gf(), gf(), gf()];
+ crypto_hash(d2, sk, 32);
+ d2[0] &= 248;
+ d2[31] &= 127;
+ d2[31] |= 64;
+ var smlen = n + 64;
+ for (i = 0; i < n; i++) sm[64 + i] = m2[i];
+ for (i = 0; i < 32; i++) sm[32 + i] = d2[32 + i];
+ crypto_hash(r2, sm.subarray(32), n + 32);
+ reduce(r2);
+ scalarbase(p2, r2);
+ pack(sm, p2);
+ for (i = 32; i < 64; i++) sm[i] = sk[i];
+ crypto_hash(h3, sm, n + 64);
+ reduce(h3);
+ for (i = 0; i < 64; i++) x[i] = 0;
+ for (i = 0; i < 32; i++) x[i] = r2[i];
+ for (i = 0; i < 32; i++) {
+ for (j = 0; j < 32; j++) {
+ x[i + j] += h3[i] * d2[j];
+ }
+ }
+ modL(sm.subarray(32), x);
+ return smlen;
+ }
+ function unpackneg(r2, p2) {
+ var t = gf(), chk = gf(), num = gf(), den = gf(), den2 = gf(), den4 = gf(), den6 = gf();
+ set25519(r2[2], gf1);
+ unpack25519(r2[1], p2);
+ S2(num, r2[1]);
+ M(den, num, D);
+ Z(num, num, r2[2]);
+ A(den, r2[2], den);
+ S2(den2, den);
+ S2(den4, den2);
+ M(den6, den4, den2);
+ M(t, den6, num);
+ M(t, t, den);
+ pow2523(t, t);
+ M(t, t, num);
+ M(t, t, den);
+ M(t, t, den);
+ M(r2[0], t, den);
+ S2(chk, r2[0]);
+ M(chk, chk, den);
+ if (neq25519(chk, num)) M(r2[0], r2[0], I);
+ S2(chk, r2[0]);
+ M(chk, chk, den);
+ if (neq25519(chk, num)) return -1;
+ if (par25519(r2[0]) === p2[31] >> 7) Z(r2[0], gf0, r2[0]);
+ M(r2[3], r2[0], r2[1]);
+ return 0;
+ }
+ function crypto_sign_open(m2, sm, n, pk) {
+ var i;
+ var t = new Uint8Array(32), h3 = new Uint8Array(64);
+ var p2 = [gf(), gf(), gf(), gf()], q = [gf(), gf(), gf(), gf()];
+ if (n < 64) return -1;
+ if (unpackneg(q, pk)) return -1;
+ for (i = 0; i < n; i++) m2[i] = sm[i];
+ for (i = 0; i < 32; i++) m2[i + 32] = pk[i];
+ crypto_hash(h3, m2, n);
+ reduce(h3);
+ scalarmult(p2, q, h3);
+ scalarbase(q, sm.subarray(32));
+ add(p2, q);
+ pack(t, p2);
+ n -= 64;
+ if (crypto_verify_32(sm, 0, t, 0)) {
+ for (i = 0; i < n; i++) m2[i] = 0;
+ return -1;
+ }
+ for (i = 0; i < n; i++) m2[i] = sm[i + 64];
+ return n;
+ }
+ var crypto_secretbox_KEYBYTES = 32, crypto_secretbox_NONCEBYTES = 24, crypto_secretbox_ZEROBYTES = 32, crypto_secretbox_BOXZEROBYTES = 16, crypto_scalarmult_BYTES = 32, crypto_scalarmult_SCALARBYTES = 32, crypto_box_PUBLICKEYBYTES = 32, crypto_box_SECRETKEYBYTES = 32, crypto_box_BEFORENMBYTES = 32, crypto_box_NONCEBYTES = crypto_secretbox_NONCEBYTES, crypto_box_ZEROBYTES = crypto_secretbox_ZEROBYTES, crypto_box_BOXZEROBYTES = crypto_secretbox_BOXZEROBYTES, crypto_sign_BYTES = 64, crypto_sign_PUBLICKEYBYTES = 32, crypto_sign_SECRETKEYBYTES = 64, crypto_sign_SEEDBYTES = 32, crypto_hash_BYTES = 64;
+ nacl.lowlevel = {
+ crypto_core_hsalsa20,
+ crypto_stream_xor,
+ crypto_stream,
+ crypto_stream_salsa20_xor,
+ crypto_stream_salsa20,
+ crypto_onetimeauth,
+ crypto_onetimeauth_verify,
+ crypto_verify_16,
+ crypto_verify_32,
+ crypto_secretbox,
+ crypto_secretbox_open,
+ crypto_scalarmult,
+ crypto_scalarmult_base,
+ crypto_box_beforenm,
+ crypto_box_afternm,
+ crypto_box,
+ crypto_box_open,
+ crypto_box_keypair,
+ crypto_hash,
+ crypto_sign,
+ crypto_sign_keypair,
+ crypto_sign_open,
+ crypto_secretbox_KEYBYTES,
+ crypto_secretbox_NONCEBYTES,
+ crypto_secretbox_ZEROBYTES,
+ crypto_secretbox_BOXZEROBYTES,
+ crypto_scalarmult_BYTES,
+ crypto_scalarmult_SCALARBYTES,
+ crypto_box_PUBLICKEYBYTES,
+ crypto_box_SECRETKEYBYTES,
+ crypto_box_BEFORENMBYTES,
+ crypto_box_NONCEBYTES,
+ crypto_box_ZEROBYTES,
+ crypto_box_BOXZEROBYTES,
+ crypto_sign_BYTES,
+ crypto_sign_PUBLICKEYBYTES,
+ crypto_sign_SECRETKEYBYTES,
+ crypto_sign_SEEDBYTES,
+ crypto_hash_BYTES,
+ gf,
+ D,
+ L,
+ pack25519,
+ unpack25519,
+ M,
+ A,
+ S: S2,
+ Z,
+ pow2523,
+ add,
+ set25519,
+ modL,
+ scalarmult,
+ scalarbase
+ };
+ function checkLengths(k2, n) {
+ if (k2.length !== crypto_secretbox_KEYBYTES) throw new Error("bad key size");
+ if (n.length !== crypto_secretbox_NONCEBYTES) throw new Error("bad nonce size");
+ }
+ function checkBoxLengths(pk, sk) {
+ if (pk.length !== crypto_box_PUBLICKEYBYTES) throw new Error("bad public key size");
+ if (sk.length !== crypto_box_SECRETKEYBYTES) throw new Error("bad secret key size");
+ }
+ function checkArrayTypes() {
+ for (var i = 0; i < arguments.length; i++) {
+ if (!(arguments[i] instanceof Uint8Array))
+ throw new TypeError("unexpected type, use Uint8Array");
+ }
+ }
+ function cleanup(arr) {
+ for (var i = 0; i < arr.length; i++) arr[i] = 0;
+ }
+ nacl.randomBytes = function(n) {
+ var b2 = new Uint8Array(n);
+ randombytes(b2, n);
+ return b2;
+ };
+ nacl.secretbox = function(msg, nonce, key) {
+ checkArrayTypes(msg, nonce, key);
+ checkLengths(key, nonce);
+ var m2 = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length);
+ var c2 = new Uint8Array(m2.length);
+ for (var i = 0; i < msg.length; i++) m2[i + crypto_secretbox_ZEROBYTES] = msg[i];
+ crypto_secretbox(c2, m2, m2.length, nonce, key);
+ return c2.subarray(crypto_secretbox_BOXZEROBYTES);
+ };
+ nacl.secretbox.open = function(box, nonce, key) {
+ checkArrayTypes(box, nonce, key);
+ checkLengths(key, nonce);
+ var c2 = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length);
+ var m2 = new Uint8Array(c2.length);
+ for (var i = 0; i < box.length; i++) c2[i + crypto_secretbox_BOXZEROBYTES] = box[i];
+ if (c2.length < 32) return null;
+ if (crypto_secretbox_open(m2, c2, c2.length, nonce, key) !== 0) return null;
+ return m2.subarray(crypto_secretbox_ZEROBYTES);
+ };
+ nacl.secretbox.keyLength = crypto_secretbox_KEYBYTES;
+ nacl.secretbox.nonceLength = crypto_secretbox_NONCEBYTES;
+ nacl.secretbox.overheadLength = crypto_secretbox_BOXZEROBYTES;
+ nacl.scalarMult = function(n, p2) {
+ checkArrayTypes(n, p2);
+ if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error("bad n size");
+ if (p2.length !== crypto_scalarmult_BYTES) throw new Error("bad p size");
+ var q = new Uint8Array(crypto_scalarmult_BYTES);
+ crypto_scalarmult(q, n, p2);
+ return q;
+ };
+ nacl.scalarMult.base = function(n) {
+ checkArrayTypes(n);
+ if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error("bad n size");
+ var q = new Uint8Array(crypto_scalarmult_BYTES);
+ crypto_scalarmult_base(q, n);
+ return q;
+ };
+ nacl.scalarMult.scalarLength = crypto_scalarmult_SCALARBYTES;
+ nacl.scalarMult.groupElementLength = crypto_scalarmult_BYTES;
+ nacl.box = function(msg, nonce, publicKey, secretKey) {
+ var k2 = nacl.box.before(publicKey, secretKey);
+ return nacl.secretbox(msg, nonce, k2);
+ };
+ nacl.box.before = function(publicKey, secretKey) {
+ checkArrayTypes(publicKey, secretKey);
+ checkBoxLengths(publicKey, secretKey);
+ var k2 = new Uint8Array(crypto_box_BEFORENMBYTES);
+ crypto_box_beforenm(k2, publicKey, secretKey);
+ return k2;
+ };
+ nacl.box.after = nacl.secretbox;
+ nacl.box.open = function(msg, nonce, publicKey, secretKey) {
+ var k2 = nacl.box.before(publicKey, secretKey);
+ return nacl.secretbox.open(msg, nonce, k2);
+ };
+ nacl.box.open.after = nacl.secretbox.open;
+ nacl.box.keyPair = function() {
+ var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);
+ var sk = new Uint8Array(crypto_box_SECRETKEYBYTES);
+ crypto_box_keypair(pk, sk);
+ return { publicKey: pk, secretKey: sk };
+ };
+ nacl.box.keyPair.fromSecretKey = function(secretKey) {
+ checkArrayTypes(secretKey);
+ if (secretKey.length !== crypto_box_SECRETKEYBYTES)
+ throw new Error("bad secret key size");
+ var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);
+ crypto_scalarmult_base(pk, secretKey);
+ return { publicKey: pk, secretKey: new Uint8Array(secretKey) };
+ };
+ nacl.box.publicKeyLength = crypto_box_PUBLICKEYBYTES;
+ nacl.box.secretKeyLength = crypto_box_SECRETKEYBYTES;
+ nacl.box.sharedKeyLength = crypto_box_BEFORENMBYTES;
+ nacl.box.nonceLength = crypto_box_NONCEBYTES;
+ nacl.box.overheadLength = nacl.secretbox.overheadLength;
+ nacl.sign = function(msg, secretKey) {
+ checkArrayTypes(msg, secretKey);
+ if (secretKey.length !== crypto_sign_SECRETKEYBYTES)
+ throw new Error("bad secret key size");
+ var signedMsg = new Uint8Array(crypto_sign_BYTES + msg.length);
+ crypto_sign(signedMsg, msg, msg.length, secretKey);
+ return signedMsg;
+ };
+ nacl.sign.open = function(signedMsg, publicKey) {
+ checkArrayTypes(signedMsg, publicKey);
+ if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)
+ throw new Error("bad public key size");
+ var tmp = new Uint8Array(signedMsg.length);
+ var mlen = crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey);
+ if (mlen < 0) return null;
+ var m2 = new Uint8Array(mlen);
+ for (var i = 0; i < m2.length; i++) m2[i] = tmp[i];
+ return m2;
+ };
+ nacl.sign.detached = function(msg, secretKey) {
+ var signedMsg = nacl.sign(msg, secretKey);
+ var sig = new Uint8Array(crypto_sign_BYTES);
+ for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i];
+ return sig;
+ };
+ nacl.sign.detached.verify = function(msg, sig, publicKey) {
+ checkArrayTypes(msg, sig, publicKey);
+ if (sig.length !== crypto_sign_BYTES)
+ throw new Error("bad signature size");
+ if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)
+ throw new Error("bad public key size");
+ var sm = new Uint8Array(crypto_sign_BYTES + msg.length);
+ var m2 = new Uint8Array(crypto_sign_BYTES + msg.length);
+ var i;
+ for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i];
+ for (i = 0; i < msg.length; i++) sm[i + crypto_sign_BYTES] = msg[i];
+ return crypto_sign_open(m2, sm, sm.length, publicKey) >= 0;
+ };
+ nacl.sign.keyPair = function() {
+ var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
+ var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
+ crypto_sign_keypair(pk, sk);
+ return { publicKey: pk, secretKey: sk };
+ };
+ nacl.sign.keyPair.fromSecretKey = function(secretKey) {
+ checkArrayTypes(secretKey);
+ if (secretKey.length !== crypto_sign_SECRETKEYBYTES)
+ throw new Error("bad secret key size");
+ var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
+ for (var i = 0; i < pk.length; i++) pk[i] = secretKey[32 + i];
+ return { publicKey: pk, secretKey: new Uint8Array(secretKey) };
+ };
+ nacl.sign.keyPair.fromSeed = function(seed) {
+ checkArrayTypes(seed);
+ if (seed.length !== crypto_sign_SEEDBYTES)
+ throw new Error("bad seed size");
+ var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
+ var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
+ for (var i = 0; i < 32; i++) sk[i] = seed[i];
+ crypto_sign_keypair(pk, sk, true);
+ return { publicKey: pk, secretKey: sk };
+ };
+ nacl.sign.publicKeyLength = crypto_sign_PUBLICKEYBYTES;
+ nacl.sign.secretKeyLength = crypto_sign_SECRETKEYBYTES;
+ nacl.sign.seedLength = crypto_sign_SEEDBYTES;
+ nacl.sign.signatureLength = crypto_sign_BYTES;
+ nacl.hash = function(msg) {
+ checkArrayTypes(msg);
+ var h3 = new Uint8Array(crypto_hash_BYTES);
+ crypto_hash(h3, msg, msg.length);
+ return h3;
+ };
+ nacl.hash.hashLength = crypto_hash_BYTES;
+ nacl.verify = function(x, y2) {
+ checkArrayTypes(x, y2);
+ if (x.length === 0 || y2.length === 0) return false;
+ if (x.length !== y2.length) return false;
+ return vn(x, 0, y2, 0, x.length) === 0 ? true : false;
+ };
+ nacl.setPRNG = function(fn) {
+ randombytes = fn;
+ };
+ (function() {
+ var crypto = typeof self !== "undefined" ? self.crypto || self.msCrypto : null;
+ if (crypto && crypto.getRandomValues) {
+ var QUOTA = 65536;
+ nacl.setPRNG(function(x, n) {
+ var i, v2 = new Uint8Array(n);
+ for (i = 0; i < n; i += QUOTA) {
+ crypto.getRandomValues(v2.subarray(i, i + Math.min(n - i, QUOTA)));
+ }
+ for (i = 0; i < n; i++) x[i] = v2[i];
+ cleanup(v2);
+ });
+ } else {
+ crypto = __webpack_require__2(982);
+ if (crypto && crypto.randomBytes) {
+ nacl.setPRNG(function(x, n) {
+ var i, v2 = crypto.randomBytes(n);
+ for (i = 0; i < n; i++) x[i] = v2[i];
+ cleanup(v2);
+ });
+ }
+ }
+ })();
+ })(module2.exports ? module2.exports : self.nacl = self.nacl || {});
+ },
+ /***/
+ 41(module2, __unused_webpack_exports, __webpack_require__2) {
+ var Base = __webpack_require__2(369), Client = __webpack_require__2(483), Server = __webpack_require__2(983);
+ var Driver = {
+ client: function(url, options) {
+ options = options || {};
+ if (options.masking === void 0) options.masking = true;
+ return new Client(url, options);
+ },
+ server: function(options) {
+ options = options || {};
+ if (options.requireMasking === void 0) options.requireMasking = true;
+ return new Server(options);
+ },
+ http: function() {
+ return Server.http.apply(Server, arguments);
+ },
+ isSecureRequest: function(request) {
+ return Server.isSecureRequest(request);
+ },
+ isWebSocket: function(request) {
+ return Base.isWebSocket(request);
+ },
+ validateOptions: function(options, validKeys) {
+ Base.validateOptions(options, validKeys);
+ }
+ };
+ module2.exports = Driver;
+ },
+ /***/
+ 369(module2, __unused_webpack_exports, __webpack_require__2) {
+ var Buffer2 = __webpack_require__2(891).Buffer, Emitter = __webpack_require__2(434).EventEmitter, util = __webpack_require__2(23), streams = __webpack_require__2(578), Headers = __webpack_require__2(160), Reader = __webpack_require__2(212);
+ var Base = function(request, url, options) {
+ Emitter.call(this);
+ Base.validateOptions(options || {}, ["maxLength", "masking", "requireMasking", "protocols"]);
+ this._request = request;
+ this._reader = new Reader();
+ this._options = options || {};
+ this._maxLength = this._options.maxLength || this.MAX_LENGTH;
+ this._headers = new Headers();
+ this.__queue = [];
+ this.readyState = 0;
+ this.url = url;
+ this.io = new streams.IO(this);
+ this.messages = new streams.Messages(this);
+ this._bindEventListeners();
+ };
+ util.inherits(Base, Emitter);
+ Base.isWebSocket = function(request) {
+ var connection = request.headers.connection || "", upgrade = request.headers.upgrade || "";
+ return request.method === "GET" && connection.toLowerCase().split(/ *, */).indexOf("upgrade") >= 0 && upgrade.toLowerCase() === "websocket";
+ };
+ Base.validateOptions = function(options, validKeys) {
+ for (var key2 in options) {
+ if (validKeys.indexOf(key2) < 0)
+ throw new Error("Unrecognized option: " + key2);
+ }
+ };
+ var instance = {
+ // This is 64MB, small enough for an average VPS to handle without
+ // crashing from process out of memory
+ MAX_LENGTH: 67108863,
+ STATES: ["connecting", "open", "closing", "closed"],
+ _bindEventListeners: function() {
+ var self2 = this;
+ this.messages.on("error", function() {
+ });
+ this.on("message", function(event) {
+ var messages = self2.messages;
+ if (messages.readable) messages.emit("data", event.data);
+ });
+ this.on("error", function(error) {
+ var messages = self2.messages;
+ if (messages.readable) messages.emit("error", error);
+ });
+ this.on("close", function() {
+ var messages = self2.messages;
+ if (!messages.readable) return;
+ messages.readable = messages.writable = false;
+ messages.emit("end");
+ });
+ },
+ getState: function() {
+ return this.STATES[this.readyState] || null;
+ },
+ addExtension: function(extension) {
+ return false;
+ },
+ setHeader: function(name, value) {
+ if (this.readyState > 0) return false;
+ this._headers.set(name, value);
+ return true;
+ },
+ start: function() {
+ if (this.readyState !== 0) return false;
+ if (!Base.isWebSocket(this._request))
+ return this._failHandshake(new Error("Not a WebSocket request"));
+ var response;
+ try {
+ response = this._handshakeResponse();
+ } catch (error) {
+ return this._failHandshake(error);
+ }
+ this._write(response);
+ if (this._stage !== -1) this._open();
+ return true;
+ },
+ _failHandshake: function(error) {
+ var headers = new Headers();
+ headers.set("Content-Type", "text/plain");
+ headers.set("Content-Length", Buffer2.byteLength(error.message, "utf8"));
+ headers = ["HTTP/1.1 400 Bad Request", headers.toString(), error.message];
+ this._write(Buffer2.from(headers.join("\r\n"), "utf8"));
+ this._fail("protocol_error", error.message);
+ return false;
+ },
+ text: function(message) {
+ return this.frame(message);
+ },
+ binary: function(message) {
+ return false;
+ },
+ ping: function() {
+ return false;
+ },
+ pong: function() {
+ return false;
+ },
+ close: function(reason, code) {
+ if (this.readyState !== 1) return false;
+ this.readyState = 3;
+ this.emit("close", new Base.CloseEvent(null, null));
+ return true;
+ },
+ _open: function() {
+ this.readyState = 1;
+ this.__queue.forEach(function(args) {
+ this.frame.apply(this, args);
+ }, this);
+ this.__queue = [];
+ this.emit("open", new Base.OpenEvent());
+ },
+ _queue: function(message) {
+ this.__queue.push(message);
+ return true;
+ },
+ _write: function(chunk) {
+ var io = this.io;
+ if (io.readable) io.emit("data", chunk);
+ },
+ _fail: function(type, message) {
+ this.readyState = 2;
+ this.emit("error", new Error(message));
+ this.close();
+ }
+ };
+ for (var key in instance)
+ Base.prototype[key] = instance[key];
+ Base.ConnectEvent = function() {
+ };
+ Base.OpenEvent = function() {
+ };
+ Base.CloseEvent = function(code, reason) {
+ this.code = code;
+ this.reason = reason;
+ };
+ Base.MessageEvent = function(data) {
+ this.data = data;
+ };
+ Base.PingEvent = function(data) {
+ this.data = data;
+ };
+ Base.PongEvent = function(data) {
+ this.data = data;
+ };
+ module2.exports = Base;
+ },
+ /***/
+ 483(module2, __unused_webpack_exports, __webpack_require__2) {
+ var Buffer2 = __webpack_require__2(891).Buffer, crypto = __webpack_require__2(982), url = __webpack_require__2(16), util = __webpack_require__2(23), HttpParser = __webpack_require__2(565), Base = __webpack_require__2(369), Hybi = __webpack_require__2(518), Proxy = __webpack_require__2(662);
+ var Client = function(_url, options) {
+ this.version = "hybi-" + Hybi.VERSION;
+ Hybi.call(this, null, _url, options);
+ this.readyState = -1;
+ this._key = Client.generateKey();
+ this._accept = Hybi.generateAccept(this._key);
+ this._http = new HttpParser("response");
+ var uri = url.parse(this.url), auth = uri.auth && Buffer2.from(uri.auth, "utf8").toString("base64");
+ if (this.VALID_PROTOCOLS.indexOf(uri.protocol) < 0)
+ throw new Error(this.url + " is not a valid WebSocket URL");
+ this._pathname = (uri.pathname || "/") + (uri.search || "");
+ this._headers.set("Host", uri.host);
+ this._headers.set("Upgrade", "websocket");
+ this._headers.set("Connection", "Upgrade");
+ this._headers.set("Sec-WebSocket-Key", this._key);
+ this._headers.set("Sec-WebSocket-Version", Hybi.VERSION);
+ if (this._protocols.length > 0)
+ this._headers.set("Sec-WebSocket-Protocol", this._protocols.join(", "));
+ if (auth)
+ this._headers.set("Authorization", "Basic " + auth);
+ };
+ util.inherits(Client, Hybi);
+ Client.generateKey = function() {
+ return crypto.randomBytes(16).toString("base64");
+ };
+ var instance = {
+ VALID_PROTOCOLS: ["ws:", "wss:"],
+ proxy: function(origin, options) {
+ return new Proxy(this, origin, options);
+ },
+ start: function() {
+ if (this.readyState !== -1) return false;
+ this._write(this._handshakeRequest());
+ this.readyState = 0;
+ return true;
+ },
+ parse: function(chunk) {
+ if (this.readyState === 3) return;
+ if (this.readyState > 0) return Hybi.prototype.parse.call(this, chunk);
+ this._http.parse(chunk);
+ if (!this._http.isComplete()) return;
+ this._validateHandshake();
+ if (this.readyState === 3) return;
+ this._open();
+ this.parse(this._http.body);
+ },
+ _handshakeRequest: function() {
+ var extensions = this._extensions.generateOffer();
+ if (extensions)
+ this._headers.set("Sec-WebSocket-Extensions", extensions);
+ var start = "GET " + this._pathname + " HTTP/1.1", headers = [start, this._headers.toString(), ""];
+ return Buffer2.from(headers.join("\r\n"), "utf8");
+ },
+ _failHandshake: function(message) {
+ message = "Error during WebSocket handshake: " + message;
+ this.readyState = 3;
+ this.emit("error", new Error(message));
+ this.emit("close", new Base.CloseEvent(this.ERRORS.protocol_error, message));
+ },
+ _validateHandshake: function() {
+ this.statusCode = this._http.statusCode;
+ this.headers = this._http.headers;
+ if (this._http.error)
+ return this._failHandshake(this._http.error.message);
+ if (this._http.statusCode !== 101)
+ return this._failHandshake("Unexpected response code: " + this._http.statusCode);
+ var headers = this._http.headers, upgrade = headers["upgrade"] || "", connection = headers["connection"] || "", accept = headers["sec-websocket-accept"] || "", protocol = headers["sec-websocket-protocol"] || "";
+ if (upgrade === "")
+ return this._failHandshake("'Upgrade' header is missing");
+ if (upgrade.toLowerCase() !== "websocket")
+ return this._failHandshake("'Upgrade' header value is not 'WebSocket'");
+ if (connection === "")
+ return this._failHandshake("'Connection' header is missing");
+ if (connection.toLowerCase() !== "upgrade")
+ return this._failHandshake("'Connection' header value is not 'Upgrade'");
+ if (accept !== this._accept)
+ return this._failHandshake("Sec-WebSocket-Accept mismatch");
+ this.protocol = null;
+ if (protocol !== "") {
+ if (this._protocols.indexOf(protocol) < 0)
+ return this._failHandshake("Sec-WebSocket-Protocol mismatch");
+ else
+ this.protocol = protocol;
+ }
+ try {
+ this._extensions.activate(this.headers["sec-websocket-extensions"]);
+ } catch (e) {
+ return this._failHandshake(e.message);
+ }
+ }
+ };
+ for (var key in instance)
+ Client.prototype[key] = instance[key];
+ module2.exports = Client;
+ },
+ /***/
+ 61(module2, __unused_webpack_exports, __webpack_require__2) {
+ var Buffer2 = __webpack_require__2(891).Buffer, Base = __webpack_require__2(369), util = __webpack_require__2(23);
+ var Draft75 = function(request, url, options) {
+ Base.apply(this, arguments);
+ this._stage = 0;
+ this.version = "hixie-75";
+ this._headers.set("Upgrade", "WebSocket");
+ this._headers.set("Connection", "Upgrade");
+ this._headers.set("WebSocket-Origin", this._request.headers.origin);
+ this._headers.set("WebSocket-Location", this.url);
+ };
+ util.inherits(Draft75, Base);
+ var instance = {
+ close: function() {
+ if (this.readyState === 3) return false;
+ this.readyState = 3;
+ this.emit("close", new Base.CloseEvent(null, null));
+ return true;
+ },
+ parse: function(chunk) {
+ if (this.readyState > 1) return;
+ this._reader.put(chunk);
+ this._reader.eachByte(function(octet) {
+ var message;
+ switch (this._stage) {
+ case -1:
+ this._body.push(octet);
+ this._sendHandshakeBody();
+ break;
+ case 0:
+ this._parseLeadingByte(octet);
+ break;
+ case 1:
+ this._length = (octet & 127) + 128 * this._length;
+ if (this._closing && this._length === 0) {
+ return this.close();
+ } else if ((octet & 128) !== 128) {
+ if (this._length === 0) {
+ this._stage = 0;
+ } else {
+ this._skipped = 0;
+ this._stage = 2;
+ }
+ }
+ break;
+ case 2:
+ if (octet === 255) {
+ this._stage = 0;
+ message = Buffer2.from(this._buffer).toString("utf8", 0, this._buffer.length);
+ this.emit("message", new Base.MessageEvent(message));
+ } else {
+ if (this._length) {
+ this._skipped += 1;
+ if (this._skipped === this._length)
+ this._stage = 0;
+ } else {
+ this._buffer.push(octet);
+ if (this._buffer.length > this._maxLength) return this.close();
+ }
+ }
+ break;
+ }
+ }, this);
+ },
+ frame: function(buffer) {
+ if (this.readyState === 0) return this._queue([buffer]);
+ if (this.readyState > 1) return false;
+ if (typeof buffer !== "string") buffer = buffer.toString();
+ var length = Buffer2.byteLength(buffer), frame = Buffer2.allocUnsafe(length + 2);
+ frame[0] = 0;
+ frame.write(buffer, 1);
+ frame[frame.length - 1] = 255;
+ this._write(frame);
+ return true;
+ },
+ _handshakeResponse: function() {
+ var start = "HTTP/1.1 101 Web Socket Protocol Handshake", headers = [start, this._headers.toString(), ""];
+ return Buffer2.from(headers.join("\r\n"), "utf8");
+ },
+ _parseLeadingByte: function(octet) {
+ if ((octet & 128) === 128) {
+ this._length = 0;
+ this._stage = 1;
+ } else {
+ delete this._length;
+ delete this._skipped;
+ this._buffer = [];
+ this._stage = 2;
+ }
+ }
+ };
+ for (var key in instance)
+ Draft75.prototype[key] = instance[key];
+ module2.exports = Draft75;
+ },
+ /***/
+ 476(module2, __unused_webpack_exports, __webpack_require__2) {
+ var Buffer2 = __webpack_require__2(891).Buffer, Base = __webpack_require__2(369), Draft75 = __webpack_require__2(61), crypto = __webpack_require__2(982), util = __webpack_require__2(23);
+ var numberFromKey = function(key2) {
+ return parseInt((key2.match(/[0-9]/g) || []).join(""), 10);
+ };
+ var spacesInKey = function(key2) {
+ return (key2.match(/ /g) || []).length;
+ };
+ var Draft76 = function(request, url, options) {
+ Draft75.apply(this, arguments);
+ this._stage = -1;
+ this._body = [];
+ this.version = "hixie-76";
+ this._headers.clear();
+ this._headers.set("Upgrade", "WebSocket");
+ this._headers.set("Connection", "Upgrade");
+ this._headers.set("Sec-WebSocket-Origin", this._request.headers.origin);
+ this._headers.set("Sec-WebSocket-Location", this.url);
+ };
+ util.inherits(Draft76, Draft75);
+ var instance = {
+ BODY_SIZE: 8,
+ start: function() {
+ if (!Draft75.prototype.start.call(this)) return false;
+ this._started = true;
+ this._sendHandshakeBody();
+ return true;
+ },
+ close: function() {
+ if (this.readyState === 3) return false;
+ if (this.readyState === 1) this._write(Buffer2.from([255, 0]));
+ this.readyState = 3;
+ this.emit("close", new Base.CloseEvent(null, null));
+ return true;
+ },
+ _handshakeResponse: function() {
+ var headers = this._request.headers, key1 = headers["sec-websocket-key1"], key2 = headers["sec-websocket-key2"];
+ if (!key1) throw new Error("Missing required header: Sec-WebSocket-Key1");
+ if (!key2) throw new Error("Missing required header: Sec-WebSocket-Key2");
+ var number1 = numberFromKey(key1), spaces1 = spacesInKey(key1), number2 = numberFromKey(key2), spaces2 = spacesInKey(key2);
+ if (number1 % spaces1 !== 0 || number2 % spaces2 !== 0)
+ throw new Error("Client sent invalid Sec-WebSocket-Key headers");
+ this._keyValues = [number1 / spaces1, number2 / spaces2];
+ var start = "HTTP/1.1 101 WebSocket Protocol Handshake", headers = [start, this._headers.toString(), ""];
+ return Buffer2.from(headers.join("\r\n"), "binary");
+ },
+ _handshakeSignature: function() {
+ if (this._body.length < this.BODY_SIZE) return null;
+ var md5 = crypto.createHash("md5"), buffer = Buffer2.allocUnsafe(8 + this.BODY_SIZE);
+ buffer.writeUInt32BE(this._keyValues[0], 0);
+ buffer.writeUInt32BE(this._keyValues[1], 4);
+ Buffer2.from(this._body).copy(buffer, 8, 0, this.BODY_SIZE);
+ md5.update(buffer);
+ return Buffer2.from(md5.digest("binary"), "binary");
+ },
+ _sendHandshakeBody: function() {
+ if (!this._started) return;
+ var signature = this._handshakeSignature();
+ if (!signature) return;
+ this._write(signature);
+ this._stage = 0;
+ this._open();
+ if (this._body.length > this.BODY_SIZE)
+ this.parse(this._body.slice(this.BODY_SIZE));
+ },
+ _parseLeadingByte: function(octet) {
+ if (octet !== 255)
+ return Draft75.prototype._parseLeadingByte.call(this, octet);
+ this._closing = true;
+ this._length = 0;
+ this._stage = 1;
+ }
+ };
+ for (var key in instance)
+ Draft76.prototype[key] = instance[key];
+ module2.exports = Draft76;
+ },
+ /***/
+ 160(module2) {
+ var Headers = function() {
+ this.clear();
+ };
+ Headers.prototype.ALLOWED_DUPLICATES = ["set-cookie", "set-cookie2", "warning", "www-authenticate"];
+ Headers.prototype.clear = function() {
+ this._sent = {};
+ this._lines = [];
+ };
+ Headers.prototype.set = function(name, value) {
+ if (value === void 0) return;
+ name = this._strip(name);
+ value = this._strip(value);
+ var key = name.toLowerCase();
+ if (!this._sent.hasOwnProperty(key) || this.ALLOWED_DUPLICATES.indexOf(key) >= 0) {
+ this._sent[key] = true;
+ this._lines.push(name + ": " + value + "\r\n");
+ }
+ };
+ Headers.prototype.toString = function() {
+ return this._lines.join("");
+ };
+ Headers.prototype._strip = function(string) {
+ return string.toString().replace(/^ */, "").replace(/ *$/, "");
+ };
+ module2.exports = Headers;
+ },
+ /***/
+ 518(module2, __unused_webpack_exports, __webpack_require__2) {
+ var Buffer2 = __webpack_require__2(891).Buffer, crypto = __webpack_require__2(982), util = __webpack_require__2(23), Extensions = __webpack_require__2(769), Base = __webpack_require__2(369), Frame = __webpack_require__2(68), Message = __webpack_require__2(814);
+ var Hybi = function(request, url, options) {
+ Base.apply(this, arguments);
+ this._extensions = new Extensions();
+ this._stage = 0;
+ this._masking = this._options.masking;
+ this._protocols = this._options.protocols || [];
+ this._requireMasking = this._options.requireMasking;
+ this._pingCallbacks = {};
+ if (typeof this._protocols === "string")
+ this._protocols = this._protocols.split(/ *, */);
+ if (!this._request) return;
+ var protos = this._request.headers["sec-websocket-protocol"], supported = this._protocols;
+ if (protos !== void 0) {
+ if (typeof protos === "string") protos = protos.split(/ *, */);
+ this.protocol = protos.filter(function(p2) {
+ return supported.indexOf(p2) >= 0;
+ })[0];
+ }
+ this.version = "hybi-" + Hybi.VERSION;
+ };
+ util.inherits(Hybi, Base);
+ Hybi.VERSION = "13";
+ Hybi.mask = function(payload, mask, offset) {
+ if (!mask || mask.length === 0) return payload;
+ offset = offset || 0;
+ for (var i = 0, n = payload.length - offset; i < n; i++) {
+ payload[offset + i] = payload[offset + i] ^ mask[i % 4];
+ }
+ return payload;
+ };
+ Hybi.generateAccept = function(key2) {
+ var sha1 = crypto.createHash("sha1");
+ sha1.update(key2 + Hybi.GUID);
+ return sha1.digest("base64");
+ };
+ Hybi.GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+ var instance = {
+ FIN: 128,
+ MASK: 128,
+ RSV1: 64,
+ RSV2: 32,
+ RSV3: 16,
+ OPCODE: 15,
+ LENGTH: 127,
+ OPCODES: {
+ continuation: 0,
+ text: 1,
+ binary: 2,
+ close: 8,
+ ping: 9,
+ pong: 10
+ },
+ OPCODE_CODES: [0, 1, 2, 8, 9, 10],
+ MESSAGE_OPCODES: [0, 1, 2],
+ OPENING_OPCODES: [1, 2],
+ ERRORS: {
+ normal_closure: 1e3,
+ going_away: 1001,
+ protocol_error: 1002,
+ unacceptable: 1003,
+ encoding_error: 1007,
+ policy_violation: 1008,
+ too_large: 1009,
+ extension_error: 1010,
+ unexpected_condition: 1011
+ },
+ ERROR_CODES: [1e3, 1001, 1002, 1003, 1007, 1008, 1009, 1010, 1011],
+ DEFAULT_ERROR_CODE: 1e3,
+ MIN_RESERVED_ERROR: 3e3,
+ MAX_RESERVED_ERROR: 4999,
+ // http://www.w3.org/International/questions/qa-forms-utf-8.en.php
+ UTF8_MATCH: /^([\x00-\x7F]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})*$/,
+ addExtension: function(extension) {
+ this._extensions.add(extension);
+ return true;
+ },
+ parse: function(chunk) {
+ this._reader.put(chunk);
+ var buffer = true;
+ while (buffer) {
+ switch (this._stage) {
+ case 0:
+ buffer = this._reader.read(1);
+ if (buffer) this._parseOpcode(buffer[0]);
+ break;
+ case 1:
+ buffer = this._reader.read(1);
+ if (buffer) this._parseLength(buffer[0]);
+ break;
+ case 2:
+ buffer = this._reader.read(this._frame.lengthBytes);
+ if (buffer) this._parseExtendedLength(buffer);
+ break;
+ case 3:
+ buffer = this._reader.read(4);
+ if (buffer) {
+ this._stage = 4;
+ this._frame.maskingKey = buffer;
+ }
+ break;
+ case 4:
+ buffer = this._reader.read(this._frame.length);
+ if (buffer) {
+ this._stage = 0;
+ this._emitFrame(buffer);
+ }
+ break;
+ default:
+ buffer = null;
+ }
+ }
+ },
+ text: function(message) {
+ if (this.readyState > 1) return false;
+ return this.frame(message, "text");
+ },
+ binary: function(message) {
+ if (this.readyState > 1) return false;
+ return this.frame(message, "binary");
+ },
+ ping: function(message, callback) {
+ if (this.readyState > 1) return false;
+ message = message || "";
+ if (callback) this._pingCallbacks[message] = callback;
+ return this.frame(message, "ping");
+ },
+ pong: function(message) {
+ if (this.readyState > 1) return false;
+ message = message || "";
+ return this.frame(message, "pong");
+ },
+ close: function(reason, code) {
+ reason = reason || "";
+ code = code || this.ERRORS.normal_closure;
+ if (this.readyState <= 0) {
+ this.readyState = 3;
+ this.emit("close", new Base.CloseEvent(code, reason));
+ return true;
+ } else if (this.readyState === 1) {
+ this.readyState = 2;
+ this._extensions.close(function() {
+ this.frame(reason, "close", code);
+ }, this);
+ return true;
+ } else {
+ return false;
+ }
+ },
+ frame: function(buffer, type, code) {
+ if (this.readyState <= 0) return this._queue([buffer, type, code]);
+ if (this.readyState > 2) return false;
+ if (buffer instanceof Array) buffer = Buffer2.from(buffer);
+ if (typeof buffer === "number") buffer = buffer.toString();
+ var message = new Message(), isText = typeof buffer === "string", payload, copy;
+ message.rsv1 = message.rsv2 = message.rsv3 = false;
+ message.opcode = this.OPCODES[type || (isText ? "text" : "binary")];
+ payload = isText ? Buffer2.from(buffer, "utf8") : buffer;
+ if (code) {
+ copy = payload;
+ payload = Buffer2.allocUnsafe(2 + copy.length);
+ payload.writeUInt16BE(code, 0);
+ copy.copy(payload, 2);
+ }
+ message.data = payload;
+ var onMessageReady = function(message2) {
+ var frame = new Frame();
+ frame.final = true;
+ frame.rsv1 = message2.rsv1;
+ frame.rsv2 = message2.rsv2;
+ frame.rsv3 = message2.rsv3;
+ frame.opcode = message2.opcode;
+ frame.masked = !!this._masking;
+ frame.length = message2.data.length;
+ frame.payload = message2.data;
+ if (frame.masked) frame.maskingKey = crypto.randomBytes(4);
+ this._sendFrame(frame);
+ };
+ if (this.MESSAGE_OPCODES.indexOf(message.opcode) >= 0)
+ this._extensions.processOutgoingMessage(message, function(error, message2) {
+ if (error) return this._fail("extension_error", error.message);
+ onMessageReady.call(this, message2);
+ }, this);
+ else
+ onMessageReady.call(this, message);
+ return true;
+ },
+ _sendFrame: function(frame) {
+ var length = frame.length, header = length <= 125 ? 2 : length <= 65535 ? 4 : 10, offset = header + (frame.masked ? 4 : 0), buffer = Buffer2.allocUnsafe(offset + length), masked = frame.masked ? this.MASK : 0;
+ buffer[0] = (frame.final ? this.FIN : 0) | (frame.rsv1 ? this.RSV1 : 0) | (frame.rsv2 ? this.RSV2 : 0) | (frame.rsv3 ? this.RSV3 : 0) | frame.opcode;
+ if (length <= 125) {
+ buffer[1] = masked | length;
+ } else if (length <= 65535) {
+ buffer[1] = masked | 126;
+ buffer.writeUInt16BE(length, 2);
+ } else {
+ buffer[1] = masked | 127;
+ buffer.writeUInt32BE(Math.floor(length / 4294967296), 2);
+ buffer.writeUInt32BE(length % 4294967296, 6);
+ }
+ frame.payload.copy(buffer, offset);
+ if (frame.masked) {
+ frame.maskingKey.copy(buffer, header);
+ Hybi.mask(buffer, frame.maskingKey, offset);
+ }
+ this._write(buffer);
+ },
+ _handshakeResponse: function() {
+ var secKey = this._request.headers["sec-websocket-key"], version = this._request.headers["sec-websocket-version"];
+ if (version !== Hybi.VERSION)
+ throw new Error("Unsupported WebSocket version: " + version);
+ if (typeof secKey !== "string")
+ throw new Error("Missing handshake request header: Sec-WebSocket-Key");
+ this._headers.set("Upgrade", "websocket");
+ this._headers.set("Connection", "Upgrade");
+ this._headers.set("Sec-WebSocket-Accept", Hybi.generateAccept(secKey));
+ if (this.protocol) this._headers.set("Sec-WebSocket-Protocol", this.protocol);
+ var extensions = this._extensions.generateResponse(this._request.headers["sec-websocket-extensions"]);
+ if (extensions) this._headers.set("Sec-WebSocket-Extensions", extensions);
+ var start = "HTTP/1.1 101 Switching Protocols", headers = [start, this._headers.toString(), ""];
+ return Buffer2.from(headers.join("\r\n"), "utf8");
+ },
+ _shutdown: function(code, reason, error) {
+ delete this._frame;
+ delete this._message;
+ this._stage = 5;
+ var sendCloseFrame = this.readyState === 1;
+ this.readyState = 2;
+ this._extensions.close(function() {
+ if (sendCloseFrame) this.frame(reason, "close", code);
+ this.readyState = 3;
+ if (error) this.emit("error", new Error(reason));
+ this.emit("close", new Base.CloseEvent(code, reason));
+ }, this);
+ },
+ _fail: function(type, message) {
+ if (this.readyState > 1) return;
+ this._shutdown(this.ERRORS[type], message, true);
+ },
+ _parseOpcode: function(octet) {
+ var rsvs = [this.RSV1, this.RSV2, this.RSV3].map(function(rsv) {
+ return (octet & rsv) === rsv;
+ });
+ var frame = this._frame = new Frame();
+ frame.final = (octet & this.FIN) === this.FIN;
+ frame.rsv1 = rsvs[0];
+ frame.rsv2 = rsvs[1];
+ frame.rsv3 = rsvs[2];
+ frame.opcode = octet & this.OPCODE;
+ this._stage = 1;
+ if (!this._extensions.validFrameRsv(frame))
+ return this._fail(
+ "protocol_error",
+ "One or more reserved bits are on: reserved1 = " + (frame.rsv1 ? 1 : 0) + ", reserved2 = " + (frame.rsv2 ? 1 : 0) + ", reserved3 = " + (frame.rsv3 ? 1 : 0)
+ );
+ if (this.OPCODE_CODES.indexOf(frame.opcode) < 0)
+ return this._fail("protocol_error", "Unrecognized frame opcode: " + frame.opcode);
+ if (this.MESSAGE_OPCODES.indexOf(frame.opcode) < 0 && !frame.final)
+ return this._fail("protocol_error", "Received fragmented control frame: opcode = " + frame.opcode);
+ if (this._message && this.OPENING_OPCODES.indexOf(frame.opcode) >= 0)
+ return this._fail("protocol_error", "Received new data frame but previous continuous frame is unfinished");
+ },
+ _parseLength: function(octet) {
+ var frame = this._frame;
+ frame.masked = (octet & this.MASK) === this.MASK;
+ frame.length = octet & this.LENGTH;
+ if (frame.length >= 0 && frame.length <= 125) {
+ this._stage = frame.masked ? 3 : 4;
+ if (!this._checkFrameLength()) return;
+ } else {
+ this._stage = 2;
+ frame.lengthBytes = frame.length === 126 ? 2 : 8;
+ }
+ if (this._requireMasking && !frame.masked)
+ return this._fail("unacceptable", "Received unmasked frame but masking is required");
+ },
+ _parseExtendedLength: function(buffer) {
+ var frame = this._frame;
+ frame.length = this._readUInt(buffer);
+ this._stage = frame.masked ? 3 : 4;
+ if (this.MESSAGE_OPCODES.indexOf(frame.opcode) < 0 && frame.length > 125)
+ return this._fail("protocol_error", "Received control frame having too long payload: " + frame.length);
+ if (!this._checkFrameLength()) return;
+ },
+ _checkFrameLength: function() {
+ var length = this._message ? this._message.length : 0;
+ if (length + this._frame.length > this._maxLength) {
+ this._fail("too_large", "WebSocket frame length too large");
+ return false;
+ } else {
+ return true;
+ }
+ },
+ _emitFrame: function(buffer) {
+ var frame = this._frame, payload = frame.payload = Hybi.mask(buffer, frame.maskingKey), opcode = frame.opcode, message, code, reason, callbacks, callback;
+ delete this._frame;
+ if (opcode === this.OPCODES.continuation) {
+ if (!this._message) return this._fail("protocol_error", "Received unexpected continuation frame");
+ this._message.pushFrame(frame);
+ }
+ if (opcode === this.OPCODES.text || opcode === this.OPCODES.binary) {
+ this._message = new Message();
+ this._message.pushFrame(frame);
+ }
+ if (frame.final && this.MESSAGE_OPCODES.indexOf(opcode) >= 0)
+ return this._emitMessage(this._message);
+ if (opcode === this.OPCODES.close) {
+ code = payload.length >= 2 ? payload.readUInt16BE(0) : null;
+ reason = payload.length > 2 ? this._encode(payload.slice(2)) : null;
+ if (!(payload.length === 0) && !(code !== null && code >= this.MIN_RESERVED_ERROR && code <= this.MAX_RESERVED_ERROR) && this.ERROR_CODES.indexOf(code) < 0)
+ code = this.ERRORS.protocol_error;
+ if (payload.length > 125 || payload.length > 2 && !reason)
+ code = this.ERRORS.protocol_error;
+ this._shutdown(code || this.DEFAULT_ERROR_CODE, reason || "");
+ }
+ if (opcode === this.OPCODES.ping) {
+ this.frame(payload, "pong");
+ this.emit("ping", new Base.PingEvent(payload.toString()));
+ }
+ if (opcode === this.OPCODES.pong) {
+ callbacks = this._pingCallbacks;
+ message = this._encode(payload);
+ callback = callbacks[message];
+ delete callbacks[message];
+ if (callback) callback();
+ this.emit("pong", new Base.PongEvent(payload.toString()));
+ }
+ },
+ _emitMessage: function(message) {
+ var message = this._message;
+ message.read();
+ delete this._message;
+ this._extensions.processIncomingMessage(message, function(error, message2) {
+ if (error) return this._fail("extension_error", error.message);
+ var payload = message2.data;
+ if (message2.opcode === this.OPCODES.text) payload = this._encode(payload);
+ if (payload === null)
+ return this._fail("encoding_error", "Could not decode a text frame as UTF-8");
+ else
+ this.emit("message", new Base.MessageEvent(payload));
+ }, this);
+ },
+ _encode: function(buffer) {
+ try {
+ var string = buffer.toString("binary", 0, buffer.length);
+ if (!this.UTF8_MATCH.test(string)) return null;
+ } catch (e) {
+ }
+ return buffer.toString("utf8", 0, buffer.length);
+ },
+ _readUInt: function(buffer) {
+ if (buffer.length === 2) return buffer.readUInt16BE(0);
+ return buffer.readUInt32BE(0) * 4294967296 + buffer.readUInt32BE(4);
+ }
+ };
+ for (var key in instance)
+ Hybi.prototype[key] = instance[key];
+ module2.exports = Hybi;
+ },
+ /***/
+ 68(module2) {
+ var Frame = function() {
+ };
+ var instance = {
+ final: false,
+ rsv1: false,
+ rsv2: false,
+ rsv3: false,
+ opcode: null,
+ masked: false,
+ maskingKey: null,
+ lengthBytes: 1,
+ length: 0,
+ payload: null
+ };
+ for (var key in instance)
+ Frame.prototype[key] = instance[key];
+ module2.exports = Frame;
+ },
+ /***/
+ 814(module2, __unused_webpack_exports, __webpack_require__2) {
+ var Buffer2 = __webpack_require__2(891).Buffer;
+ var Message = function() {
+ this.rsv1 = false;
+ this.rsv2 = false;
+ this.rsv3 = false;
+ this.opcode = null;
+ this.length = 0;
+ this._chunks = [];
+ };
+ var instance = {
+ read: function() {
+ return this.data = this.data || Buffer2.concat(this._chunks, this.length);
+ },
+ pushFrame: function(frame) {
+ this.rsv1 = this.rsv1 || frame.rsv1;
+ this.rsv2 = this.rsv2 || frame.rsv2;
+ this.rsv3 = this.rsv3 || frame.rsv3;
+ if (this.opcode === null) this.opcode = frame.opcode;
+ this._chunks.push(frame.payload);
+ this.length += frame.length;
+ }
+ };
+ for (var key in instance)
+ Message.prototype[key] = instance[key];
+ module2.exports = Message;
+ },
+ /***/
+ 662(module2, __unused_webpack_exports, __webpack_require__2) {
+ var Buffer2 = __webpack_require__2(891).Buffer, Stream = __webpack_require__2(203).Stream, url = __webpack_require__2(16), util = __webpack_require__2(23), Base = __webpack_require__2(369), Headers = __webpack_require__2(160), HttpParser = __webpack_require__2(565);
+ var PORTS = { "ws:": 80, "wss:": 443 };
+ var Proxy = function(client, origin, options) {
+ this._client = client;
+ this._http = new HttpParser("response");
+ this._origin = typeof client.url === "object" ? client.url : url.parse(client.url);
+ this._url = typeof origin === "object" ? origin : url.parse(origin);
+ this._options = options || {};
+ this._state = 0;
+ this.readable = this.writable = true;
+ this._paused = false;
+ this._headers = new Headers();
+ this._headers.set("Host", this._origin.host);
+ this._headers.set("Connection", "keep-alive");
+ this._headers.set("Proxy-Connection", "keep-alive");
+ var auth = this._url.auth && Buffer2.from(this._url.auth, "utf8").toString("base64");
+ if (auth) this._headers.set("Proxy-Authorization", "Basic " + auth);
+ };
+ util.inherits(Proxy, Stream);
+ var instance = {
+ setHeader: function(name, value) {
+ if (this._state !== 0) return false;
+ this._headers.set(name, value);
+ return true;
+ },
+ start: function() {
+ if (this._state !== 0) return false;
+ this._state = 1;
+ var origin = this._origin, port = origin.port || PORTS[origin.protocol], start = "CONNECT " + origin.hostname + ":" + port + " HTTP/1.1";
+ var headers = [start, this._headers.toString(), ""];
+ this.emit("data", Buffer2.from(headers.join("\r\n"), "utf8"));
+ return true;
+ },
+ pause: function() {
+ this._paused = true;
+ },
+ resume: function() {
+ this._paused = false;
+ this.emit("drain");
+ },
+ write: function(chunk) {
+ if (!this.writable) return false;
+ this._http.parse(chunk);
+ if (!this._http.isComplete()) return !this._paused;
+ this.statusCode = this._http.statusCode;
+ this.headers = this._http.headers;
+ if (this.statusCode === 200) {
+ this.emit("connect", new Base.ConnectEvent());
+ } else {
+ var message = "Can't establish a connection to the server at " + this._origin.href;
+ this.emit("error", new Error(message));
+ }
+ this.end();
+ return !this._paused;
+ },
+ end: function(chunk) {
+ if (!this.writable) return;
+ if (chunk !== void 0) this.write(chunk);
+ this.readable = this.writable = false;
+ this.emit("close");
+ this.emit("end");
+ },
+ destroy: function() {
+ this.end();
+ }
+ };
+ for (var key in instance)
+ Proxy.prototype[key] = instance[key];
+ module2.exports = Proxy;
+ },
+ /***/
+ 983(module2, __unused_webpack_exports, __webpack_require__2) {
+ var util = __webpack_require__2(23), HttpParser = __webpack_require__2(565), Base = __webpack_require__2(369), Draft75 = __webpack_require__2(61), Draft76 = __webpack_require__2(476), Hybi = __webpack_require__2(518);
+ var Server = function(options) {
+ Base.call(this, null, null, options);
+ this._http = new HttpParser("request");
+ };
+ util.inherits(Server, Base);
+ var instance = {
+ EVENTS: ["open", "message", "error", "close", "ping", "pong"],
+ _bindEventListeners: function() {
+ this.messages.on("error", function() {
+ });
+ this.on("error", function() {
+ });
+ },
+ parse: function(chunk) {
+ if (this._delegate) return this._delegate.parse(chunk);
+ this._http.parse(chunk);
+ if (!this._http.isComplete()) return;
+ this.method = this._http.method;
+ this.url = this._http.url;
+ this.headers = this._http.headers;
+ this.body = this._http.body;
+ var self2 = this;
+ this._delegate = Server.http(this, this._options);
+ this._delegate.messages = this.messages;
+ this._delegate.io = this.io;
+ this._open();
+ this.EVENTS.forEach(function(event) {
+ this._delegate.on(event, function(e) {
+ self2.emit(event, e);
+ });
+ }, this);
+ this.protocol = this._delegate.protocol;
+ this.version = this._delegate.version;
+ this.parse(this._http.body);
+ this.emit("connect", new Base.ConnectEvent());
+ },
+ _open: function() {
+ this.__queue.forEach(function(msg) {
+ this._delegate[msg[0]].apply(this._delegate, msg[1]);
+ }, this);
+ this.__queue = [];
+ }
+ };
+ ["addExtension", "setHeader", "start", "frame", "text", "binary", "ping", "close"].forEach(function(method) {
+ instance[method] = function() {
+ if (this._delegate) {
+ return this._delegate[method].apply(this._delegate, arguments);
+ } else {
+ this.__queue.push([method, arguments]);
+ return true;
+ }
+ };
+ });
+ for (var key in instance)
+ Server.prototype[key] = instance[key];
+ Server.isSecureRequest = function(request) {
+ if (request.connection && request.connection.authorized !== void 0) return true;
+ if (request.socket && request.socket.secure) return true;
+ var headers = request.headers;
+ if (!headers) return false;
+ if (headers["https"] === "on") return true;
+ if (headers["x-forwarded-ssl"] === "on") return true;
+ if (headers["x-forwarded-scheme"] === "https") return true;
+ if (headers["x-forwarded-proto"] === "https") return true;
+ return false;
+ };
+ Server.determineUrl = function(request) {
+ var scheme = this.isSecureRequest(request) ? "wss:" : "ws:";
+ return scheme + "//" + request.headers.host + request.url;
+ };
+ Server.http = function(request, options) {
+ options = options || {};
+ if (options.requireMasking === void 0) options.requireMasking = true;
+ var headers = request.headers, version = headers["sec-websocket-version"], key2 = headers["sec-websocket-key"], key1 = headers["sec-websocket-key1"], key22 = headers["sec-websocket-key2"], url = this.determineUrl(request);
+ if (version || key2)
+ return new Hybi(request, url, options);
+ else if (key1 || key22)
+ return new Draft76(request, url, options);
+ else
+ return new Draft75(request, url, options);
+ };
+ module2.exports = Server;
+ },
+ /***/
+ 212(module2, __unused_webpack_exports, __webpack_require__2) {
+ var Buffer2 = __webpack_require__2(891).Buffer;
+ var StreamReader = function() {
+ this._queue = [];
+ this._queueSize = 0;
+ this._offset = 0;
+ };
+ StreamReader.prototype.put = function(buffer) {
+ if (!buffer || buffer.length === 0) return;
+ if (!Buffer2.isBuffer(buffer)) buffer = Buffer2.from(buffer);
+ this._queue.push(buffer);
+ this._queueSize += buffer.length;
+ };
+ StreamReader.prototype.read = function(length) {
+ if (length > this._queueSize) return null;
+ if (length === 0) return Buffer2.alloc(0);
+ this._queueSize -= length;
+ var queue = this._queue, remain = length, first = queue[0], buffers, buffer;
+ if (first.length >= length) {
+ if (first.length === length) {
+ return queue.shift();
+ } else {
+ buffer = first.slice(0, length);
+ queue[0] = first.slice(length);
+ return buffer;
+ }
+ }
+ for (var i = 0, n = queue.length; i < n; i++) {
+ if (remain < queue[i].length) break;
+ remain -= queue[i].length;
+ }
+ buffers = queue.splice(0, i);
+ if (remain > 0 && queue.length > 0) {
+ buffers.push(queue[0].slice(0, remain));
+ queue[0] = queue[0].slice(remain);
+ }
+ return Buffer2.concat(buffers, length);
+ };
+ StreamReader.prototype.eachByte = function(callback, context) {
+ var buffer, n, index;
+ while (this._queue.length > 0) {
+ buffer = this._queue[0];
+ n = buffer.length;
+ while (this._offset < n) {
+ index = this._offset;
+ this._offset += 1;
+ callback.call(context, buffer[index]);
+ }
+ this._offset = 0;
+ this._queue.shift();
+ }
+ };
+ module2.exports = StreamReader;
+ },
+ /***/
+ 565(module2, __unused_webpack_exports, __webpack_require__2) {
+ var NodeHTTPParser = __webpack_require__2(895).e, Buffer2 = __webpack_require__2(891).Buffer;
+ var TYPES = {
+ request: NodeHTTPParser.REQUEST || "request",
+ response: NodeHTTPParser.RESPONSE || "response"
+ };
+ var HttpParser = function(type) {
+ this._type = type;
+ this._parser = new NodeHTTPParser(TYPES[type]);
+ this._complete = false;
+ this.headers = {};
+ var current = null, self2 = this;
+ this._parser.onHeaderField = function(b2, start, length) {
+ current = b2.toString("utf8", start, start + length).toLowerCase();
+ };
+ this._parser.onHeaderValue = function(b2, start, length) {
+ var value = b2.toString("utf8", start, start + length);
+ if (self2.headers.hasOwnProperty(current))
+ self2.headers[current] += ", " + value;
+ else
+ self2.headers[current] = value;
+ };
+ this._parser.onHeadersComplete = this._parser[NodeHTTPParser.kOnHeadersComplete] = function(majorVersion, minorVersion, headers, method, pathname, statusCode) {
+ var info = arguments[0];
+ if (typeof info === "object") {
+ method = info.method;
+ pathname = info.url;
+ statusCode = info.statusCode;
+ headers = info.headers;
+ }
+ self2.method = typeof method === "number" ? HttpParser.METHODS[method] : method;
+ self2.statusCode = statusCode;
+ self2.url = pathname;
+ if (!headers) return;
+ for (var i = 0, n = headers.length, key, value; i < n; i += 2) {
+ key = headers[i].toLowerCase();
+ value = headers[i + 1];
+ if (self2.headers.hasOwnProperty(key))
+ self2.headers[key] += ", " + value;
+ else
+ self2.headers[key] = value;
+ }
+ self2._complete = true;
+ };
+ };
+ HttpParser.METHODS = {
+ 0: "DELETE",
+ 1: "GET",
+ 2: "HEAD",
+ 3: "POST",
+ 4: "PUT",
+ 5: "CONNECT",
+ 6: "OPTIONS",
+ 7: "TRACE",
+ 8: "COPY",
+ 9: "LOCK",
+ 10: "MKCOL",
+ 11: "MOVE",
+ 12: "PROPFIND",
+ 13: "PROPPATCH",
+ 14: "SEARCH",
+ 15: "UNLOCK",
+ 16: "BIND",
+ 17: "REBIND",
+ 18: "UNBIND",
+ 19: "ACL",
+ 20: "REPORT",
+ 21: "MKACTIVITY",
+ 22: "CHECKOUT",
+ 23: "MERGE",
+ 24: "M-SEARCH",
+ 25: "NOTIFY",
+ 26: "SUBSCRIBE",
+ 27: "UNSUBSCRIBE",
+ 28: "PATCH",
+ 29: "PURGE",
+ 30: "MKCALENDAR",
+ 31: "LINK",
+ 32: "UNLINK"
+ };
+ var VERSION = process.version ? process.version.match(/[0-9]+/g).map(function(n) {
+ return parseInt(n, 10);
+ }) : [];
+ if (VERSION[0] === 0 && VERSION[1] === 12) {
+ HttpParser.METHODS[16] = "REPORT";
+ HttpParser.METHODS[17] = "MKACTIVITY";
+ HttpParser.METHODS[18] = "CHECKOUT";
+ HttpParser.METHODS[19] = "MERGE";
+ HttpParser.METHODS[20] = "M-SEARCH";
+ HttpParser.METHODS[21] = "NOTIFY";
+ HttpParser.METHODS[22] = "SUBSCRIBE";
+ HttpParser.METHODS[23] = "UNSUBSCRIBE";
+ HttpParser.METHODS[24] = "PATCH";
+ HttpParser.METHODS[25] = "PURGE";
+ }
+ HttpParser.prototype.isComplete = function() {
+ return this._complete;
+ };
+ HttpParser.prototype.parse = function(chunk) {
+ var consumed = this._parser.execute(chunk, 0, chunk.length);
+ if (typeof consumed !== "number") {
+ this.error = consumed;
+ this._complete = true;
+ return;
+ }
+ if (this._complete)
+ this.body = consumed < chunk.length ? chunk.slice(consumed) : Buffer2.alloc(0);
+ };
+ module2.exports = HttpParser;
+ },
+ /***/
+ 578(__unused_webpack_module, exports$1, __webpack_require__2) {
+ var Stream = __webpack_require__2(203).Stream, util = __webpack_require__2(23);
+ var IO = function(driver) {
+ this.readable = this.writable = true;
+ this._paused = false;
+ this._driver = driver;
+ };
+ util.inherits(IO, Stream);
+ IO.prototype.pause = function() {
+ this._paused = true;
+ this._driver.messages._paused = true;
+ };
+ IO.prototype.resume = function() {
+ this._paused = false;
+ this.emit("drain");
+ var messages = this._driver.messages;
+ messages._paused = false;
+ messages.emit("drain");
+ };
+ IO.prototype.write = function(chunk) {
+ if (!this.writable) return false;
+ this._driver.parse(chunk);
+ return !this._paused;
+ };
+ IO.prototype.end = function(chunk) {
+ if (!this.writable) return;
+ if (chunk !== void 0) this.write(chunk);
+ this.writable = false;
+ var messages = this._driver.messages;
+ if (messages.readable) {
+ messages.readable = messages.writable = false;
+ messages.emit("end");
+ }
+ };
+ IO.prototype.destroy = function() {
+ this.end();
+ };
+ var Messages = function(driver) {
+ this.readable = this.writable = true;
+ this._paused = false;
+ this._driver = driver;
+ };
+ util.inherits(Messages, Stream);
+ Messages.prototype.pause = function() {
+ this._driver.io._paused = true;
+ };
+ Messages.prototype.resume = function() {
+ this._driver.io._paused = false;
+ this._driver.io.emit("drain");
+ };
+ Messages.prototype.write = function(message) {
+ if (!this.writable) return false;
+ if (typeof message === "string") this._driver.text(message);
+ else this._driver.binary(message);
+ return !this._paused;
+ };
+ Messages.prototype.end = function(message) {
+ if (message !== void 0) this.write(message);
+ };
+ Messages.prototype.destroy = function() {
+ };
+ exports$1.IO = IO;
+ exports$1.Messages = Messages;
+ },
+ /***/
+ 80(module2) {
+ var TOKEN = /([!#\$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+)/, NOTOKEN = /([^!#\$%&'\*\+\-\.\^_`\|~0-9A-Za-z])/g, QUOTED = /"((?:\\[\x00-\x7f]|[^\x00-\x08\x0a-\x1f\x7f"\\])*)"/, PARAM = new RegExp(TOKEN.source + "(?:=(?:" + TOKEN.source + "|" + QUOTED.source + "))?"), EXT = new RegExp(TOKEN.source + "(?: *; *" + PARAM.source + ")*", "g"), EXT_LIST = new RegExp("^" + EXT.source + "(?: *, *" + EXT.source + ")*$"), NUMBER = /^-?(0|[1-9][0-9]*)(\.[0-9]+)?$/;
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
+ var Parser = {
+ parseHeader: function(header) {
+ var offers = new Offers();
+ if (header === "" || header === void 0) return offers;
+ if (!EXT_LIST.test(header))
+ throw new SyntaxError("Invalid Sec-WebSocket-Extensions header: " + header);
+ var values = header.match(EXT);
+ values.forEach(function(value) {
+ var params = value.match(new RegExp(PARAM.source, "g")), name = params.shift(), offer = {};
+ params.forEach(function(param) {
+ var args = param.match(PARAM), key = args[1], data;
+ if (args[2] !== void 0) {
+ data = args[2];
+ } else if (args[3] !== void 0) {
+ data = args[3].replace(/\\/g, "");
+ } else {
+ data = true;
+ }
+ if (NUMBER.test(data)) data = parseFloat(data);
+ if (hasOwnProperty.call(offer, key)) {
+ offer[key] = [].concat(offer[key]);
+ offer[key].push(data);
+ } else {
+ offer[key] = data;
+ }
+ }, this);
+ offers.push(name, offer);
+ }, this);
+ return offers;
+ },
+ serializeParams: function(name, params) {
+ var values = [];
+ var print = function(key2, value) {
+ if (value instanceof Array) {
+ value.forEach(function(v2) {
+ print(key2, v2);
+ });
+ } else if (value === true) {
+ values.push(key2);
+ } else if (typeof value === "number") {
+ values.push(key2 + "=" + value);
+ } else if (NOTOKEN.test(value)) {
+ values.push(key2 + '="' + value.replace(/"/g, '\\"') + '"');
+ } else {
+ values.push(key2 + "=" + value);
+ }
+ };
+ for (var key in params) print(key, params[key]);
+ return [name].concat(values).join("; ");
+ }
+ };
+ var Offers = function() {
+ this._byName = {};
+ this._inOrder = [];
+ };
+ Offers.prototype.push = function(name, params) {
+ if (!hasOwnProperty.call(this._byName, name))
+ this._byName[name] = [];
+ this._byName[name].push(params);
+ this._inOrder.push({ name, params });
+ };
+ Offers.prototype.eachOffer = function(callback, context) {
+ var list = this._inOrder;
+ for (var i = 0, n = list.length; i < n; i++)
+ callback.call(context, list[i].name, list[i].params);
+ };
+ Offers.prototype.byName = function(name) {
+ return this._byName[name] || [];
+ };
+ Offers.prototype.toArray = function() {
+ return this._inOrder.slice();
+ };
+ module2.exports = Parser;
+ },
+ /***/
+ 152(module2, __unused_webpack_exports, __webpack_require__2) {
+ var Functor = __webpack_require__2(277), Pledge = __webpack_require__2(521);
+ var Cell = function(tuple) {
+ this._ext = tuple[0];
+ this._session = tuple[1];
+ this._functors = {
+ incoming: new Functor(this._session, "processIncomingMessage"),
+ outgoing: new Functor(this._session, "processOutgoingMessage")
+ };
+ };
+ Cell.prototype.pending = function(direction) {
+ var functor = this._functors[direction];
+ if (!functor._stopped) functor.pending += 1;
+ };
+ Cell.prototype.incoming = function(error, message, callback, context) {
+ this._exec("incoming", error, message, callback, context);
+ };
+ Cell.prototype.outgoing = function(error, message, callback, context) {
+ this._exec("outgoing", error, message, callback, context);
+ };
+ Cell.prototype.close = function() {
+ this._closed = this._closed || new Pledge();
+ this._doClose();
+ return this._closed;
+ };
+ Cell.prototype._exec = function(direction, error, message, callback, context) {
+ this._functors[direction].call(error, message, function(err, msg) {
+ if (err) err.message = this._ext.name + ": " + err.message;
+ callback.call(context, err, msg);
+ this._doClose();
+ }, this);
+ };
+ Cell.prototype._doClose = function() {
+ var fin = this._functors.incoming, fout = this._functors.outgoing;
+ if (!this._closed || fin.pending + fout.pending !== 0) return;
+ if (this._session) this._session.close();
+ this._session = null;
+ this._closed.done();
+ };
+ module2.exports = Cell;
+ },
+ /***/
+ 277(module2, __unused_webpack_exports, __webpack_require__2) {
+ var RingBuffer = __webpack_require__2(411);
+ var Functor = function(session, method) {
+ this._session = session;
+ this._method = method;
+ this._queue = new RingBuffer(Functor.QUEUE_SIZE);
+ this._stopped = false;
+ this.pending = 0;
+ };
+ Functor.QUEUE_SIZE = 8;
+ Functor.prototype.call = function(error, message, callback, context) {
+ if (this._stopped) return;
+ var record = { error, message, callback, context, done: false }, called = false, self2 = this;
+ this._queue.push(record);
+ if (record.error) {
+ record.done = true;
+ this._stop();
+ return this._flushQueue();
+ }
+ var handler = function(err, msg) {
+ if (!(called ^ (called = true))) return;
+ if (err) {
+ self2._stop();
+ record.error = err;
+ record.message = null;
+ } else {
+ record.message = msg;
+ }
+ record.done = true;
+ self2._flushQueue();
+ };
+ try {
+ this._session[this._method](message, handler);
+ } catch (err) {
+ handler(err);
+ }
+ };
+ Functor.prototype._stop = function() {
+ this.pending = this._queue.length;
+ this._stopped = true;
+ };
+ Functor.prototype._flushQueue = function() {
+ var queue = this._queue, record;
+ while (queue.length > 0 && queue.peek().done) {
+ record = queue.shift();
+ if (record.error) {
+ this.pending = 0;
+ queue.clear();
+ } else {
+ this.pending -= 1;
+ }
+ record.callback.call(record.context, record.error, record.message);
+ }
+ };
+ module2.exports = Functor;
+ },
+ /***/
+ 862(module2, __unused_webpack_exports, __webpack_require__2) {
+ var Cell = __webpack_require__2(152), Pledge = __webpack_require__2(521);
+ var Pipeline = function(sessions) {
+ this._cells = sessions.map(function(session) {
+ return new Cell(session);
+ });
+ this._stopped = { incoming: false, outgoing: false };
+ };
+ Pipeline.prototype.processIncomingMessage = function(message, callback, context) {
+ if (this._stopped.incoming) return;
+ this._loop("incoming", this._cells.length - 1, -1, -1, message, callback, context);
+ };
+ Pipeline.prototype.processOutgoingMessage = function(message, callback, context) {
+ if (this._stopped.outgoing) return;
+ this._loop("outgoing", 0, this._cells.length, 1, message, callback, context);
+ };
+ Pipeline.prototype.close = function(callback, context) {
+ this._stopped = { incoming: true, outgoing: true };
+ var closed = this._cells.map(function(a) {
+ return a.close();
+ });
+ if (callback)
+ Pledge.all(closed).then(function() {
+ callback.call(context);
+ });
+ };
+ Pipeline.prototype._loop = function(direction, start, end, step, message, callback, context) {
+ var cells = this._cells, n = cells.length, self2 = this;
+ while (n--) cells[n].pending(direction);
+ var pipe = function(index, error, msg) {
+ if (index === end) return callback.call(context, error, msg);
+ cells[index][direction](error, msg, function(err, m2) {
+ if (err) self2._stopped[direction] = true;
+ pipe(index + step, err, m2);
+ });
+ };
+ pipe(start, null, message);
+ };
+ module2.exports = Pipeline;
+ },
+ /***/
+ 521(module2, __unused_webpack_exports, __webpack_require__2) {
+ var RingBuffer = __webpack_require__2(411);
+ var Pledge = function() {
+ this._complete = false;
+ this._callbacks = new RingBuffer(Pledge.QUEUE_SIZE);
+ };
+ Pledge.QUEUE_SIZE = 4;
+ Pledge.all = function(list) {
+ var pledge = new Pledge(), pending = list.length, n = pending;
+ if (pending === 0) pledge.done();
+ while (n--) list[n].then(function() {
+ pending -= 1;
+ if (pending === 0) pledge.done();
+ });
+ return pledge;
+ };
+ Pledge.prototype.then = function(callback) {
+ if (this._complete) callback();
+ else this._callbacks.push(callback);
+ };
+ Pledge.prototype.done = function() {
+ this._complete = true;
+ var callbacks = this._callbacks, callback;
+ while (callback = callbacks.shift()) callback();
+ };
+ module2.exports = Pledge;
+ },
+ /***/
+ 411(module2) {
+ var RingBuffer = function(bufferSize) {
+ this._bufferSize = bufferSize;
+ this.clear();
+ };
+ RingBuffer.prototype.clear = function() {
+ this._buffer = new Array(this._bufferSize);
+ this._ringOffset = 0;
+ this._ringSize = this._bufferSize;
+ this._head = 0;
+ this._tail = 0;
+ this.length = 0;
+ };
+ RingBuffer.prototype.push = function(value) {
+ var expandBuffer = false, expandRing = false;
+ if (this._ringSize < this._bufferSize) {
+ expandBuffer = this._tail === 0;
+ } else if (this._ringOffset === this._ringSize) {
+ expandBuffer = true;
+ expandRing = this._tail === 0;
+ }
+ if (expandBuffer) {
+ this._tail = this._bufferSize;
+ this._buffer = this._buffer.concat(new Array(this._bufferSize));
+ this._bufferSize = this._buffer.length;
+ if (expandRing)
+ this._ringSize = this._bufferSize;
+ }
+ this._buffer[this._tail] = value;
+ this.length += 1;
+ if (this._tail < this._ringSize) this._ringOffset += 1;
+ this._tail = (this._tail + 1) % this._bufferSize;
+ };
+ RingBuffer.prototype.peek = function() {
+ if (this.length === 0) return void 0;
+ return this._buffer[this._head];
+ };
+ RingBuffer.prototype.shift = function() {
+ if (this.length === 0) return void 0;
+ var value = this._buffer[this._head];
+ this._buffer[this._head] = void 0;
+ this.length -= 1;
+ this._ringOffset -= 1;
+ if (this._ringOffset === 0 && this.length > 0) {
+ this._head = this._ringSize;
+ this._ringOffset = this.length;
+ this._ringSize = this._bufferSize;
+ } else {
+ this._head = (this._head + 1) % this._ringSize;
+ }
+ return value;
+ };
+ module2.exports = RingBuffer;
+ },
+ /***/
+ 769(module2, __unused_webpack_exports, __webpack_require__2) {
+ var Parser = __webpack_require__2(80), Pipeline = __webpack_require__2(862);
+ var Extensions = function() {
+ this._rsv1 = this._rsv2 = this._rsv3 = null;
+ this._byName = {};
+ this._inOrder = [];
+ this._sessions = [];
+ this._index = {};
+ };
+ Extensions.MESSAGE_OPCODES = [1, 2];
+ var instance = {
+ add: function(ext) {
+ if (typeof ext.name !== "string") throw new TypeError("extension.name must be a string");
+ if (ext.type !== "permessage") throw new TypeError('extension.type must be "permessage"');
+ if (typeof ext.rsv1 !== "boolean") throw new TypeError("extension.rsv1 must be true or false");
+ if (typeof ext.rsv2 !== "boolean") throw new TypeError("extension.rsv2 must be true or false");
+ if (typeof ext.rsv3 !== "boolean") throw new TypeError("extension.rsv3 must be true or false");
+ if (this._byName.hasOwnProperty(ext.name))
+ throw new TypeError('An extension with name "' + ext.name + '" is already registered');
+ this._byName[ext.name] = ext;
+ this._inOrder.push(ext);
+ },
+ generateOffer: function() {
+ var sessions = [], offer = [], index = {};
+ this._inOrder.forEach(function(ext) {
+ var session = ext.createClientSession();
+ if (!session) return;
+ var record = [ext, session];
+ sessions.push(record);
+ index[ext.name] = record;
+ var offers = session.generateOffer();
+ offers = offers ? [].concat(offers) : [];
+ offers.forEach(function(off) {
+ offer.push(Parser.serializeParams(ext.name, off));
+ }, this);
+ }, this);
+ this._sessions = sessions;
+ this._index = index;
+ return offer.length > 0 ? offer.join(", ") : null;
+ },
+ activate: function(header) {
+ var responses = Parser.parseHeader(header), sessions = [];
+ responses.eachOffer(function(name, params) {
+ var record = this._index[name];
+ if (!record)
+ throw new Error('Server sent an extension response for unknown extension "' + name + '"');
+ var ext = record[0], session = record[1], reserved = this._reserved(ext);
+ if (reserved)
+ throw new Error("Server sent two extension responses that use the RSV" + reserved[0] + ' bit: "' + reserved[1] + '" and "' + ext.name + '"');
+ if (session.activate(params) !== true)
+ throw new Error("Server sent unacceptable extension parameters: " + Parser.serializeParams(name, params));
+ this._reserve(ext);
+ sessions.push(record);
+ }, this);
+ this._sessions = sessions;
+ this._pipeline = new Pipeline(sessions);
+ },
+ generateResponse: function(header) {
+ var sessions = [], response = [], offers = Parser.parseHeader(header);
+ this._inOrder.forEach(function(ext) {
+ var offer = offers.byName(ext.name);
+ if (offer.length === 0 || this._reserved(ext)) return;
+ var session = ext.createServerSession(offer);
+ if (!session) return;
+ this._reserve(ext);
+ sessions.push([ext, session]);
+ response.push(Parser.serializeParams(ext.name, session.generateResponse()));
+ }, this);
+ this._sessions = sessions;
+ this._pipeline = new Pipeline(sessions);
+ return response.length > 0 ? response.join(", ") : null;
+ },
+ validFrameRsv: function(frame) {
+ var allowed = { rsv1: false, rsv2: false, rsv3: false }, ext;
+ if (Extensions.MESSAGE_OPCODES.indexOf(frame.opcode) >= 0) {
+ for (var i = 0, n = this._sessions.length; i < n; i++) {
+ ext = this._sessions[i][0];
+ allowed.rsv1 = allowed.rsv1 || ext.rsv1;
+ allowed.rsv2 = allowed.rsv2 || ext.rsv2;
+ allowed.rsv3 = allowed.rsv3 || ext.rsv3;
+ }
+ }
+ return (allowed.rsv1 || !frame.rsv1) && (allowed.rsv2 || !frame.rsv2) && (allowed.rsv3 || !frame.rsv3);
+ },
+ processIncomingMessage: function(message, callback, context) {
+ this._pipeline.processIncomingMessage(message, callback, context);
+ },
+ processOutgoingMessage: function(message, callback, context) {
+ this._pipeline.processOutgoingMessage(message, callback, context);
+ },
+ close: function(callback, context) {
+ if (!this._pipeline) return callback.call(context);
+ this._pipeline.close(callback, context);
+ },
+ _reserve: function(ext) {
+ this._rsv1 = this._rsv1 || ext.rsv1 && ext.name;
+ this._rsv2 = this._rsv2 || ext.rsv2 && ext.name;
+ this._rsv3 = this._rsv3 || ext.rsv3 && ext.name;
+ },
+ _reserved: function(ext) {
+ if (this._rsv1 && ext.rsv1) return [1, this._rsv1];
+ if (this._rsv2 && ext.rsv2) return [2, this._rsv2];
+ if (this._rsv3 && ext.rsv3) return [3, this._rsv3];
+ return false;
+ }
+ };
+ for (var key in instance)
+ Extensions.prototype[key] = instance[key];
+ module2.exports = Extensions;
+ },
+ /***/
+ 407(__unused_webpack_module, exports$1, __webpack_require__2) {
+ var Url = __webpack_require__2(16);
+ var spawn = __webpack_require__2(317).spawn;
+ var fs = __webpack_require__2(896);
+ exports$1.z = function() {
+ var self2 = this;
+ var http = __webpack_require__2(611);
+ var https = __webpack_require__2(692);
+ var request;
+ var response;
+ var settings = {};
+ var disableHeaderCheck = false;
+ var defaultHeaders = {
+ "User-Agent": "node-XMLHttpRequest",
+ "Accept": "*/*"
+ };
+ var headers = {};
+ var headersCase = {};
+ var forbiddenRequestHeaders = [
+ "accept-charset",
+ "accept-encoding",
+ "access-control-request-headers",
+ "access-control-request-method",
+ "connection",
+ "content-length",
+ "content-transfer-encoding",
+ "cookie",
+ "cookie2",
+ "date",
+ "expect",
+ "host",
+ "keep-alive",
+ "origin",
+ "referer",
+ "te",
+ "trailer",
+ "transfer-encoding",
+ "upgrade",
+ "via"
+ ];
+ var forbiddenRequestMethods = [
+ "TRACE",
+ "TRACK",
+ "CONNECT"
+ ];
+ var sendFlag = false;
+ var errorFlag = false;
+ var listeners = {};
+ this.UNSENT = 0;
+ this.OPENED = 1;
+ this.HEADERS_RECEIVED = 2;
+ this.LOADING = 3;
+ this.DONE = 4;
+ this.readyState = this.UNSENT;
+ this.onreadystatechange = null;
+ this.responseText = "";
+ this.responseXML = "";
+ this.status = null;
+ this.statusText = null;
+ this.withCredentials = false;
+ var isAllowedHttpHeader = function(header) {
+ return disableHeaderCheck || header && forbiddenRequestHeaders.indexOf(header.toLowerCase()) === -1;
+ };
+ var isAllowedHttpMethod = function(method) {
+ return method && forbiddenRequestMethods.indexOf(method) === -1;
+ };
+ this.open = function(method, url, async, user, password) {
+ this.abort();
+ errorFlag = false;
+ if (!isAllowedHttpMethod(method)) {
+ throw new Error("SecurityError: Request method not allowed");
+ }
+ settings = {
+ "method": method,
+ "url": url.toString(),
+ "async": typeof async !== "boolean" ? true : async,
+ "user": user || null,
+ "password": password || null
+ };
+ setState(this.OPENED);
+ };
+ this.setDisableHeaderCheck = function(state) {
+ disableHeaderCheck = state;
+ };
+ this.setRequestHeader = function(header, value) {
+ if (this.readyState !== this.OPENED) {
+ throw new Error("INVALID_STATE_ERR: setRequestHeader can only be called when state is OPEN");
+ }
+ if (!isAllowedHttpHeader(header)) {
+ console.warn('Refused to set unsafe header "' + header + '"');
+ return;
+ }
+ if (sendFlag) {
+ throw new Error("INVALID_STATE_ERR: send flag is true");
+ }
+ header = headersCase[header.toLowerCase()] || header;
+ headersCase[header.toLowerCase()] = header;
+ headers[header] = headers[header] ? headers[header] + ", " + value : value;
+ };
+ this.getResponseHeader = function(header) {
+ if (typeof header === "string" && this.readyState > this.OPENED && response && response.headers && response.headers[header.toLowerCase()] && !errorFlag) {
+ return response.headers[header.toLowerCase()];
+ }
+ return null;
+ };
+ this.getAllResponseHeaders = function() {
+ if (this.readyState < this.HEADERS_RECEIVED || errorFlag) {
+ return "";
+ }
+ var result = "";
+ for (var i in response.headers) {
+ if (i !== "set-cookie" && i !== "set-cookie2") {
+ result += i + ": " + response.headers[i] + "\r\n";
+ }
+ }
+ return result.substr(0, result.length - 2);
+ };
+ this.getRequestHeader = function(name) {
+ if (typeof name === "string" && headersCase[name.toLowerCase()]) {
+ return headers[headersCase[name.toLowerCase()]];
+ }
+ return "";
+ };
+ this.send = function(data) {
+ if (this.readyState !== this.OPENED) {
+ throw new Error("INVALID_STATE_ERR: connection must be opened before send() is called");
+ }
+ if (sendFlag) {
+ throw new Error("INVALID_STATE_ERR: send has already been called");
+ }
+ var ssl = false, local = false;
+ var url = Url.parse(settings.url);
+ var host;
+ switch (url.protocol) {
+ case "https:":
+ ssl = true;
+ // SSL & non-SSL both need host, no break here.
+ case "http:":
+ host = url.hostname;
+ break;
+ case "file:":
+ local = true;
+ break;
+ case void 0:
+ case null:
+ case "":
+ host = "localhost";
+ break;
+ default:
+ throw new Error("Protocol not supported.");
+ }
+ if (local) {
+ if (settings.method !== "GET") {
+ throw new Error("XMLHttpRequest: Only GET method is supported");
+ }
+ if (settings.async) {
+ fs.readFile(url.pathname, "utf8", function(error, data2) {
+ if (error) {
+ self2.handleError(error);
+ } else {
+ self2.status = 200;
+ self2.responseText = data2;
+ setState(self2.DONE);
+ }
+ });
+ } else {
+ try {
+ this.responseText = fs.readFileSync(url.pathname, "utf8");
+ this.status = 200;
+ setState(self2.DONE);
+ } catch (e) {
+ this.handleError(e);
+ }
+ }
+ return;
+ }
+ var port = url.port || (ssl ? 443 : 80);
+ var uri = url.pathname + (url.search ? url.search : "");
+ for (var name in defaultHeaders) {
+ if (!headersCase[name.toLowerCase()]) {
+ headers[name] = defaultHeaders[name];
+ }
+ }
+ headers.Host = host;
+ if (!(ssl && port === 443 || port === 80)) {
+ headers.Host += ":" + url.port;
+ }
+ if (settings.user) {
+ if (typeof settings.password === "undefined") {
+ settings.password = "";
+ }
+ var authBuf = new Buffer(settings.user + ":" + settings.password);
+ headers.Authorization = "Basic " + authBuf.toString("base64");
+ }
+ if (settings.method === "GET" || settings.method === "HEAD") {
+ data = null;
+ } else if (data) {
+ headers["Content-Length"] = Buffer.isBuffer(data) ? data.length : Buffer.byteLength(data);
+ if (!headers["Content-Type"]) {
+ headers["Content-Type"] = "text/plain;charset=UTF-8";
+ }
+ } else if (settings.method === "POST") {
+ headers["Content-Length"] = 0;
+ }
+ var options = {
+ host,
+ port,
+ path: uri,
+ method: settings.method,
+ headers,
+ agent: false,
+ withCredentials: self2.withCredentials
+ };
+ errorFlag = false;
+ if (settings.async) {
+ var doRequest = ssl ? https.request : http.request;
+ sendFlag = true;
+ self2.dispatchEvent("readystatechange");
+ var responseHandler = function responseHandler2(resp2) {
+ response = resp2;
+ if (response.statusCode === 301 || response.statusCode === 302 || response.statusCode === 303 || response.statusCode === 307) {
+ settings.url = response.headers.location;
+ var url2 = Url.parse(settings.url);
+ host = url2.hostname;
+ var newOptions = {
+ hostname: url2.hostname,
+ port: url2.port,
+ path: url2.path,
+ method: response.statusCode === 303 ? "GET" : settings.method,
+ headers,
+ withCredentials: self2.withCredentials
+ };
+ request = doRequest(newOptions, responseHandler2).on("error", errorHandler);
+ request.end();
+ return;
+ }
+ response.setEncoding("utf8");
+ setState(self2.HEADERS_RECEIVED);
+ self2.status = response.statusCode;
+ response.on("data", function(chunk) {
+ if (chunk) {
+ self2.responseText += chunk;
+ }
+ if (sendFlag) {
+ setState(self2.LOADING);
+ }
+ });
+ response.on("end", function() {
+ if (sendFlag) {
+ setState(self2.DONE);
+ sendFlag = false;
+ }
+ });
+ response.on("error", function(error) {
+ self2.handleError(error);
+ });
+ };
+ var errorHandler = function errorHandler2(error) {
+ self2.handleError(error);
+ };
+ request = doRequest(options, responseHandler).on("error", errorHandler);
+ if (data) {
+ request.write(data);
+ }
+ request.end();
+ self2.dispatchEvent("loadstart");
+ } else {
+ var contentFile = ".node-xmlhttprequest-content-" + process.pid;
+ var syncFile = ".node-xmlhttprequest-sync-" + process.pid;
+ fs.writeFileSync(syncFile, "", "utf8");
+ var execString = "var http = require('http'), https = require('https'), fs = require('fs');var doRequest = http" + (ssl ? "s" : "") + ".request;var options = " + JSON.stringify(options) + ";var responseText = '';var req = doRequest(options, function(response) {response.setEncoding('utf8');response.on('data', function(chunk) { responseText += chunk;});response.on('end', function() {fs.writeFileSync('" + contentFile + "', JSON.stringify({err: null, data: {statusCode: response.statusCode, headers: response.headers, text: responseText}}), 'utf8');fs.unlinkSync('" + syncFile + "');});response.on('error', function(error) {fs.writeFileSync('" + contentFile + "', JSON.stringify({err: error}), 'utf8');fs.unlinkSync('" + syncFile + "');});}).on('error', function(error) {fs.writeFileSync('" + contentFile + "', JSON.stringify({err: error}), 'utf8');fs.unlinkSync('" + syncFile + "');});" + (data ? "req.write('" + JSON.stringify(data).slice(1, -1).replace(/'/g, "\\'") + "');" : "") + "req.end();";
+ var syncProc = spawn(process.argv[0], ["-e", execString]);
+ while (fs.existsSync(syncFile)) {
+ }
+ var resp = JSON.parse(fs.readFileSync(contentFile, "utf8"));
+ syncProc.stdin.end();
+ fs.unlinkSync(contentFile);
+ if (resp.err) {
+ self2.handleError(resp.err);
+ } else {
+ response = resp.data;
+ self2.status = resp.data.statusCode;
+ self2.responseText = resp.data.text;
+ setState(self2.DONE);
+ }
+ }
+ };
+ this.handleError = function(error) {
+ this.status = 0;
+ this.statusText = error;
+ this.responseText = error.stack;
+ errorFlag = true;
+ setState(this.DONE);
+ this.dispatchEvent("error");
+ };
+ this.abort = function() {
+ if (request) {
+ request.abort();
+ request = null;
+ }
+ headers = defaultHeaders;
+ this.status = 0;
+ this.responseText = "";
+ this.responseXML = "";
+ errorFlag = true;
+ if (this.readyState !== this.UNSENT && (this.readyState !== this.OPENED || sendFlag) && this.readyState !== this.DONE) {
+ sendFlag = false;
+ setState(this.DONE);
+ }
+ this.readyState = this.UNSENT;
+ this.dispatchEvent("abort");
+ };
+ this.addEventListener = function(event, callback) {
+ if (!(event in listeners)) {
+ listeners[event] = [];
+ }
+ listeners[event].push(callback);
+ };
+ this.removeEventListener = function(event, callback) {
+ if (event in listeners) {
+ listeners[event] = listeners[event].filter(function(ev) {
+ return ev !== callback;
+ });
+ }
+ };
+ this.dispatchEvent = function(event) {
+ if (typeof self2["on" + event] === "function") {
+ self2["on" + event]();
+ }
+ if (event in listeners) {
+ for (var i = 0, len = listeners[event].length; i < len; i++) {
+ listeners[event][i].call(self2);
+ }
+ }
+ };
+ var setState = function(state) {
+ if (state == self2.LOADING || self2.readyState !== state) {
+ self2.readyState = state;
+ if (settings.async || self2.readyState < self2.OPENED || self2.readyState === self2.DONE) {
+ self2.dispatchEvent("readystatechange");
+ }
+ if (self2.readyState === self2.DONE && !errorFlag) {
+ self2.dispatchEvent("load");
+ self2.dispatchEvent("loadend");
+ }
+ }
+ };
+ };
+ },
+ /***/
+ 42(module2, __unused_webpack_exports, __webpack_require__2) {
+ module2.exports = __webpack_require__2(368)["default"];
+ },
+ /***/
+ 368(__unused_webpack_module, __webpack_exports__2, __webpack_require__2) {
+ __webpack_require__2.d(__webpack_exports__2, {
+ "default": () => (
+ /* binding */
+ PusherWithEncryption
+ )
+ });
+ function encode(s) {
+ return btoa(utob(s));
+ }
+ var fromCharCode = String.fromCharCode;
+ var b64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ var cb_utob = function(c2) {
+ var cc = c2.charCodeAt(0);
+ return cc < 128 ? c2 : cc < 2048 ? fromCharCode(192 | cc >>> 6) + fromCharCode(128 | cc & 63) : fromCharCode(224 | cc >>> 12 & 15) + fromCharCode(128 | cc >>> 6 & 63) + fromCharCode(128 | cc & 63);
+ };
+ var utob = function(u2) {
+ return u2.replace(/[^\x00-\x7F]/g, cb_utob);
+ };
+ var cb_encode = function(ccc) {
+ var padlen = [0, 2, 1][ccc.length % 3];
+ var ord = ccc.charCodeAt(0) << 16 | (ccc.length > 1 ? ccc.charCodeAt(1) : 0) << 8 | (ccc.length > 2 ? ccc.charCodeAt(2) : 0);
+ var chars = [
+ b64chars.charAt(ord >>> 18),
+ b64chars.charAt(ord >>> 12 & 63),
+ padlen >= 2 ? "=" : b64chars.charAt(ord >>> 6 & 63),
+ padlen >= 1 ? "=" : b64chars.charAt(ord & 63)
+ ];
+ return chars.join("");
+ };
+ var btoa = commonjsGlobal.btoa || function(b2) {
+ return b2.replace(/[\s\S]{1,3}/g, cb_encode);
+ };
+ class Timer {
+ constructor(set, clear, delay, callback) {
+ this.clear = clear;
+ this.timer = set(() => {
+ if (this.timer) {
+ this.timer = callback(this.timer);
+ }
+ }, delay);
+ }
+ isRunning() {
+ return this.timer !== null;
+ }
+ ensureAborted() {
+ if (this.timer) {
+ this.clear(this.timer);
+ this.timer = null;
+ }
+ }
+ }
+ const abstract_timer = Timer;
+ function timers_clearTimeout(timer) {
+ commonjsGlobal.clearTimeout(timer);
+ }
+ function timers_clearInterval(timer) {
+ commonjsGlobal.clearInterval(timer);
+ }
+ class OneOffTimer extends abstract_timer {
+ constructor(delay, callback) {
+ super(setTimeout, timers_clearTimeout, delay, function(timer) {
+ callback();
+ return null;
+ });
+ }
+ }
+ class PeriodicTimer extends abstract_timer {
+ constructor(delay, callback) {
+ super(setInterval, timers_clearInterval, delay, function(timer) {
+ callback();
+ return timer;
+ });
+ }
+ }
+ var Util = {
+ now() {
+ if (Date.now) {
+ return Date.now();
+ } else {
+ return (/* @__PURE__ */ new Date()).valueOf();
+ }
+ },
+ defer(callback) {
+ return new OneOffTimer(0, callback);
+ },
+ method(name, ...args) {
+ var boundArguments = Array.prototype.slice.call(arguments, 1);
+ return function(object) {
+ return object[name].apply(object, boundArguments.concat(arguments));
+ };
+ }
+ };
+ const util = Util;
+ function extend(target, ...sources) {
+ for (var i = 0; i < sources.length; i++) {
+ var extensions = sources[i];
+ for (var property in extensions) {
+ if (extensions[property] && extensions[property].constructor && extensions[property].constructor === Object) {
+ target[property] = extend(target[property] || {}, extensions[property]);
+ } else {
+ target[property] = extensions[property];
+ }
+ }
+ }
+ return target;
+ }
+ function stringify() {
+ var m2 = ["Pusher"];
+ for (var i = 0; i < arguments.length; i++) {
+ if (typeof arguments[i] === "string") {
+ m2.push(arguments[i]);
+ } else {
+ m2.push(safeJSONStringify(arguments[i]));
+ }
+ }
+ return m2.join(" : ");
+ }
+ function arrayIndexOf(array, item) {
+ var nativeIndexOf = Array.prototype.indexOf;
+ if (array === null) {
+ return -1;
+ }
+ if (nativeIndexOf && array.indexOf === nativeIndexOf) {
+ return array.indexOf(item);
+ }
+ for (var i = 0, l2 = array.length; i < l2; i++) {
+ if (array[i] === item) {
+ return i;
+ }
+ }
+ return -1;
+ }
+ function objectApply(object, f2) {
+ for (var key in object) {
+ if (Object.prototype.hasOwnProperty.call(object, key)) {
+ f2(object[key], key, object);
+ }
+ }
+ }
+ function keys(object) {
+ var keys2 = [];
+ objectApply(object, function(_2, key) {
+ keys2.push(key);
+ });
+ return keys2;
+ }
+ function values(object) {
+ var values2 = [];
+ objectApply(object, function(value) {
+ values2.push(value);
+ });
+ return values2;
+ }
+ function apply(array, f2, context) {
+ for (var i = 0; i < array.length; i++) {
+ f2.call(context || commonjsGlobal, array[i], i, array);
+ }
+ }
+ function map(array, f2) {
+ var result = [];
+ for (var i = 0; i < array.length; i++) {
+ result.push(f2(array[i], i, array, result));
+ }
+ return result;
+ }
+ function mapObject(object, f2) {
+ var result = {};
+ objectApply(object, function(value, key) {
+ result[key] = f2(value);
+ });
+ return result;
+ }
+ function filter(array, test) {
+ test = test || function(value) {
+ return !!value;
+ };
+ var result = [];
+ for (var i = 0; i < array.length; i++) {
+ if (test(array[i], i, array, result)) {
+ result.push(array[i]);
+ }
+ }
+ return result;
+ }
+ function filterObject(object, test) {
+ var result = {};
+ objectApply(object, function(value, key) {
+ if (test && test(value, key, object, result) || Boolean(value)) {
+ result[key] = value;
+ }
+ });
+ return result;
+ }
+ function flatten(object) {
+ var result = [];
+ objectApply(object, function(value, key) {
+ result.push([key, value]);
+ });
+ return result;
+ }
+ function any(array, test) {
+ for (var i = 0; i < array.length; i++) {
+ if (test(array[i], i, array)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ function collections_all(array, test) {
+ for (var i = 0; i < array.length; i++) {
+ if (!test(array[i], i, array)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ function encodeParamsObject(data) {
+ return mapObject(data, function(value) {
+ if (typeof value === "object") {
+ value = safeJSONStringify(value);
+ }
+ return encodeURIComponent(encode(value.toString()));
+ });
+ }
+ function buildQueryString(data) {
+ var params = filterObject(data, function(value) {
+ return value !== void 0;
+ });
+ var query = map(flatten(encodeParamsObject(params)), util.method("join", "=")).join("&");
+ return query;
+ }
+ function decycleObject(object) {
+ var objects = [], paths = [];
+ return (function derez(value, path) {
+ var i, name, nu;
+ switch (typeof value) {
+ case "object":
+ if (!value) {
+ return null;
+ }
+ for (i = 0; i < objects.length; i += 1) {
+ if (objects[i] === value) {
+ return { $ref: paths[i] };
+ }
+ }
+ objects.push(value);
+ paths.push(path);
+ if (Object.prototype.toString.apply(value) === "[object Array]") {
+ nu = [];
+ for (i = 0; i < value.length; i += 1) {
+ nu[i] = derez(value[i], path + "[" + i + "]");
+ }
+ } else {
+ nu = {};
+ for (name in value) {
+ if (Object.prototype.hasOwnProperty.call(value, name)) {
+ nu[name] = derez(value[name], path + "[" + JSON.stringify(name) + "]");
+ }
+ }
+ }
+ return nu;
+ case "number":
+ case "string":
+ case "boolean":
+ return value;
+ }
+ })(object, "$");
+ }
+ function safeJSONStringify(source) {
+ try {
+ return JSON.stringify(source);
+ } catch (e) {
+ return JSON.stringify(decycleObject(source));
+ }
+ }
+ var Defaults = {
+ VERSION: "8.5.0",
+ PROTOCOL: 7,
+ wsPort: 80,
+ wssPort: 443,
+ wsPath: "",
+ httpHost: "sockjs.pusher.com",
+ httpPort: 80,
+ httpsPort: 443,
+ httpPath: "/pusher",
+ stats_host: "stats.pusher.com",
+ authEndpoint: "/pusher/auth",
+ authTransport: "ajax",
+ activityTimeout: 12e4,
+ pongTimeout: 3e4,
+ unavailableTimeout: 1e4,
+ userAuthentication: {
+ endpoint: "/pusher/user-auth",
+ transport: "ajax"
+ },
+ channelAuthorization: {
+ endpoint: "/pusher/auth",
+ transport: "ajax"
+ }
+ };
+ const defaults = Defaults;
+ function getGenericURL(baseScheme, params, path) {
+ var scheme = baseScheme + (params.useTLS ? "s" : "");
+ var host = params.useTLS ? params.hostTLS : params.hostNonTLS;
+ return scheme + "://" + host + path;
+ }
+ function getGenericPath(key, queryString) {
+ var path = "/app/" + key;
+ var query = "?protocol=" + defaults.PROTOCOL + "&client=js&version=" + defaults.VERSION + (queryString ? "&" + queryString : "");
+ return path + query;
+ }
+ var ws = {
+ getInitial: function(key, params) {
+ var path = (params.httpPath || "") + getGenericPath(key, "flash=false");
+ return getGenericURL("ws", params, path);
+ }
+ };
+ var http = {
+ getInitial: function(key, params) {
+ var path = (params.httpPath || "/pusher") + getGenericPath(key);
+ return getGenericURL("http", params, path);
+ }
+ };
+ class CallbackRegistry {
+ constructor() {
+ this._callbacks = {};
+ }
+ get(name) {
+ return this._callbacks[prefix(name)];
+ }
+ add(name, callback, context) {
+ var prefixedEventName = prefix(name);
+ this._callbacks[prefixedEventName] = this._callbacks[prefixedEventName] || [];
+ this._callbacks[prefixedEventName].push({
+ fn: callback,
+ context
+ });
+ }
+ remove(name, callback, context) {
+ if (!name && !callback && !context) {
+ this._callbacks = {};
+ return;
+ }
+ var names = name ? [prefix(name)] : keys(this._callbacks);
+ if (callback || context) {
+ this.removeCallback(names, callback, context);
+ } else {
+ this.removeAllCallbacks(names);
+ }
+ }
+ removeCallback(names, callback, context) {
+ apply(names, function(name) {
+ this._callbacks[name] = filter(this._callbacks[name] || [], function(binding) {
+ return callback && callback !== binding.fn || context && context !== binding.context;
+ });
+ if (this._callbacks[name].length === 0) {
+ delete this._callbacks[name];
+ }
+ }, this);
+ }
+ removeAllCallbacks(names) {
+ apply(names, function(name) {
+ delete this._callbacks[name];
+ }, this);
+ }
+ }
+ function prefix(name) {
+ return "_" + name;
+ }
+ class Dispatcher {
+ constructor(failThrough) {
+ this.callbacks = new CallbackRegistry();
+ this.global_callbacks = [];
+ this.failThrough = failThrough;
+ }
+ bind(eventName, callback, context) {
+ this.callbacks.add(eventName, callback, context);
+ return this;
+ }
+ bind_global(callback) {
+ this.global_callbacks.push(callback);
+ return this;
+ }
+ unbind(eventName, callback, context) {
+ this.callbacks.remove(eventName, callback, context);
+ return this;
+ }
+ unbind_global(callback) {
+ if (!callback) {
+ this.global_callbacks = [];
+ return this;
+ }
+ this.global_callbacks = filter(this.global_callbacks || [], (c2) => c2 !== callback);
+ return this;
+ }
+ unbind_all() {
+ this.unbind();
+ this.unbind_global();
+ return this;
+ }
+ emit(eventName, data, metadata) {
+ for (var i = 0; i < this.global_callbacks.length; i++) {
+ this.global_callbacks[i](eventName, data);
+ }
+ var callbacks = this.callbacks.get(eventName);
+ var args = [];
+ if (metadata) {
+ args.push(data, metadata);
+ } else if (data) {
+ args.push(data);
+ }
+ if (callbacks && callbacks.length > 0) {
+ for (var i = 0; i < callbacks.length; i++) {
+ callbacks[i].fn.apply(callbacks[i].context || commonjsGlobal, args);
+ }
+ } else if (this.failThrough) {
+ this.failThrough(eventName, data);
+ }
+ return this;
+ }
+ }
+ class Logger {
+ constructor() {
+ this.globalLog = (message) => {
+ if (commonjsGlobal.console && commonjsGlobal.console.log) {
+ commonjsGlobal.console.log(message);
+ }
+ };
+ }
+ debug(...args) {
+ this.log(this.globalLog, args);
+ }
+ warn(...args) {
+ this.log(this.globalLogWarn, args);
+ }
+ error(...args) {
+ this.log(this.globalLogError, args);
+ }
+ globalLogWarn(message) {
+ if (commonjsGlobal.console && commonjsGlobal.console.warn) {
+ commonjsGlobal.console.warn(message);
+ } else {
+ this.globalLog(message);
+ }
+ }
+ globalLogError(message) {
+ if (commonjsGlobal.console && commonjsGlobal.console.error) {
+ commonjsGlobal.console.error(message);
+ } else {
+ this.globalLogWarn(message);
+ }
+ }
+ log(defaultLoggingFunction, ...args) {
+ var message = stringify.apply(this, arguments);
+ if (pusher2.log) {
+ pusher2.log(message);
+ } else if (pusher2.logToConsole) {
+ const log = defaultLoggingFunction.bind(this);
+ log(message);
+ }
+ }
+ }
+ const logger = new Logger();
+ class TransportConnection extends Dispatcher {
+ constructor(hooks2, name, priority, key, options) {
+ super();
+ this.initialize = node_runtime.transportConnectionInitializer;
+ this.hooks = hooks2;
+ this.name = name;
+ this.priority = priority;
+ this.key = key;
+ this.options = options;
+ this.state = "new";
+ this.timeline = options.timeline;
+ this.activityTimeout = options.activityTimeout;
+ this.id = this.timeline.generateUniqueID();
+ }
+ handlesActivityChecks() {
+ return Boolean(this.hooks.handlesActivityChecks);
+ }
+ supportsPing() {
+ return Boolean(this.hooks.supportsPing);
+ }
+ connect() {
+ if (this.socket || this.state !== "initialized") {
+ return false;
+ }
+ var url = this.hooks.urls.getInitial(this.key, this.options);
+ try {
+ this.socket = this.hooks.getSocket(url, this.options);
+ } catch (e) {
+ util.defer(() => {
+ this.onError(e);
+ this.changeState("closed");
+ });
+ return false;
+ }
+ this.bindListeners();
+ logger.debug("Connecting", { transport: this.name, url });
+ this.changeState("connecting");
+ return true;
+ }
+ close() {
+ if (this.socket) {
+ this.socket.close();
+ return true;
+ } else {
+ return false;
+ }
+ }
+ send(data) {
+ if (this.state === "open") {
+ util.defer(() => {
+ if (this.socket) {
+ this.socket.send(data);
+ }
+ });
+ return true;
+ } else {
+ return false;
+ }
+ }
+ ping() {
+ if (this.state === "open" && this.supportsPing()) {
+ this.socket.ping();
+ }
+ }
+ onOpen() {
+ if (this.hooks.beforeOpen) {
+ this.hooks.beforeOpen(this.socket, this.hooks.urls.getPath(this.key, this.options));
+ }
+ this.changeState("open");
+ this.socket.onopen = void 0;
+ }
+ onError(error) {
+ this.emit("error", { type: "WebSocketError", error });
+ this.timeline.error(this.buildTimelineMessage({ error: error.toString() }));
+ }
+ onClose(closeEvent) {
+ if (closeEvent) {
+ this.changeState("closed", {
+ code: closeEvent.code,
+ reason: closeEvent.reason,
+ wasClean: closeEvent.wasClean
+ });
+ } else {
+ this.changeState("closed");
+ }
+ this.unbindListeners();
+ this.socket = void 0;
+ }
+ onMessage(message) {
+ this.emit("message", message);
+ }
+ onActivity() {
+ this.emit("activity");
+ }
+ bindListeners() {
+ this.socket.onopen = () => {
+ this.onOpen();
+ };
+ this.socket.onerror = (error) => {
+ this.onError(error);
+ };
+ this.socket.onclose = (closeEvent) => {
+ this.onClose(closeEvent);
+ };
+ this.socket.onmessage = (message) => {
+ this.onMessage(message);
+ };
+ if (this.supportsPing()) {
+ this.socket.onactivity = () => {
+ this.onActivity();
+ };
+ }
+ }
+ unbindListeners() {
+ if (this.socket) {
+ this.socket.onopen = void 0;
+ this.socket.onerror = void 0;
+ this.socket.onclose = void 0;
+ this.socket.onmessage = void 0;
+ if (this.supportsPing()) {
+ this.socket.onactivity = void 0;
+ }
+ }
+ }
+ changeState(state2, params) {
+ this.state = state2;
+ this.timeline.info(this.buildTimelineMessage({
+ state: state2,
+ params
+ }));
+ this.emit(state2, params);
+ }
+ buildTimelineMessage(message) {
+ return extend({ cid: this.id }, message);
+ }
+ }
+ class Transport {
+ constructor(hooks2) {
+ this.hooks = hooks2;
+ }
+ isSupported(environment) {
+ return this.hooks.isSupported(environment);
+ }
+ createConnection(name, priority, key, options) {
+ return new TransportConnection(this.hooks, name, priority, key, options);
+ }
+ }
+ var WSTransport = new Transport({
+ urls: ws,
+ handlesActivityChecks: false,
+ supportsPing: false,
+ isInitialized: function() {
+ return Boolean(node_runtime.getWebSocketAPI());
+ },
+ isSupported: function() {
+ return Boolean(node_runtime.getWebSocketAPI());
+ },
+ getSocket: function(url) {
+ return node_runtime.createWebSocket(url);
+ }
+ });
+ var httpConfiguration = {
+ urls: http,
+ handlesActivityChecks: false,
+ supportsPing: true,
+ isInitialized: function() {
+ return true;
+ }
+ };
+ var streamingConfiguration = extend({
+ getSocket: function(url) {
+ return node_runtime.HTTPFactory.createStreamingSocket(url);
+ }
+ }, httpConfiguration);
+ var pollingConfiguration = extend({
+ getSocket: function(url) {
+ return node_runtime.HTTPFactory.createPollingSocket(url);
+ }
+ }, httpConfiguration);
+ var xhrConfiguration = {
+ isSupported: function() {
+ return node_runtime.isXHRSupported();
+ }
+ };
+ var XHRStreamingTransport = new Transport(extend({}, streamingConfiguration, xhrConfiguration));
+ var XHRPollingTransport = new Transport(extend({}, pollingConfiguration, xhrConfiguration));
+ var Transports = {
+ ws: WSTransport,
+ xhr_streaming: XHRStreamingTransport,
+ xhr_polling: XHRPollingTransport
+ };
+ const transports = Transports;
+ class AssistantToTheTransportManager {
+ constructor(manager, transport, options) {
+ this.manager = manager;
+ this.transport = transport;
+ this.minPingDelay = options.minPingDelay;
+ this.maxPingDelay = options.maxPingDelay;
+ this.pingDelay = void 0;
+ }
+ createConnection(name, priority, key, options) {
+ options = extend({}, options, {
+ activityTimeout: this.pingDelay
+ });
+ var connection = this.transport.createConnection(name, priority, key, options);
+ var openTimestamp = null;
+ var onOpen = function() {
+ connection.unbind("open", onOpen);
+ connection.bind("closed", onClosed);
+ openTimestamp = util.now();
+ };
+ var onClosed = (closeEvent) => {
+ connection.unbind("closed", onClosed);
+ if (closeEvent.code === 1002 || closeEvent.code === 1003) {
+ this.manager.reportDeath();
+ } else if (!closeEvent.wasClean && openTimestamp) {
+ var lifespan = util.now() - openTimestamp;
+ if (lifespan < 2 * this.maxPingDelay) {
+ this.manager.reportDeath();
+ this.pingDelay = Math.max(lifespan / 2, this.minPingDelay);
+ }
+ }
+ };
+ connection.bind("open", onOpen);
+ return connection;
+ }
+ isSupported(environment) {
+ return this.manager.isAlive() && this.transport.isSupported(environment);
+ }
+ }
+ const Protocol = {
+ decodeMessage: function(messageEvent) {
+ try {
+ var messageData = JSON.parse(messageEvent.data);
+ var pusherEventData = messageData.data;
+ if (typeof pusherEventData === "string") {
+ try {
+ pusherEventData = JSON.parse(messageData.data);
+ } catch (e) {
+ }
+ }
+ var pusherEvent = {
+ event: messageData.event,
+ channel: messageData.channel,
+ data: pusherEventData
+ };
+ if (messageData.user_id) {
+ pusherEvent.user_id = messageData.user_id;
+ }
+ return pusherEvent;
+ } catch (e) {
+ throw { type: "MessageParseError", error: e, data: messageEvent.data };
+ }
+ },
+ encodeMessage: function(event) {
+ return JSON.stringify(event);
+ },
+ processHandshake: function(messageEvent) {
+ var message = Protocol.decodeMessage(messageEvent);
+ if (message.event === "pusher:connection_established") {
+ if (!message.data.activity_timeout) {
+ throw "No activity timeout specified in handshake";
+ }
+ return {
+ action: "connected",
+ id: message.data.socket_id,
+ activityTimeout: message.data.activity_timeout * 1e3
+ };
+ } else if (message.event === "pusher:error") {
+ return {
+ action: this.getCloseAction(message.data),
+ error: this.getCloseError(message.data)
+ };
+ } else {
+ throw "Invalid handshake";
+ }
+ },
+ getCloseAction: function(closeEvent) {
+ if (closeEvent.code < 4e3) {
+ if (closeEvent.code >= 1002 && closeEvent.code <= 1004) {
+ return "backoff";
+ } else {
+ return null;
+ }
+ } else if (closeEvent.code === 4e3) {
+ return "tls_only";
+ } else if (closeEvent.code < 4100) {
+ return "refused";
+ } else if (closeEvent.code < 4200) {
+ return "backoff";
+ } else if (closeEvent.code < 4300) {
+ return "retry";
+ } else {
+ return "refused";
+ }
+ },
+ getCloseError: function(closeEvent) {
+ if (closeEvent.code !== 1e3 && closeEvent.code !== 1001) {
+ return {
+ type: "PusherError",
+ data: {
+ code: closeEvent.code,
+ message: closeEvent.reason || closeEvent.message
+ }
+ };
+ } else {
+ return null;
+ }
+ }
+ };
+ const protocol = Protocol;
+ class Connection extends Dispatcher {
+ constructor(id, transport) {
+ super();
+ this.id = id;
+ this.transport = transport;
+ this.activityTimeout = transport.activityTimeout;
+ this.bindListeners();
+ }
+ handlesActivityChecks() {
+ return this.transport.handlesActivityChecks();
+ }
+ send(data) {
+ return this.transport.send(data);
+ }
+ send_event(name, data, channel) {
+ var event = { event: name, data };
+ if (channel) {
+ event.channel = channel;
+ }
+ logger.debug("Event sent", event);
+ return this.send(protocol.encodeMessage(event));
+ }
+ ping() {
+ if (this.transport.supportsPing()) {
+ this.transport.ping();
+ } else {
+ this.send_event("pusher:ping", {});
+ }
+ }
+ close() {
+ this.transport.close();
+ }
+ bindListeners() {
+ var listeners = {
+ message: (messageEvent) => {
+ var pusherEvent;
+ try {
+ pusherEvent = protocol.decodeMessage(messageEvent);
+ } catch (e) {
+ this.emit("error", {
+ type: "MessageParseError",
+ error: e,
+ data: messageEvent.data
+ });
+ }
+ if (pusherEvent !== void 0) {
+ logger.debug("Event recd", pusherEvent);
+ switch (pusherEvent.event) {
+ case "pusher:error":
+ this.emit("error", {
+ type: "PusherError",
+ data: pusherEvent.data
+ });
+ break;
+ case "pusher:ping":
+ this.emit("ping");
+ break;
+ case "pusher:pong":
+ this.emit("pong");
+ break;
+ }
+ this.emit("message", pusherEvent);
+ }
+ },
+ activity: () => {
+ this.emit("activity");
+ },
+ error: (error) => {
+ this.emit("error", error);
+ },
+ closed: (closeEvent) => {
+ unbindListeners();
+ if (closeEvent && closeEvent.code) {
+ this.handleCloseEvent(closeEvent);
+ }
+ this.transport = null;
+ this.emit("closed");
+ }
+ };
+ var unbindListeners = () => {
+ objectApply(listeners, (listener, event) => {
+ this.transport.unbind(event, listener);
+ });
+ };
+ objectApply(listeners, (listener, event) => {
+ this.transport.bind(event, listener);
+ });
+ }
+ handleCloseEvent(closeEvent) {
+ var action = protocol.getCloseAction(closeEvent);
+ var error = protocol.getCloseError(closeEvent);
+ if (error) {
+ this.emit("error", error);
+ }
+ if (action) {
+ this.emit(action, { action, error });
+ }
+ }
+ }
+ class Handshake {
+ constructor(transport, callback) {
+ this.transport = transport;
+ this.callback = callback;
+ this.bindListeners();
+ }
+ close() {
+ this.unbindListeners();
+ this.transport.close();
+ }
+ bindListeners() {
+ this.onMessage = (m2) => {
+ this.unbindListeners();
+ var result;
+ try {
+ result = protocol.processHandshake(m2);
+ } catch (e) {
+ this.finish("error", { error: e });
+ this.transport.close();
+ return;
+ }
+ if (result.action === "connected") {
+ this.finish("connected", {
+ connection: new Connection(result.id, this.transport),
+ activityTimeout: result.activityTimeout
+ });
+ } else {
+ this.finish(result.action, { error: result.error });
+ this.transport.close();
+ }
+ };
+ this.onClosed = (closeEvent) => {
+ this.unbindListeners();
+ var action = protocol.getCloseAction(closeEvent) || "backoff";
+ var error = protocol.getCloseError(closeEvent);
+ this.finish(action, { error });
+ };
+ this.transport.bind("message", this.onMessage);
+ this.transport.bind("closed", this.onClosed);
+ }
+ unbindListeners() {
+ this.transport.unbind("message", this.onMessage);
+ this.transport.unbind("closed", this.onClosed);
+ }
+ finish(action, params) {
+ this.callback(extend({ transport: this.transport, action }, params));
+ }
+ }
+ class TimelineSender {
+ constructor(timeline, options) {
+ this.timeline = timeline;
+ this.options = options || {};
+ }
+ send(useTLS, callback) {
+ if (this.timeline.isEmpty()) {
+ return;
+ }
+ this.timeline.send(node_runtime.TimelineTransport.getAgent(this, useTLS), callback);
+ }
+ }
+ class BadEventName extends Error {
+ constructor(msg) {
+ super(msg);
+ Object.setPrototypeOf(this, new.target.prototype);
+ }
+ }
+ class BadChannelName extends Error {
+ constructor(msg) {
+ super(msg);
+ Object.setPrototypeOf(this, new.target.prototype);
+ }
+ }
+ class TransportPriorityTooLow extends Error {
+ constructor(msg) {
+ super(msg);
+ Object.setPrototypeOf(this, new.target.prototype);
+ }
+ }
+ class TransportClosed extends Error {
+ constructor(msg) {
+ super(msg);
+ Object.setPrototypeOf(this, new.target.prototype);
+ }
+ }
+ class UnsupportedFeature extends Error {
+ constructor(msg) {
+ super(msg);
+ Object.setPrototypeOf(this, new.target.prototype);
+ }
+ }
+ class UnsupportedTransport extends Error {
+ constructor(msg) {
+ super(msg);
+ Object.setPrototypeOf(this, new.target.prototype);
+ }
+ }
+ class UnsupportedStrategy extends Error {
+ constructor(msg) {
+ super(msg);
+ Object.setPrototypeOf(this, new.target.prototype);
+ }
+ }
+ class HTTPAuthError extends Error {
+ constructor(status, msg) {
+ super(msg);
+ this.status = status;
+ Object.setPrototypeOf(this, new.target.prototype);
+ }
+ }
+ const urlStore = {
+ baseUrl: "https://pusher.com",
+ urls: {
+ authenticationEndpoint: {
+ path: "/docs/channels/server_api/authenticating_users"
+ },
+ authorizationEndpoint: {
+ path: "/docs/channels/server_api/authorizing-users/"
+ },
+ javascriptQuickStart: {
+ path: "/docs/javascript_quick_start"
+ },
+ triggeringClientEvents: {
+ path: "/docs/client_api_guide/client_events#trigger-events"
+ },
+ encryptedChannelSupport: {
+ fullUrl: "https://github.com/pusher/pusher-js/tree/cc491015371a4bde5743d1c87a0fbac0feb53195#encrypted-channel-support"
+ }
+ }
+ };
+ const buildLogSuffix = function(key) {
+ const urlPrefix = "See:";
+ const urlObj = urlStore.urls[key];
+ if (!urlObj)
+ return "";
+ let url;
+ if (urlObj.fullUrl) {
+ url = urlObj.fullUrl;
+ } else if (urlObj.path) {
+ url = urlStore.baseUrl + urlObj.path;
+ }
+ if (!url)
+ return "";
+ return `${urlPrefix} ${url}`;
+ };
+ const url_store = { buildLogSuffix };
+ class Channel extends Dispatcher {
+ constructor(name, pusher3) {
+ super(function(event, data) {
+ logger.debug("No callbacks on " + name + " for " + event);
+ });
+ this.name = name;
+ this.pusher = pusher3;
+ this.subscribed = false;
+ this.subscriptionPending = false;
+ this.subscriptionCancelled = false;
+ }
+ authorize(socketId, callback) {
+ return callback(null, { auth: "" });
+ }
+ trigger(event, data) {
+ if (event.indexOf("client-") !== 0) {
+ throw new BadEventName("Event '" + event + "' does not start with 'client-'");
+ }
+ if (!this.subscribed) {
+ var suffix = url_store.buildLogSuffix("triggeringClientEvents");
+ logger.warn(`Client event triggered before channel 'subscription_succeeded' event . ${suffix}`);
+ }
+ return this.pusher.send_event(event, data, this.name);
+ }
+ disconnect() {
+ this.subscribed = false;
+ this.subscriptionPending = false;
+ }
+ handleEvent(event) {
+ var eventName = event.event;
+ var data = event.data;
+ if (eventName === "pusher_internal:subscription_succeeded") {
+ this.handleSubscriptionSucceededEvent(event);
+ } else if (eventName === "pusher_internal:subscription_count") {
+ this.handleSubscriptionCountEvent(event);
+ } else if (eventName.indexOf("pusher_internal:") !== 0) {
+ var metadata = {};
+ this.emit(eventName, data, metadata);
+ }
+ }
+ handleSubscriptionSucceededEvent(event) {
+ this.subscriptionPending = false;
+ this.subscribed = true;
+ if (this.subscriptionCancelled) {
+ this.pusher.unsubscribe(this.name);
+ } else {
+ this.emit("pusher:subscription_succeeded", event.data);
+ }
+ }
+ handleSubscriptionCountEvent(event) {
+ if (event.data.subscription_count) {
+ this.subscriptionCount = event.data.subscription_count;
+ }
+ this.emit("pusher:subscription_count", event.data);
+ }
+ subscribe() {
+ if (this.subscribed) {
+ return;
+ }
+ this.subscriptionPending = true;
+ this.subscriptionCancelled = false;
+ this.authorize(this.pusher.connection.socket_id, (error, data) => {
+ if (error) {
+ this.subscriptionPending = false;
+ logger.error(error.toString());
+ this.emit("pusher:subscription_error", Object.assign({}, {
+ type: "AuthError",
+ error: error.message
+ }, error instanceof HTTPAuthError ? { status: error.status } : {}));
+ } else {
+ this.pusher.send_event("pusher:subscribe", {
+ auth: data.auth,
+ channel_data: data.channel_data,
+ channel: this.name
+ });
+ }
+ });
+ }
+ unsubscribe() {
+ this.subscribed = false;
+ this.pusher.send_event("pusher:unsubscribe", {
+ channel: this.name
+ });
+ }
+ cancelSubscription() {
+ this.subscriptionCancelled = true;
+ }
+ reinstateSubscription() {
+ this.subscriptionCancelled = false;
+ }
+ }
+ class PrivateChannel extends Channel {
+ authorize(socketId, callback) {
+ return this.pusher.config.channelAuthorizer({
+ channelName: this.name,
+ socketId
+ }, callback);
+ }
+ }
+ class Members {
+ constructor() {
+ this.reset();
+ }
+ get(id) {
+ if (Object.prototype.hasOwnProperty.call(this.members, id)) {
+ return {
+ id,
+ info: this.members[id]
+ };
+ } else {
+ return null;
+ }
+ }
+ each(callback) {
+ objectApply(this.members, (member, id) => {
+ callback(this.get(id));
+ });
+ }
+ setMyID(id) {
+ this.myID = id;
+ }
+ onSubscription(subscriptionData) {
+ this.members = subscriptionData.presence.hash;
+ this.count = subscriptionData.presence.count;
+ this.me = this.get(this.myID);
+ }
+ addMember(memberData) {
+ if (this.get(memberData.user_id) === null) {
+ this.count++;
+ }
+ this.members[memberData.user_id] = memberData.user_info;
+ return this.get(memberData.user_id);
+ }
+ removeMember(memberData) {
+ var member = this.get(memberData.user_id);
+ if (member) {
+ delete this.members[memberData.user_id];
+ this.count--;
+ }
+ return member;
+ }
+ reset() {
+ this.members = {};
+ this.count = 0;
+ this.myID = null;
+ this.me = null;
+ }
+ }
+ var __awaiter = function(thisArg, _arguments, P, generator) {
+ function adopt(value) {
+ return value instanceof P ? value : new P(function(resolve) {
+ resolve(value);
+ });
+ }
+ return new (P || (P = Promise))(function(resolve, reject) {
+ function fulfilled(value) {
+ try {
+ step(generator.next(value));
+ } catch (e) {
+ reject(e);
+ }
+ }
+ function rejected(value) {
+ try {
+ step(generator["throw"](value));
+ } catch (e) {
+ reject(e);
+ }
+ }
+ function step(result) {
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
+ }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+ };
+ class PresenceChannel extends PrivateChannel {
+ constructor(name, pusher3) {
+ super(name, pusher3);
+ this.members = new Members();
+ }
+ authorize(socketId, callback) {
+ super.authorize(socketId, (error, authData) => __awaiter(this, void 0, void 0, function* () {
+ if (!error) {
+ authData = authData;
+ if (authData.channel_data != null) {
+ var channelData = JSON.parse(authData.channel_data);
+ this.members.setMyID(channelData.user_id);
+ } else {
+ yield this.pusher.user.signinDonePromise;
+ if (this.pusher.user.user_data != null) {
+ this.members.setMyID(this.pusher.user.user_data.id);
+ } else {
+ let suffix = url_store.buildLogSuffix("authorizationEndpoint");
+ logger.error(`Invalid auth response for channel '${this.name}', expected 'channel_data' field. ${suffix}, or the user should be signed in.`);
+ callback("Invalid auth response");
+ return;
+ }
+ }
+ }
+ callback(error, authData);
+ }));
+ }
+ handleEvent(event) {
+ var eventName = event.event;
+ if (eventName.indexOf("pusher_internal:") === 0) {
+ this.handleInternalEvent(event);
+ } else {
+ var data = event.data;
+ var metadata = {};
+ if (event.user_id) {
+ metadata.user_id = event.user_id;
+ }
+ this.emit(eventName, data, metadata);
+ }
+ }
+ handleInternalEvent(event) {
+ var eventName = event.event;
+ var data = event.data;
+ switch (eventName) {
+ case "pusher_internal:subscription_succeeded":
+ this.handleSubscriptionSucceededEvent(event);
+ break;
+ case "pusher_internal:subscription_count":
+ this.handleSubscriptionCountEvent(event);
+ break;
+ case "pusher_internal:member_added":
+ var addedMember = this.members.addMember(data);
+ this.emit("pusher:member_added", addedMember);
+ break;
+ case "pusher_internal:member_removed":
+ var removedMember = this.members.removeMember(data);
+ if (removedMember) {
+ this.emit("pusher:member_removed", removedMember);
+ }
+ break;
+ }
+ }
+ handleSubscriptionSucceededEvent(event) {
+ this.subscriptionPending = false;
+ this.subscribed = true;
+ if (this.subscriptionCancelled) {
+ this.pusher.unsubscribe(this.name);
+ } else {
+ this.members.onSubscription(event.data);
+ this.emit("pusher:subscription_succeeded", this.members);
+ }
+ }
+ disconnect() {
+ this.members.reset();
+ super.disconnect();
+ }
+ }
+ var utf8 = __webpack_require__2(978);
+ var base64 = __webpack_require__2(594);
+ class EncryptedChannel extends PrivateChannel {
+ constructor(name, pusher3, nacl) {
+ super(name, pusher3);
+ this.key = null;
+ this.nacl = nacl;
+ }
+ authorize(socketId, callback) {
+ super.authorize(socketId, (error, authData) => {
+ if (error) {
+ callback(error, authData);
+ return;
+ }
+ let sharedSecret = authData["shared_secret"];
+ if (!sharedSecret) {
+ callback(new Error(`No shared_secret key in auth payload for encrypted channel: ${this.name}`), null);
+ return;
+ }
+ this.key = (0, base64.decode)(sharedSecret);
+ delete authData["shared_secret"];
+ callback(null, authData);
+ });
+ }
+ trigger(event, data) {
+ throw new UnsupportedFeature("Client events are not currently supported for encrypted channels");
+ }
+ handleEvent(event) {
+ var eventName = event.event;
+ var data = event.data;
+ if (eventName.indexOf("pusher_internal:") === 0 || eventName.indexOf("pusher:") === 0) {
+ super.handleEvent(event);
+ return;
+ }
+ this.handleEncryptedEvent(eventName, data);
+ }
+ handleEncryptedEvent(event, data) {
+ if (!this.key) {
+ logger.debug("Received encrypted event before key has been retrieved from the authEndpoint");
+ return;
+ }
+ if (!data.ciphertext || !data.nonce) {
+ logger.error("Unexpected format for encrypted event, expected object with `ciphertext` and `nonce` fields, got: " + data);
+ return;
+ }
+ let cipherText = (0, base64.decode)(data.ciphertext);
+ if (cipherText.length < this.nacl.secretbox.overheadLength) {
+ logger.error(`Expected encrypted event ciphertext length to be ${this.nacl.secretbox.overheadLength}, got: ${cipherText.length}`);
+ return;
+ }
+ let nonce = (0, base64.decode)(data.nonce);
+ if (nonce.length < this.nacl.secretbox.nonceLength) {
+ logger.error(`Expected encrypted event nonce length to be ${this.nacl.secretbox.nonceLength}, got: ${nonce.length}`);
+ return;
+ }
+ let bytes = this.nacl.secretbox.open(cipherText, nonce, this.key);
+ if (bytes === null) {
+ logger.debug("Failed to decrypt an event, probably because it was encrypted with a different key. Fetching a new key from the authEndpoint...");
+ this.authorize(this.pusher.connection.socket_id, (error, authData) => {
+ if (error) {
+ logger.error(`Failed to make a request to the authEndpoint: ${authData}. Unable to fetch new key, so dropping encrypted event`);
+ return;
+ }
+ bytes = this.nacl.secretbox.open(cipherText, nonce, this.key);
+ if (bytes === null) {
+ logger.error(`Failed to decrypt event with new key. Dropping encrypted event`);
+ return;
+ }
+ this.emit(event, this.getDataToEmit(bytes));
+ return;
+ });
+ return;
+ }
+ this.emit(event, this.getDataToEmit(bytes));
+ }
+ getDataToEmit(bytes) {
+ let raw = (0, utf8.D4)(bytes);
+ try {
+ return JSON.parse(raw);
+ } catch (_a) {
+ return raw;
+ }
+ }
+ }
+ class ConnectionManager extends Dispatcher {
+ constructor(key, options) {
+ super();
+ this.state = "initialized";
+ this.connection = null;
+ this.key = key;
+ this.options = options;
+ this.timeline = this.options.timeline;
+ this.usingTLS = this.options.useTLS;
+ this.errorCallbacks = this.buildErrorCallbacks();
+ this.connectionCallbacks = this.buildConnectionCallbacks(this.errorCallbacks);
+ this.handshakeCallbacks = this.buildHandshakeCallbacks(this.errorCallbacks);
+ var Network2 = node_runtime.getNetwork();
+ Network2.bind("online", () => {
+ this.timeline.info({ netinfo: "online" });
+ if (this.state === "connecting" || this.state === "unavailable") {
+ this.retryIn(0);
+ }
+ });
+ Network2.bind("offline", () => {
+ this.timeline.info({ netinfo: "offline" });
+ if (this.connection) {
+ this.sendActivityCheck();
+ }
+ });
+ this.updateStrategy();
+ }
+ switchCluster(key) {
+ this.key = key;
+ this.updateStrategy();
+ this.retryIn(0);
+ }
+ connect() {
+ if (this.connection || this.runner) {
+ return;
+ }
+ if (!this.strategy.isSupported()) {
+ this.updateState("failed");
+ return;
+ }
+ this.updateState("connecting");
+ this.startConnecting();
+ this.setUnavailableTimer();
+ }
+ send(data) {
+ if (this.connection) {
+ return this.connection.send(data);
+ } else {
+ return false;
+ }
+ }
+ send_event(name, data, channel) {
+ if (this.connection) {
+ return this.connection.send_event(name, data, channel);
+ } else {
+ return false;
+ }
+ }
+ disconnect() {
+ this.disconnectInternally();
+ this.updateState("disconnected");
+ }
+ isUsingTLS() {
+ return this.usingTLS;
+ }
+ startConnecting() {
+ var callback = (error, handshake) => {
+ if (error) {
+ this.runner = this.strategy.connect(0, callback);
+ } else {
+ if (handshake.action === "error") {
+ this.emit("error", {
+ type: "HandshakeError",
+ error: handshake.error
+ });
+ this.timeline.error({ handshakeError: handshake.error });
+ } else {
+ this.abortConnecting();
+ this.handshakeCallbacks[handshake.action](handshake);
+ }
+ }
+ };
+ this.runner = this.strategy.connect(0, callback);
+ }
+ abortConnecting() {
+ if (this.runner) {
+ this.runner.abort();
+ this.runner = null;
+ }
+ }
+ disconnectInternally() {
+ this.abortConnecting();
+ this.clearRetryTimer();
+ this.clearUnavailableTimer();
+ if (this.connection) {
+ var connection = this.abandonConnection();
+ connection.close();
+ }
+ }
+ updateStrategy() {
+ this.strategy = this.options.getStrategy({
+ key: this.key,
+ timeline: this.timeline,
+ useTLS: this.usingTLS
+ });
+ }
+ retryIn(delay) {
+ this.timeline.info({ action: "retry", delay });
+ if (delay > 0) {
+ this.emit("connecting_in", Math.round(delay / 1e3));
+ }
+ this.retryTimer = new OneOffTimer(delay || 0, () => {
+ this.disconnectInternally();
+ this.connect();
+ });
+ }
+ clearRetryTimer() {
+ if (this.retryTimer) {
+ this.retryTimer.ensureAborted();
+ this.retryTimer = null;
+ }
+ }
+ setUnavailableTimer() {
+ this.unavailableTimer = new OneOffTimer(this.options.unavailableTimeout, () => {
+ this.updateState("unavailable");
+ });
+ }
+ clearUnavailableTimer() {
+ if (this.unavailableTimer) {
+ this.unavailableTimer.ensureAborted();
+ }
+ }
+ sendActivityCheck() {
+ this.stopActivityCheck();
+ this.connection.ping();
+ this.activityTimer = new OneOffTimer(this.options.pongTimeout, () => {
+ this.timeline.error({ pong_timed_out: this.options.pongTimeout });
+ this.retryIn(0);
+ });
+ }
+ resetActivityCheck() {
+ this.stopActivityCheck();
+ if (this.connection && !this.connection.handlesActivityChecks()) {
+ this.activityTimer = new OneOffTimer(this.activityTimeout, () => {
+ this.sendActivityCheck();
+ });
+ }
+ }
+ stopActivityCheck() {
+ if (this.activityTimer) {
+ this.activityTimer.ensureAborted();
+ }
+ }
+ buildConnectionCallbacks(errorCallbacks) {
+ return extend({}, errorCallbacks, {
+ message: (message) => {
+ this.resetActivityCheck();
+ this.emit("message", message);
+ },
+ ping: () => {
+ this.send_event("pusher:pong", {});
+ },
+ activity: () => {
+ this.resetActivityCheck();
+ },
+ error: (error) => {
+ this.emit("error", error);
+ },
+ closed: () => {
+ this.abandonConnection();
+ if (this.shouldRetry()) {
+ this.retryIn(1e3);
+ }
+ }
+ });
+ }
+ buildHandshakeCallbacks(errorCallbacks) {
+ return extend({}, errorCallbacks, {
+ connected: (handshake) => {
+ this.activityTimeout = Math.min(this.options.activityTimeout, handshake.activityTimeout, handshake.connection.activityTimeout || Infinity);
+ this.clearUnavailableTimer();
+ this.setConnection(handshake.connection);
+ this.socket_id = this.connection.id;
+ this.updateState("connected", { socket_id: this.socket_id });
+ }
+ });
+ }
+ buildErrorCallbacks() {
+ let withErrorEmitted = (callback) => {
+ return (result) => {
+ if (result.error) {
+ this.emit("error", { type: "WebSocketError", error: result.error });
+ }
+ callback(result);
+ };
+ };
+ return {
+ tls_only: withErrorEmitted(() => {
+ this.usingTLS = true;
+ this.updateStrategy();
+ this.retryIn(0);
+ }),
+ refused: withErrorEmitted(() => {
+ this.disconnect();
+ }),
+ backoff: withErrorEmitted(() => {
+ this.retryIn(1e3);
+ }),
+ retry: withErrorEmitted(() => {
+ this.retryIn(0);
+ })
+ };
+ }
+ setConnection(connection) {
+ this.connection = connection;
+ for (var event in this.connectionCallbacks) {
+ this.connection.bind(event, this.connectionCallbacks[event]);
+ }
+ this.resetActivityCheck();
+ }
+ abandonConnection() {
+ if (!this.connection) {
+ return;
+ }
+ this.stopActivityCheck();
+ for (var event in this.connectionCallbacks) {
+ this.connection.unbind(event, this.connectionCallbacks[event]);
+ }
+ var connection = this.connection;
+ this.connection = null;
+ return connection;
+ }
+ updateState(newState, data) {
+ var previousState = this.state;
+ this.state = newState;
+ if (previousState !== newState) {
+ var newStateDescription = newState;
+ if (newStateDescription === "connected") {
+ newStateDescription += " with new socket ID " + data.socket_id;
+ }
+ logger.debug("State changed", previousState + " -> " + newStateDescription);
+ this.timeline.info({ state: newState, params: data });
+ this.emit("state_change", { previous: previousState, current: newState });
+ this.emit(newState, data);
+ }
+ }
+ shouldRetry() {
+ return this.state === "connecting" || this.state === "connected";
+ }
+ }
+ class Channels {
+ constructor() {
+ this.channels = {};
+ }
+ add(name, pusher3) {
+ if (!this.channels[name]) {
+ this.channels[name] = createChannel(name, pusher3);
+ }
+ return this.channels[name];
+ }
+ all() {
+ return values(this.channels);
+ }
+ find(name) {
+ return this.channels[name];
+ }
+ remove(name) {
+ var channel = this.channels[name];
+ delete this.channels[name];
+ return channel;
+ }
+ disconnect() {
+ objectApply(this.channels, function(channel) {
+ channel.disconnect();
+ });
+ }
+ }
+ function createChannel(name, pusher3) {
+ if (name.indexOf("private-encrypted-") === 0) {
+ if (pusher3.config.nacl) {
+ return factory.createEncryptedChannel(name, pusher3, pusher3.config.nacl);
+ }
+ let errMsg = "Tried to subscribe to a private-encrypted- channel but no nacl implementation available";
+ let suffix = url_store.buildLogSuffix("encryptedChannelSupport");
+ throw new UnsupportedFeature(`${errMsg}. ${suffix}`);
+ } else if (name.indexOf("private-") === 0) {
+ return factory.createPrivateChannel(name, pusher3);
+ } else if (name.indexOf("presence-") === 0) {
+ return factory.createPresenceChannel(name, pusher3);
+ } else if (name.indexOf("#") === 0) {
+ throw new BadChannelName('Cannot create a channel with name "' + name + '".');
+ } else {
+ return factory.createChannel(name, pusher3);
+ }
+ }
+ var Factory = {
+ createChannels() {
+ return new Channels();
+ },
+ createConnectionManager(key, options) {
+ return new ConnectionManager(key, options);
+ },
+ createChannel(name, pusher3) {
+ return new Channel(name, pusher3);
+ },
+ createPrivateChannel(name, pusher3) {
+ return new PrivateChannel(name, pusher3);
+ },
+ createPresenceChannel(name, pusher3) {
+ return new PresenceChannel(name, pusher3);
+ },
+ createEncryptedChannel(name, pusher3, nacl) {
+ return new EncryptedChannel(name, pusher3, nacl);
+ },
+ createTimelineSender(timeline, options) {
+ return new TimelineSender(timeline, options);
+ },
+ createHandshake(transport, callback) {
+ return new Handshake(transport, callback);
+ },
+ createAssistantToTheTransportManager(manager, transport, options) {
+ return new AssistantToTheTransportManager(manager, transport, options);
+ }
+ };
+ const factory = Factory;
+ class TransportManager {
+ constructor(options) {
+ this.options = options || {};
+ this.livesLeft = this.options.lives || Infinity;
+ }
+ getAssistant(transport) {
+ return factory.createAssistantToTheTransportManager(this, transport, {
+ minPingDelay: this.options.minPingDelay,
+ maxPingDelay: this.options.maxPingDelay
+ });
+ }
+ isAlive() {
+ return this.livesLeft > 0;
+ }
+ reportDeath() {
+ this.livesLeft -= 1;
+ }
+ }
+ class SequentialStrategy {
+ constructor(strategies, options) {
+ this.strategies = strategies;
+ this.loop = Boolean(options.loop);
+ this.failFast = Boolean(options.failFast);
+ this.timeout = options.timeout;
+ this.timeoutLimit = options.timeoutLimit;
+ }
+ isSupported() {
+ return any(this.strategies, util.method("isSupported"));
+ }
+ connect(minPriority, callback) {
+ var strategies = this.strategies;
+ var current = 0;
+ var timeout = this.timeout;
+ var runner = null;
+ var tryNextStrategy = (error, handshake) => {
+ if (handshake) {
+ callback(null, handshake);
+ } else {
+ current = current + 1;
+ if (this.loop) {
+ current = current % strategies.length;
+ }
+ if (current < strategies.length) {
+ if (timeout) {
+ timeout = timeout * 2;
+ if (this.timeoutLimit) {
+ timeout = Math.min(timeout, this.timeoutLimit);
+ }
+ }
+ runner = this.tryStrategy(strategies[current], minPriority, { timeout, failFast: this.failFast }, tryNextStrategy);
+ } else {
+ callback(true);
+ }
+ }
+ };
+ runner = this.tryStrategy(strategies[current], minPriority, { timeout, failFast: this.failFast }, tryNextStrategy);
+ return {
+ abort: function() {
+ runner.abort();
+ },
+ forceMinPriority: function(p2) {
+ minPriority = p2;
+ if (runner) {
+ runner.forceMinPriority(p2);
+ }
+ }
+ };
+ }
+ tryStrategy(strategy, minPriority, options, callback) {
+ var timer = null;
+ var runner = null;
+ if (options.timeout > 0) {
+ timer = new OneOffTimer(options.timeout, function() {
+ runner.abort();
+ callback(true);
+ });
+ }
+ runner = strategy.connect(minPriority, function(error, handshake) {
+ if (error && timer && timer.isRunning() && !options.failFast) {
+ return;
+ }
+ if (timer) {
+ timer.ensureAborted();
+ }
+ callback(error, handshake);
+ });
+ return {
+ abort: function() {
+ if (timer) {
+ timer.ensureAborted();
+ }
+ runner.abort();
+ },
+ forceMinPriority: function(p2) {
+ runner.forceMinPriority(p2);
+ }
+ };
+ }
+ }
+ class BestConnectedEverStrategy {
+ constructor(strategies) {
+ this.strategies = strategies;
+ }
+ isSupported() {
+ return any(this.strategies, util.method("isSupported"));
+ }
+ connect(minPriority, callback) {
+ return connect(this.strategies, minPriority, function(i, runners) {
+ return function(error, handshake) {
+ runners[i].error = error;
+ if (error) {
+ if (allRunnersFailed(runners)) {
+ callback(true);
+ }
+ return;
+ }
+ apply(runners, function(runner) {
+ runner.forceMinPriority(handshake.transport.priority);
+ });
+ callback(null, handshake);
+ };
+ });
+ }
+ }
+ function connect(strategies, minPriority, callbackBuilder) {
+ var runners = map(strategies, function(strategy, i, _2, rs) {
+ return strategy.connect(minPriority, callbackBuilder(i, rs));
+ });
+ return {
+ abort: function() {
+ apply(runners, abortRunner);
+ },
+ forceMinPriority: function(p2) {
+ apply(runners, function(runner) {
+ runner.forceMinPriority(p2);
+ });
+ }
+ };
+ }
+ function allRunnersFailed(runners) {
+ return collections_all(runners, function(runner) {
+ return Boolean(runner.error);
+ });
+ }
+ function abortRunner(runner) {
+ if (!runner.error && !runner.aborted) {
+ runner.abort();
+ runner.aborted = true;
+ }
+ }
+ class WebSocketPrioritizedCachedStrategy {
+ constructor(strategy, transports2, options) {
+ this.strategy = strategy;
+ this.transports = transports2;
+ this.ttl = options.ttl || 1800 * 1e3;
+ this.usingTLS = options.useTLS;
+ this.timeline = options.timeline;
+ }
+ isSupported() {
+ return this.strategy.isSupported();
+ }
+ connect(minPriority, callback) {
+ var usingTLS = this.usingTLS;
+ var info = fetchTransportCache(usingTLS);
+ var cacheSkipCount = info && info.cacheSkipCount ? info.cacheSkipCount : 0;
+ var strategies = [this.strategy];
+ if (info && info.timestamp + this.ttl >= util.now()) {
+ var transport = this.transports[info.transport];
+ if (transport) {
+ if (["ws", "wss"].includes(info.transport) || cacheSkipCount > 3) {
+ this.timeline.info({
+ cached: true,
+ transport: info.transport,
+ latency: info.latency
+ });
+ strategies.push(new SequentialStrategy([transport], {
+ timeout: info.latency * 2 + 1e3,
+ failFast: true
+ }));
+ } else {
+ cacheSkipCount++;
+ }
+ }
+ }
+ var startTimestamp = util.now();
+ var runner = strategies.pop().connect(minPriority, function cb(error, handshake) {
+ if (error) {
+ flushTransportCache(usingTLS);
+ if (strategies.length > 0) {
+ startTimestamp = util.now();
+ runner = strategies.pop().connect(minPriority, cb);
+ } else {
+ callback(error);
+ }
+ } else {
+ storeTransportCache(usingTLS, handshake.transport.name, util.now() - startTimestamp, cacheSkipCount);
+ callback(null, handshake);
+ }
+ });
+ return {
+ abort: function() {
+ runner.abort();
+ },
+ forceMinPriority: function(p2) {
+ minPriority = p2;
+ if (runner) {
+ runner.forceMinPriority(p2);
+ }
+ }
+ };
+ }
+ }
+ function getTransportCacheKey(usingTLS) {
+ return "pusherTransport" + (usingTLS ? "TLS" : "NonTLS");
+ }
+ function fetchTransportCache(usingTLS) {
+ var storage = node_runtime.getLocalStorage();
+ if (storage) {
+ try {
+ var serializedCache = storage[getTransportCacheKey(usingTLS)];
+ if (serializedCache) {
+ return JSON.parse(serializedCache);
+ }
+ } catch (e) {
+ flushTransportCache(usingTLS);
+ }
+ }
+ return null;
+ }
+ function storeTransportCache(usingTLS, transport, latency, cacheSkipCount) {
+ var storage = node_runtime.getLocalStorage();
+ if (storage) {
+ try {
+ storage[getTransportCacheKey(usingTLS)] = safeJSONStringify({
+ timestamp: util.now(),
+ transport,
+ latency,
+ cacheSkipCount
+ });
+ } catch (e) {
+ }
+ }
+ }
+ function flushTransportCache(usingTLS) {
+ var storage = node_runtime.getLocalStorage();
+ if (storage) {
+ try {
+ delete storage[getTransportCacheKey(usingTLS)];
+ } catch (e) {
+ }
+ }
+ }
+ class DelayedStrategy {
+ constructor(strategy, { delay: number }) {
+ this.strategy = strategy;
+ this.options = { delay: number };
+ }
+ isSupported() {
+ return this.strategy.isSupported();
+ }
+ connect(minPriority, callback) {
+ var strategy = this.strategy;
+ var runner;
+ var timer = new OneOffTimer(this.options.delay, function() {
+ runner = strategy.connect(minPriority, callback);
+ });
+ return {
+ abort: function() {
+ timer.ensureAborted();
+ if (runner) {
+ runner.abort();
+ }
+ },
+ forceMinPriority: function(p2) {
+ minPriority = p2;
+ if (runner) {
+ runner.forceMinPriority(p2);
+ }
+ }
+ };
+ }
+ }
+ class IfStrategy {
+ constructor(test, trueBranch, falseBranch) {
+ this.test = test;
+ this.trueBranch = trueBranch;
+ this.falseBranch = falseBranch;
+ }
+ isSupported() {
+ var branch = this.test() ? this.trueBranch : this.falseBranch;
+ return branch.isSupported();
+ }
+ connect(minPriority, callback) {
+ var branch = this.test() ? this.trueBranch : this.falseBranch;
+ return branch.connect(minPriority, callback);
+ }
+ }
+ class FirstConnectedStrategy {
+ constructor(strategy) {
+ this.strategy = strategy;
+ }
+ isSupported() {
+ return this.strategy.isSupported();
+ }
+ connect(minPriority, callback) {
+ var runner = this.strategy.connect(minPriority, function(error, handshake) {
+ if (handshake) {
+ runner.abort();
+ }
+ callback(error, handshake);
+ });
+ return runner;
+ }
+ }
+ function testSupportsStrategy(strategy) {
+ return function() {
+ return strategy.isSupported();
+ };
+ }
+ var getDefaultStrategy = function(config, baseOptions, defineTransport2) {
+ var definedTransports = {};
+ function defineTransportStrategy(name, type, priority, options, manager) {
+ var transport = defineTransport2(config, name, type, priority, options, manager);
+ definedTransports[name] = transport;
+ return transport;
+ }
+ var ws_options = Object.assign({}, baseOptions, {
+ hostNonTLS: config.wsHost + ":" + config.wsPort,
+ hostTLS: config.wsHost + ":" + config.wssPort,
+ httpPath: config.wsPath
+ });
+ var wss_options = extend({}, ws_options, {
+ useTLS: true
+ });
+ var http_options = Object.assign({}, baseOptions, {
+ hostNonTLS: config.httpHost + ":" + config.httpPort,
+ hostTLS: config.httpHost + ":" + config.httpsPort,
+ httpPath: config.httpPath
+ });
+ var timeouts = {
+ loop: true,
+ timeout: 15e3,
+ timeoutLimit: 6e4
+ };
+ var ws_manager = new TransportManager({
+ minPingDelay: 1e4,
+ maxPingDelay: config.activityTimeout
+ });
+ var streaming_manager = new TransportManager({
+ lives: 2,
+ minPingDelay: 1e4,
+ maxPingDelay: config.activityTimeout
+ });
+ var ws_transport = defineTransportStrategy("ws", "ws", 3, ws_options, ws_manager);
+ var wss_transport = defineTransportStrategy("wss", "ws", 3, wss_options, ws_manager);
+ var xhr_streaming_transport = defineTransportStrategy("xhr_streaming", "xhr_streaming", 1, http_options, streaming_manager);
+ var xhr_polling_transport = defineTransportStrategy("xhr_polling", "xhr_polling", 1, http_options);
+ var ws_loop = new SequentialStrategy([ws_transport], timeouts);
+ var wss_loop = new SequentialStrategy([wss_transport], timeouts);
+ var streaming_loop = new SequentialStrategy([xhr_streaming_transport], timeouts);
+ var polling_loop = new SequentialStrategy([xhr_polling_transport], timeouts);
+ var http_loop = new SequentialStrategy([
+ new IfStrategy(testSupportsStrategy(streaming_loop), new BestConnectedEverStrategy([
+ streaming_loop,
+ new DelayedStrategy(polling_loop, { delay: 4e3 })
+ ]), polling_loop)
+ ], timeouts);
+ var wsStrategy;
+ if (baseOptions.useTLS) {
+ wsStrategy = new BestConnectedEverStrategy([
+ ws_loop,
+ new DelayedStrategy(http_loop, { delay: 2e3 })
+ ]);
+ } else {
+ wsStrategy = new BestConnectedEverStrategy([
+ ws_loop,
+ new DelayedStrategy(wss_loop, { delay: 2e3 }),
+ new DelayedStrategy(http_loop, { delay: 5e3 })
+ ]);
+ }
+ return new WebSocketPrioritizedCachedStrategy(new FirstConnectedStrategy(new IfStrategy(testSupportsStrategy(ws_transport), wsStrategy, http_loop)), definedTransports, {
+ ttl: 18e5,
+ timeline: baseOptions.timeline,
+ useTLS: baseOptions.useTLS
+ });
+ };
+ const default_strategy = getDefaultStrategy;
+ function transport_connection_initializer() {
+ var self2 = this;
+ self2.timeline.info(self2.buildTimelineMessage({
+ transport: self2.name + (self2.options.useTLS ? "s" : "")
+ }));
+ if (self2.hooks.isInitialized()) {
+ self2.changeState("initialized");
+ } else {
+ self2.onClose();
+ }
+ }
+ const MAX_BUFFER_LENGTH = 256 * 1024;
+ class HTTPRequest extends Dispatcher {
+ constructor(hooks2, method, url) {
+ super();
+ this.hooks = hooks2;
+ this.method = method;
+ this.url = url;
+ }
+ start(payload) {
+ this.position = 0;
+ this.xhr = this.hooks.getRequest(this);
+ this.unloader = () => {
+ this.close();
+ };
+ node_runtime.addUnloadListener(this.unloader);
+ this.xhr.open(this.method, this.url, true);
+ if (this.xhr.setRequestHeader) {
+ this.xhr.setRequestHeader("Content-Type", "application/json");
+ }
+ this.xhr.send(payload);
+ }
+ close() {
+ if (this.unloader) {
+ node_runtime.removeUnloadListener(this.unloader);
+ this.unloader = null;
+ }
+ if (this.xhr) {
+ this.hooks.abortRequest(this.xhr);
+ this.xhr = null;
+ }
+ }
+ onChunk(status, data) {
+ while (true) {
+ var chunk = this.advanceBuffer(data);
+ if (chunk) {
+ this.emit("chunk", { status, data: chunk });
+ } else {
+ break;
+ }
+ }
+ if (this.isBufferTooLong(data)) {
+ this.emit("buffer_too_long");
+ }
+ }
+ advanceBuffer(buffer) {
+ var unreadData = buffer.slice(this.position);
+ var endOfLinePosition = unreadData.indexOf("\n");
+ if (endOfLinePosition !== -1) {
+ this.position += endOfLinePosition + 1;
+ return unreadData.slice(0, endOfLinePosition);
+ } else {
+ return null;
+ }
+ }
+ isBufferTooLong(buffer) {
+ return this.position === buffer.length && buffer.length > MAX_BUFFER_LENGTH;
+ }
+ }
+ var State;
+ (function(State2) {
+ State2[State2["CONNECTING"] = 0] = "CONNECTING";
+ State2[State2["OPEN"] = 1] = "OPEN";
+ State2[State2["CLOSED"] = 3] = "CLOSED";
+ })(State || (State = {}));
+ const state = State;
+ var autoIncrement = 1;
+ class HTTPSocket {
+ constructor(hooks2, url) {
+ this.hooks = hooks2;
+ this.session = randomNumber(1e3) + "/" + randomString(8);
+ this.location = getLocation(url);
+ this.readyState = state.CONNECTING;
+ this.openStream();
+ }
+ send(payload) {
+ return this.sendRaw(JSON.stringify([payload]));
+ }
+ ping() {
+ this.hooks.sendHeartbeat(this);
+ }
+ close(code, reason) {
+ this.onClose(code, reason, true);
+ }
+ sendRaw(payload) {
+ if (this.readyState === state.OPEN) {
+ try {
+ node_runtime.createSocketRequest("POST", getUniqueURL(getSendURL(this.location, this.session))).start(payload);
+ return true;
+ } catch (e) {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+ reconnect() {
+ this.closeStream();
+ this.openStream();
+ }
+ onClose(code, reason, wasClean) {
+ this.closeStream();
+ this.readyState = state.CLOSED;
+ if (this.onclose) {
+ this.onclose({
+ code,
+ reason,
+ wasClean
+ });
+ }
+ }
+ onChunk(chunk) {
+ if (chunk.status !== 200) {
+ return;
+ }
+ if (this.readyState === state.OPEN) {
+ this.onActivity();
+ }
+ var payload;
+ var type = chunk.data.slice(0, 1);
+ switch (type) {
+ case "o":
+ payload = JSON.parse(chunk.data.slice(1) || "{}");
+ this.onOpen(payload);
+ break;
+ case "a":
+ payload = JSON.parse(chunk.data.slice(1) || "[]");
+ for (var i = 0; i < payload.length; i++) {
+ this.onEvent(payload[i]);
+ }
+ break;
+ case "m":
+ payload = JSON.parse(chunk.data.slice(1) || "null");
+ this.onEvent(payload);
+ break;
+ case "h":
+ this.hooks.onHeartbeat(this);
+ break;
+ case "c":
+ payload = JSON.parse(chunk.data.slice(1) || "[]");
+ this.onClose(payload[0], payload[1], true);
+ break;
+ }
+ }
+ onOpen(options) {
+ if (this.readyState === state.CONNECTING) {
+ if (options && options.hostname) {
+ this.location.base = replaceHost(this.location.base, options.hostname);
+ }
+ this.readyState = state.OPEN;
+ if (this.onopen) {
+ this.onopen();
+ }
+ } else {
+ this.onClose(1006, "Server lost session", true);
+ }
+ }
+ onEvent(event) {
+ if (this.readyState === state.OPEN && this.onmessage) {
+ this.onmessage({ data: event });
+ }
+ }
+ onActivity() {
+ if (this.onactivity) {
+ this.onactivity();
+ }
+ }
+ onError(error) {
+ if (this.onerror) {
+ this.onerror(error);
+ }
+ }
+ openStream() {
+ this.stream = node_runtime.createSocketRequest("POST", getUniqueURL(this.hooks.getReceiveURL(this.location, this.session)));
+ this.stream.bind("chunk", (chunk) => {
+ this.onChunk(chunk);
+ });
+ this.stream.bind("finished", (status) => {
+ this.hooks.onFinished(this, status);
+ });
+ this.stream.bind("buffer_too_long", () => {
+ this.reconnect();
+ });
+ try {
+ this.stream.start();
+ } catch (error) {
+ util.defer(() => {
+ this.onError(error);
+ this.onClose(1006, "Could not start streaming", false);
+ });
+ }
+ }
+ closeStream() {
+ if (this.stream) {
+ this.stream.unbind_all();
+ this.stream.close();
+ this.stream = null;
+ }
+ }
+ }
+ function getLocation(url) {
+ var parts = /([^\?]*)\/*(\??.*)/.exec(url);
+ return {
+ base: parts[1],
+ queryString: parts[2]
+ };
+ }
+ function getSendURL(url, session) {
+ return url.base + "/" + session + "/xhr_send";
+ }
+ function getUniqueURL(url) {
+ var separator = url.indexOf("?") === -1 ? "?" : "&";
+ return url + separator + "t=" + +/* @__PURE__ */ new Date() + "&n=" + autoIncrement++;
+ }
+ function replaceHost(url, hostname) {
+ var urlParts = /(https?:\/\/)([^\/:]+)((\/|:)?.*)/.exec(url);
+ return urlParts[1] + hostname + urlParts[3];
+ }
+ function randomNumber(max) {
+ return node_runtime.randomInt(max);
+ }
+ function randomString(length) {
+ var result = [];
+ for (var i = 0; i < length; i++) {
+ result.push(randomNumber(32).toString(32));
+ }
+ return result.join("");
+ }
+ const http_socket = HTTPSocket;
+ var hooks = {
+ getReceiveURL: function(url, session) {
+ return url.base + "/" + session + "/xhr_streaming" + url.queryString;
+ },
+ onHeartbeat: function(socket) {
+ socket.sendRaw("[]");
+ },
+ sendHeartbeat: function(socket) {
+ socket.sendRaw("[]");
+ },
+ onFinished: function(socket, status) {
+ socket.onClose(1006, "Connection interrupted (" + status + ")", false);
+ }
+ };
+ const http_streaming_socket = hooks;
+ var http_polling_socket_hooks = {
+ getReceiveURL: function(url, session) {
+ return url.base + "/" + session + "/xhr" + url.queryString;
+ },
+ onHeartbeat: function() {
+ },
+ sendHeartbeat: function(socket) {
+ socket.sendRaw("[]");
+ },
+ onFinished: function(socket, status) {
+ if (status === 200) {
+ socket.reconnect();
+ } else {
+ socket.onClose(1006, "Connection interrupted (" + status + ")", false);
+ }
+ }
+ };
+ const http_polling_socket = http_polling_socket_hooks;
+ var http_xhr_request_hooks = {
+ getRequest: function(socket) {
+ var Constructor = node_runtime.getXHRAPI();
+ var xhr2 = new Constructor();
+ xhr2.onreadystatechange = xhr2.onprogress = function() {
+ switch (xhr2.readyState) {
+ case 3:
+ if (xhr2.responseText && xhr2.responseText.length > 0) {
+ socket.onChunk(xhr2.status, xhr2.responseText);
+ }
+ break;
+ case 4:
+ if (xhr2.responseText && xhr2.responseText.length > 0) {
+ socket.onChunk(xhr2.status, xhr2.responseText);
+ }
+ socket.emit("finished", xhr2.status);
+ socket.close();
+ break;
+ }
+ };
+ return xhr2;
+ },
+ abortRequest: function(xhr2) {
+ xhr2.onreadystatechange = null;
+ xhr2.abort();
+ }
+ };
+ const http_xhr_request = http_xhr_request_hooks;
+ var HTTP = {
+ createStreamingSocket(url) {
+ return this.createSocket(http_streaming_socket, url);
+ },
+ createPollingSocket(url) {
+ return this.createSocket(http_polling_socket, url);
+ },
+ createSocket(hooks2, url) {
+ return new http_socket(hooks2, url);
+ },
+ createXHR(method, url) {
+ return this.createRequest(http_xhr_request, method, url);
+ },
+ createRequest(hooks2, method, url) {
+ return new HTTPRequest(hooks2, method, url);
+ }
+ };
+ const http_http = HTTP;
+ var Isomorphic = {
+ getDefaultStrategy: default_strategy,
+ Transports: transports,
+ transportConnectionInitializer: transport_connection_initializer,
+ HTTPFactory: http_http,
+ setup(PusherClass) {
+ PusherClass.ready();
+ },
+ getLocalStorage() {
+ return void 0;
+ },
+ getClientFeatures() {
+ return keys(filterObject({ ws: transports.ws }, function(t) {
+ return t.isSupported({});
+ }));
+ },
+ getProtocol() {
+ return "http:";
+ },
+ isXHRSupported() {
+ return true;
+ },
+ createSocketRequest(method, url) {
+ if (this.isXHRSupported()) {
+ return this.HTTPFactory.createXHR(method, url);
+ } else {
+ throw "Cross-origin HTTP requests are not supported";
+ }
+ },
+ createXHR() {
+ var Constructor = this.getXHRAPI();
+ return new Constructor();
+ },
+ createWebSocket(url) {
+ var Constructor = this.getWebSocketAPI();
+ return new Constructor(url);
+ },
+ addUnloadListener(listener) {
+ },
+ removeUnloadListener(listener) {
+ }
+ };
+ const runtime = Isomorphic;
+ var websocket = __webpack_require__2(555);
+ var XMLHttpRequest = __webpack_require__2(407);
+ class NetInfo extends Dispatcher {
+ isOnline() {
+ return true;
+ }
+ }
+ var Network = new NetInfo();
+ var AuthRequestType;
+ (function(AuthRequestType2) {
+ AuthRequestType2["UserAuthentication"] = "user-authentication";
+ AuthRequestType2["ChannelAuthorization"] = "channel-authorization";
+ })(AuthRequestType || (AuthRequestType = {}));
+ const ajax = function(context, query, authOptions, authRequestType, callback) {
+ const xhr2 = node_runtime.createXHR();
+ xhr2.open("POST", authOptions.endpoint, true);
+ xhr2.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
+ for (var headerName in authOptions.headers) {
+ xhr2.setRequestHeader(headerName, authOptions.headers[headerName]);
+ }
+ if (authOptions.headersProvider != null) {
+ let dynamicHeaders = authOptions.headersProvider();
+ for (var headerName in dynamicHeaders) {
+ xhr2.setRequestHeader(headerName, dynamicHeaders[headerName]);
+ }
+ }
+ xhr2.onreadystatechange = function() {
+ if (xhr2.readyState === 4) {
+ if (xhr2.status === 200) {
+ let data;
+ let parsed = false;
+ try {
+ data = JSON.parse(xhr2.responseText);
+ parsed = true;
+ } catch (e) {
+ callback(new HTTPAuthError(200, `JSON returned from ${authRequestType.toString()} endpoint was invalid, yet status code was 200. Data was: ${xhr2.responseText}`), null);
+ }
+ if (parsed) {
+ callback(null, data);
+ }
+ } else {
+ let suffix = "";
+ switch (authRequestType) {
+ case AuthRequestType.UserAuthentication:
+ suffix = url_store.buildLogSuffix("authenticationEndpoint");
+ break;
+ case AuthRequestType.ChannelAuthorization:
+ suffix = `Clients must be authorized to join private or presence channels. ${url_store.buildLogSuffix("authorizationEndpoint")}`;
+ break;
+ }
+ callback(new HTTPAuthError(xhr2.status, `Unable to retrieve auth string from ${authRequestType.toString()} endpoint - received status: ${xhr2.status} from ${authOptions.endpoint}. ${suffix}`), null);
+ }
+ }
+ };
+ xhr2.send(query);
+ return xhr2;
+ };
+ const xhr_auth = ajax;
+ var getAgent = function(sender, useTLS) {
+ return function(data, callback) {
+ var scheme = "http" + (useTLS ? "s" : "") + "://";
+ var url = scheme + (sender.host || sender.options.host) + sender.options.path;
+ var query = buildQueryString(data);
+ url += "/2?" + query;
+ var xhr2 = node_runtime.createXHR();
+ xhr2.open("GET", url, true);
+ xhr2.onreadystatechange = function() {
+ if (xhr2.readyState === 4) {
+ let { status, responseText } = xhr2;
+ if (status !== 200) {
+ logger.debug(`TimelineSender Error: received ${status} from stats.pusher.com`);
+ return;
+ }
+ try {
+ var { host } = JSON.parse(responseText);
+ } catch (e) {
+ logger.debug(`TimelineSenderError: invalid response ${responseText}`);
+ }
+ if (host) {
+ sender.host = host;
+ }
+ }
+ };
+ xhr2.send();
+ };
+ };
+ var xhr = {
+ name: "xhr",
+ getAgent
+ };
+ const xhr_timeline = xhr;
+ var external_crypto_ = __webpack_require__2(982);
+ const { getDefaultStrategy: runtime_getDefaultStrategy, Transports: runtime_Transports, setup, getProtocol, isXHRSupported, getLocalStorage, createXHR, createWebSocket, addUnloadListener, removeUnloadListener, transportConnectionInitializer, createSocketRequest, HTTPFactory } = runtime;
+ const NodeJS = {
+ getDefaultStrategy: runtime_getDefaultStrategy,
+ Transports: runtime_Transports,
+ setup,
+ getProtocol,
+ isXHRSupported,
+ createSocketRequest,
+ getLocalStorage,
+ createXHR,
+ createWebSocket,
+ addUnloadListener,
+ removeUnloadListener,
+ transportConnectionInitializer,
+ HTTPFactory,
+ TimelineTransport: xhr_timeline,
+ getAuthorizers() {
+ return { ajax: xhr_auth };
+ },
+ getWebSocketAPI() {
+ return websocket.Client;
+ },
+ getXHRAPI() {
+ return XMLHttpRequest.z;
+ },
+ getNetwork() {
+ return Network;
+ },
+ randomInt(max) {
+ return (0, external_crypto_.randomInt)(max);
+ }
+ };
+ const node_runtime = NodeJS;
+ var TimelineLevel;
+ (function(TimelineLevel2) {
+ TimelineLevel2[TimelineLevel2["ERROR"] = 3] = "ERROR";
+ TimelineLevel2[TimelineLevel2["INFO"] = 6] = "INFO";
+ TimelineLevel2[TimelineLevel2["DEBUG"] = 7] = "DEBUG";
+ })(TimelineLevel || (TimelineLevel = {}));
+ const level = TimelineLevel;
+ class Timeline {
+ constructor(key, session, options) {
+ this.key = key;
+ this.session = session;
+ this.events = [];
+ this.options = options || {};
+ this.sent = 0;
+ this.uniqueID = 0;
+ }
+ log(level2, event) {
+ if (level2 <= this.options.level) {
+ this.events.push(extend({}, event, { timestamp: util.now() }));
+ if (this.options.limit && this.events.length > this.options.limit) {
+ this.events.shift();
+ }
+ }
+ }
+ error(event) {
+ this.log(level.ERROR, event);
+ }
+ info(event) {
+ this.log(level.INFO, event);
+ }
+ debug(event) {
+ this.log(level.DEBUG, event);
+ }
+ isEmpty() {
+ return this.events.length === 0;
+ }
+ send(sendfn, callback) {
+ var data = extend({
+ session: this.session,
+ bundle: this.sent + 1,
+ key: this.key,
+ lib: "js",
+ version: this.options.version,
+ cluster: this.options.cluster,
+ features: this.options.features,
+ timeline: this.events
+ }, this.options.params);
+ this.events = [];
+ sendfn(data, (error, result) => {
+ if (!error) {
+ this.sent++;
+ }
+ if (callback) {
+ callback(error, result);
+ }
+ });
+ return true;
+ }
+ generateUniqueID() {
+ this.uniqueID++;
+ return this.uniqueID;
+ }
+ }
+ class TransportStrategy {
+ constructor(name, priority, transport, options) {
+ this.name = name;
+ this.priority = priority;
+ this.transport = transport;
+ this.options = options || {};
+ }
+ isSupported() {
+ return this.transport.isSupported({
+ useTLS: this.options.useTLS
+ });
+ }
+ connect(minPriority, callback) {
+ if (!this.isSupported()) {
+ return failAttempt(new UnsupportedStrategy(), callback);
+ } else if (this.priority < minPriority) {
+ return failAttempt(new TransportPriorityTooLow(), callback);
+ }
+ var connected = false;
+ var transport = this.transport.createConnection(this.name, this.priority, this.options.key, this.options);
+ var handshake = null;
+ var onInitialized = function() {
+ transport.unbind("initialized", onInitialized);
+ transport.connect();
+ };
+ var onOpen = function() {
+ handshake = factory.createHandshake(transport, function(result) {
+ connected = true;
+ unbindListeners();
+ callback(null, result);
+ });
+ };
+ var onError = function(error) {
+ unbindListeners();
+ callback(error);
+ };
+ var onClosed = function() {
+ unbindListeners();
+ var serializedTransport;
+ serializedTransport = safeJSONStringify(transport);
+ callback(new TransportClosed(serializedTransport));
+ };
+ var unbindListeners = function() {
+ transport.unbind("initialized", onInitialized);
+ transport.unbind("open", onOpen);
+ transport.unbind("error", onError);
+ transport.unbind("closed", onClosed);
+ };
+ transport.bind("initialized", onInitialized);
+ transport.bind("open", onOpen);
+ transport.bind("error", onError);
+ transport.bind("closed", onClosed);
+ transport.initialize();
+ return {
+ abort: () => {
+ if (connected) {
+ return;
+ }
+ unbindListeners();
+ if (handshake) {
+ handshake.close();
+ } else {
+ transport.close();
+ }
+ },
+ forceMinPriority: (p2) => {
+ if (connected) {
+ return;
+ }
+ if (this.priority < p2) {
+ if (handshake) {
+ handshake.close();
+ } else {
+ transport.close();
+ }
+ }
+ }
+ };
+ }
+ }
+ function failAttempt(error, callback) {
+ util.defer(function() {
+ callback(error);
+ });
+ return {
+ abort: function() {
+ },
+ forceMinPriority: function() {
+ }
+ };
+ }
+ const { Transports: strategy_builder_Transports } = node_runtime;
+ var defineTransport = function(config, name, type, priority, options, manager) {
+ var transportClass = strategy_builder_Transports[type];
+ if (!transportClass) {
+ throw new UnsupportedTransport(type);
+ }
+ var enabled = (!config.enabledTransports || arrayIndexOf(config.enabledTransports, name) !== -1) && (!config.disabledTransports || arrayIndexOf(config.disabledTransports, name) === -1);
+ var transport;
+ if (enabled) {
+ options = Object.assign({ ignoreNullOrigin: config.ignoreNullOrigin }, options);
+ transport = new TransportStrategy(name, priority, manager ? manager.getAssistant(transportClass) : transportClass, options);
+ } else {
+ transport = strategy_builder_UnsupportedStrategy;
+ }
+ return transport;
+ };
+ var strategy_builder_UnsupportedStrategy = {
+ isSupported: function() {
+ return false;
+ },
+ connect: function(_2, callback) {
+ var deferred = util.defer(function() {
+ callback(new UnsupportedStrategy());
+ });
+ return {
+ abort: function() {
+ deferred.ensureAborted();
+ },
+ forceMinPriority: function() {
+ }
+ };
+ }
+ };
+ function validateOptions(options) {
+ if (options == null) {
+ throw "You must pass an options object";
+ }
+ if (options.cluster == null) {
+ throw "Options object must provide a cluster";
+ }
+ if ("disableStats" in options) {
+ logger.warn("The disableStats option is deprecated in favor of enableStats");
+ }
+ }
+ const composeChannelQuery = (params, authOptions) => {
+ var query = "socket_id=" + encodeURIComponent(params.socketId);
+ for (var key in authOptions.params) {
+ query += "&" + encodeURIComponent(key) + "=" + encodeURIComponent(authOptions.params[key]);
+ }
+ if (authOptions.paramsProvider != null) {
+ let dynamicParams = authOptions.paramsProvider();
+ for (var key in dynamicParams) {
+ query += "&" + encodeURIComponent(key) + "=" + encodeURIComponent(dynamicParams[key]);
+ }
+ }
+ return query;
+ };
+ const UserAuthenticator = (authOptions) => {
+ if (typeof node_runtime.getAuthorizers()[authOptions.transport] === "undefined") {
+ throw `'${authOptions.transport}' is not a recognized auth transport`;
+ }
+ return (params, callback) => {
+ const query = composeChannelQuery(params, authOptions);
+ node_runtime.getAuthorizers()[authOptions.transport](node_runtime, query, authOptions, AuthRequestType.UserAuthentication, callback);
+ };
+ };
+ const user_authenticator = UserAuthenticator;
+ const channel_authorizer_composeChannelQuery = (params, authOptions) => {
+ var query = "socket_id=" + encodeURIComponent(params.socketId);
+ query += "&channel_name=" + encodeURIComponent(params.channelName);
+ for (var key in authOptions.params) {
+ query += "&" + encodeURIComponent(key) + "=" + encodeURIComponent(authOptions.params[key]);
+ }
+ if (authOptions.paramsProvider != null) {
+ let dynamicParams = authOptions.paramsProvider();
+ for (var key in dynamicParams) {
+ query += "&" + encodeURIComponent(key) + "=" + encodeURIComponent(dynamicParams[key]);
+ }
+ }
+ return query;
+ };
+ const ChannelAuthorizer = (authOptions) => {
+ if (typeof node_runtime.getAuthorizers()[authOptions.transport] === "undefined") {
+ throw `'${authOptions.transport}' is not a recognized auth transport`;
+ }
+ return (params, callback) => {
+ const query = channel_authorizer_composeChannelQuery(params, authOptions);
+ node_runtime.getAuthorizers()[authOptions.transport](node_runtime, query, authOptions, AuthRequestType.ChannelAuthorization, callback);
+ };
+ };
+ const channel_authorizer = ChannelAuthorizer;
+ const ChannelAuthorizerProxy = (pusher3, authOptions, channelAuthorizerGenerator) => {
+ const deprecatedAuthorizerOptions = {
+ authTransport: authOptions.transport,
+ authEndpoint: authOptions.endpoint,
+ auth: {
+ params: authOptions.params,
+ headers: authOptions.headers
+ }
+ };
+ return (params, callback) => {
+ const channel = pusher3.channel(params.channelName);
+ const channelAuthorizer = channelAuthorizerGenerator(channel, deprecatedAuthorizerOptions);
+ channelAuthorizer.authorize(params.socketId, callback);
+ };
+ };
+ function getConfig(opts, pusher3) {
+ let config = {
+ activityTimeout: opts.activityTimeout || defaults.activityTimeout,
+ cluster: opts.cluster,
+ httpPath: opts.httpPath || defaults.httpPath,
+ httpPort: opts.httpPort || defaults.httpPort,
+ httpsPort: opts.httpsPort || defaults.httpsPort,
+ pongTimeout: opts.pongTimeout || defaults.pongTimeout,
+ statsHost: opts.statsHost || defaults.stats_host,
+ unavailableTimeout: opts.unavailableTimeout || defaults.unavailableTimeout,
+ wsPath: opts.wsPath || defaults.wsPath,
+ wsPort: opts.wsPort || defaults.wsPort,
+ wssPort: opts.wssPort || defaults.wssPort,
+ enableStats: getEnableStatsConfig(opts),
+ httpHost: getHttpHost(opts),
+ useTLS: shouldUseTLS(opts),
+ wsHost: getWebsocketHost(opts),
+ userAuthenticator: buildUserAuthenticator(opts),
+ channelAuthorizer: buildChannelAuthorizer(opts, pusher3)
+ };
+ if ("disabledTransports" in opts)
+ config.disabledTransports = opts.disabledTransports;
+ if ("enabledTransports" in opts)
+ config.enabledTransports = opts.enabledTransports;
+ if ("ignoreNullOrigin" in opts)
+ config.ignoreNullOrigin = opts.ignoreNullOrigin;
+ if ("timelineParams" in opts)
+ config.timelineParams = opts.timelineParams;
+ if ("nacl" in opts) {
+ config.nacl = opts.nacl;
+ }
+ return config;
+ }
+ function getHttpHost(opts) {
+ if (opts.httpHost) {
+ return opts.httpHost;
+ }
+ if (opts.cluster) {
+ return `sockjs-${opts.cluster}.pusher.com`;
+ }
+ return defaults.httpHost;
+ }
+ function getWebsocketHost(opts) {
+ if (opts.wsHost) {
+ return opts.wsHost;
+ }
+ return getWebsocketHostFromCluster(opts.cluster);
+ }
+ function getWebsocketHostFromCluster(cluster) {
+ return `ws-${cluster}.pusher.com`;
+ }
+ function shouldUseTLS(opts) {
+ if (node_runtime.getProtocol() === "https:") {
+ return true;
+ } else if (opts.forceTLS === false) {
+ return false;
+ }
+ return true;
+ }
+ function getEnableStatsConfig(opts) {
+ if ("enableStats" in opts) {
+ return opts.enableStats;
+ }
+ if ("disableStats" in opts) {
+ return !opts.disableStats;
+ }
+ return false;
+ }
+ const hasCustomHandler = (auth) => {
+ return "customHandler" in auth && auth["customHandler"] != null;
+ };
+ function buildUserAuthenticator(opts) {
+ const userAuthentication = Object.assign(Object.assign({}, defaults.userAuthentication), opts.userAuthentication);
+ if (hasCustomHandler(userAuthentication)) {
+ return userAuthentication["customHandler"];
+ }
+ return user_authenticator(userAuthentication);
+ }
+ function buildChannelAuth(opts, pusher3) {
+ let channelAuthorization;
+ if ("channelAuthorization" in opts) {
+ channelAuthorization = Object.assign(Object.assign({}, defaults.channelAuthorization), opts.channelAuthorization);
+ } else {
+ channelAuthorization = {
+ transport: opts.authTransport || defaults.authTransport,
+ endpoint: opts.authEndpoint || defaults.authEndpoint
+ };
+ if ("auth" in opts) {
+ if ("params" in opts.auth)
+ channelAuthorization.params = opts.auth.params;
+ if ("headers" in opts.auth)
+ channelAuthorization.headers = opts.auth.headers;
+ }
+ if ("authorizer" in opts) {
+ return {
+ customHandler: ChannelAuthorizerProxy(pusher3, channelAuthorization, opts.authorizer)
+ };
+ }
+ }
+ return channelAuthorization;
+ }
+ function buildChannelAuthorizer(opts, pusher3) {
+ const channelAuthorization = buildChannelAuth(opts, pusher3);
+ if (hasCustomHandler(channelAuthorization)) {
+ return channelAuthorization["customHandler"];
+ }
+ return channel_authorizer(channelAuthorization);
+ }
+ class WatchlistFacade extends Dispatcher {
+ constructor(pusher3) {
+ super(function(eventName, data) {
+ logger.debug(`No callbacks on watchlist events for ${eventName}`);
+ });
+ this.pusher = pusher3;
+ this.bindWatchlistInternalEvent();
+ }
+ handleEvent(pusherEvent) {
+ pusherEvent.data.events.forEach((watchlistEvent) => {
+ this.emit(watchlistEvent.name, watchlistEvent);
+ });
+ }
+ bindWatchlistInternalEvent() {
+ this.pusher.connection.bind("message", (pusherEvent) => {
+ var eventName = pusherEvent.event;
+ if (eventName === "pusher_internal:watchlist_events") {
+ this.handleEvent(pusherEvent);
+ }
+ });
+ }
+ }
+ function flatPromise() {
+ let resolve, reject;
+ const promise = new Promise((res, rej) => {
+ resolve = res;
+ reject = rej;
+ });
+ return { promise, resolve, reject };
+ }
+ const flat_promise = flatPromise;
+ class UserFacade extends Dispatcher {
+ constructor(pusher3) {
+ super(function(eventName, data) {
+ logger.debug("No callbacks on user for " + eventName);
+ });
+ this.signin_requested = false;
+ this.user_data = null;
+ this.serverToUserChannel = null;
+ this.signinDonePromise = null;
+ this._signinDoneResolve = null;
+ this._onAuthorize = (err, authData) => {
+ if (err) {
+ logger.warn(`Error during signin: ${err}`);
+ this._cleanup();
+ return;
+ }
+ this.pusher.send_event("pusher:signin", {
+ auth: authData.auth,
+ user_data: authData.user_data
+ });
+ };
+ this.pusher = pusher3;
+ this.pusher.connection.bind("state_change", ({ previous, current }) => {
+ if (previous !== "connected" && current === "connected") {
+ this._signin();
+ }
+ if (previous === "connected" && current !== "connected") {
+ this._cleanup();
+ this._newSigninPromiseIfNeeded();
+ }
+ });
+ this.watchlist = new WatchlistFacade(pusher3);
+ this.pusher.connection.bind("message", (event) => {
+ var eventName = event.event;
+ if (eventName === "pusher:signin_success") {
+ this._onSigninSuccess(event.data);
+ }
+ if (this.serverToUserChannel && this.serverToUserChannel.name === event.channel) {
+ this.serverToUserChannel.handleEvent(event);
+ }
+ });
+ }
+ signin() {
+ if (this.signin_requested) {
+ return;
+ }
+ this.signin_requested = true;
+ this._signin();
+ }
+ _signin() {
+ if (!this.signin_requested) {
+ return;
+ }
+ this._newSigninPromiseIfNeeded();
+ if (this.pusher.connection.state !== "connected") {
+ return;
+ }
+ this.pusher.config.userAuthenticator({
+ socketId: this.pusher.connection.socket_id
+ }, this._onAuthorize);
+ }
+ _onSigninSuccess(data) {
+ try {
+ this.user_data = JSON.parse(data.user_data);
+ } catch (e) {
+ logger.error(`Failed parsing user data after signin: ${data.user_data}`);
+ this._cleanup();
+ return;
+ }
+ if (typeof this.user_data.id !== "string" || this.user_data.id === "") {
+ logger.error(`user_data doesn't contain an id. user_data: ${this.user_data}`);
+ this._cleanup();
+ return;
+ }
+ this._signinDoneResolve();
+ this._subscribeChannels();
+ }
+ _subscribeChannels() {
+ const ensure_subscribed = (channel) => {
+ if (channel.subscriptionPending && channel.subscriptionCancelled) {
+ channel.reinstateSubscription();
+ } else if (!channel.subscriptionPending && this.pusher.connection.state === "connected") {
+ channel.subscribe();
+ }
+ };
+ this.serverToUserChannel = new Channel(`#server-to-user-${this.user_data.id}`, this.pusher);
+ this.serverToUserChannel.bind_global((eventName, data) => {
+ if (eventName.indexOf("pusher_internal:") === 0 || eventName.indexOf("pusher:") === 0) {
+ return;
+ }
+ this.emit(eventName, data);
+ });
+ ensure_subscribed(this.serverToUserChannel);
+ }
+ _cleanup() {
+ this.user_data = null;
+ if (this.serverToUserChannel) {
+ this.serverToUserChannel.unbind_all();
+ this.serverToUserChannel.disconnect();
+ this.serverToUserChannel = null;
+ }
+ if (this.signin_requested) {
+ this._signinDoneResolve();
+ }
+ }
+ _newSigninPromiseIfNeeded() {
+ if (!this.signin_requested) {
+ return;
+ }
+ if (this.signinDonePromise && !this.signinDonePromise.done) {
+ return;
+ }
+ const { promise, resolve } = flat_promise();
+ promise.done = false;
+ const setDone = () => {
+ promise.done = true;
+ };
+ promise.then(setDone).catch(setDone);
+ this.signinDonePromise = promise;
+ this._signinDoneResolve = resolve;
+ }
+ }
+ class Pusher2 {
+ static ready() {
+ Pusher2.isReady = true;
+ for (var i = 0, l2 = Pusher2.instances.length; i < l2; i++) {
+ Pusher2.instances[i].connect();
+ }
+ }
+ static getClientFeatures() {
+ return keys(filterObject({ ws: node_runtime.Transports.ws }, function(t) {
+ return t.isSupported({});
+ }));
+ }
+ constructor(app_key, options) {
+ checkAppKey(app_key);
+ validateOptions(options);
+ this.key = app_key;
+ this.options = options;
+ this.config = getConfig(this.options, this);
+ this.channels = factory.createChannels();
+ this.global_emitter = new Dispatcher();
+ this.sessionID = node_runtime.randomInt(1e9);
+ this.timeline = new Timeline(this.key, this.sessionID, {
+ cluster: this.config.cluster,
+ features: Pusher2.getClientFeatures(),
+ params: this.config.timelineParams || {},
+ limit: 50,
+ level: level.INFO,
+ version: defaults.VERSION
+ });
+ if (this.config.enableStats) {
+ this.timelineSender = factory.createTimelineSender(this.timeline, {
+ host: this.config.statsHost,
+ path: "/timeline/v2/" + node_runtime.TimelineTransport.name
+ });
+ }
+ var getStrategy = (options2) => {
+ return node_runtime.getDefaultStrategy(this.config, options2, defineTransport);
+ };
+ this.connection = factory.createConnectionManager(this.key, {
+ getStrategy,
+ timeline: this.timeline,
+ activityTimeout: this.config.activityTimeout,
+ pongTimeout: this.config.pongTimeout,
+ unavailableTimeout: this.config.unavailableTimeout,
+ useTLS: Boolean(this.config.useTLS)
+ });
+ this.connection.bind("connected", () => {
+ this.subscribeAll();
+ if (this.timelineSender) {
+ this.timelineSender.send(this.connection.isUsingTLS());
+ }
+ });
+ this.connection.bind("message", (event) => {
+ var eventName = event.event;
+ var internal = eventName.indexOf("pusher_internal:") === 0;
+ if (event.channel) {
+ var channel = this.channel(event.channel);
+ if (channel) {
+ channel.handleEvent(event);
+ }
+ }
+ if (!internal) {
+ this.global_emitter.emit(event.event, event.data);
+ }
+ });
+ this.connection.bind("connecting", () => {
+ this.channels.disconnect();
+ });
+ this.connection.bind("disconnected", () => {
+ this.channels.disconnect();
+ });
+ this.connection.bind("error", (err) => {
+ logger.warn(err);
+ });
+ Pusher2.instances.push(this);
+ this.timeline.info({ instances: Pusher2.instances.length });
+ this.user = new UserFacade(this);
+ if (Pusher2.isReady) {
+ this.connect();
+ }
+ }
+ switchCluster(options) {
+ const { appKey, cluster } = options;
+ this.key = appKey;
+ this.options = Object.assign(Object.assign({}, this.options), { cluster });
+ this.config = getConfig(this.options, this);
+ this.connection.switchCluster(this.key);
+ }
+ channel(name) {
+ return this.channels.find(name);
+ }
+ allChannels() {
+ return this.channels.all();
+ }
+ connect() {
+ this.connection.connect();
+ if (this.timelineSender) {
+ if (!this.timelineSenderTimer) {
+ var usingTLS = this.connection.isUsingTLS();
+ var timelineSender = this.timelineSender;
+ this.timelineSenderTimer = new PeriodicTimer(6e4, function() {
+ timelineSender.send(usingTLS);
+ });
+ }
+ }
+ }
+ disconnect() {
+ this.connection.disconnect();
+ if (this.timelineSenderTimer) {
+ this.timelineSenderTimer.ensureAborted();
+ this.timelineSenderTimer = null;
+ }
+ }
+ bind(event_name, callback, context) {
+ this.global_emitter.bind(event_name, callback, context);
+ return this;
+ }
+ unbind(event_name, callback, context) {
+ this.global_emitter.unbind(event_name, callback, context);
+ return this;
+ }
+ bind_global(callback) {
+ this.global_emitter.bind_global(callback);
+ return this;
+ }
+ unbind_global(callback) {
+ this.global_emitter.unbind_global(callback);
+ return this;
+ }
+ unbind_all(callback) {
+ this.global_emitter.unbind_all();
+ return this;
+ }
+ subscribeAll() {
+ var channelName;
+ for (channelName in this.channels.channels) {
+ if (this.channels.channels.hasOwnProperty(channelName)) {
+ this.subscribe(channelName);
+ }
+ }
+ }
+ subscribe(channel_name) {
+ var channel = this.channels.add(channel_name, this);
+ if (channel.subscriptionPending && channel.subscriptionCancelled) {
+ channel.reinstateSubscription();
+ } else if (!channel.subscriptionPending && this.connection.state === "connected") {
+ channel.subscribe();
+ }
+ return channel;
+ }
+ unsubscribe(channel_name) {
+ var channel = this.channels.find(channel_name);
+ if (channel && channel.subscriptionPending) {
+ channel.cancelSubscription();
+ } else {
+ channel = this.channels.remove(channel_name);
+ if (channel && channel.subscribed) {
+ channel.unsubscribe();
+ }
+ }
+ }
+ send_event(event_name, data, channel) {
+ return this.connection.send_event(event_name, data, channel);
+ }
+ shouldUseTLS() {
+ return this.config.useTLS;
+ }
+ signin() {
+ this.user.signin();
+ }
+ }
+ Pusher2.instances = [];
+ Pusher2.isReady = false;
+ Pusher2.logToConsole = false;
+ Pusher2.Runtime = node_runtime;
+ Pusher2.ScriptReceivers = node_runtime.ScriptReceivers;
+ Pusher2.DependenciesReceivers = node_runtime.DependenciesReceivers;
+ Pusher2.auth_callbacks = node_runtime.auth_callbacks;
+ const pusher2 = Pusher2;
+ function checkAppKey(key) {
+ if (key === null || key === void 0) {
+ throw "You must pass your app key when you instantiate Pusher.";
+ }
+ }
+ node_runtime.setup(Pusher2);
+ var nacl_fast = __webpack_require__2(601);
+ class PusherWithEncryption extends pusher2 {
+ constructor(app_key, options) {
+ pusher2.logToConsole = PusherWithEncryption.logToConsole;
+ pusher2.log = PusherWithEncryption.log;
+ validateOptions(options);
+ options.nacl = nacl_fast;
+ super(app_key, options);
+ }
+ }
+ },
+ /***/
+ 613(module2) {
+ module2.exports = require$$4$2;
+ },
+ /***/
+ 181(module2) {
+ module2.exports = require$$1$1;
+ },
+ /***/
+ 317(module2) {
+ module2.exports = require$$2;
+ },
+ /***/
+ 982(module2) {
+ module2.exports = require$$1;
+ },
+ /***/
+ 434(module2) {
+ module2.exports = require$$4$1;
+ },
+ /***/
+ 896(module2) {
+ module2.exports = require$$6;
+ },
+ /***/
+ 611(module2) {
+ module2.exports = require$$3;
+ },
+ /***/
+ 692(module2) {
+ module2.exports = require$$4;
+ },
+ /***/
+ 278(module2) {
+ module2.exports = require$$8;
+ },
+ /***/
+ 203(module2) {
+ module2.exports = stream;
+ },
+ /***/
+ 756(module2) {
+ module2.exports = require$$10;
+ },
+ /***/
+ 16(module2) {
+ module2.exports = require$$5;
+ },
+ /***/
+ 23(module2) {
+ module2.exports = require$$0;
+ }
+ /******/
+ };
+ var __webpack_module_cache__ = {};
+ function __webpack_require__(moduleId) {
+ var cachedModule = __webpack_module_cache__[moduleId];
+ if (cachedModule !== void 0) {
+ return cachedModule.exports;
+ }
+ var module2 = __webpack_module_cache__[moduleId] = {
+ /******/
+ // no module.id needed
+ /******/
+ // no module.loaded needed
+ /******/
+ exports: {}
+ /******/
+ };
+ __webpack_modules__[moduleId].call(module2.exports, module2, module2.exports, __webpack_require__);
+ return module2.exports;
+ }
+ (() => {
+ __webpack_require__.d = (exports$1, definition) => {
+ for (var key in definition) {
+ if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports$1, key)) {
+ Object.defineProperty(exports$1, key, { enumerable: true, get: definition[key] });
+ }
+ }
+ };
+ })();
+ (() => {
+ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
+ })();
+ var __webpack_exports__ = __webpack_require__(42);
+ module.exports.Pusher = __webpack_exports__;
+ })();
+ })(pusher);
+ return pusher.exports;
+}
+var pusherExports = requirePusher();
+const Pusher = /* @__PURE__ */ getDefaultExportFromCjs(pusherExports);
+export {
+ E,
+ Pusher as P
+};
diff --git a/bootstrap/ssr/assets/vendor-tiptap-DSw66HfW.js b/bootstrap/ssr/assets/vendor-tiptap-DSw66HfW.js
new file mode 100644
index 00000000..b953fda0
--- /dev/null
+++ b/bootstrap/ssr/assets/vendor-tiptap-DSw66HfW.js
@@ -0,0 +1,27177 @@
+var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
+function getDefaultExportFromCjs(x) {
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
+}
+var react = { exports: {} };
+var react_production = {};
+var hasRequiredReact_production;
+function requireReact_production() {
+ if (hasRequiredReact_production) return react_production;
+ hasRequiredReact_production = 1;
+ var REACT_ELEMENT_TYPE = /* @__PURE__ */ Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = /* @__PURE__ */ Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = /* @__PURE__ */ Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = /* @__PURE__ */ Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = /* @__PURE__ */ Symbol.for("react.profiler"), REACT_CONSUMER_TYPE = /* @__PURE__ */ Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = /* @__PURE__ */ Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = /* @__PURE__ */ Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = /* @__PURE__ */ Symbol.for("react.suspense"), REACT_MEMO_TYPE = /* @__PURE__ */ Symbol.for("react.memo"), REACT_LAZY_TYPE = /* @__PURE__ */ Symbol.for("react.lazy"), REACT_ACTIVITY_TYPE = /* @__PURE__ */ Symbol.for("react.activity"), MAYBE_ITERATOR_SYMBOL = Symbol.iterator;
+ function getIteratorFn(maybeIterable) {
+ if (null === maybeIterable || "object" !== typeof maybeIterable) return null;
+ maybeIterable = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable["@@iterator"];
+ return "function" === typeof maybeIterable ? maybeIterable : null;
+ }
+ var ReactNoopUpdateQueue = {
+ isMounted: function() {
+ return false;
+ },
+ enqueueForceUpdate: function() {
+ },
+ enqueueReplaceState: function() {
+ },
+ enqueueSetState: function() {
+ }
+ }, assign = Object.assign, emptyObject = {};
+ function Component(props, context, updater) {
+ this.props = props;
+ this.context = context;
+ this.refs = emptyObject;
+ this.updater = updater || ReactNoopUpdateQueue;
+ }
+ Component.prototype.isReactComponent = {};
+ Component.prototype.setState = function(partialState, callback) {
+ if ("object" !== typeof partialState && "function" !== typeof partialState && null != partialState)
+ throw Error(
+ "takes an object of state variables to update or a function which returns an object of state variables."
+ );
+ this.updater.enqueueSetState(this, partialState, callback, "setState");
+ };
+ Component.prototype.forceUpdate = function(callback) {
+ this.updater.enqueueForceUpdate(this, callback, "forceUpdate");
+ };
+ function ComponentDummy() {
+ }
+ ComponentDummy.prototype = Component.prototype;
+ function PureComponent(props, context, updater) {
+ this.props = props;
+ this.context = context;
+ this.refs = emptyObject;
+ this.updater = updater || ReactNoopUpdateQueue;
+ }
+ var pureComponentPrototype = PureComponent.prototype = new ComponentDummy();
+ pureComponentPrototype.constructor = PureComponent;
+ assign(pureComponentPrototype, Component.prototype);
+ pureComponentPrototype.isPureReactComponent = true;
+ var isArrayImpl = Array.isArray;
+ function noop2() {
+ }
+ var ReactSharedInternals = { H: null, A: null, T: null, S: null }, hasOwnProperty2 = Object.prototype.hasOwnProperty;
+ function ReactElement(type, key, props) {
+ var refProp = props.ref;
+ return {
+ $$typeof: REACT_ELEMENT_TYPE,
+ type,
+ key,
+ ref: void 0 !== refProp ? refProp : null,
+ props
+ };
+ }
+ function cloneAndReplaceKey(oldElement, newKey) {
+ return ReactElement(oldElement.type, newKey, oldElement.props);
+ }
+ function isValidElement(object) {
+ return "object" === typeof object && null !== object && object.$$typeof === REACT_ELEMENT_TYPE;
+ }
+ function escape(key) {
+ var escaperLookup = { "=": "=0", ":": "=2" };
+ return "$" + key.replace(/[=:]/g, function(match) {
+ return escaperLookup[match];
+ });
+ }
+ var userProvidedKeyEscapeRegex = /\/+/g;
+ function getElementKey(element, index) {
+ return "object" === typeof element && null !== element && null != element.key ? escape("" + element.key) : index.toString(36);
+ }
+ function resolveThenable(thenable) {
+ switch (thenable.status) {
+ case "fulfilled":
+ return thenable.value;
+ case "rejected":
+ throw thenable.reason;
+ default:
+ switch ("string" === typeof thenable.status ? thenable.then(noop2, noop2) : (thenable.status = "pending", thenable.then(
+ function(fulfilledValue) {
+ "pending" === thenable.status && (thenable.status = "fulfilled", thenable.value = fulfilledValue);
+ },
+ function(error) {
+ "pending" === thenable.status && (thenable.status = "rejected", thenable.reason = error);
+ }
+ )), thenable.status) {
+ case "fulfilled":
+ return thenable.value;
+ case "rejected":
+ throw thenable.reason;
+ }
+ }
+ throw thenable;
+ }
+ function mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) {
+ var type = typeof children;
+ if ("undefined" === type || "boolean" === type) children = null;
+ var invokeCallback = false;
+ if (null === children) invokeCallback = true;
+ else
+ switch (type) {
+ case "bigint":
+ case "string":
+ case "number":
+ invokeCallback = true;
+ break;
+ case "object":
+ switch (children.$$typeof) {
+ case REACT_ELEMENT_TYPE:
+ case REACT_PORTAL_TYPE:
+ invokeCallback = true;
+ break;
+ case REACT_LAZY_TYPE:
+ return invokeCallback = children._init, mapIntoArray(
+ invokeCallback(children._payload),
+ array,
+ escapedPrefix,
+ nameSoFar,
+ callback
+ );
+ }
+ }
+ if (invokeCallback)
+ return callback = callback(children), invokeCallback = "" === nameSoFar ? "." + getElementKey(children, 0) : nameSoFar, isArrayImpl(callback) ? (escapedPrefix = "", null != invokeCallback && (escapedPrefix = invokeCallback.replace(userProvidedKeyEscapeRegex, "$&/") + "/"), mapIntoArray(callback, array, escapedPrefix, "", function(c) {
+ return c;
+ })) : null != callback && (isValidElement(callback) && (callback = cloneAndReplaceKey(
+ callback,
+ escapedPrefix + (null == callback.key || children && children.key === callback.key ? "" : ("" + callback.key).replace(
+ userProvidedKeyEscapeRegex,
+ "$&/"
+ ) + "/") + invokeCallback
+ )), array.push(callback)), 1;
+ invokeCallback = 0;
+ var nextNamePrefix = "" === nameSoFar ? "." : nameSoFar + ":";
+ if (isArrayImpl(children))
+ for (var i = 0; i < children.length; i++)
+ nameSoFar = children[i], type = nextNamePrefix + getElementKey(nameSoFar, i), invokeCallback += mapIntoArray(
+ nameSoFar,
+ array,
+ escapedPrefix,
+ type,
+ callback
+ );
+ else if (i = getIteratorFn(children), "function" === typeof i)
+ for (children = i.call(children), i = 0; !(nameSoFar = children.next()).done; )
+ nameSoFar = nameSoFar.value, type = nextNamePrefix + getElementKey(nameSoFar, i++), invokeCallback += mapIntoArray(
+ nameSoFar,
+ array,
+ escapedPrefix,
+ type,
+ callback
+ );
+ else if ("object" === type) {
+ if ("function" === typeof children.then)
+ return mapIntoArray(
+ resolveThenable(children),
+ array,
+ escapedPrefix,
+ nameSoFar,
+ callback
+ );
+ array = String(children);
+ throw Error(
+ "Objects are not valid as a React child (found: " + ("[object Object]" === array ? "object with keys {" + Object.keys(children).join(", ") + "}" : array) + "). If you meant to render a collection of children, use an array instead."
+ );
+ }
+ return invokeCallback;
+ }
+ function mapChildren2(children, func, context) {
+ if (null == children) return children;
+ var result = [], count = 0;
+ mapIntoArray(children, result, "", "", function(child) {
+ return func.call(context, child, count++);
+ });
+ return result;
+ }
+ function lazyInitializer(payload) {
+ if (-1 === payload._status) {
+ var ctor = payload._result;
+ ctor = ctor();
+ ctor.then(
+ function(moduleObject) {
+ if (0 === payload._status || -1 === payload._status)
+ payload._status = 1, payload._result = moduleObject;
+ },
+ function(error) {
+ if (0 === payload._status || -1 === payload._status)
+ payload._status = 2, payload._result = error;
+ }
+ );
+ -1 === payload._status && (payload._status = 0, payload._result = ctor);
+ }
+ if (1 === payload._status) return payload._result.default;
+ throw payload._result;
+ }
+ var reportGlobalError = "function" === typeof reportError ? reportError : function(error) {
+ if ("object" === typeof window && "function" === typeof window.ErrorEvent) {
+ var event = new window.ErrorEvent("error", {
+ bubbles: true,
+ cancelable: true,
+ message: "object" === typeof error && null !== error && "string" === typeof error.message ? String(error.message) : String(error),
+ error
+ });
+ if (!window.dispatchEvent(event)) return;
+ } else if ("object" === typeof process && "function" === typeof process.emit) {
+ process.emit("uncaughtException", error);
+ return;
+ }
+ console.error(error);
+ }, Children = {
+ map: mapChildren2,
+ forEach: function(children, forEachFunc, forEachContext) {
+ mapChildren2(
+ children,
+ function() {
+ forEachFunc.apply(this, arguments);
+ },
+ forEachContext
+ );
+ },
+ count: function(children) {
+ var n = 0;
+ mapChildren2(children, function() {
+ n++;
+ });
+ return n;
+ },
+ toArray: function(children) {
+ return mapChildren2(children, function(child) {
+ return child;
+ }) || [];
+ },
+ only: function(children) {
+ if (!isValidElement(children))
+ throw Error(
+ "React.Children.only expected to receive a single React element child."
+ );
+ return children;
+ }
+ };
+ react_production.Activity = REACT_ACTIVITY_TYPE;
+ react_production.Children = Children;
+ react_production.Component = Component;
+ react_production.Fragment = REACT_FRAGMENT_TYPE;
+ react_production.Profiler = REACT_PROFILER_TYPE;
+ react_production.PureComponent = PureComponent;
+ react_production.StrictMode = REACT_STRICT_MODE_TYPE;
+ react_production.Suspense = REACT_SUSPENSE_TYPE;
+ react_production.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = ReactSharedInternals;
+ react_production.__COMPILER_RUNTIME = {
+ __proto__: null,
+ c: function(size) {
+ return ReactSharedInternals.H.useMemoCache(size);
+ }
+ };
+ react_production.cache = function(fn) {
+ return function() {
+ return fn.apply(null, arguments);
+ };
+ };
+ react_production.cacheSignal = function() {
+ return null;
+ };
+ react_production.cloneElement = function(element, config, children) {
+ if (null === element || void 0 === element)
+ throw Error(
+ "The argument must be a React element, but you passed " + element + "."
+ );
+ var props = assign({}, element.props), key = element.key;
+ if (null != config)
+ for (propName in void 0 !== config.key && (key = "" + config.key), config)
+ !hasOwnProperty2.call(config, propName) || "key" === propName || "__self" === propName || "__source" === propName || "ref" === propName && void 0 === config.ref || (props[propName] = config[propName]);
+ var propName = arguments.length - 2;
+ if (1 === propName) props.children = children;
+ else if (1 < propName) {
+ for (var childArray = Array(propName), i = 0; i < propName; i++)
+ childArray[i] = arguments[i + 2];
+ props.children = childArray;
+ }
+ return ReactElement(element.type, key, props);
+ };
+ react_production.createContext = function(defaultValue) {
+ defaultValue = {
+ $$typeof: REACT_CONTEXT_TYPE,
+ _currentValue: defaultValue,
+ _currentValue2: defaultValue,
+ _threadCount: 0,
+ Provider: null,
+ Consumer: null
+ };
+ defaultValue.Provider = defaultValue;
+ defaultValue.Consumer = {
+ $$typeof: REACT_CONSUMER_TYPE,
+ _context: defaultValue
+ };
+ return defaultValue;
+ };
+ react_production.createElement = function(type, config, children) {
+ var propName, props = {}, key = null;
+ if (null != config)
+ for (propName in void 0 !== config.key && (key = "" + config.key), config)
+ hasOwnProperty2.call(config, propName) && "key" !== propName && "__self" !== propName && "__source" !== propName && (props[propName] = config[propName]);
+ var childrenLength = arguments.length - 2;
+ if (1 === childrenLength) props.children = children;
+ else if (1 < childrenLength) {
+ for (var childArray = Array(childrenLength), i = 0; i < childrenLength; i++)
+ childArray[i] = arguments[i + 2];
+ props.children = childArray;
+ }
+ if (type && type.defaultProps)
+ for (propName in childrenLength = type.defaultProps, childrenLength)
+ void 0 === props[propName] && (props[propName] = childrenLength[propName]);
+ return ReactElement(type, key, props);
+ };
+ react_production.createRef = function() {
+ return { current: null };
+ };
+ react_production.forwardRef = function(render) {
+ return { $$typeof: REACT_FORWARD_REF_TYPE, render };
+ };
+ react_production.isValidElement = isValidElement;
+ react_production.lazy = function(ctor) {
+ return {
+ $$typeof: REACT_LAZY_TYPE,
+ _payload: { _status: -1, _result: ctor },
+ _init: lazyInitializer
+ };
+ };
+ react_production.memo = function(type, compare) {
+ return {
+ $$typeof: REACT_MEMO_TYPE,
+ type,
+ compare: void 0 === compare ? null : compare
+ };
+ };
+ react_production.startTransition = function(scope) {
+ var prevTransition = ReactSharedInternals.T, currentTransition = {};
+ ReactSharedInternals.T = currentTransition;
+ try {
+ var returnValue = scope(), onStartTransitionFinish = ReactSharedInternals.S;
+ null !== onStartTransitionFinish && onStartTransitionFinish(currentTransition, returnValue);
+ "object" === typeof returnValue && null !== returnValue && "function" === typeof returnValue.then && returnValue.then(noop2, reportGlobalError);
+ } catch (error) {
+ reportGlobalError(error);
+ } finally {
+ null !== prevTransition && null !== currentTransition.types && (prevTransition.types = currentTransition.types), ReactSharedInternals.T = prevTransition;
+ }
+ };
+ react_production.unstable_useCacheRefresh = function() {
+ return ReactSharedInternals.H.useCacheRefresh();
+ };
+ react_production.use = function(usable) {
+ return ReactSharedInternals.H.use(usable);
+ };
+ react_production.useActionState = function(action, initialState, permalink) {
+ return ReactSharedInternals.H.useActionState(action, initialState, permalink);
+ };
+ react_production.useCallback = function(callback, deps) {
+ return ReactSharedInternals.H.useCallback(callback, deps);
+ };
+ react_production.useContext = function(Context) {
+ return ReactSharedInternals.H.useContext(Context);
+ };
+ react_production.useDebugValue = function() {
+ };
+ react_production.useDeferredValue = function(value, initialValue) {
+ return ReactSharedInternals.H.useDeferredValue(value, initialValue);
+ };
+ react_production.useEffect = function(create, deps) {
+ return ReactSharedInternals.H.useEffect(create, deps);
+ };
+ react_production.useEffectEvent = function(callback) {
+ return ReactSharedInternals.H.useEffectEvent(callback);
+ };
+ react_production.useId = function() {
+ return ReactSharedInternals.H.useId();
+ };
+ react_production.useImperativeHandle = function(ref, create, deps) {
+ return ReactSharedInternals.H.useImperativeHandle(ref, create, deps);
+ };
+ react_production.useInsertionEffect = function(create, deps) {
+ return ReactSharedInternals.H.useInsertionEffect(create, deps);
+ };
+ react_production.useLayoutEffect = function(create, deps) {
+ return ReactSharedInternals.H.useLayoutEffect(create, deps);
+ };
+ react_production.useMemo = function(create, deps) {
+ return ReactSharedInternals.H.useMemo(create, deps);
+ };
+ react_production.useOptimistic = function(passthrough, reducer) {
+ return ReactSharedInternals.H.useOptimistic(passthrough, reducer);
+ };
+ react_production.useReducer = function(reducer, initialArg, init2) {
+ return ReactSharedInternals.H.useReducer(reducer, initialArg, init2);
+ };
+ react_production.useRef = function(initialValue) {
+ return ReactSharedInternals.H.useRef(initialValue);
+ };
+ react_production.useState = function(initialState) {
+ return ReactSharedInternals.H.useState(initialState);
+ };
+ react_production.useSyncExternalStore = function(subscribe, getSnapshot, getServerSnapshot) {
+ return ReactSharedInternals.H.useSyncExternalStore(
+ subscribe,
+ getSnapshot,
+ getServerSnapshot
+ );
+ };
+ react_production.useTransition = function() {
+ return ReactSharedInternals.H.useTransition();
+ };
+ react_production.version = "19.2.4";
+ return react_production;
+}
+var react_development = { exports: {} };
+react_development.exports;
+var hasRequiredReact_development;
+function requireReact_development() {
+ if (hasRequiredReact_development) return react_development.exports;
+ hasRequiredReact_development = 1;
+ (function(module, exports$1) {
+ "production" !== process.env.NODE_ENV && (function() {
+ function defineDeprecationWarning(methodName, info) {
+ Object.defineProperty(Component.prototype, methodName, {
+ get: function() {
+ console.warn(
+ "%s(...) is deprecated in plain JavaScript React classes. %s",
+ info[0],
+ info[1]
+ );
+ }
+ });
+ }
+ function getIteratorFn(maybeIterable) {
+ if (null === maybeIterable || "object" !== typeof maybeIterable)
+ return null;
+ maybeIterable = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable["@@iterator"];
+ return "function" === typeof maybeIterable ? maybeIterable : null;
+ }
+ function warnNoop(publicInstance, callerName) {
+ publicInstance = (publicInstance = publicInstance.constructor) && (publicInstance.displayName || publicInstance.name) || "ReactClass";
+ var warningKey = publicInstance + "." + callerName;
+ didWarnStateUpdateForUnmountedComponent[warningKey] || (console.error(
+ "Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.",
+ callerName,
+ publicInstance
+ ), didWarnStateUpdateForUnmountedComponent[warningKey] = true);
+ }
+ function Component(props, context, updater) {
+ this.props = props;
+ this.context = context;
+ this.refs = emptyObject;
+ this.updater = updater || ReactNoopUpdateQueue;
+ }
+ function ComponentDummy() {
+ }
+ function PureComponent(props, context, updater) {
+ this.props = props;
+ this.context = context;
+ this.refs = emptyObject;
+ this.updater = updater || ReactNoopUpdateQueue;
+ }
+ function noop2() {
+ }
+ function testStringCoercion(value) {
+ return "" + value;
+ }
+ function checkKeyStringCoercion(value) {
+ try {
+ testStringCoercion(value);
+ var JSCompiler_inline_result = false;
+ } catch (e) {
+ JSCompiler_inline_result = true;
+ }
+ if (JSCompiler_inline_result) {
+ JSCompiler_inline_result = console;
+ var JSCompiler_temp_const = JSCompiler_inline_result.error;
+ var JSCompiler_inline_result$jscomp$0 = "function" === typeof Symbol && Symbol.toStringTag && value[Symbol.toStringTag] || value.constructor.name || "Object";
+ JSCompiler_temp_const.call(
+ JSCompiler_inline_result,
+ "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
+ JSCompiler_inline_result$jscomp$0
+ );
+ return testStringCoercion(value);
+ }
+ }
+ function getComponentNameFromType(type) {
+ if (null == type) return null;
+ if ("function" === typeof type)
+ return type.$$typeof === REACT_CLIENT_REFERENCE ? null : type.displayName || type.name || null;
+ if ("string" === typeof type) return type;
+ switch (type) {
+ case REACT_FRAGMENT_TYPE:
+ return "Fragment";
+ case REACT_PROFILER_TYPE:
+ return "Profiler";
+ case REACT_STRICT_MODE_TYPE:
+ return "StrictMode";
+ case REACT_SUSPENSE_TYPE:
+ return "Suspense";
+ case REACT_SUSPENSE_LIST_TYPE:
+ return "SuspenseList";
+ case REACT_ACTIVITY_TYPE:
+ return "Activity";
+ }
+ if ("object" === typeof type)
+ switch ("number" === typeof type.tag && console.error(
+ "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
+ ), type.$$typeof) {
+ case REACT_PORTAL_TYPE:
+ return "Portal";
+ case REACT_CONTEXT_TYPE:
+ return type.displayName || "Context";
+ case REACT_CONSUMER_TYPE:
+ return (type._context.displayName || "Context") + ".Consumer";
+ case REACT_FORWARD_REF_TYPE:
+ var innerType = type.render;
+ type = type.displayName;
+ type || (type = innerType.displayName || innerType.name || "", type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef");
+ return type;
+ case REACT_MEMO_TYPE:
+ return innerType = type.displayName || null, null !== innerType ? innerType : getComponentNameFromType(type.type) || "Memo";
+ case REACT_LAZY_TYPE:
+ innerType = type._payload;
+ type = type._init;
+ try {
+ return getComponentNameFromType(type(innerType));
+ } catch (x) {
+ }
+ }
+ return null;
+ }
+ function getTaskName(type) {
+ if (type === REACT_FRAGMENT_TYPE) return "<>";
+ if ("object" === typeof type && null !== type && type.$$typeof === REACT_LAZY_TYPE)
+ return "<...>";
+ try {
+ var name = getComponentNameFromType(type);
+ return name ? "<" + name + ">" : "<...>";
+ } catch (x) {
+ return "<...>";
+ }
+ }
+ function getOwner() {
+ var dispatcher = ReactSharedInternals.A;
+ return null === dispatcher ? null : dispatcher.getOwner();
+ }
+ function UnknownOwner() {
+ return Error("react-stack-top-frame");
+ }
+ function hasValidKey(config) {
+ if (hasOwnProperty2.call(config, "key")) {
+ var getter = Object.getOwnPropertyDescriptor(config, "key").get;
+ if (getter && getter.isReactWarning) return false;
+ }
+ return void 0 !== config.key;
+ }
+ function defineKeyPropWarningGetter(props, displayName) {
+ function warnAboutAccessingKey() {
+ specialPropKeyWarningShown || (specialPropKeyWarningShown = true, console.error(
+ "%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",
+ displayName
+ ));
+ }
+ warnAboutAccessingKey.isReactWarning = true;
+ Object.defineProperty(props, "key", {
+ get: warnAboutAccessingKey,
+ configurable: true
+ });
+ }
+ function elementRefGetterWithDeprecationWarning() {
+ var componentName = getComponentNameFromType(this.type);
+ didWarnAboutElementRef[componentName] || (didWarnAboutElementRef[componentName] = true, console.error(
+ "Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."
+ ));
+ componentName = this.props.ref;
+ return void 0 !== componentName ? componentName : null;
+ }
+ function ReactElement(type, key, props, owner, debugStack, debugTask) {
+ var refProp = props.ref;
+ type = {
+ $$typeof: REACT_ELEMENT_TYPE,
+ type,
+ key,
+ props,
+ _owner: owner
+ };
+ null !== (void 0 !== refProp ? refProp : null) ? Object.defineProperty(type, "ref", {
+ enumerable: false,
+ get: elementRefGetterWithDeprecationWarning
+ }) : Object.defineProperty(type, "ref", { enumerable: false, value: null });
+ type._store = {};
+ Object.defineProperty(type._store, "validated", {
+ configurable: false,
+ enumerable: false,
+ writable: true,
+ value: 0
+ });
+ Object.defineProperty(type, "_debugInfo", {
+ configurable: false,
+ enumerable: false,
+ writable: true,
+ value: null
+ });
+ Object.defineProperty(type, "_debugStack", {
+ configurable: false,
+ enumerable: false,
+ writable: true,
+ value: debugStack
+ });
+ Object.defineProperty(type, "_debugTask", {
+ configurable: false,
+ enumerable: false,
+ writable: true,
+ value: debugTask
+ });
+ Object.freeze && (Object.freeze(type.props), Object.freeze(type));
+ return type;
+ }
+ function cloneAndReplaceKey(oldElement, newKey) {
+ newKey = ReactElement(
+ oldElement.type,
+ newKey,
+ oldElement.props,
+ oldElement._owner,
+ oldElement._debugStack,
+ oldElement._debugTask
+ );
+ oldElement._store && (newKey._store.validated = oldElement._store.validated);
+ return newKey;
+ }
+ function validateChildKeys(node) {
+ isValidElement(node) ? node._store && (node._store.validated = 1) : "object" === typeof node && null !== node && node.$$typeof === REACT_LAZY_TYPE && ("fulfilled" === node._payload.status ? isValidElement(node._payload.value) && node._payload.value._store && (node._payload.value._store.validated = 1) : node._store && (node._store.validated = 1));
+ }
+ function isValidElement(object) {
+ return "object" === typeof object && null !== object && object.$$typeof === REACT_ELEMENT_TYPE;
+ }
+ function escape(key) {
+ var escaperLookup = { "=": "=0", ":": "=2" };
+ return "$" + key.replace(/[=:]/g, function(match) {
+ return escaperLookup[match];
+ });
+ }
+ function getElementKey(element, index) {
+ return "object" === typeof element && null !== element && null != element.key ? (checkKeyStringCoercion(element.key), escape("" + element.key)) : index.toString(36);
+ }
+ function resolveThenable(thenable) {
+ switch (thenable.status) {
+ case "fulfilled":
+ return thenable.value;
+ case "rejected":
+ throw thenable.reason;
+ default:
+ switch ("string" === typeof thenable.status ? thenable.then(noop2, noop2) : (thenable.status = "pending", thenable.then(
+ function(fulfilledValue) {
+ "pending" === thenable.status && (thenable.status = "fulfilled", thenable.value = fulfilledValue);
+ },
+ function(error) {
+ "pending" === thenable.status && (thenable.status = "rejected", thenable.reason = error);
+ }
+ )), thenable.status) {
+ case "fulfilled":
+ return thenable.value;
+ case "rejected":
+ throw thenable.reason;
+ }
+ }
+ throw thenable;
+ }
+ function mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) {
+ var type = typeof children;
+ if ("undefined" === type || "boolean" === type) children = null;
+ var invokeCallback = false;
+ if (null === children) invokeCallback = true;
+ else
+ switch (type) {
+ case "bigint":
+ case "string":
+ case "number":
+ invokeCallback = true;
+ break;
+ case "object":
+ switch (children.$$typeof) {
+ case REACT_ELEMENT_TYPE:
+ case REACT_PORTAL_TYPE:
+ invokeCallback = true;
+ break;
+ case REACT_LAZY_TYPE:
+ return invokeCallback = children._init, mapIntoArray(
+ invokeCallback(children._payload),
+ array,
+ escapedPrefix,
+ nameSoFar,
+ callback
+ );
+ }
+ }
+ if (invokeCallback) {
+ invokeCallback = children;
+ callback = callback(invokeCallback);
+ var childKey = "" === nameSoFar ? "." + getElementKey(invokeCallback, 0) : nameSoFar;
+ isArrayImpl(callback) ? (escapedPrefix = "", null != childKey && (escapedPrefix = childKey.replace(userProvidedKeyEscapeRegex, "$&/") + "/"), mapIntoArray(callback, array, escapedPrefix, "", function(c) {
+ return c;
+ })) : null != callback && (isValidElement(callback) && (null != callback.key && (invokeCallback && invokeCallback.key === callback.key || checkKeyStringCoercion(callback.key)), escapedPrefix = cloneAndReplaceKey(
+ callback,
+ escapedPrefix + (null == callback.key || invokeCallback && invokeCallback.key === callback.key ? "" : ("" + callback.key).replace(
+ userProvidedKeyEscapeRegex,
+ "$&/"
+ ) + "/") + childKey
+ ), "" !== nameSoFar && null != invokeCallback && isValidElement(invokeCallback) && null == invokeCallback.key && invokeCallback._store && !invokeCallback._store.validated && (escapedPrefix._store.validated = 2), callback = escapedPrefix), array.push(callback));
+ return 1;
+ }
+ invokeCallback = 0;
+ childKey = "" === nameSoFar ? "." : nameSoFar + ":";
+ if (isArrayImpl(children))
+ for (var i = 0; i < children.length; i++)
+ nameSoFar = children[i], type = childKey + getElementKey(nameSoFar, i), invokeCallback += mapIntoArray(
+ nameSoFar,
+ array,
+ escapedPrefix,
+ type,
+ callback
+ );
+ else if (i = getIteratorFn(children), "function" === typeof i)
+ for (i === children.entries && (didWarnAboutMaps || console.warn(
+ "Using Maps as children is not supported. Use an array of keyed ReactElements instead."
+ ), didWarnAboutMaps = true), children = i.call(children), i = 0; !(nameSoFar = children.next()).done; )
+ nameSoFar = nameSoFar.value, type = childKey + getElementKey(nameSoFar, i++), invokeCallback += mapIntoArray(
+ nameSoFar,
+ array,
+ escapedPrefix,
+ type,
+ callback
+ );
+ else if ("object" === type) {
+ if ("function" === typeof children.then)
+ return mapIntoArray(
+ resolveThenable(children),
+ array,
+ escapedPrefix,
+ nameSoFar,
+ callback
+ );
+ array = String(children);
+ throw Error(
+ "Objects are not valid as a React child (found: " + ("[object Object]" === array ? "object with keys {" + Object.keys(children).join(", ") + "}" : array) + "). If you meant to render a collection of children, use an array instead."
+ );
+ }
+ return invokeCallback;
+ }
+ function mapChildren2(children, func, context) {
+ if (null == children) return children;
+ var result = [], count = 0;
+ mapIntoArray(children, result, "", "", function(child) {
+ return func.call(context, child, count++);
+ });
+ return result;
+ }
+ function lazyInitializer(payload) {
+ if (-1 === payload._status) {
+ var ioInfo = payload._ioInfo;
+ null != ioInfo && (ioInfo.start = ioInfo.end = performance.now());
+ ioInfo = payload._result;
+ var thenable = ioInfo();
+ thenable.then(
+ function(moduleObject) {
+ if (0 === payload._status || -1 === payload._status) {
+ payload._status = 1;
+ payload._result = moduleObject;
+ var _ioInfo = payload._ioInfo;
+ null != _ioInfo && (_ioInfo.end = performance.now());
+ void 0 === thenable.status && (thenable.status = "fulfilled", thenable.value = moduleObject);
+ }
+ },
+ function(error) {
+ if (0 === payload._status || -1 === payload._status) {
+ payload._status = 2;
+ payload._result = error;
+ var _ioInfo2 = payload._ioInfo;
+ null != _ioInfo2 && (_ioInfo2.end = performance.now());
+ void 0 === thenable.status && (thenable.status = "rejected", thenable.reason = error);
+ }
+ }
+ );
+ ioInfo = payload._ioInfo;
+ if (null != ioInfo) {
+ ioInfo.value = thenable;
+ var displayName = thenable.displayName;
+ "string" === typeof displayName && (ioInfo.name = displayName);
+ }
+ -1 === payload._status && (payload._status = 0, payload._result = thenable);
+ }
+ if (1 === payload._status)
+ return ioInfo = payload._result, void 0 === ioInfo && console.error(
+ "lazy: Expected the result of a dynamic import() call. Instead received: %s\n\nYour code should look like: \n const MyComponent = lazy(() => import('./MyComponent'))\n\nDid you accidentally put curly braces around the import?",
+ ioInfo
+ ), "default" in ioInfo || console.error(
+ "lazy: Expected the result of a dynamic import() call. Instead received: %s\n\nYour code should look like: \n const MyComponent = lazy(() => import('./MyComponent'))",
+ ioInfo
+ ), ioInfo.default;
+ throw payload._result;
+ }
+ function resolveDispatcher() {
+ var dispatcher = ReactSharedInternals.H;
+ null === dispatcher && console.error(
+ "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem."
+ );
+ return dispatcher;
+ }
+ function releaseAsyncTransition() {
+ ReactSharedInternals.asyncTransitions--;
+ }
+ function enqueueTask(task) {
+ if (null === enqueueTaskImpl)
+ try {
+ var requireString = ("require" + Math.random()).slice(0, 7);
+ enqueueTaskImpl = (module && module[requireString]).call(
+ module,
+ "timers"
+ ).setImmediate;
+ } catch (_err) {
+ enqueueTaskImpl = function(callback) {
+ false === didWarnAboutMessageChannel && (didWarnAboutMessageChannel = true, "undefined" === typeof MessageChannel && console.error(
+ "This browser does not have a MessageChannel implementation, so enqueuing tasks via await act(async () => ...) will fail. Please file an issue at https://github.com/facebook/react/issues if you encounter this warning."
+ ));
+ var channel = new MessageChannel();
+ channel.port1.onmessage = callback;
+ channel.port2.postMessage(void 0);
+ };
+ }
+ return enqueueTaskImpl(task);
+ }
+ function aggregateErrors(errors) {
+ return 1 < errors.length && "function" === typeof AggregateError ? new AggregateError(errors) : errors[0];
+ }
+ function popActScope(prevActQueue, prevActScopeDepth) {
+ prevActScopeDepth !== actScopeDepth - 1 && console.error(
+ "You seem to have overlapping act() calls, this is not supported. Be sure to await previous act() calls before making a new one. "
+ );
+ actScopeDepth = prevActScopeDepth;
+ }
+ function recursivelyFlushAsyncActWork(returnValue, resolve, reject) {
+ var queue = ReactSharedInternals.actQueue;
+ if (null !== queue)
+ if (0 !== queue.length)
+ try {
+ flushActQueue(queue);
+ enqueueTask(function() {
+ return recursivelyFlushAsyncActWork(returnValue, resolve, reject);
+ });
+ return;
+ } catch (error) {
+ ReactSharedInternals.thrownErrors.push(error);
+ }
+ else ReactSharedInternals.actQueue = null;
+ 0 < ReactSharedInternals.thrownErrors.length ? (queue = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(queue)) : resolve(returnValue);
+ }
+ function flushActQueue(queue) {
+ if (!isFlushing) {
+ isFlushing = true;
+ var i = 0;
+ try {
+ for (; i < queue.length; i++) {
+ var callback = queue[i];
+ do {
+ ReactSharedInternals.didUsePromise = false;
+ var continuation = callback(false);
+ if (null !== continuation) {
+ if (ReactSharedInternals.didUsePromise) {
+ queue[i] = callback;
+ queue.splice(0, i);
+ return;
+ }
+ callback = continuation;
+ } else break;
+ } while (1);
+ }
+ queue.length = 0;
+ } catch (error) {
+ queue.splice(0, i + 1), ReactSharedInternals.thrownErrors.push(error);
+ } finally {
+ isFlushing = false;
+ }
+ }
+ }
+ "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
+ var REACT_ELEMENT_TYPE = /* @__PURE__ */ Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = /* @__PURE__ */ Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = /* @__PURE__ */ Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = /* @__PURE__ */ Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = /* @__PURE__ */ Symbol.for("react.profiler"), REACT_CONSUMER_TYPE = /* @__PURE__ */ Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = /* @__PURE__ */ Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = /* @__PURE__ */ Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = /* @__PURE__ */ Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = /* @__PURE__ */ Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = /* @__PURE__ */ Symbol.for("react.memo"), REACT_LAZY_TYPE = /* @__PURE__ */ Symbol.for("react.lazy"), REACT_ACTIVITY_TYPE = /* @__PURE__ */ Symbol.for("react.activity"), MAYBE_ITERATOR_SYMBOL = Symbol.iterator, didWarnStateUpdateForUnmountedComponent = {}, ReactNoopUpdateQueue = {
+ isMounted: function() {
+ return false;
+ },
+ enqueueForceUpdate: function(publicInstance) {
+ warnNoop(publicInstance, "forceUpdate");
+ },
+ enqueueReplaceState: function(publicInstance) {
+ warnNoop(publicInstance, "replaceState");
+ },
+ enqueueSetState: function(publicInstance) {
+ warnNoop(publicInstance, "setState");
+ }
+ }, assign = Object.assign, emptyObject = {};
+ Object.freeze(emptyObject);
+ Component.prototype.isReactComponent = {};
+ Component.prototype.setState = function(partialState, callback) {
+ if ("object" !== typeof partialState && "function" !== typeof partialState && null != partialState)
+ throw Error(
+ "takes an object of state variables to update or a function which returns an object of state variables."
+ );
+ this.updater.enqueueSetState(this, partialState, callback, "setState");
+ };
+ Component.prototype.forceUpdate = function(callback) {
+ this.updater.enqueueForceUpdate(this, callback, "forceUpdate");
+ };
+ var deprecatedAPIs = {
+ isMounted: [
+ "isMounted",
+ "Instead, make sure to clean up subscriptions and pending requests in componentWillUnmount to prevent memory leaks."
+ ],
+ replaceState: [
+ "replaceState",
+ "Refactor your code to use setState instead (see https://github.com/facebook/react/issues/3236)."
+ ]
+ };
+ for (fnName in deprecatedAPIs)
+ deprecatedAPIs.hasOwnProperty(fnName) && defineDeprecationWarning(fnName, deprecatedAPIs[fnName]);
+ ComponentDummy.prototype = Component.prototype;
+ deprecatedAPIs = PureComponent.prototype = new ComponentDummy();
+ deprecatedAPIs.constructor = PureComponent;
+ assign(deprecatedAPIs, Component.prototype);
+ deprecatedAPIs.isPureReactComponent = true;
+ var isArrayImpl = Array.isArray, REACT_CLIENT_REFERENCE = /* @__PURE__ */ Symbol.for("react.client.reference"), ReactSharedInternals = {
+ H: null,
+ A: null,
+ T: null,
+ S: null,
+ actQueue: null,
+ asyncTransitions: 0,
+ isBatchingLegacy: false,
+ didScheduleLegacyUpdate: false,
+ didUsePromise: false,
+ thrownErrors: [],
+ getCurrentStack: null,
+ recentlyCreatedOwnerStacks: 0
+ }, hasOwnProperty2 = Object.prototype.hasOwnProperty, createTask = console.createTask ? console.createTask : function() {
+ return null;
+ };
+ deprecatedAPIs = {
+ react_stack_bottom_frame: function(callStackForError) {
+ return callStackForError();
+ }
+ };
+ var specialPropKeyWarningShown, didWarnAboutOldJSXRuntime;
+ var didWarnAboutElementRef = {};
+ var unknownOwnerDebugStack = deprecatedAPIs.react_stack_bottom_frame.bind(
+ deprecatedAPIs,
+ UnknownOwner
+ )();
+ var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));
+ var didWarnAboutMaps = false, userProvidedKeyEscapeRegex = /\/+/g, reportGlobalError = "function" === typeof reportError ? reportError : function(error) {
+ if ("object" === typeof window && "function" === typeof window.ErrorEvent) {
+ var event = new window.ErrorEvent("error", {
+ bubbles: true,
+ cancelable: true,
+ message: "object" === typeof error && null !== error && "string" === typeof error.message ? String(error.message) : String(error),
+ error
+ });
+ if (!window.dispatchEvent(event)) return;
+ } else if ("object" === typeof process && "function" === typeof process.emit) {
+ process.emit("uncaughtException", error);
+ return;
+ }
+ console.error(error);
+ }, didWarnAboutMessageChannel = false, enqueueTaskImpl = null, actScopeDepth = 0, didWarnNoAwaitAct = false, isFlushing = false, queueSeveralMicrotasks = "function" === typeof queueMicrotask ? function(callback) {
+ queueMicrotask(function() {
+ return queueMicrotask(callback);
+ });
+ } : enqueueTask;
+ deprecatedAPIs = Object.freeze({
+ __proto__: null,
+ c: function(size) {
+ return resolveDispatcher().useMemoCache(size);
+ }
+ });
+ var fnName = {
+ map: mapChildren2,
+ forEach: function(children, forEachFunc, forEachContext) {
+ mapChildren2(
+ children,
+ function() {
+ forEachFunc.apply(this, arguments);
+ },
+ forEachContext
+ );
+ },
+ count: function(children) {
+ var n = 0;
+ mapChildren2(children, function() {
+ n++;
+ });
+ return n;
+ },
+ toArray: function(children) {
+ return mapChildren2(children, function(child) {
+ return child;
+ }) || [];
+ },
+ only: function(children) {
+ if (!isValidElement(children))
+ throw Error(
+ "React.Children.only expected to receive a single React element child."
+ );
+ return children;
+ }
+ };
+ exports$1.Activity = REACT_ACTIVITY_TYPE;
+ exports$1.Children = fnName;
+ exports$1.Component = Component;
+ exports$1.Fragment = REACT_FRAGMENT_TYPE;
+ exports$1.Profiler = REACT_PROFILER_TYPE;
+ exports$1.PureComponent = PureComponent;
+ exports$1.StrictMode = REACT_STRICT_MODE_TYPE;
+ exports$1.Suspense = REACT_SUSPENSE_TYPE;
+ exports$1.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = ReactSharedInternals;
+ exports$1.__COMPILER_RUNTIME = deprecatedAPIs;
+ exports$1.act = function(callback) {
+ var prevActQueue = ReactSharedInternals.actQueue, prevActScopeDepth = actScopeDepth;
+ actScopeDepth++;
+ var queue = ReactSharedInternals.actQueue = null !== prevActQueue ? prevActQueue : [], didAwaitActCall = false;
+ try {
+ var result = callback();
+ } catch (error) {
+ ReactSharedInternals.thrownErrors.push(error);
+ }
+ if (0 < ReactSharedInternals.thrownErrors.length)
+ throw popActScope(prevActQueue, prevActScopeDepth), callback = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, callback;
+ if (null !== result && "object" === typeof result && "function" === typeof result.then) {
+ var thenable = result;
+ queueSeveralMicrotasks(function() {
+ didAwaitActCall || didWarnNoAwaitAct || (didWarnNoAwaitAct = true, console.error(
+ "You called act(async () => ...) without await. This could lead to unexpected testing behaviour, interleaving multiple act calls and mixing their scopes. You should - await act(async () => ...);"
+ ));
+ });
+ return {
+ then: function(resolve, reject) {
+ didAwaitActCall = true;
+ thenable.then(
+ function(returnValue) {
+ popActScope(prevActQueue, prevActScopeDepth);
+ if (0 === prevActScopeDepth) {
+ try {
+ flushActQueue(queue), enqueueTask(function() {
+ return recursivelyFlushAsyncActWork(
+ returnValue,
+ resolve,
+ reject
+ );
+ });
+ } catch (error$0) {
+ ReactSharedInternals.thrownErrors.push(error$0);
+ }
+ if (0 < ReactSharedInternals.thrownErrors.length) {
+ var _thrownError = aggregateErrors(
+ ReactSharedInternals.thrownErrors
+ );
+ ReactSharedInternals.thrownErrors.length = 0;
+ reject(_thrownError);
+ }
+ } else resolve(returnValue);
+ },
+ function(error) {
+ popActScope(prevActQueue, prevActScopeDepth);
+ 0 < ReactSharedInternals.thrownErrors.length ? (error = aggregateErrors(
+ ReactSharedInternals.thrownErrors
+ ), ReactSharedInternals.thrownErrors.length = 0, reject(error)) : reject(error);
+ }
+ );
+ }
+ };
+ }
+ var returnValue$jscomp$0 = result;
+ popActScope(prevActQueue, prevActScopeDepth);
+ 0 === prevActScopeDepth && (flushActQueue(queue), 0 !== queue.length && queueSeveralMicrotasks(function() {
+ didAwaitActCall || didWarnNoAwaitAct || (didWarnNoAwaitAct = true, console.error(
+ "A component suspended inside an `act` scope, but the `act` call was not awaited. When testing React components that depend on asynchronous data, you must await the result:\n\nawait act(() => ...)"
+ ));
+ }), ReactSharedInternals.actQueue = null);
+ if (0 < ReactSharedInternals.thrownErrors.length)
+ throw callback = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, callback;
+ return {
+ then: function(resolve, reject) {
+ didAwaitActCall = true;
+ 0 === prevActScopeDepth ? (ReactSharedInternals.actQueue = queue, enqueueTask(function() {
+ return recursivelyFlushAsyncActWork(
+ returnValue$jscomp$0,
+ resolve,
+ reject
+ );
+ })) : resolve(returnValue$jscomp$0);
+ }
+ };
+ };
+ exports$1.cache = function(fn) {
+ return function() {
+ return fn.apply(null, arguments);
+ };
+ };
+ exports$1.cacheSignal = function() {
+ return null;
+ };
+ exports$1.captureOwnerStack = function() {
+ var getCurrentStack = ReactSharedInternals.getCurrentStack;
+ return null === getCurrentStack ? null : getCurrentStack();
+ };
+ exports$1.cloneElement = function(element, config, children) {
+ if (null === element || void 0 === element)
+ throw Error(
+ "The argument must be a React element, but you passed " + element + "."
+ );
+ var props = assign({}, element.props), key = element.key, owner = element._owner;
+ if (null != config) {
+ var JSCompiler_inline_result;
+ a: {
+ if (hasOwnProperty2.call(config, "ref") && (JSCompiler_inline_result = Object.getOwnPropertyDescriptor(
+ config,
+ "ref"
+ ).get) && JSCompiler_inline_result.isReactWarning) {
+ JSCompiler_inline_result = false;
+ break a;
+ }
+ JSCompiler_inline_result = void 0 !== config.ref;
+ }
+ JSCompiler_inline_result && (owner = getOwner());
+ hasValidKey(config) && (checkKeyStringCoercion(config.key), key = "" + config.key);
+ for (propName in config)
+ !hasOwnProperty2.call(config, propName) || "key" === propName || "__self" === propName || "__source" === propName || "ref" === propName && void 0 === config.ref || (props[propName] = config[propName]);
+ }
+ var propName = arguments.length - 2;
+ if (1 === propName) props.children = children;
+ else if (1 < propName) {
+ JSCompiler_inline_result = Array(propName);
+ for (var i = 0; i < propName; i++)
+ JSCompiler_inline_result[i] = arguments[i + 2];
+ props.children = JSCompiler_inline_result;
+ }
+ props = ReactElement(
+ element.type,
+ key,
+ props,
+ owner,
+ element._debugStack,
+ element._debugTask
+ );
+ for (key = 2; key < arguments.length; key++)
+ validateChildKeys(arguments[key]);
+ return props;
+ };
+ exports$1.createContext = function(defaultValue) {
+ defaultValue = {
+ $$typeof: REACT_CONTEXT_TYPE,
+ _currentValue: defaultValue,
+ _currentValue2: defaultValue,
+ _threadCount: 0,
+ Provider: null,
+ Consumer: null
+ };
+ defaultValue.Provider = defaultValue;
+ defaultValue.Consumer = {
+ $$typeof: REACT_CONSUMER_TYPE,
+ _context: defaultValue
+ };
+ defaultValue._currentRenderer = null;
+ defaultValue._currentRenderer2 = null;
+ return defaultValue;
+ };
+ exports$1.createElement = function(type, config, children) {
+ for (var i = 2; i < arguments.length; i++)
+ validateChildKeys(arguments[i]);
+ i = {};
+ var key = null;
+ if (null != config)
+ for (propName in didWarnAboutOldJSXRuntime || !("__self" in config) || "key" in config || (didWarnAboutOldJSXRuntime = true, console.warn(
+ "Your app (or one of its dependencies) is using an outdated JSX transform. Update to the modern JSX transform for faster performance: https://react.dev/link/new-jsx-transform"
+ )), hasValidKey(config) && (checkKeyStringCoercion(config.key), key = "" + config.key), config)
+ hasOwnProperty2.call(config, propName) && "key" !== propName && "__self" !== propName && "__source" !== propName && (i[propName] = config[propName]);
+ var childrenLength = arguments.length - 2;
+ if (1 === childrenLength) i.children = children;
+ else if (1 < childrenLength) {
+ for (var childArray = Array(childrenLength), _i = 0; _i < childrenLength; _i++)
+ childArray[_i] = arguments[_i + 2];
+ Object.freeze && Object.freeze(childArray);
+ i.children = childArray;
+ }
+ if (type && type.defaultProps)
+ for (propName in childrenLength = type.defaultProps, childrenLength)
+ void 0 === i[propName] && (i[propName] = childrenLength[propName]);
+ key && defineKeyPropWarningGetter(
+ i,
+ "function" === typeof type ? type.displayName || type.name || "Unknown" : type
+ );
+ var propName = 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;
+ return ReactElement(
+ type,
+ key,
+ i,
+ getOwner(),
+ propName ? Error("react-stack-top-frame") : unknownOwnerDebugStack,
+ propName ? createTask(getTaskName(type)) : unknownOwnerDebugTask
+ );
+ };
+ exports$1.createRef = function() {
+ var refObject = { current: null };
+ Object.seal(refObject);
+ return refObject;
+ };
+ exports$1.forwardRef = function(render) {
+ null != render && render.$$typeof === REACT_MEMO_TYPE ? console.error(
+ "forwardRef requires a render function but received a `memo` component. Instead of forwardRef(memo(...)), use memo(forwardRef(...))."
+ ) : "function" !== typeof render ? console.error(
+ "forwardRef requires a render function but was given %s.",
+ null === render ? "null" : typeof render
+ ) : 0 !== render.length && 2 !== render.length && console.error(
+ "forwardRef render functions accept exactly two parameters: props and ref. %s",
+ 1 === render.length ? "Did you forget to use the ref parameter?" : "Any additional parameter will be undefined."
+ );
+ null != render && null != render.defaultProps && console.error(
+ "forwardRef render functions do not support defaultProps. Did you accidentally pass a React component?"
+ );
+ var elementType = { $$typeof: REACT_FORWARD_REF_TYPE, render }, ownName;
+ Object.defineProperty(elementType, "displayName", {
+ enumerable: false,
+ configurable: true,
+ get: function() {
+ return ownName;
+ },
+ set: function(name) {
+ ownName = name;
+ render.name || render.displayName || (Object.defineProperty(render, "name", { value: name }), render.displayName = name);
+ }
+ });
+ return elementType;
+ };
+ exports$1.isValidElement = isValidElement;
+ exports$1.lazy = function(ctor) {
+ ctor = { _status: -1, _result: ctor };
+ var lazyType = {
+ $$typeof: REACT_LAZY_TYPE,
+ _payload: ctor,
+ _init: lazyInitializer
+ }, ioInfo = {
+ name: "lazy",
+ start: -1,
+ end: -1,
+ value: null,
+ owner: null,
+ debugStack: Error("react-stack-top-frame"),
+ debugTask: console.createTask ? console.createTask("lazy()") : null
+ };
+ ctor._ioInfo = ioInfo;
+ lazyType._debugInfo = [{ awaited: ioInfo }];
+ return lazyType;
+ };
+ exports$1.memo = function(type, compare) {
+ null == type && console.error(
+ "memo: The first argument must be a component. Instead received: %s",
+ null === type ? "null" : typeof type
+ );
+ compare = {
+ $$typeof: REACT_MEMO_TYPE,
+ type,
+ compare: void 0 === compare ? null : compare
+ };
+ var ownName;
+ Object.defineProperty(compare, "displayName", {
+ enumerable: false,
+ configurable: true,
+ get: function() {
+ return ownName;
+ },
+ set: function(name) {
+ ownName = name;
+ type.name || type.displayName || (Object.defineProperty(type, "name", { value: name }), type.displayName = name);
+ }
+ });
+ return compare;
+ };
+ exports$1.startTransition = function(scope) {
+ var prevTransition = ReactSharedInternals.T, currentTransition = {};
+ currentTransition._updatedFibers = /* @__PURE__ */ new Set();
+ ReactSharedInternals.T = currentTransition;
+ try {
+ var returnValue = scope(), onStartTransitionFinish = ReactSharedInternals.S;
+ null !== onStartTransitionFinish && onStartTransitionFinish(currentTransition, returnValue);
+ "object" === typeof returnValue && null !== returnValue && "function" === typeof returnValue.then && (ReactSharedInternals.asyncTransitions++, returnValue.then(releaseAsyncTransition, releaseAsyncTransition), returnValue.then(noop2, reportGlobalError));
+ } catch (error) {
+ reportGlobalError(error);
+ } finally {
+ null === prevTransition && currentTransition._updatedFibers && (scope = currentTransition._updatedFibers.size, currentTransition._updatedFibers.clear(), 10 < scope && console.warn(
+ "Detected a large number of updates inside startTransition. If this is due to a subscription please re-write it to use React provided hooks. Otherwise concurrent mode guarantees are off the table."
+ )), null !== prevTransition && null !== currentTransition.types && (null !== prevTransition.types && prevTransition.types !== currentTransition.types && console.error(
+ "We expected inner Transitions to have transferred the outer types set and that you cannot add to the outer Transition while inside the inner.This is a bug in React."
+ ), prevTransition.types = currentTransition.types), ReactSharedInternals.T = prevTransition;
+ }
+ };
+ exports$1.unstable_useCacheRefresh = function() {
+ return resolveDispatcher().useCacheRefresh();
+ };
+ exports$1.use = function(usable) {
+ return resolveDispatcher().use(usable);
+ };
+ exports$1.useActionState = function(action, initialState, permalink) {
+ return resolveDispatcher().useActionState(
+ action,
+ initialState,
+ permalink
+ );
+ };
+ exports$1.useCallback = function(callback, deps) {
+ return resolveDispatcher().useCallback(callback, deps);
+ };
+ exports$1.useContext = function(Context) {
+ var dispatcher = resolveDispatcher();
+ Context.$$typeof === REACT_CONSUMER_TYPE && console.error(
+ "Calling useContext(Context.Consumer) is not supported and will cause bugs. Did you mean to call useContext(Context) instead?"
+ );
+ return dispatcher.useContext(Context);
+ };
+ exports$1.useDebugValue = function(value, formatterFn) {
+ return resolveDispatcher().useDebugValue(value, formatterFn);
+ };
+ exports$1.useDeferredValue = function(value, initialValue) {
+ return resolveDispatcher().useDeferredValue(value, initialValue);
+ };
+ exports$1.useEffect = function(create, deps) {
+ null == create && console.warn(
+ "React Hook useEffect requires an effect callback. Did you forget to pass a callback to the hook?"
+ );
+ return resolveDispatcher().useEffect(create, deps);
+ };
+ exports$1.useEffectEvent = function(callback) {
+ return resolveDispatcher().useEffectEvent(callback);
+ };
+ exports$1.useId = function() {
+ return resolveDispatcher().useId();
+ };
+ exports$1.useImperativeHandle = function(ref, create, deps) {
+ return resolveDispatcher().useImperativeHandle(ref, create, deps);
+ };
+ exports$1.useInsertionEffect = function(create, deps) {
+ null == create && console.warn(
+ "React Hook useInsertionEffect requires an effect callback. Did you forget to pass a callback to the hook?"
+ );
+ return resolveDispatcher().useInsertionEffect(create, deps);
+ };
+ exports$1.useLayoutEffect = function(create, deps) {
+ null == create && console.warn(
+ "React Hook useLayoutEffect requires an effect callback. Did you forget to pass a callback to the hook?"
+ );
+ return resolveDispatcher().useLayoutEffect(create, deps);
+ };
+ exports$1.useMemo = function(create, deps) {
+ return resolveDispatcher().useMemo(create, deps);
+ };
+ exports$1.useOptimistic = function(passthrough, reducer) {
+ return resolveDispatcher().useOptimistic(passthrough, reducer);
+ };
+ exports$1.useReducer = function(reducer, initialArg, init2) {
+ return resolveDispatcher().useReducer(reducer, initialArg, init2);
+ };
+ exports$1.useRef = function(initialValue) {
+ return resolveDispatcher().useRef(initialValue);
+ };
+ exports$1.useState = function(initialState) {
+ return resolveDispatcher().useState(initialState);
+ };
+ exports$1.useSyncExternalStore = function(subscribe, getSnapshot, getServerSnapshot) {
+ return resolveDispatcher().useSyncExternalStore(
+ subscribe,
+ getSnapshot,
+ getServerSnapshot
+ );
+ };
+ exports$1.useTransition = function() {
+ return resolveDispatcher().useTransition();
+ };
+ exports$1.version = "19.2.4";
+ "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
+ })();
+ })(react_development, react_development.exports);
+ return react_development.exports;
+}
+var hasRequiredReact;
+function requireReact() {
+ if (hasRequiredReact) return react.exports;
+ hasRequiredReact = 1;
+ if (process.env.NODE_ENV === "production") {
+ react.exports = requireReact_production();
+ } else {
+ react.exports = requireReact_development();
+ }
+ return react.exports;
+}
+var reactExports = requireReact();
+const React = /* @__PURE__ */ getDefaultExportFromCjs(reactExports);
+var reactDom = { exports: {} };
+var reactDom_production = {};
+var hasRequiredReactDom_production;
+function requireReactDom_production() {
+ if (hasRequiredReactDom_production) return reactDom_production;
+ hasRequiredReactDom_production = 1;
+ var React2 = requireReact();
+ function formatProdErrorMessage(code) {
+ var url = "https://react.dev/errors/" + code;
+ if (1 < arguments.length) {
+ url += "?args[]=" + encodeURIComponent(arguments[1]);
+ for (var i = 2; i < arguments.length; i++)
+ url += "&args[]=" + encodeURIComponent(arguments[i]);
+ }
+ return "Minified React error #" + code + "; visit " + url + " for the full message or use the non-minified dev environment for full errors and additional helpful warnings.";
+ }
+ function noop2() {
+ }
+ var Internals = {
+ d: {
+ f: noop2,
+ r: function() {
+ throw Error(formatProdErrorMessage(522));
+ },
+ D: noop2,
+ C: noop2,
+ L: noop2,
+ m: noop2,
+ X: noop2,
+ S: noop2,
+ M: noop2
+ },
+ p: 0,
+ findDOMNode: null
+ }, REACT_PORTAL_TYPE = /* @__PURE__ */ Symbol.for("react.portal");
+ function createPortal$1(children, containerInfo, implementation) {
+ var key = 3 < arguments.length && void 0 !== arguments[3] ? arguments[3] : null;
+ return {
+ $$typeof: REACT_PORTAL_TYPE,
+ key: null == key ? null : "" + key,
+ children,
+ containerInfo,
+ implementation
+ };
+ }
+ var ReactSharedInternals = React2.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
+ function getCrossOriginStringAs(as, input) {
+ if ("font" === as) return "";
+ if ("string" === typeof input)
+ return "use-credentials" === input ? input : "";
+ }
+ reactDom_production.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = Internals;
+ reactDom_production.createPortal = function(children, container) {
+ var key = 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null;
+ if (!container || 1 !== container.nodeType && 9 !== container.nodeType && 11 !== container.nodeType)
+ throw Error(formatProdErrorMessage(299));
+ return createPortal$1(children, container, null, key);
+ };
+ reactDom_production.flushSync = function(fn) {
+ var previousTransition = ReactSharedInternals.T, previousUpdatePriority = Internals.p;
+ try {
+ if (ReactSharedInternals.T = null, Internals.p = 2, fn) return fn();
+ } finally {
+ ReactSharedInternals.T = previousTransition, Internals.p = previousUpdatePriority, Internals.d.f();
+ }
+ };
+ reactDom_production.preconnect = function(href, options) {
+ "string" === typeof href && (options ? (options = options.crossOrigin, options = "string" === typeof options ? "use-credentials" === options ? options : "" : void 0) : options = null, Internals.d.C(href, options));
+ };
+ reactDom_production.prefetchDNS = function(href) {
+ "string" === typeof href && Internals.d.D(href);
+ };
+ reactDom_production.preinit = function(href, options) {
+ if ("string" === typeof href && options && "string" === typeof options.as) {
+ var as = options.as, crossOrigin = getCrossOriginStringAs(as, options.crossOrigin), integrity = "string" === typeof options.integrity ? options.integrity : void 0, fetchPriority = "string" === typeof options.fetchPriority ? options.fetchPriority : void 0;
+ "style" === as ? Internals.d.S(
+ href,
+ "string" === typeof options.precedence ? options.precedence : void 0,
+ {
+ crossOrigin,
+ integrity,
+ fetchPriority
+ }
+ ) : "script" === as && Internals.d.X(href, {
+ crossOrigin,
+ integrity,
+ fetchPriority,
+ nonce: "string" === typeof options.nonce ? options.nonce : void 0
+ });
+ }
+ };
+ reactDom_production.preinitModule = function(href, options) {
+ if ("string" === typeof href)
+ if ("object" === typeof options && null !== options) {
+ if (null == options.as || "script" === options.as) {
+ var crossOrigin = getCrossOriginStringAs(
+ options.as,
+ options.crossOrigin
+ );
+ Internals.d.M(href, {
+ crossOrigin,
+ integrity: "string" === typeof options.integrity ? options.integrity : void 0,
+ nonce: "string" === typeof options.nonce ? options.nonce : void 0
+ });
+ }
+ } else null == options && Internals.d.M(href);
+ };
+ reactDom_production.preload = function(href, options) {
+ if ("string" === typeof href && "object" === typeof options && null !== options && "string" === typeof options.as) {
+ var as = options.as, crossOrigin = getCrossOriginStringAs(as, options.crossOrigin);
+ Internals.d.L(href, as, {
+ crossOrigin,
+ integrity: "string" === typeof options.integrity ? options.integrity : void 0,
+ nonce: "string" === typeof options.nonce ? options.nonce : void 0,
+ type: "string" === typeof options.type ? options.type : void 0,
+ fetchPriority: "string" === typeof options.fetchPriority ? options.fetchPriority : void 0,
+ referrerPolicy: "string" === typeof options.referrerPolicy ? options.referrerPolicy : void 0,
+ imageSrcSet: "string" === typeof options.imageSrcSet ? options.imageSrcSet : void 0,
+ imageSizes: "string" === typeof options.imageSizes ? options.imageSizes : void 0,
+ media: "string" === typeof options.media ? options.media : void 0
+ });
+ }
+ };
+ reactDom_production.preloadModule = function(href, options) {
+ if ("string" === typeof href)
+ if (options) {
+ var crossOrigin = getCrossOriginStringAs(options.as, options.crossOrigin);
+ Internals.d.m(href, {
+ as: "string" === typeof options.as && "script" !== options.as ? options.as : void 0,
+ crossOrigin,
+ integrity: "string" === typeof options.integrity ? options.integrity : void 0
+ });
+ } else Internals.d.m(href);
+ };
+ reactDom_production.requestFormReset = function(form) {
+ Internals.d.r(form);
+ };
+ reactDom_production.unstable_batchedUpdates = function(fn, a) {
+ return fn(a);
+ };
+ reactDom_production.useFormState = function(action, initialState, permalink) {
+ return ReactSharedInternals.H.useFormState(action, initialState, permalink);
+ };
+ reactDom_production.useFormStatus = function() {
+ return ReactSharedInternals.H.useHostTransitionStatus();
+ };
+ reactDom_production.version = "19.2.4";
+ return reactDom_production;
+}
+var reactDom_development = {};
+var hasRequiredReactDom_development;
+function requireReactDom_development() {
+ if (hasRequiredReactDom_development) return reactDom_development;
+ hasRequiredReactDom_development = 1;
+ "production" !== process.env.NODE_ENV && (function() {
+ function noop2() {
+ }
+ function testStringCoercion(value) {
+ return "" + value;
+ }
+ function createPortal$1(children, containerInfo, implementation) {
+ var key = 3 < arguments.length && void 0 !== arguments[3] ? arguments[3] : null;
+ try {
+ testStringCoercion(key);
+ var JSCompiler_inline_result = false;
+ } catch (e) {
+ JSCompiler_inline_result = true;
+ }
+ JSCompiler_inline_result && (console.error(
+ "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
+ "function" === typeof Symbol && Symbol.toStringTag && key[Symbol.toStringTag] || key.constructor.name || "Object"
+ ), testStringCoercion(key));
+ return {
+ $$typeof: REACT_PORTAL_TYPE,
+ key: null == key ? null : "" + key,
+ children,
+ containerInfo,
+ implementation
+ };
+ }
+ function getCrossOriginStringAs(as, input) {
+ if ("font" === as) return "";
+ if ("string" === typeof input)
+ return "use-credentials" === input ? input : "";
+ }
+ function getValueDescriptorExpectingObjectForWarning(thing) {
+ return null === thing ? "`null`" : void 0 === thing ? "`undefined`" : "" === thing ? "an empty string" : 'something with type "' + typeof thing + '"';
+ }
+ function getValueDescriptorExpectingEnumForWarning(thing) {
+ return null === thing ? "`null`" : void 0 === thing ? "`undefined`" : "" === thing ? "an empty string" : "string" === typeof thing ? JSON.stringify(thing) : "number" === typeof thing ? "`" + thing + "`" : 'something with type "' + typeof thing + '"';
+ }
+ function resolveDispatcher() {
+ var dispatcher = ReactSharedInternals.H;
+ null === dispatcher && console.error(
+ "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem."
+ );
+ return dispatcher;
+ }
+ "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
+ var React2 = requireReact(), Internals = {
+ d: {
+ f: noop2,
+ r: function() {
+ throw Error(
+ "Invalid form element. requestFormReset must be passed a form that was rendered by React."
+ );
+ },
+ D: noop2,
+ C: noop2,
+ L: noop2,
+ m: noop2,
+ X: noop2,
+ S: noop2,
+ M: noop2
+ },
+ p: 0,
+ findDOMNode: null
+ }, REACT_PORTAL_TYPE = /* @__PURE__ */ Symbol.for("react.portal"), ReactSharedInternals = React2.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
+ "function" === typeof Map && null != Map.prototype && "function" === typeof Map.prototype.forEach && "function" === typeof Set && null != Set.prototype && "function" === typeof Set.prototype.clear && "function" === typeof Set.prototype.forEach || console.error(
+ "React depends on Map and Set built-in types. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills"
+ );
+ reactDom_development.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = Internals;
+ reactDom_development.createPortal = function(children, container) {
+ var key = 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null;
+ if (!container || 1 !== container.nodeType && 9 !== container.nodeType && 11 !== container.nodeType)
+ throw Error("Target container is not a DOM element.");
+ return createPortal$1(children, container, null, key);
+ };
+ reactDom_development.flushSync = function(fn) {
+ var previousTransition = ReactSharedInternals.T, previousUpdatePriority = Internals.p;
+ try {
+ if (ReactSharedInternals.T = null, Internals.p = 2, fn)
+ return fn();
+ } finally {
+ ReactSharedInternals.T = previousTransition, Internals.p = previousUpdatePriority, Internals.d.f() && console.error(
+ "flushSync was called from inside a lifecycle method. React cannot flush when React is already rendering. Consider moving this call to a scheduler task or micro task."
+ );
+ }
+ };
+ reactDom_development.preconnect = function(href, options) {
+ "string" === typeof href && href ? null != options && "object" !== typeof options ? console.error(
+ "ReactDOM.preconnect(): Expected the `options` argument (second) to be an object but encountered %s instead. The only supported option at this time is `crossOrigin` which accepts a string.",
+ getValueDescriptorExpectingEnumForWarning(options)
+ ) : null != options && "string" !== typeof options.crossOrigin && console.error(
+ "ReactDOM.preconnect(): Expected the `crossOrigin` option (second argument) to be a string but encountered %s instead. Try removing this option or passing a string value instead.",
+ getValueDescriptorExpectingObjectForWarning(options.crossOrigin)
+ ) : console.error(
+ "ReactDOM.preconnect(): Expected the `href` argument (first) to be a non-empty string but encountered %s instead.",
+ getValueDescriptorExpectingObjectForWarning(href)
+ );
+ "string" === typeof href && (options ? (options = options.crossOrigin, options = "string" === typeof options ? "use-credentials" === options ? options : "" : void 0) : options = null, Internals.d.C(href, options));
+ };
+ reactDom_development.prefetchDNS = function(href) {
+ if ("string" !== typeof href || !href)
+ console.error(
+ "ReactDOM.prefetchDNS(): Expected the `href` argument (first) to be a non-empty string but encountered %s instead.",
+ getValueDescriptorExpectingObjectForWarning(href)
+ );
+ else if (1 < arguments.length) {
+ var options = arguments[1];
+ "object" === typeof options && options.hasOwnProperty("crossOrigin") ? console.error(
+ "ReactDOM.prefetchDNS(): Expected only one argument, `href`, but encountered %s as a second argument instead. This argument is reserved for future options and is currently disallowed. It looks like the you are attempting to set a crossOrigin property for this DNS lookup hint. Browsers do not perform DNS queries using CORS and setting this attribute on the resource hint has no effect. Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.",
+ getValueDescriptorExpectingEnumForWarning(options)
+ ) : console.error(
+ "ReactDOM.prefetchDNS(): Expected only one argument, `href`, but encountered %s as a second argument instead. This argument is reserved for future options and is currently disallowed. Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.",
+ getValueDescriptorExpectingEnumForWarning(options)
+ );
+ }
+ "string" === typeof href && Internals.d.D(href);
+ };
+ reactDom_development.preinit = function(href, options) {
+ "string" === typeof href && href ? null == options || "object" !== typeof options ? console.error(
+ "ReactDOM.preinit(): Expected the `options` argument (second) to be an object with an `as` property describing the type of resource to be preinitialized but encountered %s instead.",
+ getValueDescriptorExpectingEnumForWarning(options)
+ ) : "style" !== options.as && "script" !== options.as && console.error(
+ 'ReactDOM.preinit(): Expected the `as` property in the `options` argument (second) to contain a valid value describing the type of resource to be preinitialized but encountered %s instead. Valid values for `as` are "style" and "script".',
+ getValueDescriptorExpectingEnumForWarning(options.as)
+ ) : console.error(
+ "ReactDOM.preinit(): Expected the `href` argument (first) to be a non-empty string but encountered %s instead.",
+ getValueDescriptorExpectingObjectForWarning(href)
+ );
+ if ("string" === typeof href && options && "string" === typeof options.as) {
+ var as = options.as, crossOrigin = getCrossOriginStringAs(as, options.crossOrigin), integrity = "string" === typeof options.integrity ? options.integrity : void 0, fetchPriority = "string" === typeof options.fetchPriority ? options.fetchPriority : void 0;
+ "style" === as ? Internals.d.S(
+ href,
+ "string" === typeof options.precedence ? options.precedence : void 0,
+ {
+ crossOrigin,
+ integrity,
+ fetchPriority
+ }
+ ) : "script" === as && Internals.d.X(href, {
+ crossOrigin,
+ integrity,
+ fetchPriority,
+ nonce: "string" === typeof options.nonce ? options.nonce : void 0
+ });
+ }
+ };
+ reactDom_development.preinitModule = function(href, options) {
+ var encountered = "";
+ "string" === typeof href && href || (encountered += " The `href` argument encountered was " + getValueDescriptorExpectingObjectForWarning(href) + ".");
+ void 0 !== options && "object" !== typeof options ? encountered += " The `options` argument encountered was " + getValueDescriptorExpectingObjectForWarning(options) + "." : options && "as" in options && "script" !== options.as && (encountered += " The `as` option encountered was " + getValueDescriptorExpectingEnumForWarning(options.as) + ".");
+ if (encountered)
+ console.error(
+ "ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` string and, optionally, an `options` object with a valid `as` property.%s",
+ encountered
+ );
+ else
+ switch (encountered = options && "string" === typeof options.as ? options.as : "script", encountered) {
+ case "script":
+ break;
+ default:
+ encountered = getValueDescriptorExpectingEnumForWarning(encountered), console.error(
+ 'ReactDOM.preinitModule(): Currently the only supported "as" type for this function is "script" but received "%s" instead. This warning was generated for `href` "%s". In the future other module types will be supported, aligning with the import-attributes proposal. Learn more here: (https://github.com/tc39/proposal-import-attributes)',
+ encountered,
+ href
+ );
+ }
+ if ("string" === typeof href)
+ if ("object" === typeof options && null !== options) {
+ if (null == options.as || "script" === options.as)
+ encountered = getCrossOriginStringAs(
+ options.as,
+ options.crossOrigin
+ ), Internals.d.M(href, {
+ crossOrigin: encountered,
+ integrity: "string" === typeof options.integrity ? options.integrity : void 0,
+ nonce: "string" === typeof options.nonce ? options.nonce : void 0
+ });
+ } else null == options && Internals.d.M(href);
+ };
+ reactDom_development.preload = function(href, options) {
+ var encountered = "";
+ "string" === typeof href && href || (encountered += " The `href` argument encountered was " + getValueDescriptorExpectingObjectForWarning(href) + ".");
+ null == options || "object" !== typeof options ? encountered += " The `options` argument encountered was " + getValueDescriptorExpectingObjectForWarning(options) + "." : "string" === typeof options.as && options.as || (encountered += " The `as` option encountered was " + getValueDescriptorExpectingObjectForWarning(options.as) + ".");
+ encountered && console.error(
+ 'ReactDOM.preload(): Expected two arguments, a non-empty `href` string and an `options` object with an `as` property valid for a `` tag.%s',
+ encountered
+ );
+ if ("string" === typeof href && "object" === typeof options && null !== options && "string" === typeof options.as) {
+ encountered = options.as;
+ var crossOrigin = getCrossOriginStringAs(
+ encountered,
+ options.crossOrigin
+ );
+ Internals.d.L(href, encountered, {
+ crossOrigin,
+ integrity: "string" === typeof options.integrity ? options.integrity : void 0,
+ nonce: "string" === typeof options.nonce ? options.nonce : void 0,
+ type: "string" === typeof options.type ? options.type : void 0,
+ fetchPriority: "string" === typeof options.fetchPriority ? options.fetchPriority : void 0,
+ referrerPolicy: "string" === typeof options.referrerPolicy ? options.referrerPolicy : void 0,
+ imageSrcSet: "string" === typeof options.imageSrcSet ? options.imageSrcSet : void 0,
+ imageSizes: "string" === typeof options.imageSizes ? options.imageSizes : void 0,
+ media: "string" === typeof options.media ? options.media : void 0
+ });
+ }
+ };
+ reactDom_development.preloadModule = function(href, options) {
+ var encountered = "";
+ "string" === typeof href && href || (encountered += " The `href` argument encountered was " + getValueDescriptorExpectingObjectForWarning(href) + ".");
+ void 0 !== options && "object" !== typeof options ? encountered += " The `options` argument encountered was " + getValueDescriptorExpectingObjectForWarning(options) + "." : options && "as" in options && "string" !== typeof options.as && (encountered += " The `as` option encountered was " + getValueDescriptorExpectingObjectForWarning(options.as) + ".");
+ encountered && console.error(
+ 'ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, an `options` object with an `as` property valid for a `` tag.%s',
+ encountered
+ );
+ "string" === typeof href && (options ? (encountered = getCrossOriginStringAs(
+ options.as,
+ options.crossOrigin
+ ), Internals.d.m(href, {
+ as: "string" === typeof options.as && "script" !== options.as ? options.as : void 0,
+ crossOrigin: encountered,
+ integrity: "string" === typeof options.integrity ? options.integrity : void 0
+ })) : Internals.d.m(href));
+ };
+ reactDom_development.requestFormReset = function(form) {
+ Internals.d.r(form);
+ };
+ reactDom_development.unstable_batchedUpdates = function(fn, a) {
+ return fn(a);
+ };
+ reactDom_development.useFormState = function(action, initialState, permalink) {
+ return resolveDispatcher().useFormState(action, initialState, permalink);
+ };
+ reactDom_development.useFormStatus = function() {
+ return resolveDispatcher().useHostTransitionStatus();
+ };
+ reactDom_development.version = "19.2.4";
+ "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
+ })();
+ return reactDom_development;
+}
+var hasRequiredReactDom;
+function requireReactDom() {
+ if (hasRequiredReactDom) return reactDom.exports;
+ hasRequiredReactDom = 1;
+ function checkDCE() {
+ if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined" || typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE !== "function") {
+ return;
+ }
+ if (process.env.NODE_ENV !== "production") {
+ throw new Error("^_^");
+ }
+ try {
+ __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(checkDCE);
+ } catch (err) {
+ console.error(err);
+ }
+ }
+ if (process.env.NODE_ENV === "production") {
+ checkDCE();
+ reactDom.exports = requireReactDom_production();
+ } else {
+ reactDom.exports = requireReactDom_development();
+ }
+ return reactDom.exports;
+}
+var reactDomExports = requireReactDom();
+const ReactDOM = /* @__PURE__ */ getDefaultExportFromCjs(reactDomExports);
+var shim = { exports: {} };
+var useSyncExternalStoreShim_production = {};
+var hasRequiredUseSyncExternalStoreShim_production;
+function requireUseSyncExternalStoreShim_production() {
+ if (hasRequiredUseSyncExternalStoreShim_production) return useSyncExternalStoreShim_production;
+ hasRequiredUseSyncExternalStoreShim_production = 1;
+ var React2 = requireReact();
+ function is(x, y) {
+ return x === y && (0 !== x || 1 / x === 1 / y) || x !== x && y !== y;
+ }
+ var objectIs = "function" === typeof Object.is ? Object.is : is, useState = React2.useState, useEffect = React2.useEffect, useLayoutEffect = React2.useLayoutEffect, useDebugValue = React2.useDebugValue;
+ function useSyncExternalStore$2(subscribe, getSnapshot) {
+ var value = getSnapshot(), _useState = useState({ inst: { value, getSnapshot } }), inst = _useState[0].inst, forceUpdate = _useState[1];
+ useLayoutEffect(
+ function() {
+ inst.value = value;
+ inst.getSnapshot = getSnapshot;
+ checkIfSnapshotChanged(inst) && forceUpdate({ inst });
+ },
+ [subscribe, value, getSnapshot]
+ );
+ useEffect(
+ function() {
+ checkIfSnapshotChanged(inst) && forceUpdate({ inst });
+ return subscribe(function() {
+ checkIfSnapshotChanged(inst) && forceUpdate({ inst });
+ });
+ },
+ [subscribe]
+ );
+ useDebugValue(value);
+ return value;
+ }
+ function checkIfSnapshotChanged(inst) {
+ var latestGetSnapshot = inst.getSnapshot;
+ inst = inst.value;
+ try {
+ var nextValue = latestGetSnapshot();
+ return !objectIs(inst, nextValue);
+ } catch (error) {
+ return true;
+ }
+ }
+ function useSyncExternalStore$1(subscribe, getSnapshot) {
+ return getSnapshot();
+ }
+ var shim2 = "undefined" === typeof window || "undefined" === typeof window.document || "undefined" === typeof window.document.createElement ? useSyncExternalStore$1 : useSyncExternalStore$2;
+ useSyncExternalStoreShim_production.useSyncExternalStore = void 0 !== React2.useSyncExternalStore ? React2.useSyncExternalStore : shim2;
+ return useSyncExternalStoreShim_production;
+}
+var useSyncExternalStoreShim_development = {};
+var hasRequiredUseSyncExternalStoreShim_development;
+function requireUseSyncExternalStoreShim_development() {
+ if (hasRequiredUseSyncExternalStoreShim_development) return useSyncExternalStoreShim_development;
+ hasRequiredUseSyncExternalStoreShim_development = 1;
+ "production" !== process.env.NODE_ENV && (function() {
+ function is(x, y) {
+ return x === y && (0 !== x || 1 / x === 1 / y) || x !== x && y !== y;
+ }
+ function useSyncExternalStore$2(subscribe, getSnapshot) {
+ didWarnOld18Alpha || void 0 === React2.startTransition || (didWarnOld18Alpha = true, console.error(
+ "You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."
+ ));
+ var value = getSnapshot();
+ if (!didWarnUncachedGetSnapshot) {
+ var cachedValue = getSnapshot();
+ objectIs(value, cachedValue) || (console.error(
+ "The result of getSnapshot should be cached to avoid an infinite loop"
+ ), didWarnUncachedGetSnapshot = true);
+ }
+ cachedValue = useState({
+ inst: { value, getSnapshot }
+ });
+ var inst = cachedValue[0].inst, forceUpdate = cachedValue[1];
+ useLayoutEffect(
+ function() {
+ inst.value = value;
+ inst.getSnapshot = getSnapshot;
+ checkIfSnapshotChanged(inst) && forceUpdate({ inst });
+ },
+ [subscribe, value, getSnapshot]
+ );
+ useEffect(
+ function() {
+ checkIfSnapshotChanged(inst) && forceUpdate({ inst });
+ return subscribe(function() {
+ checkIfSnapshotChanged(inst) && forceUpdate({ inst });
+ });
+ },
+ [subscribe]
+ );
+ useDebugValue(value);
+ return value;
+ }
+ function checkIfSnapshotChanged(inst) {
+ var latestGetSnapshot = inst.getSnapshot;
+ inst = inst.value;
+ try {
+ var nextValue = latestGetSnapshot();
+ return !objectIs(inst, nextValue);
+ } catch (error) {
+ return true;
+ }
+ }
+ function useSyncExternalStore$1(subscribe, getSnapshot) {
+ return getSnapshot();
+ }
+ "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
+ var React2 = requireReact(), objectIs = "function" === typeof Object.is ? Object.is : is, useState = React2.useState, useEffect = React2.useEffect, useLayoutEffect = React2.useLayoutEffect, useDebugValue = React2.useDebugValue, didWarnOld18Alpha = false, didWarnUncachedGetSnapshot = false, shim2 = "undefined" === typeof window || "undefined" === typeof window.document || "undefined" === typeof window.document.createElement ? useSyncExternalStore$1 : useSyncExternalStore$2;
+ useSyncExternalStoreShim_development.useSyncExternalStore = void 0 !== React2.useSyncExternalStore ? React2.useSyncExternalStore : shim2;
+ "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
+ })();
+ return useSyncExternalStoreShim_development;
+}
+var hasRequiredShim;
+function requireShim() {
+ if (hasRequiredShim) return shim.exports;
+ hasRequiredShim = 1;
+ if (process.env.NODE_ENV === "production") {
+ shim.exports = requireUseSyncExternalStoreShim_production();
+ } else {
+ shim.exports = requireUseSyncExternalStoreShim_development();
+ }
+ return shim.exports;
+}
+var shimExports = requireShim();
+var jsxRuntime = { exports: {} };
+var reactJsxRuntime_production = {};
+var hasRequiredReactJsxRuntime_production;
+function requireReactJsxRuntime_production() {
+ if (hasRequiredReactJsxRuntime_production) return reactJsxRuntime_production;
+ hasRequiredReactJsxRuntime_production = 1;
+ var REACT_ELEMENT_TYPE = /* @__PURE__ */ Symbol.for("react.transitional.element"), REACT_FRAGMENT_TYPE = /* @__PURE__ */ Symbol.for("react.fragment");
+ function jsxProd(type, config, maybeKey) {
+ var key = null;
+ void 0 !== maybeKey && (key = "" + maybeKey);
+ void 0 !== config.key && (key = "" + config.key);
+ if ("key" in config) {
+ maybeKey = {};
+ for (var propName in config)
+ "key" !== propName && (maybeKey[propName] = config[propName]);
+ } else maybeKey = config;
+ config = maybeKey.ref;
+ return {
+ $$typeof: REACT_ELEMENT_TYPE,
+ type,
+ key,
+ ref: void 0 !== config ? config : null,
+ props: maybeKey
+ };
+ }
+ reactJsxRuntime_production.Fragment = REACT_FRAGMENT_TYPE;
+ reactJsxRuntime_production.jsx = jsxProd;
+ reactJsxRuntime_production.jsxs = jsxProd;
+ return reactJsxRuntime_production;
+}
+var reactJsxRuntime_development = {};
+var hasRequiredReactJsxRuntime_development;
+function requireReactJsxRuntime_development() {
+ if (hasRequiredReactJsxRuntime_development) return reactJsxRuntime_development;
+ hasRequiredReactJsxRuntime_development = 1;
+ "production" !== process.env.NODE_ENV && (function() {
+ function getComponentNameFromType(type) {
+ if (null == type) return null;
+ if ("function" === typeof type)
+ return type.$$typeof === REACT_CLIENT_REFERENCE ? null : type.displayName || type.name || null;
+ if ("string" === typeof type) return type;
+ switch (type) {
+ case REACT_FRAGMENT_TYPE:
+ return "Fragment";
+ case REACT_PROFILER_TYPE:
+ return "Profiler";
+ case REACT_STRICT_MODE_TYPE:
+ return "StrictMode";
+ case REACT_SUSPENSE_TYPE:
+ return "Suspense";
+ case REACT_SUSPENSE_LIST_TYPE:
+ return "SuspenseList";
+ case REACT_ACTIVITY_TYPE:
+ return "Activity";
+ }
+ if ("object" === typeof type)
+ switch ("number" === typeof type.tag && console.error(
+ "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
+ ), type.$$typeof) {
+ case REACT_PORTAL_TYPE:
+ return "Portal";
+ case REACT_CONTEXT_TYPE:
+ return type.displayName || "Context";
+ case REACT_CONSUMER_TYPE:
+ return (type._context.displayName || "Context") + ".Consumer";
+ case REACT_FORWARD_REF_TYPE:
+ var innerType = type.render;
+ type = type.displayName;
+ type || (type = innerType.displayName || innerType.name || "", type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef");
+ return type;
+ case REACT_MEMO_TYPE:
+ return innerType = type.displayName || null, null !== innerType ? innerType : getComponentNameFromType(type.type) || "Memo";
+ case REACT_LAZY_TYPE:
+ innerType = type._payload;
+ type = type._init;
+ try {
+ return getComponentNameFromType(type(innerType));
+ } catch (x) {
+ }
+ }
+ return null;
+ }
+ function testStringCoercion(value) {
+ return "" + value;
+ }
+ function checkKeyStringCoercion(value) {
+ try {
+ testStringCoercion(value);
+ var JSCompiler_inline_result = false;
+ } catch (e) {
+ JSCompiler_inline_result = true;
+ }
+ if (JSCompiler_inline_result) {
+ JSCompiler_inline_result = console;
+ var JSCompiler_temp_const = JSCompiler_inline_result.error;
+ var JSCompiler_inline_result$jscomp$0 = "function" === typeof Symbol && Symbol.toStringTag && value[Symbol.toStringTag] || value.constructor.name || "Object";
+ JSCompiler_temp_const.call(
+ JSCompiler_inline_result,
+ "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
+ JSCompiler_inline_result$jscomp$0
+ );
+ return testStringCoercion(value);
+ }
+ }
+ function getTaskName(type) {
+ if (type === REACT_FRAGMENT_TYPE) return "<>";
+ if ("object" === typeof type && null !== type && type.$$typeof === REACT_LAZY_TYPE)
+ return "<...>";
+ try {
+ var name = getComponentNameFromType(type);
+ return name ? "<" + name + ">" : "<...>";
+ } catch (x) {
+ return "<...>";
+ }
+ }
+ function getOwner() {
+ var dispatcher = ReactSharedInternals.A;
+ return null === dispatcher ? null : dispatcher.getOwner();
+ }
+ function UnknownOwner() {
+ return Error("react-stack-top-frame");
+ }
+ function hasValidKey(config) {
+ if (hasOwnProperty2.call(config, "key")) {
+ var getter = Object.getOwnPropertyDescriptor(config, "key").get;
+ if (getter && getter.isReactWarning) return false;
+ }
+ return void 0 !== config.key;
+ }
+ function defineKeyPropWarningGetter(props, displayName) {
+ function warnAboutAccessingKey() {
+ specialPropKeyWarningShown || (specialPropKeyWarningShown = true, console.error(
+ "%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",
+ displayName
+ ));
+ }
+ warnAboutAccessingKey.isReactWarning = true;
+ Object.defineProperty(props, "key", {
+ get: warnAboutAccessingKey,
+ configurable: true
+ });
+ }
+ function elementRefGetterWithDeprecationWarning() {
+ var componentName = getComponentNameFromType(this.type);
+ didWarnAboutElementRef[componentName] || (didWarnAboutElementRef[componentName] = true, console.error(
+ "Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."
+ ));
+ componentName = this.props.ref;
+ return void 0 !== componentName ? componentName : null;
+ }
+ function ReactElement(type, key, props, owner, debugStack, debugTask) {
+ var refProp = props.ref;
+ type = {
+ $$typeof: REACT_ELEMENT_TYPE,
+ type,
+ key,
+ props,
+ _owner: owner
+ };
+ null !== (void 0 !== refProp ? refProp : null) ? Object.defineProperty(type, "ref", {
+ enumerable: false,
+ get: elementRefGetterWithDeprecationWarning
+ }) : Object.defineProperty(type, "ref", { enumerable: false, value: null });
+ type._store = {};
+ Object.defineProperty(type._store, "validated", {
+ configurable: false,
+ enumerable: false,
+ writable: true,
+ value: 0
+ });
+ Object.defineProperty(type, "_debugInfo", {
+ configurable: false,
+ enumerable: false,
+ writable: true,
+ value: null
+ });
+ Object.defineProperty(type, "_debugStack", {
+ configurable: false,
+ enumerable: false,
+ writable: true,
+ value: debugStack
+ });
+ Object.defineProperty(type, "_debugTask", {
+ configurable: false,
+ enumerable: false,
+ writable: true,
+ value: debugTask
+ });
+ Object.freeze && (Object.freeze(type.props), Object.freeze(type));
+ return type;
+ }
+ function jsxDEVImpl(type, config, maybeKey, isStaticChildren, debugStack, debugTask) {
+ var children = config.children;
+ if (void 0 !== children)
+ if (isStaticChildren)
+ if (isArrayImpl(children)) {
+ for (isStaticChildren = 0; isStaticChildren < children.length; isStaticChildren++)
+ validateChildKeys(children[isStaticChildren]);
+ Object.freeze && Object.freeze(children);
+ } else
+ console.error(
+ "React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."
+ );
+ else validateChildKeys(children);
+ if (hasOwnProperty2.call(config, "key")) {
+ children = getComponentNameFromType(type);
+ var keys2 = Object.keys(config).filter(function(k) {
+ return "key" !== k;
+ });
+ isStaticChildren = 0 < keys2.length ? "{key: someKey, " + keys2.join(": ..., ") + ": ...}" : "{key: someKey}";
+ didWarnAboutKeySpread[children + isStaticChildren] || (keys2 = 0 < keys2.length ? "{" + keys2.join(": ..., ") + ": ...}" : "{}", console.error(
+ 'A props object containing a "key" prop is being spread into JSX:\n let props = %s;\n <%s {...props} />\nReact keys must be passed directly to JSX without using spread:\n let props = %s;\n <%s key={someKey} {...props} />',
+ isStaticChildren,
+ children,
+ keys2,
+ children
+ ), didWarnAboutKeySpread[children + isStaticChildren] = true);
+ }
+ children = null;
+ void 0 !== maybeKey && (checkKeyStringCoercion(maybeKey), children = "" + maybeKey);
+ hasValidKey(config) && (checkKeyStringCoercion(config.key), children = "" + config.key);
+ if ("key" in config) {
+ maybeKey = {};
+ for (var propName in config)
+ "key" !== propName && (maybeKey[propName] = config[propName]);
+ } else maybeKey = config;
+ children && defineKeyPropWarningGetter(
+ maybeKey,
+ "function" === typeof type ? type.displayName || type.name || "Unknown" : type
+ );
+ return ReactElement(
+ type,
+ children,
+ maybeKey,
+ getOwner(),
+ debugStack,
+ debugTask
+ );
+ }
+ function validateChildKeys(node) {
+ isValidElement(node) ? node._store && (node._store.validated = 1) : "object" === typeof node && null !== node && node.$$typeof === REACT_LAZY_TYPE && ("fulfilled" === node._payload.status ? isValidElement(node._payload.value) && node._payload.value._store && (node._payload.value._store.validated = 1) : node._store && (node._store.validated = 1));
+ }
+ function isValidElement(object) {
+ return "object" === typeof object && null !== object && object.$$typeof === REACT_ELEMENT_TYPE;
+ }
+ var React2 = requireReact(), REACT_ELEMENT_TYPE = /* @__PURE__ */ Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = /* @__PURE__ */ Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = /* @__PURE__ */ Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = /* @__PURE__ */ Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = /* @__PURE__ */ Symbol.for("react.profiler"), REACT_CONSUMER_TYPE = /* @__PURE__ */ Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = /* @__PURE__ */ Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = /* @__PURE__ */ Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = /* @__PURE__ */ Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = /* @__PURE__ */ Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = /* @__PURE__ */ Symbol.for("react.memo"), REACT_LAZY_TYPE = /* @__PURE__ */ Symbol.for("react.lazy"), REACT_ACTIVITY_TYPE = /* @__PURE__ */ Symbol.for("react.activity"), REACT_CLIENT_REFERENCE = /* @__PURE__ */ Symbol.for("react.client.reference"), ReactSharedInternals = React2.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, hasOwnProperty2 = Object.prototype.hasOwnProperty, isArrayImpl = Array.isArray, createTask = console.createTask ? console.createTask : function() {
+ return null;
+ };
+ React2 = {
+ react_stack_bottom_frame: function(callStackForError) {
+ return callStackForError();
+ }
+ };
+ var specialPropKeyWarningShown;
+ var didWarnAboutElementRef = {};
+ var unknownOwnerDebugStack = React2.react_stack_bottom_frame.bind(
+ React2,
+ UnknownOwner
+ )();
+ var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));
+ var didWarnAboutKeySpread = {};
+ reactJsxRuntime_development.Fragment = REACT_FRAGMENT_TYPE;
+ reactJsxRuntime_development.jsx = function(type, config, maybeKey) {
+ var trackActualOwner = 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;
+ return jsxDEVImpl(
+ type,
+ config,
+ maybeKey,
+ false,
+ trackActualOwner ? Error("react-stack-top-frame") : unknownOwnerDebugStack,
+ trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask
+ );
+ };
+ reactJsxRuntime_development.jsxs = function(type, config, maybeKey) {
+ var trackActualOwner = 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;
+ return jsxDEVImpl(
+ type,
+ config,
+ maybeKey,
+ true,
+ trackActualOwner ? Error("react-stack-top-frame") : unknownOwnerDebugStack,
+ trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask
+ );
+ };
+ })();
+ return reactJsxRuntime_development;
+}
+var hasRequiredJsxRuntime;
+function requireJsxRuntime() {
+ if (hasRequiredJsxRuntime) return jsxRuntime.exports;
+ hasRequiredJsxRuntime = 1;
+ if (process.env.NODE_ENV === "production") {
+ jsxRuntime.exports = requireReactJsxRuntime_production();
+ } else {
+ jsxRuntime.exports = requireReactJsxRuntime_development();
+ }
+ return jsxRuntime.exports;
+}
+var jsxRuntimeExports = requireJsxRuntime();
+function OrderedMap(content) {
+ this.content = content;
+}
+OrderedMap.prototype = {
+ constructor: OrderedMap,
+ find: function(key) {
+ for (var i = 0; i < this.content.length; i += 2)
+ if (this.content[i] === key) return i;
+ return -1;
+ },
+ // :: (string) → ?any
+ // Retrieve the value stored under `key`, or return undefined when
+ // no such key exists.
+ get: function(key) {
+ var found2 = this.find(key);
+ return found2 == -1 ? void 0 : this.content[found2 + 1];
+ },
+ // :: (string, any, ?string) → OrderedMap
+ // Create a new map by replacing the value of `key` with a new
+ // value, or adding a binding to the end of the map. If `newKey` is
+ // given, the key of the binding will be replaced with that key.
+ update: function(key, value, newKey) {
+ var self2 = newKey && newKey != key ? this.remove(newKey) : this;
+ var found2 = self2.find(key), content = self2.content.slice();
+ if (found2 == -1) {
+ content.push(newKey || key, value);
+ } else {
+ content[found2 + 1] = value;
+ if (newKey) content[found2] = newKey;
+ }
+ return new OrderedMap(content);
+ },
+ // :: (string) → OrderedMap
+ // Return a map with the given key removed, if it existed.
+ remove: function(key) {
+ var found2 = this.find(key);
+ if (found2 == -1) return this;
+ var content = this.content.slice();
+ content.splice(found2, 2);
+ return new OrderedMap(content);
+ },
+ // :: (string, any) → OrderedMap
+ // Add a new key to the start of the map.
+ addToStart: function(key, value) {
+ return new OrderedMap([key, value].concat(this.remove(key).content));
+ },
+ // :: (string, any) → OrderedMap
+ // Add a new key to the end of the map.
+ addToEnd: function(key, value) {
+ var content = this.remove(key).content.slice();
+ content.push(key, value);
+ return new OrderedMap(content);
+ },
+ // :: (string, string, any) → OrderedMap
+ // Add a key after the given key. If `place` is not found, the new
+ // key is added to the end.
+ addBefore: function(place, key, value) {
+ var without = this.remove(key), content = without.content.slice();
+ var found2 = without.find(place);
+ content.splice(found2 == -1 ? content.length : found2, 0, key, value);
+ return new OrderedMap(content);
+ },
+ // :: ((key: string, value: any))
+ // Call the given function for each key/value pair in the map, in
+ // order.
+ forEach: function(f) {
+ for (var i = 0; i < this.content.length; i += 2)
+ f(this.content[i], this.content[i + 1]);
+ },
+ // :: (union