commit fce566a8b9ff577ba4541c6d69c4c2a682b630fc Author: hshub Date: Tue Apr 16 22:26:30 2024 +0000 v2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5b5d3a9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,42 @@ +# ---> macOS +# General +.DS_Store +._.DS_Store +._* +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +/uploads/* +etc/avatars/* +etc/previews/* + +etc/vendor/ +etc/config.json +test.php +test.js + +node_modules/ +package-lock.json +composer.lock diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..5ef2312 --- /dev/null +++ b/.htaccess @@ -0,0 +1,20 @@ + + Header set Access-Control-Allow-Origin "*" + Header set Access-Control-Allow-Methods: "GET" + + + + Header set Cache-Control "max-age=1800, public" + + + Header set Cache-Control "max-age=63072000, public" + + + Header set Cache-Control "max-age=63072000, public" + + +RewriteEngine on +RewriteRule ^avatar/([A-Za-z0-9]+)/?$ etc/avatar.php?id=$1 +RewriteRule ^preview/([A-Za-z0-9]+)/?$ etc/preview.php?id=$1 + +RewriteRule ^invite/([A-Za-z0-9-]+)/?$ id.php?invite=$1 \ No newline at end of file diff --git a/.well-known/wallets/HNS b/.well-known/wallets/HNS new file mode 100644 index 0000000..1226642 --- /dev/null +++ b/.well-known/wallets/HNS @@ -0,0 +1 @@ +hs1qf0cxy6ukhgjlmqfhe0tpw800t2tcul4s0szwqa diff --git a/api.php b/api.php new file mode 100644 index 0000000..a8551f0 --- /dev/null +++ b/api.php @@ -0,0 +1,236 @@ + true, + "fields" => [] + ]; + + foreach ($data as $key => $value) { + if (!is_array($data[$key])) { + $data[$key] = trim($value, ". ".chr(194).chr(160).PHP_EOL); + } + } + + switch ($data["action"]) { + case "setPublicKey": + case "getPublicKey": + case "saveSettings": + case "getGifCategories": + case "searchGifs": + case "pushToken": + case "getMessage": + if ($data["session"]) { + $keyValid = @sql("SELECT * FROM `sessions` WHERE `id` = ?", [$data["session"]]); + if (!$keyValid) { + error("Invalid key."); + } + } + else { + error("Missing key."); + } + break; + } + + switch ($data["action"]) { + case "checkName": + if (!activeDomainForName($data["domain"])) { + error("The domain provided isn't available to message."); + } + break; + + case "startSession": + $code = "V2-".generateCode("session"); + sql("INSERT INTO `sessions` (id) VALUES (?)", [$code]); + $output["session"] = $code; + break; + + case "setPublicKey": + $insert = sql("UPDATE `sessions` SET `pubkey` = ? WHERE `id` = ? AND `pubkey` IS NULL", [$data["pubkey"], $data["session"]]); + break; + + case "getPublicKey": + $key = @sql("SELECT `pubkey` FROM `sessions` WHERE `id` = ?", [$data["session"]])[0]["pubkey"]; + $output["pubkey"] = $key; + break; + + case "getAddress": + $address = @sql("SELECT `address` FROM `domains` WHERE `id` = ?", [$data["domain"]])[0]; + if ($address["address"]) { + $output["address"] = $address["address"]; + } + break; + + case "saveSettings": + $settings = json_decode($data["settings"], true); + + $domainInfo = domainForID($data["domain"]); + $tld = tldForDomain($domainInfo["domain"]); + + if (@$settings["avatar"]) { + if (in_array($tld, getStakedNames())) { + $settings["avatar"] = trim($settings["avatar"]); + + if (!validImage($settings["avatar"])) { + error("The Avatar URL provided isn't a valid image."); + } + + sql("UPDATE `domains` SET `avatar` = ? WHERE `id` = ? AND `session` = ?", [$settings["avatar"], $data["domain"], $data["session"]]); + + $output["avatar"] = $settings["avatar"]; + } + else { + error("Only SLD's of staked TLD's can set an Avatar here."); + } + } + + if (@$settings["address"]) { + if (in_array($tld, getStakedHIP2Names())) { + $settings["address"] = trim($settings["address"]); + + if (!validateAddress($settings["address"])) { + error("The HNS Address provided isn't valid."); + } + + sql("UPDATE `domains` SET `address` = ? WHERE `id` = ? AND `session` = ?", [$settings["address"], $data["domain"], $data["session"]]); + } + else { + error("Only SLD's of certain staked TLD's can set an address here."); + } + } + break; + + case "getMetaTags": + $checkCache = @sql("SELECT `id`, `link`, `title`, `description`, `image`, `video` FROM `previews` WHERE `link` = ?", [$data["url"]])[0]; + if ($checkCache) { + unset($checkCache["link"]); + + foreach ($checkCache as $key => $value) { + if (!$value) { + unset($checkCache[$key]); + } + } + + $tags = $checkCache; + } + else { + $tags = fetchMetaTags($data["url"]); + } + + if (@$tags["id"]) { + if (@$tags["title"]) { + $output["tags"] = $tags; + } + + if (@$output["tags"]["image"]) { + $output["tags"]["image"] = "/preview/".$tags["id"]; + } + + if (@$output["tags"]["description"]) { + $output["tags"]["description"] = $output["tags"]["description"]; + } + } + break; + + case "getGifCategories": + $categories = []; + $getGifs = file_get_contents("https://tenor.googleapis.com/v2/categories?key=".$GLOBALS["tenorKey"]."&client_key=HNSChat&limit=20"); + $json = json_decode($getGifs, true); + + if (@$json["tags"]) { + foreach ($json["tags"] as $key => $tag) { + $categories[] = [ + "term" => @$tag["searchterm"], + "gif" => @$tag["image"] + ]; + } + } + + $output["categories"] = $categories; + break; + + case "searchGifs": + if (@$data["query"]) { + $gifs = []; + $getGifs = file_get_contents("https://tenor.googleapis.com/v2/search?q=".urlencode($data["query"])."&key=".$GLOBALS["tenorKey"]."&client_key=HNSChat&limit=100"); + $json = json_decode($getGifs, true); + + if (@$json["results"]) { + foreach ($json["results"] as $key => $gif) { + $gifs[] = [ + "id" => @$gif["id"], + "preview" => @$gif["media_formats"]["tinygif"]["url"], + "full" => @$gif["media_formats"]["gif"]["url"], + "width" => @$gif["media_formats"]["gif"]["dims"][0], + "height" => @$gif["media_formats"]["gif"]["dims"][1], + ]; + } + } + + $output["gifs"] = $gifs; + } + break; + + case "getMessage": + $message = @sql("SELECT * FROM `messages` WHERE `id` = ?", [$data["id"]])[0]; + if ($message) { + $domain = domainForID($data["domain"]); + $channel = channelForID($message["conversation"]); + if ($channel) { + if ($channel["public"] || ($domain["tld"] == $channel["name"])) { + $output = [ + "success" => true, + "id" => $message["id"], + "time" => $message["time"], + "conversation" => $message["conversation"], + "user" => $message["user"], + "message" => $message["message"], + "reactions" => $message["reactions"], + ]; + + if (@$message["reply"]) { + $output["reply"] = true; + $output["replying"] = $message["replying"]; + } + } + } + } + break; + + case "pushToken": + if (preg_match("/^ExponentPushToken\[.+?\]$/", $data["token"])) { + $exists = @sql("SELECT JSON_CONTAINS(`push`, JSON_QUOTE(?), '$') AS `exists` FROM `sessions` WHERE `id` = ?", [$data["token"], $data["session"]])[0]["exists"]; + if (!$exists) { + sql("UPDATE `sessions` SET `push` = JSON_ARRAY_APPEND(`push`, '$', ?) WHERE `id` = ?", [$data["token"], $data["session"]]); + } + } + break; + + default: + $output["message"] = "Unknown function."; + $output["success"] = false; + break; + } + + end: + if (@$output["fields"] && @count($output["fields"])) { + $output["fields"] = array_unique($output["fields"]); + $output["success"] = false; + } + else { + unset($output["fields"]); + } + + die(json_encode($output)); +?> diff --git a/assets/css/dish.css b/assets/css/dish.css new file mode 100755 index 0000000..11c0c38 --- /dev/null +++ b/assets/css/dish.css @@ -0,0 +1,123 @@ +.Scenary { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + display: flex; + flex-direction: column; + padding: 20px; + gap: 20px; +} + +/* Container of Screen and Dish */ +.Conference { + display: flex; + flex: 1; + border-radius: 10px; + gap: 20px; + max-height: 100%; + max-width: 100%; +} + +/* Container of Cameras */ +.Dish { + overflow: scroll; + display: flex; + align-content: center; + flex-wrap: wrap; + align-items: center; + justify-content: center; + vertical-align: middle; + flex: 1; + border-radius: 10px; + background: rgba(0, 0, 0, 0.3); + + +} + +/* Camera */ +.Dish>div { + position: relative; + vertical-align: middle; + align-self: center; + border-radius: 10px; + overflow: hidden; + display: inline-block; + box-shadow: var(--shadow-dark); + background: #fff; + animation: show 0.4s ease; +} + +/* Video (check the nice property object-fit) */ +.Dish>div video { + position: absolute; + right: 0; + object-fit: cover; + bottom: 0; + width: 100%; + height: 100%; + background: #000; + border-radius: 10px; + overflow: hidden; + left: 0; + top: 0; + background-size: cover; + overflow: hidden; + -webkit-transition: margin-top 1s ease-in-out; + -moz-transition: margin-top 1s ease-in-out; + -o-transition: margin-top 1s ease-in-out; + transition: margin-top 1s ease-in-out; +} + +/* Animation of Loading Video */ +.Dish>div video.loading { + margin-top: 100%; +} + +/* Aspect Ratio Number */ +.Dish div:after { + color: #aaa; + font-size: 13px; + font-family: Arial, Helvetica, sans-serif; + position: absolute; + bottom: 20px; + left: 23px; + font-weight: 100; + content: attr(data-aspect); + display: block; +} + +/* Gray Diagonal */ +.Dish div:before { + position: absolute; + height: 100%; + background: url(./../general/diagonal.jpg); + background-size: 100% 100%; + width: 100%; + opacity: 0.3; + font-weight: 100; + content: ''; + display: block; +} + +/* Screen */ +.Screen { + flex: 2; + background: #000; + opacity: 0.8; + border-radius: 10px; +} + +/* Animation of Cameras */ +@keyframes show { + 0% { + opacity: 0; + transform: scale(0.4) translateY(20px); + } + + 100% { + opacity: 1; + transform: scale(1) translateY(0); + } +} \ No newline at end of file diff --git a/assets/css/hljs-varo.css b/assets/css/hljs-varo.css new file mode 100755 index 0000000..1c95569 --- /dev/null +++ b/assets/css/hljs-varo.css @@ -0,0 +1,123 @@ +/*! + Theme: Default + Description: Original highlight.js style + Author: (c) Ivan Sagalaev + Maintainer: @highlightjs/core-team + Website: https://highlightjs.org/ + License: see project LICENSE + Touched: 2021 +*/ + +/* +This is left on purpose making default.css the single file that can be lifted +as-is from the repository directly without the need for a build step + +Typically this "required" baseline CSS is added by `makestuff.js` during build. +*/ +pre code.hljs { + display: block; +} + +/* end baseline CSS */ + +/* Base color: saturation 0; */ + +.hljs-subst { + /* default */ +} + +/* purposely ignored */ +.hljs-formula, +.hljs-attr, +.hljs-property, +.hljs-params {} + +.hljs-comment { + color: #7a7a7a; +} +.hljs-tag, +.hljs-punctuation { + color: #7a7a7a; +} + +.hljs-tag .hljs-name, +.hljs-tag .hljs-attr { + color: #fff; +} + + +.hljs-keyword, +.hljs-attribute, +.hljs-selector-tag, +.hljs-meta .hljs-keyword, + +.hljs-doctag, +.hljs-name { + font-weight: bold; +} + + +/* User color: hue: 0 */ + +.hljs-type, +.hljs-string, +.hljs-number, +.hljs-selector-id, +.hljs-selector-class, +.hljs-quote, +.hljs-template-tag, +.hljs-deletion { + color: #409aed; +} + +.hljs-title, +.hljs-section { + color: #409aed; + font-weight: bold; +} + +.hljs-regexp, +.hljs-symbol, +.hljs-variable, +.hljs-template-variable, +.hljs-link, +.hljs-selector-attr, +.hljs-operator, +.hljs-selector-pseudo { + color: #40ed50; +} + +/* Language color: hue: 90; */ + +.hljs-literal { + color: #db4437; +} + +.hljs-built_in, +.hljs-bullet, +.hljs-code, +.hljs-addition { + color: #397300; +} + + +/* Meta color: hue: 200 */ + +.hljs-meta { + color: #7a7a7a; +} + +.hljs-meta .hljs-string { + color: #38a; +} + + +/* Misc effects */ + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} \ No newline at end of file diff --git a/assets/css/hljs.css b/assets/css/hljs.css new file mode 100755 index 0000000..a75ea91 --- /dev/null +++ b/assets/css/hljs.css @@ -0,0 +1,9 @@ +/*! + Theme: Default + Description: Original highlight.js style + Author: (c) Ivan Sagalaev + Maintainer: @highlightjs/core-team + Website: https://highlightjs.org/ + License: see project LICENSE + Touched: 2021 +*/pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#f3f3f3;color:#444}.hljs-comment{color:#697070}.hljs-punctuation,.hljs-tag{color:#444a}.hljs-tag .hljs-attr,.hljs-tag .hljs-name{color:#444}.hljs-attribute,.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-name,.hljs-selector-tag{font-weight:700}.hljs-deletion,.hljs-number,.hljs-quote,.hljs-selector-class,.hljs-selector-id,.hljs-string,.hljs-template-tag,.hljs-type{color:#800}.hljs-section,.hljs-title{color:#800;font-weight:700}.hljs-link,.hljs-operator,.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#ab5656}.hljs-literal{color:#695}.hljs-addition,.hljs-built_in,.hljs-bullet,.hljs-code{color:#397300}.hljs-meta{color:#1f7199}.hljs-meta .hljs-string{color:#38a}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/assets/css/style.css b/assets/css/style.css new file mode 100755 index 0000000..f7bbf69 --- /dev/null +++ b/assets/css/style.css @@ -0,0 +1,3036 @@ +:root { + --themeColor: #409aed; + + --positiveColor: #91b14f; + --negativeColor: #db4437; + --warningColor: #ffcf24; + + --primaryBorderColor: #1c1c1c; + --secondaryBorderColor: #252525; + --tertiaryBorderColor: #3c3c3c; + + --primaryForeground: #fff; + --secondaryForeground: #7a7a7a; + --tertiaryForeground: #a6a6a6; + + --primaryBackground: #1e1e1e; + --secondaryBackground: #232323; + --tertiaryBackground: #282828; + --quaternaryBackground: #2f2f2f; + --quinaryBackground: #3c3c3c; + --senaryBackground: #262626; + --septenaryBackground: #555; + --octonaryBackground: #1a1a1a; + + --bubbleBackground: #2d2d2d; + --bubbleSelfBackground: #409aed; + --bubbleMentionBackground: #91b14f; + + --notificationColor: #db4437; + + --scrollbarTrack: transparent; + --scrollbarThumb: #888888ee; + --scrollbarThumbHover: #555555; + + --menuIcon: url(/assets/img/icons/menu); + --usersIcon: url(/assets/img/icons/users); + --composeIcon: url(/assets/img/icons/compose); + --lockIcon: url(/assets/img/icons/lock); + --closeIcon: url(/assets/img/icons/close); + --deleteIcon: url(/assets/img/icons/trash); + --messageIcon: url(/assets/img/icons/message); + --viewIcon: url(/assets/img/icons/view); + --plusIcon: url(/assets/img/icons/plus); + --payIcon: url(/assets/img/icons/pay); + --signatureIcon: url(/assets/img/icons/signature); + --checkIcon: url(/assets/img/icons/check); + --failIcon: url(/assets/img/icons/fail); + --warningIcon: url(/assets/img/icons/warning); + --replyIcon: url(/assets/img/icons/arrow); + --emojiIcon: url(/assets/img/icons/emoji); + --gifIcon: url(/assets/img/icons/gif); + --searchIcon: url(/assets/img/icons/search); + --clipboardIcon: url(/assets/img/icons/clipboard); + --editIcon: url(/assets/img/icons/edit); + --saveIcon: url(/assets/img/icons/save); + --mentionIcon: url(/assets/img/icons/mention); + --fishIcon: url(/assets/img/icons/fish); + --replayIcon: url(/assets/img/icons/replay); + --pinIcon: url(/assets/img/icons/pin); + --videoIcon: url(/assets/img/icons/video); + --voiceIcon: url(/assets/img/icons/voice); + --screenIcon: url(/assets/img/icons/screen); + --leaveIcon: url(/assets/img/icons/leave); + --audioIcon: url(/assets/img/icons/audio); + + --handshakeIcon: url(/assets/img/handshake); + --unstoppableIcon: url(/assets/img/unstoppable); + --icannIcon: url(/assets/img/icann); +} + +::-webkit-scrollbar { + height: 5px; + width: 5px; +} +::-webkit-scrollbar-track { + background-color: var(--scrollbarTrack); +} +::-webkit-scrollbar-thumb { + background-color: var(--scrollbarThumb); +} +::-webkit-scrollbar-thumb:hover { + background-color: var(--scrollbarThumbHover); +} +.scroller { + scrollbar-color: var(--scrollbarThumb) var(--scrollbarTrack); + scrollbar-width: auto; +} +.scroller.f { + scrollbar-width: thin; +} +.scroller::-webkit-scrollbar-track { + margin-top: 0px; + margin-bottom: 0px; +} + +.positive { + color: var(--positiveColor); +} + +a { + text-decoration: none; +} + +*,*:after,*:before { + box-sizing: border-box; + background-size: contain; + background-position: center; + background-repeat: no-repeat; + -webkit-mask-size: contain; + -webkit-mask-position: center; + -webkit-mask-repeat: no-repeat; + -moz-mask-size: contain; + -moz-mask-position: center; + -moz-mask-repeat: no-repeat; + mask-size: contain; + mask-position: center; + mask-repeat: no-repeat; + font-family: "Arial"; + font-size: 15px; + letter-spacing: 0.25px; + touch-action: pan-x pan-y; +} + +body:not(.desktop) { + -webkit-touch-callout: none; + -webkit-user-callout: none; + -webkit-user-select: none; + -webkit-user-drag: none; + -webkit-user-modify: none; + -webkit-highlight: none; +} + +code { + font-size: inherit; +} + +.logo span { + font-family: "Rubik"; +} + +html,body { + background-color: var(--primaryBackground); + color: var(--primaryForeground); + height: 100%; + width: 100%; + min-width: 500px; + margin: 0; +} +body { + display: flex; + justify-content: center; + align-items: center; +} +body[data-page=chat] { + overflow: hidden; + position: fixed; +} + +div { + color: var(--primaryForeground); +} + +iframe { + outline: none; + border: 0; +} +.loading { + display: none; + position: absolute; + width: 100%; + height: 100%; + justify-content: center; + align-items: center; +} +.hidden { + display: none !important; +} +.shown:not(.flex) { + display: block !important; +} +.shown.flex { + display: flex !important; +} + +.visible { + opacity: 1 !important; +} + +.center { + text-align: center; + margin-left: auto; + margin-right: auto; +} + +.group { + display: flex; + align-items: center; +} +.group:not(.searching) div:not(.clipboard) { + margin-right: 16px; +} + +#users .title .group.normal { + margin-left: 5px; +} + +#stats .stat div:last-child { + color: var(--secondaryForeground); +} + +#stats .stat .list { + display: flex; + flex-direction: column; +} + +a, .link { + color: var(--themeColor); +} +body.desktop a:not(.previewLink):hover, body.desktop .link:hover { + cursor: pointer; + opacity: 0.5; +} + +.address { + text-align: center; + word-break: break-all; +} + +.messageHeader .title { + display: flex; + align-items: center; +} +.messageHeader .title .decoded { + margin-left: 5px; + color: var(--secondaryForeground); +} + +tr,.title,.subtitle,.button,#qrcode,.header,.user,.time,.informational,.reply,.message.payment,.reactions .reaction,.fallback,.preview .media, .messageEffect, .messageEffect > *, .pinnedMessage > *, #videoInfo .actions > * { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +.error, .destructive { + color: var(--negativeColor) !important; +} + +.response { + text-align: center; +} +.popover .response:not(:empty) { + margin-top: 10px; +} +.popover[data-name=pay] .response:empty { + margin-top: -10px; +} + +.decrypt { + display: none; +} + +.inline { + display: inline; +} +.inline.nick, .inline.channel { + font-weight: bolder; +} + +.user { + line-height: 1; +} + +body.desktop .inline:hover { + cursor: pointer; + opacity: 0.5; +} + +.icon { + height: 20px; + width: 20px; + background-color: var(--primaryForeground); + flex-shrink: 0; +} +body.desktop .icon:hover { + cursor: pointer; + opacity: 0.5; +} +.icon.menu { + -webkit-mask-image: var(--menuIcon); + -moz-mask-image: var(--menuIcon); + mask-image: var(--menuIcon); + -webkit-mask-size: 20px; + -moz-mask-size: 20px; + mask-size: 20px; +} +.icon.users { + -webkit-mask-image: var(--usersIcon); + -moz-mask-image: var(--usersIcon); + mask-image: var(--usersIcon); + -webkit-mask-size: 20px; + -moz-mask-size: 20px; + mask-size: 20px; +} +.icon.compose { + -webkit-mask-image: var(--composeIcon); + -moz-mask-image: var(--composeIcon); + mask-image: var(--composeIcon); +} +.icon.search { + -webkit-mask-image: var(--searchIcon); + -moz-mask-image: var(--searchIcon); + mask-image: var(--searchIcon); +} +.icon.lock { + -webkit-mask-image: var(--lockIcon); + -moz-mask-image: var(--lockIcon); + mask-image: var(--lockIcon); + background-color: var(--negativeColor); +} +.icon.warning { + -webkit-mask-image: var(--warningIcon); + -moz-mask-image: var(--warningIcon); + mask-image: var(--warningIcon); + background-color: var(--warningColor); +} +.icon.close { + -webkit-mask-image: var(--closeIcon); + -moz-mask-image: var(--closeIcon); + mask-image: var(--closeIcon); +} +.icon.remove { + -webkit-mask-image: var(--plusIcon); + -moz-mask-image: var(--plusIcon); + mask-image: var(--plusIcon); + transform: rotate(45deg); +} +.icon.delete { + -webkit-mask-image: var(--deleteIcon); + -moz-mask-image: var(--deleteIcon); + mask-image: var(--deleteIcon); + background-color: var(--negativeColor); +} +.icon.message { + -webkit-mask-image: var(--messageIcon); + -moz-mask-image: var(--messageIcon); + mask-image: var(--messageIcon); +} +.icon.edit { + -webkit-mask-image: var(--editIcon); + -moz-mask-image: var(--editIcon); + mask-image: var(--editIcon); +} +.icon.save { + -webkit-mask-image: var(--saveIcon); + -moz-mask-image: var(--saveIcon); + mask-image: var(--saveIcon); +} +.icon.view { + -webkit-mask-image: var(--viewIcon); + -moz-mask-image: var(--viewIcon); + mask-image: var(--viewIcon); +} +.icon.plus { + -webkit-mask-image: var(--plusIcon); + -moz-mask-image: var(--plusIcon); + mask-image: var(--plusIcon); + -webkit-mask-size: 24px; + -moz-mask-size: 24px; + mask-size: 24px; + height: 24px; + width: 24px; +} +.icon.pay { + -webkit-mask-image: var(--payIcon); + -moz-mask-image: var(--payIcon); + mask-image: var(--payIcon); + -webkit-mask-size: 24px; + -moz-mask-size: 24px; + mask-size: 24px; + height: 24px; + width: 24px; +} +.icon.signature { + -webkit-mask-image: var(--signatureIcon); + -moz-mask-image: var(--signatureIcon); + mask-image: var(--signatureIcon); + width: 32px; + padding-left: 10px; + background-color: var(--secondaryForeground); +} +.icon.signature.on { + background-color: var(--themeColor); +} +.icon.mention { + -webkit-mask-image: var(--mentionIcon); + -moz-mask-image: var(--mentionIcon); + mask-image: var(--mentionIcon); +} +.icon.fish { + -webkit-mask-image: var(--fishIcon); + -moz-mask-image: var(--fishIcon); + mask-image: var(--fishIcon); +} +.icon.pin { + -webkit-mask-image: var(--pinIcon); + -moz-mask-image: var(--pinIcon); + mask-image: var(--pinIcon); + height: 16px; +} +.icon.video { + -webkit-mask-image: var(--videoIcon); + -moz-mask-image: var(--videoIcon); + mask-image: var(--videoIcon); +} +.icon.voice { + -webkit-mask-image: var(--voiceIcon); + -moz-mask-image: var(--voiceIcon); + mask-image: var(--voiceIcon); +} +.icon.screen { + -webkit-mask-image: var(--screenIcon); + -moz-mask-image: var(--screenIcon); + mask-image: var(--screenIcon); +} +.icon.leave { + -webkit-mask-image: var(--leaveIcon); + -moz-mask-image: var(--leaveIcon); + mask-image: var(--leaveIcon); +} +.icon.audio { + background-color: transparent; + background-image: var(--audioIcon); +} +.icon.replay { + -webkit-mask-image: var(--replayIcon); + -moz-mask-image: var(--replayIcon); + mask-image: var(--replayIcon); +} +.icon.reply { + -webkit-mask-image: var(--replyIcon); + -moz-mask-image: var(--replyIcon); + mask-image: var(--replyIcon); +} +.icon.emoji { + -webkit-mask-image: var(--emojiIcon); + -moz-mask-image: var(--emojiIcon); + mask-image: var(--emojiIcon); +} +.icon.emoji.big { + -webkit-mask-size: 24px; + -moz-mask-size: 24px; + mask-size: 24px; + height: 24px; + width: 32px; +} +.icon.gif { + -webkit-mask-image: var(--gifIcon); + -moz-mask-image: var(--gifIcon); + mask-image: var(--gifIcon); +} +.icon.gif.big { + -webkit-mask-size: 30px; + -moz-mask-size: 30px; + mask-size: 30px; + height: 24px; + width: 35px; +} +.icon.clipboard { + -webkit-mask-image: var(--clipboardIcon); + -moz-mask-image: var(--clipboardIcon); + mask-image: var(--clipboardIcon); + position: absolute; + right: 10px; +} +.icon.clipboard.copied { + background-color: var(--positiveColor); +} + +.contextMenu[data-name=userContext] .type { + margin: 5px auto 0 auto; +} +.contextMenu[data-name=userContext][data-type=handshake] .type { + -webkit-mask-image: var(--handshakeIcon); + -moz-mask-image: var(--handshakeIcon); + mask-image: var(--handshakeIcon); +} +.contextMenu[data-name=userContext][data-type=unstoppable] .type { + background-image: var(--unstoppableIcon); + background-color: unset; +} +.contextMenu[data-name=userContext][data-type=icann] .type { + -webkit-mask-image: var(--icannIcon); + -moz-mask-image: var(--icannIcon); + mask-image: var(--icannIcon); +} + +body.unverified #conversations .actionHolder .icon.compose { + background-color: var(--secondaryForeground); +} + +body.unverified #conversations .actionHolder:hover, body.unverified .messageRow .hover .actions:hover { + cursor: not-allowed; +} + +body.unverified #conversations .actionHolder *, body.unverified .messageRow .hover .actions * { + pointer-events: none; +} + +#blackout { + height: 100%; + width: 100%; + position: fixed; + background-color: rgba(0,0,0,0.3); + z-index: 99999999; + display: none; + top: 0; + left: 0; +} + +.connecting { + height: 100%; + width: 100%; + position: absolute; + background-color: var(--primaryBackground); + z-index: 999999999999; + top: 0; + left: 0; + display: flex; + justify-content: center; + align-items: center; +} + +.popover { + display: none; + width: calc(100% - 20px); + max-width: 500px; + background-color: var(--quaternaryBackground); + position: absolute; + padding: 20px; + border-radius: 25px; + z-index: 99999999; +} +.popover .head { + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + padding-bottom: 10px; +} +.popover .title { + width: 100%; + font-weight: bold; + font-size: 20px; +} + +.title.small { + font-size: inherit; + font-weight: inherit; +} +.subtitle { + color: var(--secondaryForeground); +} + +.contextMenu:not([data-name=userContext]) { + width: auto; +} +.contextMenu { + min-width: 250px; + max-width: 410px; +} +.contextMenu ul { + list-style: none; + padding: 0; + margin: 0; +} +.contextMenu ul li { + text-align: center; + padding: 8px; + border-radius: 10px; +} +.contextMenu[data-name=userContext] ul:not(:first-child) li, .contextMenu[data-name=channelContext] ul:not(:first-child) li { + background-color: var(--tertiaryBackground); +} +.contextMenu[data-name=messageContext] ul li:hover, .contextMenu[data-name=userContext] ul:not(:first-child) li:hover, .contextMenu[data-name=channelContext] ul:not(:first-child) li:hover { + background-color: var(--secondaryBackground); + cursor: pointer; +} + +.contextMenu li.action { + display: flex; + align-items: center; + justify-content: center; +} + +.contextMenu li.action * { + pointer-events: none; + user-select: none; +} + +.contextMenu li.action .icon { + margin-right: 5px; +} + +.contextMenu textarea { + border-radius: 10px; + resize: none; +} + +.contextMenu[data-name=userContext] .actions { + display: none; +} +.contextMenu[data-name=userContext].me .actions { + width: 100%; + height: 20px; + display: flex; + justify-content: space-between; + position: absolute; + left: 0; + padding: 0 20px; + z-index: 1; +} + +.contextMenu[data-name=userContext] .actions .action { + display: none; +} + +.contextMenu[data-name=userContext].me:not(.editing) .action.edit { + display: block; +} + +.contextMenu[data-name=userContext].editing .action.save, .contextMenu[data-name=userContext].editing .action.close { + display: block; +} + +.contextMenu[data-name=userContext] .pic { + display: flex; + justify-content: center; + margin: 0 -10px 10px 0; +} +.contextMenu[data-name=userContext] .pic .avatar { + height: 80px; + width: 80px; +} +.contextMenu[data-name=userContext] .pic .fallback { + font-size: 40px; +} +.contextMenu[data-name=userContext] li.bio { + display: flex; + flex-direction: column; + align-items: center; + padding: 10px 0; +} +.contextMenu[data-name=userContext] .bioHolder { + width: 100%; + position: relative; +} +.contextMenu[data-name=userContext] .bioHolder .limit { + display: none; +} +.contextMenu[data-name=userContext].editing .bioHolder { + background-color: var(--tertiaryBackground); + padding: 10px 10px 20px 10px; + border-radius: 10px; + height: 120px; +} +.contextMenu[data-name=userContext] .bioHolder .bio { + white-space: pre-wrap; + max-height: 110px; + overflow-y: scroll; +} +.contextMenu[data-name=userContext] .bioHolder .bio *:not(.link) { + color: inherit; +} +.contextMenu[data-name=userContext].editing .bioHolder .bio { + height: 100%; + overflow-y: scroll; + color: var(--primaryForeground); +} +.contextMenu[data-name=userContext].editing .bioHolder .limit { + height: 20px; + padding: 5px; + color: var(--secondaryForeground); + display: flex; + justify-content: flex-end; + align-items: center; + position: absolute; + bottom: 0; + right: 0; +} +.contextMenu[data-name=userContext] textarea[name=bio] { + height: 100%; + width: 100%; + background-color: transparent; +} +.contextMenu[data-name=userContext].me div.bio:empty:after { + content: "Tell everyone about yourself."; + color: var(--secondaryForeground); +} + +.contextMenu[data-name=userContext].me ul:not(:first-child) { + display: none; +} + +.contextMenu .message { + word-break: break-word; + word-break: normal; + overflow-wrap: anywhere; +} + +.contextActions { + display: flex; + flex-direction: column; + gap: 5px; +} + +#qrcode { + background-color: var(--tertiaryBackground); + padding: 10px; + width: fit-content; + margin-left: auto; + margin-right: auto; + border-radius: 10px; + position: relative; +} +#qrlogo { + position: absolute; + top: 50%; + left: 50%; + background: var(--tertiaryBackground); + height: 50px; + width: 50px; + margin-top: -25px; + margin-left: -25px; + border-radius: 5px; +} +#qrlogo img { + height: 100%; + width: 100%; + padding: 10px; + filter: invert(100%) sepia(0%) saturate(1%) hue-rotate(305deg) brightness(106%) contrast(101%); +} + +.form { + width: 100%; + max-width: 400px; + text-align: center; + padding: 10% 10px; + align-self: flex-start; + display: flex; + flex-direction: column; + align-items: center; +} +.form .logo { + width: auto; +} +.form .logo img { + height: 60px; + width: 60px; +} +.form .logo span { + font-size: 60px; +} +.form .section { + width: inherit; +} + +.form#id { + padding: 20px 10px; + align-self: initial; + gap: 10px; +} +body[data-page=id] { + align-items: initial; +} + +.section.loading { + display: block; + position: relative; + top: 20px; +} +.logo { + width: 105px; + height: 100%; + display: flex; + align-items: center; + justify-content: space-between; +} +.logo img { + height: 30px; + width: 30px; + filter: invert(100%) sepia(0%) saturate(1%) hue-rotate(305deg) brightness(106%) contrast(101%); +} +.logo span { + font-size: 30px; + padding-left: 10px; +} + +.header .logo { + width: 60px; + height: 60px; + background-color: var(--primaryBackground); + display: flex; + align-items: center; + justify-content: center; + border-right: 1px solid var(--primaryBorderColor); +} + +body[data-page=id] .form .section { + display: none; +} + +.form .section > *:not(:last-child), .popover .body > :not(:last-child), .popover .body .content > :not(:last-child), #manageDomains .domains > *:not(:last-child) { + margin-bottom: 10px; +} + +#manageDomains .domains:empty { + display: none; +} + +#manageDomains .domains { + display: flex; + flex-direction: column; + text-align: left; +} + +#manageDomains .domains .domain { + display: flex; + width: 100%; + justify-content: space-between; + align-items: center; +} + +#manageDomains .domains .domain div { + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + line-height: 20px; +} + +.actions { + max-width: 100%; + display: flex; + justify-content: flex-end; +} +.actions .action:not(:last-child) { + margin-right: 10px; +} + +.input .action { + margin-right: 8px; + background-color: var(--secondaryForeground); +} + +.input .action.gif { + margin-left: 8px; +} + +select { + outline: none; + border: none; + background-color: var(--tertiaryBackground); + color: var(--primaryForeground); + border-radius: 10px; + display: inline-block; + font: inherit; + line-height: 1.5em; + padding: 0.5em 2.5em 0.5em 1em; + background-image: linear-gradient(45deg, transparent 50%, var(--secondaryForeground) 50%), linear-gradient(135deg, var(--secondaryForeground) 50%, transparent 50%); + background-position: calc(100% - 15px) calc(1em + 2px), calc(100% - 10px) calc(1em + 2px), calc(100% - 2.5em) 0.5em; + background-size: 5px 5px, 5px 5px, 1px 1.5em; + margin: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-appearance: none; + -moz-appearance: none; + height: 40px; +} +select:-moz-focusring { + color: transparent; + text-shadow: 0 0 0 #000; +} +input { + border-radius: 10px; +} +input[type=file] { + display: none; +} +input[name=dot] { + background: transparent; + width: 25px; + text-align: center; +} + +input[readonly] { + color: var(--secondaryForeground); +} + +input.copyable { + padding-right: 35px; +} + +input, textarea { + width: 100%; + height: 40px; + padding: 10px; + border: none; + outline: none; + background-color: var(--tertiaryBackground); + color: var(--primaryForeground); +} + +[contenteditable=true] { + border: none; + outline: none; +} + +.form .input { + text-align: center; +} + +.button { + width: 100%; + height: 40px; + background-color: var(--themeColor); + line-height: 40px; + color: var(--primaryForeground); + border-radius: 10px; + text-align: center; + overflow: hidden; +} +.disabled { + opacity: 0.5; +} +.disabled:hover { + cursor: not-allowed !important; +} +body.desktop .button:hover { + cursor: pointer; + opacity: 0.5; +} + +#holder { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; +} +#holder[data-type=channels] #users { + display: flex; +} +#holder[data-type=channels] .header .icon.users { + display: block; +} +#holder[data-type=pms] .header .icon.users { + background-color: var(--secondaryForeground); +} +#holder[data-type=pms] .header .icon.users:hover { + cursor: not-allowed; + opacity: 1; +} +#holder[data-type=pms] #users { + display: none !important; +} + +#holder .input .action[data-action=pay] { + display: none; +} +body.bob #holder[data-type=pms] .input .action[data-action=pay] { + display: block; +} + +.popover[data-name=pay] .loading { + justify-content: center; + position: relative; +} +.popover[data-name=pay] .content { + display: none; +} + +.popover[data-name=settings] .setting { + display: flex; + align-items: center; + height: 40px; +} + +#react.react { + bottom: auto !important; + position: fixed; +} + +#react, #completions { + width: calc(100% - 20px); + bottom: 10px; +} + +#completions { + left: 10px; +} +#react { + right: 10px; +} + +#react .grid { + display: none; + height: 300px; + background-color: var(--tertiaryBackground); + border-radius: 10px; + overflow-y: scroll; + padding: 5px; +} +#react .grid[data-type=emojis] .subtitle { + padding-left: 5px; + padding-top: 5px; +} +#react .grid[data-type=emojis] .emojis { + display: flex; + flex-wrap: wrap; +} +#react .grid[data-type=emojis] .emojis .emoji { + font-size: 27px; + line-height: 40px; + text-align: center; + height: 40px; + width: 40px; + border-radius: 5px; +} +#react .grid[data-type=emojis] .emojis .emoji:hover { + cursor: pointer; + background-color: var(--quinaryBackground); +} + +#react .section[data-type=categories] { + display: grid; + grid-template-columns: calc(50% - 5px) calc(50% - 5px); + padding: 5px; + gap: 10px; +} +#react .section[data-type=categories].shown { + display: grid !important; +} +#react .section[data-type=categories] .category { + height: 100px; + width: 100%; + border-radius: 5px; + position: relative; + display: flex; + align-items: center; + justify-content: center; + overflow: hidden; +} +#react .section[data-type=categories] .category:hover { + opacity: 0.7; + cursor: pointer; +} +#react .section[data-type=categories] .category > * { + pointer-events: none; +} +#react .section[data-type=categories] .category .title { + position: relative; + z-index: 1; + text-align: center; + text-shadow: 1px 1px #000; +} +#react .section[data-type=categories] .category .background { + height: 100%; + width: 100%; + background-size: cover; + position: absolute; + filter: brightness(0.7); +} + +#react .section[data-type=gifs] { + display: none; + height: 100%; +} +#react .section[data-type=gifs] .column { + display: flex; + flex-direction: column; + height: 100%; + width: 50%; + padding: 5px; +} +#react .section[data-type=gifs] .gif { + width: 100%; + margin-bottom: 10px; + border-radius: 5px; +} +#react .section[data-type=gifs] .gif:hover { + opacity: 0.7; + cursor: pointer; +} + +.setting .subtitle { + width: 50%; + padding-right: 10px; +} +.setting input, .setting select { + width: 50%; + text-align: right; +} + +.header { + width: 100%; + flex-shrink: 0; + background-color: var(--secondaryBackground); + border-bottom: 1px solid var(--primaryBorderColor); + display: flex; + align-items: center; + z-index: 9999999; +} +.header .left,.header .right { + width: 40px; + height: 40px; + display: none; + flex-shrink: 0; + position: relative; +} +.header .left > *,.header .right > * { + width: 100%; + height: 100%; +} +.header .center { + height: 100%; + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; + padding-right: 10px; +} +.header .end { + display: flex; + align-items: center; + background-color: var(--quaternaryBackground); + border-radius: 10px; +} +.header .avatar { + display: block; + margin: 0 5px 0 0; +} +.header #me .avatar { + margin: 0 5px; +} +.header .avatar:hover { + cursor: pointer; +} +.header .domain { + width: 100px; + height: 100%; +} +.header .domains { + height: 100%; + background-color: var(--tertiaryBackground); + border-radius: 10px; +} +.header .domains select:hover { + cursor: pointer; +} +#chats { + width: 100%; + height: 100%; + flex-grow: 1; + display: flex; + overflow: hidden; +} +.sidebar { + background-color: var(--tertiaryBackground); + flex-shrink: 0; + overflow: hidden; + display: flex; + flex-direction: column; + z-index: 9999999; +} +#conversations { + width: 250px; + border-right: 1px solid var(--primaryBorderColor); +} +#conversations .tabs { + background-color: var(--secondaryBackground); + display: flex; + align-items: center; + justify-content: space-evenly; + flex-shrink: 0; + flex-grow: 1; +} +#conversations .tabs .tab { + color: var(--secondaryForeground); + margin-right: 10px; + position: relative; +} +body.desktop #conversations .tabs .tab:not(.active):hover { + cursor: pointer; + opacity: 0.5; +} +.header .left.notification:after, #conversations .tabs .tab.notification:after { + content: ""; + position: absolute; + background-color: var(--notificationColor); + height: 5px; + width: 5px; + border-radius: 50%; +} +.header .left.notification:after { + top: 5px; + right: 0; +} +#conversations .tabs .tab.notification:after { + top: 0; + right: -10px; +} +#conversations .tabs .tab.active { + color: var(--primaryForeground); +} +#conversations .title .actionHolder { + margin-left: 10px; +} +#conversations .section { + max-height: 100%; + display: none; +} +#users { + width: 200px; + border-left: 1px solid var(--primaryBorderColor); + display: none; +} +#users.showing { + display: flex; +} +#users #count { + color: var(--secondaryForeground); +} +#users .user * { + pointer-events: none; +} + +#users .title .group { + width: 100%; +} + +#users .title .searching { + display: none; + align-items: center; +} +#users .title .searching div { + margin-left: 10px; +} + +.inputContainer { + z-index: 9999999; +} + +input[name=search] { + margin: 0; + padding: 10px; + height: 25px; + border-radius: 8px; +} + +.sidebar > .title { + height: 40px; + background-color: var(--secondaryBackground); + display: flex; + align-items: center; + justify-content: space-between; + padding: 10px; + flex-shrink: 0; + border-bottom: 1px solid var(--primaryBorderColor); +} +.sidebar .sections { + flex-grow: 1; + overflow: hidden; + display: flex; + flex-direction: column; +} +.sidebar .sections .section:not(:first-of-type) > .title { + border-top: 1px solid var(--primaryBorderColor); +} +.sidebar .sections .section > .title { + border-bottom: 1px solid var(--primaryBorderColor); +} +.sidebar .section > .title { + height: 25px; + line-height: 25px; + padding-left: 10px; + color: var(--secondaryForeground); + background-color: var(--secondaryBackground); +} +#users .users { + display: block; + overflow: hidden; + height: 100%; +} +.sidebar .section table { + height: 100%; + overflow-y: scroll; + overflow-y: overlay; + display: block; +} +#conversations > .footer { + height: 40px; + background-color: var(--tertiaryBackground); + display: flex; + align-items: center; + justify-content: space-evenly; + padding: 10px; + border-top: 1px solid var(--primaryBorderColor); + flex-shrink: 0; +} +.footer .action { + user-select: none; +} +table { + width: 100%; + border-collapse: collapse; +} +#conversations tr { + height: 50px; +} +#users tr, #completions tr { + height: 40px; +} +.sidebar tr, #completions tr { + display: flex; + align-items: center; + padding: 10px; +} +.sidebar tr .title { + flex-grow: 1; + text-overflow: ellipsis; + overflow: hidden; + width: 88px; + white-space: nowrap; +} +.sidebar tr .title .subtitle { + font-size: 12px; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; +} +.sidebar tr .title .subtitle span { + font-size: inherit; +} +#conversations tr.active, #completions tr.active { + background-color: var(--quinaryBackground); +} +.sidebar .section.channels tr.unread .avatar { + border: 2px solid var(--themeColor); +} +.sidebar .section.pms tr.unread .avatar .favicon { + border: 2px solid var(--notificationColor); +} +.sidebar tr.mentions .avatar { + border: 2px solid var(--notificationColor) !important; +} +body.desktop #conversations tr:not(.active):hover, body.desktop #users tr:hover, body.desktop .sidebar tr.selected { + background-color: var(--quaternaryBackground); +} +body.desktop #users tr:hover { + opacity: 1; +} +.sidebar tr:hover, #completions tr:hover { + cursor: pointer; +} + +.avatar .status.active { + width: 10px; + height: 10px; + border-radius: 50%; + background-color: var(--positiveColor); + position: absolute; + top: 0; + right: 0; + z-index: 3; + border: 2px solid var(--tertiaryBackground); +} +.contextMenu[data-name=userContext] .avatar .status.active { + width: 25px; + height: 25px; + border: 5px solid var(--quaternaryBackground); +} + +.user:hover .avatar .status.active, .user.selected .avatar .status.active { + border: 2px solid var(--quaternaryBackground); +} + +#users .user.inactive { + opacity: 0.5; +} +.avatar { + width: 30px; + height: 30px; + margin-right: 10px; + position: relative; + overflow: hidden; + flex-shrink: 0; +} +#conversations .channels tr .avatar { + border-radius: 50%; +} +tr.locked .avatar .locked, tr.locked .avatar .unclaimed { + z-index: 3; + width: 100%; + height: 100%; + background-color: var(--primaryBackground); + display: flex; + justify-content: center; + align-items: center; + top: 0; + left: 0; + position: absolute; + border-radius: 50%; +} +.favicon { + width: 100%; + height: 100%; + padding: 5px; + position: absolute; + top: 0; + left: 0; + z-index: 2; + border-radius: 50%; + background-size: cover; +} +.favicon[style*=background-image] + .fallback { + display: none; +} +.fallback { + width: 100%; + height: 100%; + background-color: var(--primaryBackground); + position: absolute; + top: 0; + left: 0; + z-index: 1; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; +} +.messageRow .avatar .fallback { + width: 100%; + height: 100%; + background-color: var(--secondaryBackground); + position: absolute; + top: 0; + left: 0; + z-index: 1; + text-align: center; + line-height: 30px; + border-radius: 50%; +} +.content { + width: 100%; + display: flex; + flex-direction: column; + justify-content: flex-end; + position: relative; +} + +.inputHolder { + min-height: 40px; + width: 100%; + flex-grow: 0; + flex-shrink: 0; + display: flex; + justify-content: center; + align-items: center; + padding: 8px; + background-color: var(--tertiaryBackground); + border-top: 1px solid var(--primaryBorderColor); + position: relative; +} +.inputHolder.locked .input { + display: none; +} +.inputHolder.locked .locked { + display: initial; +} +.input { + width: 100%; + height: 100%; + display: flex; + align-items: center; +} +.input #signature { + padding: 0; + height: 20px; + border-radius: 0; + display: none; +} +.input .inputs { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; +} +.inputs #message { + width: 100%; + line-height: 20px; + min-height: 20px; + height: 20px; + resize: none; + box-sizing: content-box; + padding: 0; + background-color: transparent; +} +.inputHolder .verify { + display: none; + text-align: center; +} +.inputHolder .locked { + display: none; + text-align: center; +} +.inputHolder .noConversations { + display: none; + text-align: center; +} +#attachments { + height: 200px; + width: 100%; + background: var(--tertiaryBackground); + display: none; +} +#attachments.shown { + display: flex; + align-items: center; + padding: 10px; +} +#attachments .attachment { + height: 100%; + width: 200px; + margin: 10px; + display: flex; + justify-content: center; + align-items: center; + position: relative; +} +#attachments .attachment .removeHolder { + background-color: var(--tertiaryBackground); + padding: 5px; + border-radius: 50%; + position: absolute; + top: -10px; + right: 0; +} +#attachments .attachment .icon.remove { + background-color: var(--negativeColor); +} +.messageHeader { + height: 40px; + flex: 1; + flex-shrink: 0; + background-color: var(--secondaryBackground); + display: flex; + align-items: center; + gap: 10px; +} +.messageHeader table { + width: auto; +} +.messageHeader tr .title .subtitle { + display: none; +} +.messageHeader tr { + display: flex; + align-items: center; + justify-content: center; +} +.messageHeader tr[data-type=channels] { + pointer-events: none; +} +.content .pinnedMessage { + display: none !important; +} +.pinnedMessage { + width: 100%; + flex: 1; + background-color: var(--secondaryBackground); + display: none; + gap: 8px; + align-items: center; + padding-left: 10px; + border-left: 1px solid var(--tertiaryBorderColor); +} +.pinnedMessage:hover { + cursor: pointer; +} +.pinnedMessage .pin { + pointer-events: none; + height: 13px; + width: 13px; +} +.pinnedMessage .message { + flex: 1; + overflow: hidden; + height: 18px; + text-overflow: ellipsis; + width: 0px; + white-space: nowrap; + color: var(--secondaryForeground); + text-align: left; + line-height: 20px; +} +#videoInfo { + height: 40px; + border-bottom: 1px solid var(--primaryBorderColor); + flex-shrink: 0; + width: 100%; + background-color: var(--secondaryBackground); + overflow: hidden; + display: none; + justify-content: space-between; + align-items: center; + padding: 10px; + gap: 10px; +} +#videoInfo .title { + display: none; + align-items: center; + gap: 5px; + color: var(--negativeColor); + font-weight: bold; +} +#videoInfo .info { + display: flex; + align-items: center; + gap: 10px; +} +#videoInfo .users { + display: flex; + padding-right: -10px; +} +#videoInfo .watching { + display: none; + align-items: center; + margin-left: -5px; + gap: 5px; +} +#videoInfo .watchers { + display: flex; +} +#videoInfo .avatar { + margin-right: 0; +} +#videoInfo .avatar:hover { + z-index: 10; + cursor: pointer; +} +#videoInfo .avatar:not(:first-child) { + margin-left: -15px; +} +#videoInfo .actions { + display: flex; + gap: 10px; +} +#videoInfo .actions > * { + display: none; +} +#videoContainer { + height: 40%; + border-bottom: 1px solid var(--primaryBorderColor); + flex-shrink: 0; + width: 100%; + background-color: var(--octonaryBackground); + overflow: hidden; + display: none; + padding: 15px; + flex-direction: column-reverse; +} +#videoContainer.publishing { + padding-top: 55px !important; +} +.videoHolder { + width: 100%; + height: 100%; + display: flex; +} +.videoHolder .screen { + flex: 2; + background-color: var(--primaryBackground); + margin: 15px; + border-radius: 10px; + display: none; + position: relative; + overflow: hidden; +} +.videoHolder .screen video { + width: 100%; + height: 100%; +} +.cams { + overflow: hidden; + display: flex; + align-content: center; + flex-wrap: wrap; + align-items: center; + justify-content: center; + vertical-align: middle; + flex: 1; + border-radius: 10px; + gap: 10px; +} +.cam { + position: relative; + vertical-align: middle; + align-self: center; + border-radius: 10px; + overflow: hidden; + display: inline-block; + max-height: 100%; + max-width: 100%; + border: 2px solid var(--octonaryBackground); +} +.cam.talking { + box-shadow: 0 0 0 2px var(--positiveColor); +} +.cam .info, .screen .info { + position: absolute; + z-index: 1; + width: 100%; + height: fit-content; + display: flex; + justify-content: space-between; + align-items: center; + padding: 5px; +} +.cam .info .icon.voice { + margin-left: 5px; + background-color: var(--negativeColor); + display: none; + height: 17px; + pointer-events: none; +} +.cam.audioMuted .info .icon.voice { + display: block; +} +.cam .background { + height: 100%; + width: 100%; + position: absolute; + z-index: 1; + display: none; +} +.cam.videoMuted .background { + display: unset; +} +.cam .background .user { + height: 100%; + width: 100%; +} +.cam .background .user > .title, .cam .background .user:after, .cam .background .user .avatar .status { + display: none; +} +.cam .background .user .avatar { + width: 100%; + height: 100%; + margin: 0; +} +.cam .background .user .avatar .fallback { + font-size: 60px; + border-radius: 0; +} +.cam .background .user .avatar .favicon { + border-radius: 0; +} +.cam video { + position: absolute; + right: 0; + object-fit: cover; + bottom: 0; + width: 100%; + height: 100%; + background: #000; + border-radius: 10px; + overflow: hidden; + left: 0; + top: 0; + background-size: cover; + overflow: hidden; + -webkit-transition: margin-top 1s ease-in-out; + -moz-transition: margin-top 1s ease-in-out; + -o-transition: margin-top 1s ease-in-out; + transition: margin-top 1s ease-in-out; +} +.cam table, .screen table { + position: relative; + display: block; + padding: 5px 10px; + background-color: var(--senaryBackground); + width: fit-content; + border-radius: 10px; + z-index: 1; +} +.cam tr, .screen tr { + display: flex; + align-items: center; +} +.cam table .user .avatar, .screen table .user .avatar { + margin-right: 5px; +} +.cam table .user:hover, .screen table .user:hover { + cursor: pointer; +} +#videoContainer.publishing .controls { + display: flex; +} +.controls { + height: 40px; + width: 100%; + display: none; + align-items: center; + justify-content: center; + gap: 10px; +} +.controls .button { + width: fit-content; + padding: 10px; +} +.controls .button > * { + pointer-events: none; +} +.controls .button.muted { + border-color: var(--negativeColor); +} + +.button.outline { + background-color: transparent; + border: 2px solid var(--themeColor); + box-sizing: border-box; + display: flex; + align-items: center; + justify-content: center; +} +#messageHolder { + height: 100%; + width: 100%; + display: flex; + flex-direction: column-reverse; + overflow-x: hidden; + overflow-y: scroll; + position: relative; + align-items: center; +} +#messages.empty { + height: 100%; + width: 100%; + align-items: center; + justify-content: center; +} +#messages.empty:after { + color: var(--secondaryForeground); + content: "There are no messages. You can be the first!"; + padding: 10px; +} +#chats .content .needSLD { + text-align: center; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + flex-direction: column; + padding: 20px; + position: absolute; +} +#chats .content .needSLD > * { + max-width: 350px; +} +#chats .content .needSLD > *:not(:last-child) { + margin-bottom: 10px; +} +#messageHolder.noScroll { + position: static; +} +#messages { + display: flex; + flex-direction: column; + padding: 0px 5px; + width: 100%; +} +.messageRow { + width: 100%; + position: relative; + padding: 0px 5px; + transition: background-color 250ms; + z-index: 9999999; +} +.messageRow.highlighted { + background-color: var(--octonaryBackground); +} +.messageRow.notice { + background-color: var(--quaternaryBackground); +} +.popover[data-name=messageContext].shown ~ #holder #messages .messageRow, #holder.replying .messageRow, #holder.reacting .messageRow { + opacity: 0.3; +} +.popover[data-name=messageContext].shown ~ #holder #messages .messageRow:is(.selecting,.selected), #holder.replying .messageRow.selected, #holder.reacting .messageRow.selected { + opacity: 1; +} + +.messageRow:not(.first) > .contents .main .user, .messageRow:not(.first) > .contents .main .avatar { + display: none; +} + +.messageRow.first { + padding-top: 5px; +} +.messageRow.last { + padding-bottom: 5px; +} +.messageRow .holder { + display: flex; + align-items: center; +} +#holder .messageRow:hover > .contents .hover > *, .messageRow:is(.selecting,.selected) > .contents .hover > * { + display: flex; + justify-content: space-evenly; +} +body:not(.desktop) .messageRow:hover > .contents .hover .actions .action.delete { + display: none; +} +.messageRow.self .holder { + justify-content: flex-end; +} +.messageRow:not(.self) .holder { + justify-content: flex-start; +} +.messageRow .actions { + width: 55px; + justify-content: space-evenly !important; +} +.messageRow .actions .action { + margin: 0; +} +.messageRow .hover { + width: 32%; + flex-shrink: 0; + display: flex; + flex-direction: column; + align-items: flex-start; +} +.messageRow .hover > * { + display: none; +} +.messageRow:not(.self) .hover > div { + margin-left: 5px; +} +.messageRow.self .hover > div { + margin-right: 5px; +} +.messageRow .time { + line-height: 12px; + font-size: 12px; + color: var(--secondaryForeground); + width: 55px; + text-align: center; +} +.messageRow.self .hover { + align-items: flex-end; +} +#messages .messageRow .message { + padding: 10px; + overflow: hidden; + max-width: 500px; +} +#messages .messageRow .preview { + background: var(--secondaryBackground); + position: relative; + width: 100%; +} +#messages .messageRow .preview > * { + line-height: 15px; +} +#messages .messageRow .preview .media { + width: 100%; + position: relative; + object-fit: contain; +} +#messages .messageRow .preview .media > * { + display: block; +} +#messages .messageRow .previewImage .media { + margin-bottom: -12px; +} + +#messages .messageRow .preview .media img { + height: 100%; + width: 100%; +} + +#messages .messageRow .preview .media iframe, #messages .messageRow .preview .media video { + height: 280px; + width: 100%; +} + +#messages .messageRow:not(.first):not(.last), #messages .messageRow.first:not(.last) { + margin: 0 0 2px 0; +} + +#messages > div, .messageFooter > div { + margin: 0 0 10px 0; +} +#messages > div:first-child { + margin: 10px 0; +} + +#messages .informational { + text-align: center; + color: var(--secondaryForeground); + padding: 5px; +} +.messageRow.informational .inline.nick, .messageRow.informational .inline.channel { + color: var(--secondaryForeground); +} +.messageRow:not(.informational) { + position: relative; +} +.messageRow:not(.emojis):not(.action):not(.notice):not([data-style=fancy]):not(.mention) .message { + background-color: var(--bubbleBackground); +} +.messageRow.self:not(.emojis):not(.action):not(.notice):not([data-style=fancy]):not(.mention) .message { + background-color: var(--bubbleSelfBackground); +} +.messageRow.action .body, .messageRow.action .body *, .messageRow.replying .reply .body.action { + font-style: italic; +} +.messageRow.action .body, .messageRow.action .body * { + color: var(--secondaryForeground); +} +.messageRow.emojis .body, .messageRow[data-style=fancy] .body { + font-size: 50px; + line-height: 50px; +} +.messageRow.dice .body { + background: linear-gradient(7deg, grey 25%, lightgrey 50%, grey, lightgrey); + -webkit-text-fill-color: transparent; + -webkit-background-clip: text; + text-shadow: 0px 1px 1px rgb(0 0 0 / 13%), 1px 2px 2px rgb(0 0 0 / 13%), 2px 4px 4px rgb(0 0 0 / 13%), 4px 8px 8px rgb(0 0 0 / 13%), 8px 16px 16px rgb(0 0 0 / 13%); +} +.messageRow[data-style=fancy] .body { + background: linear-gradient(7deg, grey 25%, lightgrey 50%, grey, lightgrey); + -webkit-text-fill-color: transparent; + -webkit-background-clip: text; + text-shadow: 0px 1px 1px rgb(0 0 0 / 13%), 1px 2px 2px rgb(0 0 0 / 13%), 2px 4px 4px rgb(0 0 0 / 13%), 4px 8px 8px rgb(0 0 0 / 13%), 8px 16px 16px rgb(0 0 0 / 13%); +} +.messageRow.action:not(.self):not(.mention) .message { + padding-left: 0 !important; + padding-right: 0 !important; +} +.messageRow.action.self .message { + padding-left: 0 !important; + padding-right: 0 !important; +} +.messageRow.emojis.replying .reply .contents, .messageRow[data-style=fancy].replying .reply .contents { + top: -19px; + position: relative; +} +.messageRow .message { + word-break: break-word; +} +.messageRow.self { + align-self: flex-end; + text-align: right; +} +.messageRow.self .message { + border-top-left-radius: 10px; + border-bottom-left-radius: 10px; +} +.messageRow.self .message .body a { + color: var(--primaryForeground); + text-decoration: underline; +} +.messageRow.mention .message .body a { + color: var(--primaryForeground); + text-decoration: underline; +} +.messageRow .message:not(.image) .body { + white-space: pre-line; + min-height: 17px; + min-width: 8px; +} +.messageRow:not(.self) .message { + border-top-right-radius: 10px; + border-bottom-right-radius: 10px; +} +.messageRow.self.first .message { + border-top-right-radius: 10px; +} +.messageRow:not(.self).first .message { + border-top-left-radius: 10px; +} +.messageRow.self.last .message { + border-bottom-right-radius: 10px; +} +.messageRow:not(.self).last .message { + border-bottom-left-radius: 10px; +} +.messageRow.mention:not(.self) .message { + background-color: var(--bubbleMentionBackground); +} +.messageRow.mention:not(.self) .message .body, .messageRow.mention:not(.self) .message .body * { + color: var(--primaryForeground) !important; +} +.message.signed:hover { + cursor: pointer; +} +.messageRow.first .contents { + padding-top: 15px; +} +.messageRow .user { + color: var(--secondaryForeground); + white-space: nowrap; +} +.messageRow:not(.informational) > .contents .user { + position: absolute; + top: 0; + font-size: 12px; + line-height: 12px; +} +.messageRow:not(.informational):not(.self) > .contents .user { + margin-left: 50px; +} +.messageRow:not(.informational).self > .contents .user { + margin-right: 50px; +} +.messageRow > .contents { + position: relative; + align-self: normal; + display: flex; + flex-direction: column; +} +.messageRow.replying { + padding-top: 20px !important; +} +.messageRow.self.replying { + display: flex; + flex-direction: column; + align-items: flex-end; +} +.messageRow.self > .reply .contents { + justify-content: flex-end; +} +.messageRow > .reply .contents { + display: flex; + width: 100%; + align-items: center; + line-height: 1.2em; +} +.messageRow > .reply .user { + padding-right: 5px; + font-size: 12px; +} +.messageRow > .reply { + display: flex; + width: 60%; + max-width: 550px; + position: absolute; + top: -12px; +} +.messageRow.self > .reply { + padding-right: 50px; +} +.messageRow:not(.self) > .reply { + padding-left: 50px; +} +.messageRow > .reply .body { + color: var(--secondaryForeground); + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + font-size: 12px; +} +.messageRow > .reply .body > * { + pointer-events: none; +} +.messageRow > .reply .body:hover { + opacity: 0.5; + cursor: pointer; +} +.messageRow.self > .reply { + justify-content: flex-end; +} +.messageRow > .reply .line { + position: absolute; + width: 30px; + height: 20px; + top: 23px; + border: 3px solid var(--quinaryBackground); + border-bottom-style: none; +} +.messageRow:not(.self) > .reply .line { + left: 16px; + border-right-style: none; + border-top-left-radius: 10px; +} +.messageRow.self > .reply .line { + right: 16px; + border-left-style: none; + border-top-right-radius: 10px; +} +.messageRow .reply .body .inline { + font-weight: inherit; + font-size: inherit; + color: inherit; + display: inline; +} +.messageRow.informational .user { + display: inline-block; + color: var(--secondaryForeground); +} +.messageRow .linkHolder:not(:empty) { + max-width: 400px; + margin: 2px 0 0 50px; + border-radius: 10px; + overflow: hidden; + background-color: var(--bubbleBackground); +} +.messageRow.self .linkHolder:not(:empty) { + align-self: flex-end; + margin: 2px 50px 0 0; +} + +.messageRow .linkHolder .info { + padding: 10px; +} + +.messageRow .linkHolder .title, .messageRow .linkHolder .subtitle { + overflow: hidden; + text-overflow: ellipsis; + -webkit-box-orient: vertical; + display: -webkit-box; +} +.messageRow .linkHolder .title { + -webkit-line-clamp: 2; + max-height: 34px; + line-height: 17px; +} +.messageRow .linkHolder .subtitle { + -webkit-line-clamp: 3; + max-height: 60px; +} +body.desktop .messageRow .user:hover { + cursor: pointer; + opacity: 0.5; +} +.messageRow.self .user { + right: 0; +} +.messageRow .avatar { + position: absolute; + height: 38px; + width: 38px; +} +.messageRow.self .avatar { + right: 0; + margin: 0; +} +.messageRow:not(.self) .holder, .messageRow:not(.self) .messageEffect { + margin-left: 50px; +} +.messageRow.self .holder, .messageRow.self .messageEffect { + margin-right: 50px; + align-self: flex-end; +} +.messageEffect { + width: fit-content; + color: var(--themeColor); + display: flex; + align-items: center; + gap: 3px; + padding: 2px 0; +} +.messageEffect .icon { + background-color: var(--themeColor); + pointer-events: none; + height: 15px; + width: 15px; +} + +.messageRow .favicon:hover { + cursor: pointer; +} +.messageRow .reactions { + display: flex; + padding: 0px 0px 3px 0px; + flex-wrap: wrap; +} +.messageRow .reactions:empty { + display: none; +} + +.messageRow.self .reactions { + justify-content: flex-end; +} + +.messageRow .reactions .reaction { + margin-top: 5px; + padding: 5px; + width: 44px; + height: 30px; + font-size: 20px; + background-color: var(--senaryBackground); + border-radius: 10px; + display: flex; + justify-content: space-around; + box-sizing: border-box; + align-items: center; +} +.messageRow .reactions .reaction:hover { + cursor: pointer; + background-color: var(--quinaryBackground) !important; +} + +.messageRow:not(.self) .reactions .reaction { + margin-right: 5px; +} +.messageRow.self .reactions .reaction { + margin-left: 5px; +} + +.messageRow:not(.self) .reactions .reaction:first-child { + margin-left: 0; +} +.messageRow.self .reactions .reaction:last-child { + margin-right: 0; +} +.messageRow .reactions .reaction.self { + border: 1px solid var(--bubbleSelfBackground); +} + + +.message.self.signed:before { + content: ""; + position: absolute; + top: 50%; + margin-top: -10px; + left: -25px; + height: 20px; + width: 20px; + -webkit-mask-image: var(--checkIcon); + -moz-mask-image: var(--checkIcon); + mask-image: var(--checkIcon); + background-color: var(--positiveColor); +} +.message:not(.self).signed:after { + content: ""; + position: absolute; + top: 50%; + margin-top: -10px; + right: -25px; + height: 20px; + width: 20px; + -webkit-mask-image: var(--checkIcon); + -moz-mask-image: var(--checkIcon); + mask-image: var(--checkIcon); + background-color: var(--positiveColor); +} +.message.self.signed.fail:before,.message:not(.self).signed.fail:after { + -webkit-mask-image: var(--failIcon); + -moz-mask-image: var(--failIcon); + mask-image: var(--failIcon); + background-color: var(--negativeColor); +} +.message .signature { + padding-top: 10px; + opacity: 0.7; + display: none; + cursor: text; +} +.message.typing { + width: 42px; +} +.message.image { + padding: 0 !important; + overflow: hidden; + display: table; +} +.message.image:not(.payment) { + background-color: transparent !important; +} +.message.payment .body { + display: flex; + align-items: center; + justify-content: center; +} +.message.payment .txMessage { + padding: 10px; + background-color: var(--bubbleBackground); +} +.messageRow.self .message.payment .txMessage { + background-color: var(--bubbleSelfBackground); +} +.message.payment .imageHolder { + display: flex; + flex-direction: column; + background-color: var(--secondaryBackground); +} +.message.payment .imageHolder img { + margin-bottom: -20px; +} +.message.payment { + padding-bottom: 50px; + background: var(--secondaryBackground); +} +.message.payment .amount { + font-size: 50px; + color: var(--positiveColor); + text-align: center; + padding-bottom: 20px; +} +.message.payment a { + text-decoration: none !important; + opacity: 1 !important; +} +.message.image img { + object-fit: contain; + display: block; + max-width: 100%; + max-height: 300px; +} +.typingCell { + height: 20px; + width: 50px; + display: flex; + justify-content: flex-end; + flex-grow: 0; + flex-shrink: 0; + display: none; +} +.messageFooter { + display: none; + padding: 0px 5px; +} + +#replying { + background-color: var(--tertiaryBackground); +} +#typing { + background-color: var(--secondaryBackground); +} + +#replying, #typing { + border-top: 1px solid var(--primaryBorderColor); + padding: 5px; + display: none; + justify-content: space-between; + align-items: center; +} +#replying .message, #typing .message { + color: var(--secondaryForeground); + font-size: 12px; +} +#replying .message span, #typing .message span { + font-size: inherit; +} +#replying .action.remove { + background-color: var(--secondaryForeground); +} + +#completions .body .list { + background-color: var(--tertiaryBackground); + border-radius: 10px; + padding: 5px; + overflow: hidden; +} + +#completions .body .list .title { + font-weight: initial; + font-size: initial; +} + +.lds-ellipsis { + display: inline-block; + position: relative; + transform: scale(0.3); + display: flex; + align-items: center; + height: 18px; + left: -7px; +} +.lds-ellipsis div { + position: absolute; + width: 13px; + height: 13px; + border-radius: 50%; + background: #fff; + animation-timing-function: cubic-bezier(0, 1, 1, 0); +} +.lds-ellipsis div:nth-child(1) { + left: 8px; + animation: lds-ellipsis1 0.6s infinite; +} +.lds-ellipsis div:nth-child(2) { + left: 8px; + animation: lds-ellipsis2 0.6s infinite; +} +.lds-ellipsis div:nth-child(3) { + left: 32px; + animation: lds-ellipsis2 0.6s infinite; +} +.lds-ellipsis div:nth-child(4) { + left: 56px; + animation: lds-ellipsis3 0.6s infinite; +} +@keyframes lds-ellipsis1 { + 0% { + transform: scale(0); + } + 100% { + transform: scale(1); + } +} +@keyframes lds-ellipsis3 { + 0% { + transform: scale(1); + } + 100% { + transform: scale(0); + } +} +@keyframes lds-ellipsis2 { + 0% { + transform: translate(0, 0); + } + 100% { + transform: translate(24px, 0); + } +} + +.lds-facebook { + display: inline-block; + position: relative; + width: 80px; + height: 80px; +} +.lds-facebook div { + display: inline-block; + position: absolute; + left: 8px; + width: 16px; + background: #fff; + animation: lds-facebook 1.2s cubic-bezier(0, 0.5, 0.5, 1) infinite; +} +.lds-facebook div:nth-child(1) { + left: 8px; + animation-delay: -0.24s; +} +.lds-facebook div:nth-child(2) { + left: 32px; + animation-delay: -0.12s; +} +.lds-facebook div:nth-child(3) { + left: 56px; + animation-delay: 0; +} +@keyframes lds-facebook { + 0% { + top: 8px; + height: 64px; + } + 50%, 100% { + top: 24px; + height: 32px; + } +} + +.lds-spinner { + color: official; + display: inline-block; + position: relative; + width: 80px; + height: 80px; +} +.lds-spinner div { + transform-origin: 40px 40px; + animation: lds-spinner 1.2s linear infinite; +} +.lds-spinner div:after { + content: " "; + display: block; + position: absolute; + top: 3px; + left: 37px; + width: 6px; + height: 18px; + border-radius: 20%; + background: #fff; +} +.lds-spinner div:nth-child(1) { + transform: rotate(0deg); + animation-delay: -1.1s; +} +.lds-spinner div:nth-child(2) { + transform: rotate(30deg); + animation-delay: -1s; +} +.lds-spinner div:nth-child(3) { + transform: rotate(60deg); + animation-delay: -0.9s; +} +.lds-spinner div:nth-child(4) { + transform: rotate(90deg); + animation-delay: -0.8s; +} +.lds-spinner div:nth-child(5) { + transform: rotate(120deg); + animation-delay: -0.7s; +} +.lds-spinner div:nth-child(6) { + transform: rotate(150deg); + animation-delay: -0.6s; +} +.lds-spinner div:nth-child(7) { + transform: rotate(180deg); + animation-delay: -0.5s; +} +.lds-spinner div:nth-child(8) { + transform: rotate(210deg); + animation-delay: -0.4s; +} +.lds-spinner div:nth-child(9) { + transform: rotate(240deg); + animation-delay: -0.3s; +} +.lds-spinner div:nth-child(10) { + transform: rotate(270deg); + animation-delay: -0.2s; +} +.lds-spinner div:nth-child(11) { + transform: rotate(300deg); + animation-delay: -0.1s; +} +.lds-spinner div:nth-child(12) { + transform: rotate(330deg); + animation-delay: 0s; +} +@keyframes lds-spinner { + 0% { + opacity: 1; + } + 100% { + opacity: 0; + } +} + +#avatars { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + z-index: -1; + opacity: 0; +} + +body.compact .messageRow { + margin: 0 0 5px 0 !important; + margin-bottom: 5px !important; + padding: 2px !important; + display: inline-grid; +} +body.compact .messageRow .holder { + margin: 0 !important; +} +body.compact .messageRow .holder { + justify-content: flex-start !important; +} +body.compact .messageRow > .contents .user { + margin: 0 !important; + right: unset !important; + height: fit-content !important; +} +body.compact .messageRow.first .contents { + padding: 0 !important; +} +body.compact .messageRow .main { + line-height: 15px; + padding: 2px; +} +body.compact .messageRow > .contents { + display: flex !important; + flex-direction: column; +} +body.compact .messageRow .message { + max-width: unset !important; + padding: 0 !important; + background-color: transparent !important; + height: 100%; +} +body.compact .messageRow .hover { + width: auto; +} +body.compact .messageRow .hover > .time { + display: block !important; + position: absolute; + left: 0; + width: 55px; + margin: 0; + top: 4px; + line-height: unset; + text-align: right; +} +body.compact .messageRow .hover > .actions { + display: none !important; +} +body.compact .messageRow .message { + border-radius: unset !important; +} +body.compact .messageRow .user { + display: block !important; +} +body.compact .messageRow > .contents .user { + position: relative; + font-size: inherit; + line-height: unset; + margin: 0 5px !important; + font-weight: bold; +} +body.compact .messageRow .avatar { + height: 17px; + width: 17px; + display: block !important; + right: unset; + margin: 0 0 0 65px; + position: relative; +} +body.compact .messageRow .avatar .fallback { + font-size: 10px; + line-height: 20px; +} +body.compact .messageRow .linkHolder { + padding: 0; +} +body.compact .messageRow .linkHolder:not(:empty) { + align-self: flex-start; + margin: 2px 0 0 75px; +} +body.compact .messageRow .preview { + margin: 0 !important; + width: 100% !important; +} +body.compact .messageRow .preview .media { + overflow: hidden; +} +body.compact .messageRow .message.image img { + border-radius: 10px; +} +body.compact .messageRow > .contents .user { + color: var(--primaryForeground); +} +body.compact .messageRow .message .body { + color: var(--tertiaryForeground); + height: 100%; +} +body.compact .messageRow.emojis .body, body.compact .messageRow[data-style=fancy] .body { + font-size: inherit; + line-height: inherit; +} +body.compact .messageRow.replying { + align-items: flex-start; +} +body.compact .messageRow > .reply { + top: 0; + left: 0; + padding: 0; + justify-content: flex-start !important; + position: relative; + width: 100%; + max-width: unset; + overflow: hidden; +} +body.compact .messageRow > .reply .line { + height: 12px; + width: 40px; + margin: 5px 0 -3px 30px; + border-left-style: solid; + border-right-style: none; + border-top-left-radius: 5px; + border-top-right-radius: 0; + position: unset; + flex-shrink: 0; +} +body.compact .messageRow > .reply .contents { + justify-content: flex-start; + margin-left: 5px; + overflow: hidden; + display: grid; + grid-auto-flow: column; + line-height: 1.2em; + margin-top: -2px; +} +body.compact .messageRow.mention { + background-color: var(--quaternaryBackground); +} +body.compact .messageRow .main { + display: flex; +} +body.compact .messageRow .react { + margin-left: 75px !important; + align-self: flex-start; +} +body.compact .messageRow .reactions .reaction { + margin-left: 0 !important; + margin-right: 5px; +} + +body.compact .messageRow .messageEffect { + margin-left: 75px !important; + align-self: flex-start; +} + + +#react .tabs { + display: flex; + font-size: inherit; +} +#react .tabs .tab { + margin: 0 10px 0 0; + color: var(--secondaryForeground); + font-size: inherit; +} +#react .tabs .tab:not(.active):hover { + opacity: 0.5; + cursor: pointer; +} +#react .tabs .tab.active { + color: var(--primaryForeground); +} +#react .search input { + display: none; +} + +.messageRow .message.payment .txMessage:after { + content: "You received a payment. Click for transaction details."; +} +.messageRow.self .message.payment .txMessage:after { + content: "You sent a payment. Click for transaction details."; +} + +#users .users .user .title:after, +#conversations .section.pms tr .title:after, +.messageRow .user:after, +#replying .name:after, +#chats .messageHeader tr[data-type=pms] .title:after, +#completions .list tr.user .title:after, +#typing .message span:after, +.popover[data-name=userContext] .user:after, +.cam .user .title:after { + content: "/"; + font-size: inherit; +} + +.popover[data-name=userContext] .user { + word-break: break-all; +} + +#messageContainer { + height: 100%; + width: 100%; + position: relative; +} + +#jumpToPresent { + position: absolute; + width: 100%; + height: 100%; + display: flex; + align-items: flex-end; + justify-content: flex-end; + z-index: 9999999; +} +#jumpToPresent > div { + padding: 5px; + background-color: var(--septenaryBackground); + opacity: 0.9; + position: fixed; + border-radius: 5px 5px 0 0; + z-index: 3; + float: right; +} +#jumpToPresent > div:hover { + cursor: pointer; + opacity: 1; +} + +#confetti-canvas { + position: absolute; + height: 100%; + top: 0; + left: 0; +} + +.popover .body { + position: relative; +} + +.popover[data-name=qr] .body { + min-height: 60px; + position: relative; +} + +#camera { + height: 350px; + width: 100%; + object-fit: cover; + pointer-events: none; +} +#frame { + display: none; +} + +@media all and (max-width: 1000px) { + html,body { + min-width: 320px; + } + #blackout { + z-index: 9999999999; + } + .popover { + min-width: 300px; + z-index: 99999999999; + } + .header { + padding: 10px; + } + .header .logo { + display: none; + } + .header .center { + padding: 0 10px; + } + .header .center .domains { + width: 17px; + } + .header .end { + padding: 0 2px; + } + .header .domains select { + background-color: var(--quaternaryBackground); + background-position: calc(100% - 10px) calc(1em + 2px), calc(100% - 5px) calc(1em + 2px), calc(100% - 2.5em) 0.5em; + width: 0px !important; + padding: 0px 7px 0 10px; + } + .header .left,.header .right { + display: flex; + justify-content: center; + align-items: center; + } + .header .pinnedMessage { + display: none !important; + } + .pinnedMessage { + height: 40px; + flex: unset; + flex-shrink: 0; + padding: 0 10px; + border-left: none; + border-bottom: 1px solid var(--primaryBorderColor); + } + .content .pinnedMessage.shown { + display: flex !important; + } + .messageHeader { + flex: unset; + flex-shrink: 0; + } + #conversations { + position: absolute; + width: 200px; + height: calc(100% - 60px); + left: -200px; + transition: left .25s; + z-index: 999999999; + } + #conversations.showing { + left: 0; + } + #users { + position: absolute; + width: 200px; + height: calc(100% - 60px); + right: -200px; + transition: right .25s; + z-index: 999999999; + } + #users.showing { + right: 0; + } + .message.payment .amount { + font-size: 30px; + } + #messages .messageRow .preview .media iframe { + height: auto; + } + + .messageRow .hover { + display: none; + } + + .contextMenu[data-name=userContext], .contextMenu[data-name=messageContext] { + top: auto !important; + bottom: 50px; + left: auto !important; + } + + body.menu .contextMenu[data-name=userContext], body.menu .contextMenu[data-name=messageContext] { + bottom: 10px; + } + + body #closeMenu { + position: absolute; + height: 100%; + width: 100%; + background-color: rgba(0,0,0,0.3); + z-index: 99999999; + display: none; + } + body.menu #closeMenu { + display: block; + } + + /* + .cam .info { + flex-direction: column; + height: 100%; + } + */ + + .cam .info table { + transform: scale(0.75); + transform-origin: 0 0; + } +} \ No newline at end of file diff --git a/assets/img/cover.png b/assets/img/cover.png new file mode 100755 index 0000000..3bd6022 Binary files /dev/null and b/assets/img/cover.png differ diff --git a/assets/img/handshake.svg b/assets/img/handshake.svg new file mode 100755 index 0000000..e6ac907 --- /dev/null +++ b/assets/img/handshake.svg @@ -0,0 +1,25 @@ + + + + + + diff --git a/assets/img/icann.png b/assets/img/icann.png new file mode 100644 index 0000000..a609e02 Binary files /dev/null and b/assets/img/icann.png differ diff --git a/assets/img/icon-128x128.png b/assets/img/icon-128x128.png new file mode 100755 index 0000000..16f0f29 Binary files /dev/null and b/assets/img/icon-128x128.png differ diff --git a/assets/img/icon-144x144.png b/assets/img/icon-144x144.png new file mode 100755 index 0000000..b36ab7b Binary files /dev/null and b/assets/img/icon-144x144.png differ diff --git a/assets/img/icon-152x152.png b/assets/img/icon-152x152.png new file mode 100755 index 0000000..ab4d8df Binary files /dev/null and b/assets/img/icon-152x152.png differ diff --git a/assets/img/icon-192x192.png b/assets/img/icon-192x192.png new file mode 100755 index 0000000..0199914 Binary files /dev/null and b/assets/img/icon-192x192.png differ diff --git a/assets/img/icon-384x384.png b/assets/img/icon-384x384.png new file mode 100755 index 0000000..50f1cb8 Binary files /dev/null and b/assets/img/icon-384x384.png differ diff --git a/assets/img/icon-48x48.png b/assets/img/icon-48x48.png new file mode 100755 index 0000000..681dd0a Binary files /dev/null and b/assets/img/icon-48x48.png differ diff --git a/assets/img/icon-512x512.png b/assets/img/icon-512x512.png new file mode 100755 index 0000000..c640ef0 Binary files /dev/null and b/assets/img/icon-512x512.png differ diff --git a/assets/img/icon-72x72.png b/assets/img/icon-72x72.png new file mode 100755 index 0000000..00a396e Binary files /dev/null and b/assets/img/icon-72x72.png differ diff --git a/assets/img/icon-96x96.png b/assets/img/icon-96x96.png new file mode 100755 index 0000000..d6fbf42 Binary files /dev/null and b/assets/img/icon-96x96.png differ diff --git a/assets/img/icons/arrow.png b/assets/img/icons/arrow.png new file mode 100755 index 0000000..ffedb67 Binary files /dev/null and b/assets/img/icons/arrow.png differ diff --git a/assets/img/icons/audio.gif b/assets/img/icons/audio.gif new file mode 100755 index 0000000..c5ab9fe Binary files /dev/null and b/assets/img/icons/audio.gif differ diff --git a/assets/img/icons/check.png b/assets/img/icons/check.png new file mode 100755 index 0000000..d4b1b6c Binary files /dev/null and b/assets/img/icons/check.png differ diff --git a/assets/img/icons/clipboard.png b/assets/img/icons/clipboard.png new file mode 100755 index 0000000..0afd425 Binary files /dev/null and b/assets/img/icons/clipboard.png differ diff --git a/assets/img/icons/close.png b/assets/img/icons/close.png new file mode 100755 index 0000000..55ba952 Binary files /dev/null and b/assets/img/icons/close.png differ diff --git a/assets/img/icons/compose.png b/assets/img/icons/compose.png new file mode 100755 index 0000000..8f42618 Binary files /dev/null and b/assets/img/icons/compose.png differ diff --git a/assets/img/icons/edit.png b/assets/img/icons/edit.png new file mode 100755 index 0000000..b52c907 Binary files /dev/null and b/assets/img/icons/edit.png differ diff --git a/assets/img/icons/emoji.png b/assets/img/icons/emoji.png new file mode 100755 index 0000000..d29f924 Binary files /dev/null and b/assets/img/icons/emoji.png differ diff --git a/assets/img/icons/fail.png b/assets/img/icons/fail.png new file mode 100755 index 0000000..93d4120 Binary files /dev/null and b/assets/img/icons/fail.png differ diff --git a/assets/img/icons/fish.png b/assets/img/icons/fish.png new file mode 100755 index 0000000..f64356d Binary files /dev/null and b/assets/img/icons/fish.png differ diff --git a/assets/img/icons/gif.png b/assets/img/icons/gif.png new file mode 100755 index 0000000..21a5a24 Binary files /dev/null and b/assets/img/icons/gif.png differ diff --git a/assets/img/icons/leave.png b/assets/img/icons/leave.png new file mode 100755 index 0000000..dbb2f2d Binary files /dev/null and b/assets/img/icons/leave.png differ diff --git a/assets/img/icons/lock.png b/assets/img/icons/lock.png new file mode 100755 index 0000000..d49c168 Binary files /dev/null and b/assets/img/icons/lock.png differ diff --git a/assets/img/icons/mention.png b/assets/img/icons/mention.png new file mode 100755 index 0000000..5b1d759 Binary files /dev/null and b/assets/img/icons/mention.png differ diff --git a/assets/img/icons/menu.png b/assets/img/icons/menu.png new file mode 100755 index 0000000..dbe6035 Binary files /dev/null and b/assets/img/icons/menu.png differ diff --git a/assets/img/icons/message.png b/assets/img/icons/message.png new file mode 100755 index 0000000..477bac8 Binary files /dev/null and b/assets/img/icons/message.png differ diff --git a/assets/img/icons/pay.png b/assets/img/icons/pay.png new file mode 100755 index 0000000..78b86ab Binary files /dev/null and b/assets/img/icons/pay.png differ diff --git a/assets/img/icons/pin.png b/assets/img/icons/pin.png new file mode 100755 index 0000000..5e03c88 Binary files /dev/null and b/assets/img/icons/pin.png differ diff --git a/assets/img/icons/plus.png b/assets/img/icons/plus.png new file mode 100755 index 0000000..b5960f3 Binary files /dev/null and b/assets/img/icons/plus.png differ diff --git a/assets/img/icons/replay.png b/assets/img/icons/replay.png new file mode 100755 index 0000000..c33182a Binary files /dev/null and b/assets/img/icons/replay.png differ diff --git a/assets/img/icons/save.png b/assets/img/icons/save.png new file mode 100755 index 0000000..6f7d010 Binary files /dev/null and b/assets/img/icons/save.png differ diff --git a/assets/img/icons/screen.png b/assets/img/icons/screen.png new file mode 100755 index 0000000..344da31 Binary files /dev/null and b/assets/img/icons/screen.png differ diff --git a/assets/img/icons/search.png b/assets/img/icons/search.png new file mode 100755 index 0000000..d9eebe3 Binary files /dev/null and b/assets/img/icons/search.png differ diff --git a/assets/img/icons/signature.png b/assets/img/icons/signature.png new file mode 100755 index 0000000..97282f2 Binary files /dev/null and b/assets/img/icons/signature.png differ diff --git a/assets/img/icons/trash.png b/assets/img/icons/trash.png new file mode 100755 index 0000000..936893a Binary files /dev/null and b/assets/img/icons/trash.png differ diff --git a/assets/img/icons/update.png b/assets/img/icons/update.png new file mode 100755 index 0000000..1004dfd Binary files /dev/null and b/assets/img/icons/update.png differ diff --git a/assets/img/icons/users.png b/assets/img/icons/users.png new file mode 100755 index 0000000..dcb5f52 Binary files /dev/null and b/assets/img/icons/users.png differ diff --git a/assets/img/icons/video.png b/assets/img/icons/video.png new file mode 100755 index 0000000..158a21f Binary files /dev/null and b/assets/img/icons/video.png differ diff --git a/assets/img/icons/view.png b/assets/img/icons/view.png new file mode 100755 index 0000000..6f62a34 Binary files /dev/null and b/assets/img/icons/view.png differ diff --git a/assets/img/icons/voice.png b/assets/img/icons/voice.png new file mode 100755 index 0000000..7e935a2 Binary files /dev/null and b/assets/img/icons/voice.png differ diff --git a/assets/img/icons/warning.png b/assets/img/icons/warning.png new file mode 100755 index 0000000..ca658cf Binary files /dev/null and b/assets/img/icons/warning.png differ diff --git a/assets/img/logo.png b/assets/img/logo.png new file mode 100755 index 0000000..c640ef0 Binary files /dev/null and b/assets/img/logo.png differ diff --git a/assets/img/unstoppable.svg b/assets/img/unstoppable.svg new file mode 100755 index 0000000..79ad7bc --- /dev/null +++ b/assets/img/unstoppable.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/assets/js/adapter.js b/assets/js/adapter.js new file mode 100755 index 0000000..3e4ab0b --- /dev/null +++ b/assets/js/adapter.js @@ -0,0 +1 @@ +!function(e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).adapter=e()}(function(){return function a(o,s,c){function d(t,e){if(!s[t]){if(!o[t]){var r="function"==typeof require&&require;if(!e&&r)return r(t,!0);if(p)return p(t,!0);var n=new Error("Cannot find module '"+t+"'");throw n.code="MODULE_NOT_FOUND",n}var i=s[t]={exports:{}};o[t][0].call(i.exports,function(e){return d(o[t][1][e]||e)},i,i.exports,a,o,s,c)}return s[t].exports}for(var p="function"==typeof require&&require,e=0;en.sctp.maxMessageSize)throw new TypeError("Message too large (can send a maximum of "+n.sctp.maxMessageSize+" bytes)");return i.apply(r,arguments)}}var r=e.RTCPeerConnection.prototype.createDataChannel;e.RTCPeerConnection.prototype.createDataChannel=function(){var e=r.apply(this,arguments);return t(e,this),e},o.wrapPeerConnectionEvent(e,"datachannel",function(e){return t(e.channel,e.target),e})},r.shimConnectionState=function(e){if(!e.RTCPeerConnection||"connectionState"in e.RTCPeerConnection.prototype)return;var r=e.RTCPeerConnection.prototype;Object.defineProperty(r,"connectionState",{get:function(){return{completed:"connected",checking:"connecting"}[this.iceConnectionState]||this.iceConnectionState},enumerable:!0,configurable:!0}),Object.defineProperty(r,"onconnectionstatechange",{get:function(){return this._onconnectionstatechange||null},set:function(e){this._onconnectionstatechange&&(this.removeEventListener("connectionstatechange",this._onconnectionstatechange),delete this._onconnectionstatechange),e&&this.addEventListener("connectionstatechange",this._onconnectionstatechange=e)},enumerable:!0,configurable:!0}),["setLocalDescription","setRemoteDescription"].forEach(function(e){var t=r[e];r[e]=function(){return this._connectionstatechangepoly||(this._connectionstatechangepoly=function(e){var t,r=e.target;return r._lastConnectionState!==r.connectionState&&(r._lastConnectionState=r.connectionState,t=new Event("connectionstatechange",e),r.dispatchEvent(t)),e},this.addEventListener("iceconnectionstatechange",this._connectionstatechangepoly)),t.apply(this,arguments)}})},r.removeAllowExtmapMixed=function(e){if(!e.RTCPeerConnection)return;var t=o.detectBrowser(e);if("chrome"===t.browser&&71<=t.version)return;var r=e.RTCPeerConnection.prototype.setRemoteDescription;e.RTCPeerConnection.prototype.setRemoteDescription=function(e){return e&&e.sdp&&-1!==e.sdp.indexOf("\na=extmap-allow-mixed")&&(e.sdp=e.sdp.split("\n").filter(function(e){return"a=extmap-allow-mixed"!==e.trim()}).join("\n")),r.apply(this,arguments)}};var n,i=e("sdp"),p=(n=i)&&n.__esModule?n:{default:n},o=function(e){{if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}}(e("./utils"))},{"./utils":15,sdp:17}],7:[function(e,t,r){"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.shimGetDisplayMedia=r.shimGetUserMedia=void 0;var n=e("./getusermedia");Object.defineProperty(r,"shimGetUserMedia",{enumerable:!0,get:function(){return n.shimGetUserMedia}});var i=e("./getdisplaymedia");Object.defineProperty(r,"shimGetDisplayMedia",{enumerable:!0,get:function(){return i.shimGetDisplayMedia}}),r.shimPeerConnection=function(e){var t=o.detectBrowser(e);{var r;e.RTCIceGatherer&&(e.RTCIceCandidate||(e.RTCIceCandidate=function(e){return e}),e.RTCSessionDescription||(e.RTCSessionDescription=function(e){return e}),t.version<15025&&(r=Object.getOwnPropertyDescriptor(e.MediaStreamTrack.prototype,"enabled"),Object.defineProperty(e.MediaStreamTrack.prototype,"enabled",{set:function(e){r.set.call(this,e);var t=new Event("enabled");t.enabled=e,this.dispatchEvent(t)}})))}!e.RTCRtpSender||"dtmf"in e.RTCRtpSender.prototype||Object.defineProperty(e.RTCRtpSender.prototype,"dtmf",{get:function(){return void 0===this._dtmf&&("audio"===this.track.kind?this._dtmf=new e.RTCDtmfSender(this):"video"===this.track.kind&&(this._dtmf=null)),this._dtmf}});e.RTCDtmfSender&&!e.RTCDTMFSender&&(e.RTCDTMFSender=e.RTCDtmfSender);var n=(0,d.default)(e,t.version);e.RTCPeerConnection=function(e){return e&&e.iceServers&&(e.iceServers=(0,s.filterIceServers)(e.iceServers,t.version),o.log("ICE servers after filtering:",e.iceServers)),new n(e)},e.RTCPeerConnection.prototype=n.prototype},r.shimReplaceTrack=function(e){!e.RTCRtpSender||"replaceTrack"in e.RTCRtpSender.prototype||(e.RTCRtpSender.prototype.replaceTrack=e.RTCRtpSender.prototype.setTrack)};var a,o=function(e){{if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}}(e("../utils")),s=e("./filtericeservers"),c=e("rtcpeerconnection-shim"),d=(a=c)&&a.__esModule?a:{default:a}},{"../utils":15,"./filtericeservers":8,"./getdisplaymedia":9,"./getusermedia":10,"rtcpeerconnection-shim":16}],8:[function(e,t,r){"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.filterIceServers=function(e,t){var n=!1;return(e=JSON.parse(JSON.stringify(e))).filter(function(e){if(e&&(e.urls||e.url)){var t=e.urls||e.url;e.url&&!e.urls&&i.deprecated("RTCIceServer.url","RTCIceServer.urls");var r="string"==typeof t;return r&&(t=[t]),t=t.filter(function(e){if(0===e.indexOf("stun:"))return!1;var t=e.startsWith("turn")&&!e.startsWith("turn:[")&&e.includes("transport=udp");return t&&!n?n=!0:t&&!n}),delete e.url,e.urls=r?t[0]:t,!!t.length}})};var i=function(e){{if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}}(e("../utils"))},{"../utils":15}],9:[function(e,t,r){"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.shimGetDisplayMedia=function(e){if(!("getDisplayMedia"in e.navigator))return;if(!e.navigator.mediaDevices)return;if(e.navigator.mediaDevices&&"getDisplayMedia"in e.navigator.mediaDevices)return;e.navigator.mediaDevices.getDisplayMedia=e.navigator.getDisplayMedia.bind(e.navigator)}},{}],10:[function(e,t,r){"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.shimGetUserMedia=function(e){var t=e&&e.navigator,r=t.mediaDevices.getUserMedia.bind(t.mediaDevices);t.mediaDevices.getUserMedia=function(e){return r(e).catch(function(e){return Promise.reject({name:{PermissionDeniedError:"NotAllowedError"}[(t=e).name]||t.name,message:t.message,constraint:t.constraint,toString:function(){return this.name}});var t})}}},{}],11:[function(e,t,r){"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.shimGetDisplayMedia=r.shimGetUserMedia=void 0;var c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n=e("./getusermedia");Object.defineProperty(r,"shimGetUserMedia",{enumerable:!0,get:function(){return n.shimGetUserMedia}});var i=e("./getdisplaymedia");Object.defineProperty(r,"shimGetDisplayMedia",{enumerable:!0,get:function(){return i.shimGetDisplayMedia}}),r.shimOnTrack=function(e){"object"===(void 0===e?"undefined":c(e))&&e.RTCTrackEvent&&"receiver"in e.RTCTrackEvent.prototype&&!("transceiver"in e.RTCTrackEvent.prototype)&&Object.defineProperty(e.RTCTrackEvent.prototype,"transceiver",{get:function(){return{receiver:this.receiver}}})},r.shimPeerConnection=function(n){var i=s.detectBrowser(n);if("object"!==(void 0===n?"undefined":c(n))||!n.RTCPeerConnection&&!n.mozRTCPeerConnection)return;!n.RTCPeerConnection&&n.mozRTCPeerConnection&&(n.RTCPeerConnection=n.mozRTCPeerConnection);i.version<53&&["setLocalDescription","setRemoteDescription","addIceCandidate"].forEach(function(e){var t=n.RTCPeerConnection.prototype[e],r=function(e,t,r){t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r;return e}({},e,function(){return arguments[0]=new("addIceCandidate"===e?n.RTCIceCandidate:n.RTCSessionDescription)(arguments[0]),t.apply(this,arguments)});n.RTCPeerConnection.prototype[e]=r[e]});{var r;i.version<68&&(r=n.RTCPeerConnection.prototype.addIceCandidate,n.RTCPeerConnection.prototype.addIceCandidate=function(e,t){return e?e&&""===e.candidate?Promise.resolve():r.apply(this,arguments):(t&&t.apply(null),Promise.resolve())})}var a={inboundrtp:"inbound-rtp",outboundrtp:"outbound-rtp",candidatepair:"candidate-pair",localcandidate:"local-candidate",remotecandidate:"remote-candidate"},o=n.RTCPeerConnection.prototype.getStats;n.RTCPeerConnection.prototype.getStats=function(){var e=Array.prototype.slice.call(arguments),t=e[0],n=e[1],r=e[2];return o.apply(this,[t||null]).then(function(r){if(i.version<53&&!n)try{r.forEach(function(e){e.type=a[e.type]||e.type})}catch(e){if("TypeError"!==e.name)throw e;r.forEach(function(e,t){r.set(t,Object.assign({},e,{type:a[e.type]||e.type}))})}return r}).then(n,r)}},r.shimSenderGetStats=function(e){if("object"!==(void 0===e?"undefined":c(e))||!e.RTCPeerConnection||!e.RTCRtpSender)return;if(e.RTCRtpSender&&"getStats"in e.RTCRtpSender.prototype)return;var r=e.RTCPeerConnection.prototype.getSenders;r&&(e.RTCPeerConnection.prototype.getSenders=function(){var t=this,e=r.apply(this,[]);return e.forEach(function(e){return e._pc=t}),e});var t=e.RTCPeerConnection.prototype.addTrack;t&&(e.RTCPeerConnection.prototype.addTrack=function(){var e=t.apply(this,arguments);return e._pc=this,e});e.RTCRtpSender.prototype.getStats=function(){return this.track?this._pc.getStats(this.track):Promise.resolve(new Map)}},r.shimReceiverGetStats=function(e){if("object"!==(void 0===e?"undefined":c(e))||!e.RTCPeerConnection||!e.RTCRtpSender)return;if(e.RTCRtpSender&&"getStats"in e.RTCRtpReceiver.prototype)return;var r=e.RTCPeerConnection.prototype.getReceivers;r&&(e.RTCPeerConnection.prototype.getReceivers=function(){var t=this,e=r.apply(this,[]);return e.forEach(function(e){return e._pc=t}),e});s.wrapPeerConnectionEvent(e,"track",function(e){return e.receiver._pc=e.srcElement,e}),e.RTCRtpReceiver.prototype.getStats=function(){return this._pc.getStats(this.track)}},r.shimRemoveStream=function(e){if(!e.RTCPeerConnection||"removeStream"in e.RTCPeerConnection.prototype)return;e.RTCPeerConnection.prototype.removeStream=function(t){var r=this;s.deprecated("removeStream","removeTrack"),this.getSenders().forEach(function(e){e.track&&t.getTracks().includes(e.track)&&r.removeTrack(e)})}},r.shimRTCDataChannel=function(e){e.DataChannel&&!e.RTCDataChannel&&(e.RTCDataChannel=e.DataChannel)},r.shimAddTransceiver=function(e){if("object"!==(void 0===e?"undefined":c(e))||!e.RTCPeerConnection)return;var s=e.RTCPeerConnection.prototype.addTransceiver;s&&(e.RTCPeerConnection.prototype.addTransceiver=function(e,t){this.setParametersPromises=[];var r=t,n=r&&"sendEncodings"in r;n&&r.sendEncodings.forEach(function(e){if("rid"in e){if(!/^[a-z0-9]{0,16}$/i.test(e.rid))throw new TypeError("Invalid RID value provided.")}if("scaleResolutionDownBy"in e&&!(1<=parseFloat(e.scaleResolutionDownBy)))throw new RangeError("scale_resolution_down_by must be >= 1.0");if("maxFramerate"in e&&!(0<=parseFloat(e.maxFramerate)))throw new RangeError("max_framerate must be >= 0.0")});var i,a,o=s.apply(this,arguments);return n&&("encodings"in(a=(i=o.sender).getParameters())||(a.encodings=r.sendEncodings,this.setParametersPromises.push(i.setParameters(a).catch(function(){})))),o})},r.shimCreateOffer=function(e){if("object"!==(void 0===e?"undefined":c(e))||!e.RTCPeerConnection)return;var r=e.RTCPeerConnection.prototype.createOffer;e.RTCPeerConnection.prototype.createOffer=function(){var e=this,t=arguments;return this.setParametersPromises&&this.setParametersPromises.length?Promise.all(this.setParametersPromises).then(function(){return r.apply(e,t)}).finally(function(){e.setParametersPromises=[]}):r.apply(this,arguments)}},r.shimCreateAnswer=function(e){if("object"!==(void 0===e?"undefined":c(e))||!e.RTCPeerConnection)return;var r=e.RTCPeerConnection.prototype.createAnswer;e.RTCPeerConnection.prototype.createAnswer=function(){var e=this,t=arguments;return this.setParametersPromises&&this.setParametersPromises.length?Promise.all(this.setParametersPromises).then(function(){return r.apply(e,t)}).finally(function(){e.setParametersPromises=[]}):r.apply(this,arguments)}};var s=function(e){{if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}}(e("../utils"))},{"../utils":15,"./getdisplaymedia":12,"./getusermedia":13}],12:[function(e,t,r){"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.shimGetDisplayMedia=function(r,n){if(r.navigator.mediaDevices&&"getDisplayMedia"in r.navigator.mediaDevices)return;if(!r.navigator.mediaDevices)return;r.navigator.mediaDevices.getDisplayMedia=function(e){if(e&&e.video)return!0===e.video?e.video={mediaSource:n}:e.video.mediaSource=n,r.navigator.mediaDevices.getUserMedia(e);var t=new DOMException("getDisplayMedia without video constraints is undefined");return t.name="NotFoundError",t.code=8,Promise.reject(t)}}},{}],13:[function(e,t,r){"use strict";Object.defineProperty(r,"__esModule",{value:!0});var c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};r.shimGetUserMedia=function(e){var t=d.detectBrowser(e),n=e&&e.navigator,r=e&&e.MediaStreamTrack;{var i,a,o,s;n.getUserMedia=function(e,t,r){d.deprecated("navigator.getUserMedia","navigator.mediaDevices.getUserMedia"),n.mediaDevices.getUserMedia(e).then(t,r)},55=r&&parseInt(n[r],10)}function c(e){return"[object Object]"===Object.prototype.toString.call(e)}function d(t,r,n){r&&!n.has(r.id)&&(n.set(r.id,r),Object.keys(r).forEach(function(e){e.endsWith("Id")?d(t,t.get(r[e]),n):e.endsWith("Ids")&&r[e].forEach(function(e){d(t,t.get(e),n)})}))}},{}],16:[function(e,t,r){"use strict";var G=e("sdp");function c(e,t,r,n,i){var a,o,s=G.writeRtpDescription(e.kind,t);return s+=G.writeIceParameters(e.iceGatherer.getLocalParameters()),s+=G.writeDtlsParameters(e.dtlsTransport.getLocalParameters(),"offer"===r?"actpass":i||"active"),s+="a=mid:"+e.mid+"\r\n",e.rtpSender&&e.rtpReceiver?s+="a=sendrecv\r\n":e.rtpSender?s+="a=sendonly\r\n":e.rtpReceiver?s+="a=recvonly\r\n":s+="a=inactive\r\n",e.rtpSender&&(a=e.rtpSender._initialTrackId||e.rtpSender.track.id,e.rtpSender._initialTrackId=a,s+="a="+(o="msid:"+(n?n.id:"-")+" "+a+"\r\n"),s+="a=ssrc:"+e.sendEncodingParameters[0].ssrc+" "+o,e.sendEncodingParameters[0].rtx&&(s+="a=ssrc:"+e.sendEncodingParameters[0].rtx.ssrc+" "+o,s+="a=ssrc-group:FID "+e.sendEncodingParameters[0].ssrc+" "+e.sendEncodingParameters[0].rtx.ssrc+"\r\n")),s+="a=ssrc:"+e.sendEncodingParameters[0].ssrc+" cname:"+G.localCName+"\r\n",e.rtpSender&&e.sendEncodingParameters[0].rtx&&(s+="a=ssrc:"+e.sendEncodingParameters[0].rtx.ssrc+" cname:"+G.localCName+"\r\n"),s}function A(d,p){function u(e,t){e=parseInt(e,10);for(var r=0;rn&&(n=e.maxptime)}),0'+(A.string.length>N?O?A.string.substring(0,Math.floor(N/2))+"โ€ฆ"+A.string.substring(A.string.length-Math.ceil(N/2),A.string.length):A.string.substring(0,N)+"โ€ฆ":A.string)+"")}});A(B);B.transform;var e=u(function(A,u){Object.defineProperty(u,"__esModule",{value:!0});var E="([a-z0-9]+(-+[a-z0-9]+)*\\.)+("+L.TLDs+")",N="a-zA-Z\\d\\-._~\\!$&*+,;=:@%'\"\\[\\]()",C="((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)",O="\\[(([a-f0-9:]+:+)+[a-f0-9]+)\\]",I="(https?:|ftps?:)\\/\\/",R="((("+I+")?("+E+"|"+C+"|("+I+")("+O+"|"+("([a-z0-9]+(-+[a-z0-9]+)*\\.)+([a-z0-9][a-z0-9-]{0,"+(Math.max.apply(t,L.TLDs.split("|").map(function(A){return A.length}))-2)+"}[a-z0-9])")+"))(?!@\\w)(:(\\d{1,5}))?)|(((https?:|ftps?:)\\/\\/)\\S+))",S=R+"((((\\/((["+N+"]+(\\/["+N+L.nonLatinAlphabetRanges+"]*)*))?)?)((\\?(["+N+"\\/?]*))?)((\\#(["+N+"\\/?]*))?))?\\b(((["+N+"\\/"+L.nonLatinAlphabetRanges+"][a-zA-Z\\d\\-_~+=\\/"+L.nonLatinAlphabetRanges+"]+)?))+)";u.email="\\b(mailto:)?([a-z0-9!#$%&'*+=?^_`{|}~-]+(\\.[a-z0-9!#$%&'*+=?^_`{|}~-]+)*)@("+E+"|"+C+")\\b",u.url="("+S+")|(\\b"+R+"(((\\/(([a-zA-Z\\d\\-._~\\!$&*+,;=:@%'\"\\[\\]()]+(\\/[a-zA-Z\\d\\-._~\\!$&*+,;=:@%'\"\\[\\]()]*)*))?)?)((\\?([a-zA-Z\\d\\-._~\\!$&*+,;=:@%'\"\\[\\]()\\/?]*))?)((\\#([a-zA-Z\\d\\-._~\\!$&*+,;=:@%'\"\\[\\]()\\/?]*))?))?\\b(([\\/]?))+)",u.file="(file:\\/\\/\\/)([a-z]+:(\\/|\\\\)+)?([\\w.]+([\\/\\\\]?)+)+",u.final="("+u.url+")|("+u.email+")|("+u.file+")",u.finalRegex=new RegExp(u.final,"gi"),u.ipRegex=new RegExp("^("+C+"|"+O+")$","i"),u.emailRegex=new RegExp("^("+u.email+")$","i"),u.fileRegex=new RegExp("^("+u.file+")$","i"),u.urlRegex=new RegExp("^("+u.url+")$","i");var T={isURL:0,isEmail:0,isFile:0,file:{fileName:0,protocol:0},email:{protocol:0,local:0,host:0},url:{ipv4:0,ipv6:0,ipv4Confirmation:0,byProtocol:0,port:0,protocol1:0,protocol2:0,protocol3:0,protocolWithDomain:0,path:0,secondPartOfPath:0,query:0,fragment:0}};u.iidxes=T;for(var B=["file:///some/file/path/filename.pdf","mailto:e+_mail.me@sub.domain.com","http://sub.domain.co.uk:3000/p/a/t/h_(asd)/h?q=abc123#dfdf","http://www.ุนุฑุจูŠ.com","http://127.0.0.1:3000/p/a/t_(asd)/h?q=abc123#dfdf","http://[2a00:1450:4025:401::67]/k/something","a.org/abc/แƒ˜_แƒ’แƒ’"].join(" "),e=null,D=0;null!==(e=u.finalRegex.exec(B));)0===D&&(T.isFile=e.lastIndexOf(e[0]),T.file.fileName=e.indexOf("filename.pdf"),T.file.protocol=e.indexOf("file:///")),1===D&&(T.isEmail=e.lastIndexOf(e[0]),T.email.protocol=e.indexOf("mailto:"),T.email.local=e.indexOf("e+_mail.me"),T.email.host=e.indexOf("sub.domain.com")),2===D&&(T.isURL=e.lastIndexOf(e[0]),T.url.protocol1=e.indexOf("http://"),T.url.protocolWithDomain=e.indexOf("http://sub.domain.co.uk:3000"),T.url.port=e.indexOf("3000"),T.url.path=e.indexOf("/p/a/t/h_(asd)/h"),T.url.query=e.indexOf("q=abc123"),T.url.fragment=e.indexOf("dfdf")),3===D&&(T.url.byProtocol=e.lastIndexOf("http://www.ุนุฑุจูŠ.com"),T.url.protocol2=e.lastIndexOf("http://")),4===D&&(T.url.ipv4=e.indexOf("127.0.0.1"),T.url.ipv4Confirmation=e.indexOf("0.")),5===D&&(T.url.ipv6=e.indexOf("2a00:1450:4025:401::67"),T.url.protocol3=e.lastIndexOf("http://")),6===D&&(T.url.secondPartOfPath=e.indexOf("แƒ’แƒ’")),D++});A(e);e.email,e.url,e.file,e.finalRegex,e.ipRegex,e.emailRegex,e.fileRegex,e.urlRegex,e.iidxes;var D=u(function(A,u){Object.defineProperty(u,"__esModule",{value:!0}),u.checkParenthesis=function(A,u,E,N){return N===u&&(E.split(A).length-E.split(u).length==1||A===u&&E.split(A).length%2==0||void 0)},u.maximumAttrLength=L.htmlAttributes.sort(function(A,u){return u.length-A.length})[0].length,u.isInsideAttribute=function(A){return/\s[a-z0-9-]+=('|")$/i.test(A)||/: ?url\(('|")?$/i.test(A)},u.isInsideAnchorTag=function(A,u,E){for(var N=A.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&"),C=new RegExp("(?=()("+N+"))[\\s\\S]*?("+N+")(?!\"|')","gi"),O=null;null!==(O=C.exec(u));){if(O.index+O[0].length===E)return!0}return!1}});A(D);D.checkParenthesis,D.maximumAttrLength,D.isInsideAttribute,D.isInsideAnchorTag;return A(u(function(A,u){Object.defineProperty(u,"__esModule",{value:!0});function T(I){for(var R=[],S=null,A=function(){var A=S.index,N=A+S[0].length,C=S[0];if("/"===I.charAt(N)&&(C+=I.charAt(N),N++),-1")&&-1 width + 20 || particle.x < -20 || particle.y > height) { + if (streamingConfetti && particles.length <= maxParticleCount) + resetParticle(particle, width, height); + else { + particles.splice(i, 1); + i--; + } + } + } + } +})(); \ No newline at end of file diff --git a/assets/js/date.js b/assets/js/date.js new file mode 100755 index 0000000..17b795c --- /dev/null +++ b/assets/js/date.js @@ -0,0 +1,94 @@ +/* eslint no-extend-native: 0 */ + +(function () { + // Defining locale + Date.shortMonths = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] + Date.longMonths = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] + Date.shortDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] + Date.longDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] + // Defining patterns + var replaceChars = { + // Day + d: function () { var d = this.getDate(); return (d < 10 ? '0' : '') + d }, + D: function () { return Date.shortDays[this.getDay()] }, + j: function () { return this.getDate() }, + l: function () { return Date.longDays[this.getDay()] }, + N: function () { var N = this.getDay(); return (N === 0 ? 7 : N) }, + S: function () { var S = this.getDate(); return (S % 10 === 1 && S !== 11 ? 'st' : (S % 10 === 2 && S !== 12 ? 'nd' : (S % 10 === 3 && S !== 13 ? 'rd' : 'th'))) }, + w: function () { return this.getDay() }, + z: function () { var d = new Date(this.getFullYear(), 0, 1); return Math.ceil((this - d) / 86400000) }, + // Week + W: function () { + var target = new Date(this.valueOf()) + var dayNr = (this.getDay() + 6) % 7 + target.setDate(target.getDate() - dayNr + 3) + var firstThursday = target.valueOf() + target.setMonth(0, 1) + if (target.getDay() !== 4) { + target.setMonth(0, 1 + ((4 - target.getDay()) + 7) % 7) + } + var retVal = 1 + Math.ceil((firstThursday - target) / 604800000) + + return (retVal < 10 ? '0' + retVal : retVal) + }, + // Month + F: function () { return Date.longMonths[this.getMonth()] }, + m: function () { var m = this.getMonth(); return (m < 9 ? '0' : '') + (m + 1) }, + M: function () { return Date.shortMonths[this.getMonth()] }, + n: function () { return this.getMonth() + 1 }, + t: function () { + var year = this.getFullYear() + var nextMonth = this.getMonth() + 1 + if (nextMonth === 12) { + year = year++ + nextMonth = 0 + } + return new Date(year, nextMonth, 0).getDate() + }, + // Year + L: function () { var L = this.getFullYear(); return (L % 400 === 0 || (L % 100 !== 0 && L % 4 === 0)) }, + o: function () { var d = new Date(this.valueOf()); d.setDate(d.getDate() - ((this.getDay() + 6) % 7) + 3); return d.getFullYear() }, + Y: function () { return this.getFullYear() }, + y: function () { return ('' + this.getFullYear()).substr(2) }, + // Time + a: function () { return this.getHours() < 12 ? 'am' : 'pm' }, + A: function () { return this.getHours() < 12 ? 'AM' : 'PM' }, + B: function () { return Math.floor((((this.getUTCHours() + 1) % 24) + this.getUTCMinutes() / 60 + this.getUTCSeconds() / 3600) * 1000 / 24) }, + g: function () { return this.getHours() % 12 || 12 }, + G: function () { return this.getHours() }, + h: function () { var h = this.getHours(); return ((h % 12 || 12) < 10 ? '0' : '') + (h % 12 || 12) }, + H: function () { var H = this.getHours(); return (H < 10 ? '0' : '') + H }, + i: function () { var i = this.getMinutes(); return (i < 10 ? '0' : '') + i }, + s: function () { var s = this.getSeconds(); return (s < 10 ? '0' : '') + s }, + v: function () { var v = this.getMilliseconds(); return (v < 10 ? '00' : (v < 100 ? '0' : '')) + v }, + // Timezone + e: function () { return Intl.DateTimeFormat().resolvedOptions().timeZone }, + I: function () { + var DST = null + for (var i = 0; i < 12; ++i) { + var d = new Date(this.getFullYear(), i, 1) + var offset = d.getTimezoneOffset() + + if (DST === null) DST = offset + else if (offset < DST) { DST = offset; break } else if (offset > DST) break + } + return (this.getTimezoneOffset() === DST) | 0 + }, + O: function () { var O = this.getTimezoneOffset(); return (-O < 0 ? '-' : '+') + (Math.abs(O / 60) < 10 ? '0' : '') + Math.floor(Math.abs(O / 60)) + (Math.abs(O % 60) === 0 ? '00' : ((Math.abs(O % 60) < 10 ? '0' : '')) + (Math.abs(O % 60))) }, + P: function () { var P = this.getTimezoneOffset(); return (-P < 0 ? '-' : '+') + (Math.abs(P / 60) < 10 ? '0' : '') + Math.floor(Math.abs(P / 60)) + ':' + (Math.abs(P % 60) === 0 ? '00' : ((Math.abs(P % 60) < 10 ? '0' : '')) + (Math.abs(P % 60))) }, + T: function () { var tz = this.toLocaleTimeString(navigator.language, {timeZoneName: 'short'}).split(' '); return tz[tz.length - 1] }, + Z: function () { return -this.getTimezoneOffset() * 60 }, + // Full Date/Time + c: function () { return this.format('Y-m-d\\TH:i:sP') }, + r: function () { return this.toString() }, + U: function () { return Math.floor(this.getTime() / 1000) } + } + + // Simulates PHP's date function + Date.prototype.format = function (format) { + var date = this + return format.replace(/(\\?)(.)/g, function (_, esc, chr) { + return (esc === '' && replaceChars[chr]) ? replaceChars[chr].call(date) : chr + }) + } +}).call(this); \ No newline at end of file diff --git a/assets/js/dish.js b/assets/js/dish.js new file mode 100755 index 0000000..9c2d4d4 --- /dev/null +++ b/assets/js/dish.js @@ -0,0 +1,275 @@ +class Dish { + + // ratios + _ratios = ['4:3', '16:9', '1:1', '1:2'] + + // default options + _dish = false + _conference = false + _cameras = 0 + _margin = 5 + _aspect = 2 + _video = false; + _ratio = this.ratio() // to perfomance call here + + // create dish + constructor(scenary) { + + // parent space to render dish + this._scenary = scenary + + // create the conference and dish + this.create() + + // render cameras + this.render() + + return this; + } + + // create Dish + create() { + + // create conference (dish and screen container) + this._conference = document.createElement('div'); + this._conference.classList.add('videoHolder'); + + // create dish (cameras container) + this._dish = document.createElement('div'); + this._dish.classList.add('cams'); + + let screen = document.createElement('div'); + screen.classList.add('screen'); + + let info = document.createElement('div'); + info.classList.add("info"); + screen.append(info); + + let table = document.createElement('table'); + info.append(table); + + let video = document.createElement('video'); + video.setAttribute("autoplay", ""); + video.setAttribute("playsinline", ""); + video.muted = true; + screen.append(video); + + // append first to scenary + this._conference.prepend(screen); + + //this.expand(); + + // append dish to conference + this._conference.appendChild(this._dish); + + } + + // set dish in scenary + append() { + + // append to scenary + this._scenary.appendChild(this._conference); + + } + + // calculate dimensions + dimensions() { + this._width = this._dish.offsetWidth - (this._margin * 2); + this._height = this._dish.offsetHeight - (this._margin * 2); + } + + // render cameras of dish + render() { + + // delete cameras (only those that are left over) + if (this._dish.children) { + for (let i = this._cameras; i < this._dish.children.length; i++) { + let Camera = this._dish.children[i] + this._dish.removeChild(Camera); + } + } + + // add cameras (only the necessary ones) + for (let i = this._dish.children.length; i < this._cameras; i++) { + let Camera = document.createElement('div') + this._dish.appendChild(Camera); + } + + } + + // resizer of cameras + resizer(width) { + + for (var s = 0; s < this._dish.children.length; s++) { + + // camera fron dish (div without class) + let element = this._dish.children[s]; + + // custom margin + element.style.margin = this._margin + "px" + + // calculate dimensions + element.style.width = width + "px" + element.style.height = (width * this._ratio) + "px" + + // to show the aspect ratio in demo (optional) + element.setAttribute('data-aspect', this._ratios[this._aspect]); + + } + } + + resize() { + + // get dimensions of dish + this.dimensions() + + // loop (i recommend you optimize this) + let max = 0 + let i = 1 + while (i < 5000) { + let area = this.area(i); + if (area === false) { + max = i - 1; + break; + } + i++; + } + + // remove margins + max = max - (this._margin * 2); + + // set dimensions to all cameras + this.resizer(max); + } + + // split aspect ratio (format n:n) + ratio() { + var ratio = this._ratios[this._aspect].split(":"); + return ratio[1] / ratio[0]; + } + + // calculate area of dish: + area(increment) { + + let i = 0; + let w = 0; + let h = increment * this._ratio + (this._margin * 2); + while (i < (this._dish.children.length)) { + if ((w + increment) > this._width) { + w = 0; + h = h + (increment * this._ratio) + (this._margin * 2); + } + w = w + increment + (this._margin * 2); + i++; + } + if (h > this._height || increment > this._width) return false; + else return increment; + + } + + // add new camera + add() { + this._cameras++; + this.render(); + this.resize(); + } + + // remove last camera + delete() { + this._cameras--; + this.render(); + this.resize(); + } + + // return ratios + ratios() { + return this._ratios; + } + + // return cameras + cameras() { + return this._cameras; + } + + // set ratio + aspect(i) { + this._aspect = i; + this._ratio = this.ratio() + this.resize(); + } + + // set screen scenary + /* + expand() { + + + // detect screen exist + let screens = this._conference.querySelector('.screen'); + if (screens) { + + // remove screen + this._conference.removeChild(screens); + + } else { + + // add div to scenary + let screen = document.createElement('div'); + screen.classList.add('screen'); + + let table = document.createElement('table'); + screen.append(table); + + let video = document.createElement('video'); + video.setAttribute("autoplay", ""); + video.setAttribute("playsinline", ""); + video.muted = true; + screen.append(video); + + // append first to scenary + this._conference.prepend(screen); + + } + this.resize(); + } + */ + + video(camera, callback, hide = false) { + + // check have video + if (this._dish.children[camera].video) { + if (hide) { + // delete video: + this._dish.children[camera].video = false + let videos = this._dish.children[camera].querySelectorAll('video'); + this._dish.children[camera].removeChild(videos[0]); + } + } else { + // set video + this._dish.children[camera].video = true + + // create video + let video = document.createElement('video'); + video.classList.add('loading'); + + // random number 1-5 + let filename = 'demo.mp4'; + video.src = `./videos/${filename}`; + video.autoplay = true; + video.loop = true; + video.muted = true; + video.playsinline = true; + video.controls = false; + + // event to show video + video.addEventListener('loadedmetadata', function () { + callback(video); + }, false); + + // append video to camera + this._dish.children[camera].appendChild(video); + + } + + } + +} \ No newline at end of file diff --git a/assets/js/e2ee.js b/assets/js/e2ee.js new file mode 100755 index 0000000..1fe6dde --- /dev/null +++ b/assets/js/e2ee.js @@ -0,0 +1,124 @@ +export class e2ee { + async generateKeys() { + const keyPair = await window.crypto.subtle.generateKey( + { + name: "ECDH", + namedCurve: "P-256", + }, + true, + ["deriveKey", "deriveBits"] + ); + + const publicKeyJwk = await window.crypto.subtle.exportKey( + "jwk", + keyPair.publicKey + ); + + const privateKeyJwk = await window.crypto.subtle.exportKey( + "jwk", + keyPair.privateKey + ); + + return { publicKeyJwk, privateKeyJwk }; + } + + async importKey(x, y, d) { + const privateKey = await window.crypto.subtle.importKey( + "jwk", + { + kty: "EC", + crv: "P-256", + x: x, + y: y, + d: d, + ext: true, + }, + { + name: "ECDH", + namedCurve: "P-256", + }, + true, + ["deriveKey", "deriveBits"] + ); + + const privateKeyJwk = await window.crypto.subtle.exportKey( + "jwk", + privateKey + ); + + return privateKeyJwk; + } + + async deriveKey(publicKeyJwk, privateKeyJwk) { + const publicKey = await window.crypto.subtle.importKey( + "jwk", + publicKeyJwk, + { + name: "ECDH", + namedCurve: "P-256", + }, + true, + [] + ); + + const privateKey = await window.crypto.subtle.importKey( + "jwk", + privateKeyJwk, + { + name: "ECDH", + namedCurve: "P-256", + }, + true, + ["deriveKey", "deriveBits"] + ); + + return await window.crypto.subtle.deriveKey( + { name: "ECDH", public: publicKey }, + privateKey, + { name: "AES-GCM", length: 256 }, + true, + ["encrypt", "decrypt"] + ); + }; + + async encryptMessage(text, derivedKey, conversation) { + const encodedText = new TextEncoder().encode(text); + + const encryptedData = await window.crypto.subtle.encrypt( + { name: "AES-GCM", iv: new TextEncoder().encode(conversation) }, + derivedKey, + encodedText + ); + + const uintArray = new Uint8Array(encryptedData); + const string = String.fromCharCode.apply(null, uintArray); + const base64Data = btoa(string); + + return base64Data; + }; + + async decryptMessage(text, derivedKey, conversation) { + try { + const initializationVector = new Uint8Array(new TextEncoder().encode(conversation)).buffer; + + const string = atob(text); + const uintArray = new Uint8Array( + [...string].map((char) => char.charCodeAt(0)) + ); + const algorithm = { + name: "AES-GCM", + iv: initializationVector, + }; + const decryptedData = await window.crypto.subtle.decrypt( + algorithm, + derivedKey, + uintArray + ); + + return new TextDecoder().decode(decryptedData); + } + catch { + return text; + } + }; +} \ No newline at end of file diff --git a/assets/js/emojis.js b/assets/js/emojis.js new file mode 100755 index 0000000..7fdaf2d --- /dev/null +++ b/assets/js/emojis.js @@ -0,0 +1,24611 @@ +// 20220328100840 +// https://raw.githubusercontent.com/github/gemoji/master/db/emoji.json + +let emojis = [ + { + "emoji": "๐Ÿ˜€", + "description": "grinning face", + "category": "Smileys & Emotion", + "aliases": [ + "grinning" + ], + "tags": [ + "smile", + "happy" + ], + "unicode_version": "6.1", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ƒ", + "description": "grinning face with big eyes", + "category": "Smileys & Emotion", + "aliases": [ + "smiley" + ], + "tags": [ + "happy", + "joy", + "haha" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜„", + "description": "grinning face with smiling eyes", + "category": "Smileys & Emotion", + "aliases": [ + "smile" + ], + "tags": [ + "happy", + "joy", + "laugh", + "pleased" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜", + "description": "beaming face with smiling eyes", + "category": "Smileys & Emotion", + "aliases": [ + "grin" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜†", + "description": "grinning squinting face", + "category": "Smileys & Emotion", + "aliases": [ + "laughing", + "satisfied" + ], + "tags": [ + "happy", + "haha" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜…", + "description": "grinning face with sweat", + "category": "Smileys & Emotion", + "aliases": [ + "sweat_smile" + ], + "tags": [ + "hot" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿคฃ", + "description": "rolling on the floor laughing", + "category": "Smileys & Emotion", + "aliases": [ + "rofl" + ], + "tags": [ + "lol", + "laughing" + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿ˜‚", + "description": "face with tears of joy", + "category": "Smileys & Emotion", + "aliases": [ + "joy" + ], + "tags": [ + "tears" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ™‚", + "description": "slightly smiling face", + "category": "Smileys & Emotion", + "aliases": [ + "slightly_smiling_face" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ™ƒ", + "description": "upside-down face", + "category": "Smileys & Emotion", + "aliases": [ + "upside_down_face" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿซ ", + "description": "melting face", + "category": "Smileys & Emotion", + "aliases": [ + "melting_face" + ], + "tags": [ + "sarcasm", + "dread" + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐Ÿ˜‰", + "description": "winking face", + "category": "Smileys & Emotion", + "aliases": [ + "wink" + ], + "tags": [ + "flirt" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜Š", + "description": "smiling face with smiling eyes", + "category": "Smileys & Emotion", + "aliases": [ + "blush" + ], + "tags": [ + "proud" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜‡", + "description": "smiling face with halo", + "category": "Smileys & Emotion", + "aliases": [ + "innocent" + ], + "tags": [ + "angel" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฅฐ", + "description": "smiling face with hearts", + "category": "Smileys & Emotion", + "aliases": [ + "smiling_face_with_three_hearts" + ], + "tags": [ + "love" + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ˜", + "description": "smiling face with heart-eyes", + "category": "Smileys & Emotion", + "aliases": [ + "heart_eyes" + ], + "tags": [ + "love", + "crush" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿคฉ", + "description": "star-struck", + "category": "Smileys & Emotion", + "aliases": [ + "star_struck" + ], + "tags": [ + "eyes" + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ˜˜", + "description": "face blowing a kiss", + "category": "Smileys & Emotion", + "aliases": [ + "kissing_heart" + ], + "tags": [ + "flirt" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜—", + "description": "kissing face", + "category": "Smileys & Emotion", + "aliases": [ + "kissing" + ], + "tags": [ + + ], + "unicode_version": "6.1", + "ios_version": "6.0" + }, + { + "emoji": "โ˜บ๏ธ", + "description": "smiling face", + "category": "Smileys & Emotion", + "aliases": [ + "relaxed" + ], + "tags": [ + "blush", + "pleased" + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜š", + "description": "kissing face with closed eyes", + "category": "Smileys & Emotion", + "aliases": [ + "kissing_closed_eyes" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜™", + "description": "kissing face with smiling eyes", + "category": "Smileys & Emotion", + "aliases": [ + "kissing_smiling_eyes" + ], + "tags": [ + + ], + "unicode_version": "6.1", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฅฒ", + "description": "smiling face with tear", + "category": "Smileys & Emotion", + "aliases": [ + "smiling_face_with_tear" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿ˜‹", + "description": "face savoring food", + "category": "Smileys & Emotion", + "aliases": [ + "yum" + ], + "tags": [ + "tongue", + "lick" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜›", + "description": "face with tongue", + "category": "Smileys & Emotion", + "aliases": [ + "stuck_out_tongue" + ], + "tags": [ + + ], + "unicode_version": "6.1", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜œ", + "description": "winking face with tongue", + "category": "Smileys & Emotion", + "aliases": [ + "stuck_out_tongue_winking_eye" + ], + "tags": [ + "prank", + "silly" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿคช", + "description": "zany face", + "category": "Smileys & Emotion", + "aliases": [ + "zany_face" + ], + "tags": [ + "goofy", + "wacky" + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ˜", + "description": "squinting face with tongue", + "category": "Smileys & Emotion", + "aliases": [ + "stuck_out_tongue_closed_eyes" + ], + "tags": [ + "prank" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿค‘", + "description": "money-mouth face", + "category": "Smileys & Emotion", + "aliases": [ + "money_mouth_face" + ], + "tags": [ + "rich" + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿค—", + "description": "smiling face with open hands", + "category": "Smileys & Emotion", + "aliases": [ + "hugs" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿคญ", + "description": "face with hand over mouth", + "category": "Smileys & Emotion", + "aliases": [ + "hand_over_mouth" + ], + "tags": [ + "quiet", + "whoops" + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿซข", + "description": "face with open eyes and hand over mouth", + "category": "Smileys & Emotion", + "aliases": [ + "face_with_open_eyes_and_hand_over_mouth" + ], + "tags": [ + "gasp", + "shock" + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐Ÿซฃ", + "description": "face with peeking eye", + "category": "Smileys & Emotion", + "aliases": [ + "face_with_peeking_eye" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐Ÿคซ", + "description": "shushing face", + "category": "Smileys & Emotion", + "aliases": [ + "shushing_face" + ], + "tags": [ + "silence", + "quiet" + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿค”", + "description": "thinking face", + "category": "Smileys & Emotion", + "aliases": [ + "thinking" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿซก", + "description": "saluting face", + "category": "Smileys & Emotion", + "aliases": [ + "saluting_face" + ], + "tags": [ + "respect" + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐Ÿค", + "description": "zipper-mouth face", + "category": "Smileys & Emotion", + "aliases": [ + "zipper_mouth_face" + ], + "tags": [ + "silence", + "hush" + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿคจ", + "description": "face with raised eyebrow", + "category": "Smileys & Emotion", + "aliases": [ + "raised_eyebrow" + ], + "tags": [ + "suspicious" + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ˜", + "description": "neutral face", + "category": "Smileys & Emotion", + "aliases": [ + "neutral_face" + ], + "tags": [ + "meh" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜‘", + "description": "expressionless face", + "category": "Smileys & Emotion", + "aliases": [ + "expressionless" + ], + "tags": [ + + ], + "unicode_version": "6.1", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ถ", + "description": "face without mouth", + "category": "Smileys & Emotion", + "aliases": [ + "no_mouth" + ], + "tags": [ + "mute", + "silence" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿซฅ", + "description": "dotted line face", + "category": "Smileys & Emotion", + "aliases": [ + "dotted_line_face" + ], + "tags": [ + "invisible" + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐Ÿ˜ถโ€๐ŸŒซ๏ธ", + "description": "face in clouds", + "category": "Smileys & Emotion", + "aliases": [ + "face_in_clouds" + ], + "tags": [ + + ], + "unicode_version": "13.1", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿ˜", + "description": "smirking face", + "category": "Smileys & Emotion", + "aliases": [ + "smirk" + ], + "tags": [ + "smug" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜’", + "description": "unamused face", + "category": "Smileys & Emotion", + "aliases": [ + "unamused" + ], + "tags": [ + "meh" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ™„", + "description": "face with rolling eyes", + "category": "Smileys & Emotion", + "aliases": [ + "roll_eyes" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ˜ฌ", + "description": "grimacing face", + "category": "Smileys & Emotion", + "aliases": [ + "grimacing" + ], + "tags": [ + + ], + "unicode_version": "6.1", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ฎโ€๐Ÿ’จ", + "description": "face exhaling", + "category": "Smileys & Emotion", + "aliases": [ + "face_exhaling" + ], + "tags": [ + + ], + "unicode_version": "13.1", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿคฅ", + "description": "lying face", + "category": "Smileys & Emotion", + "aliases": [ + "lying_face" + ], + "tags": [ + "liar" + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿ˜Œ", + "description": "relieved face", + "category": "Smileys & Emotion", + "aliases": [ + "relieved" + ], + "tags": [ + "whew" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜”", + "description": "pensive face", + "category": "Smileys & Emotion", + "aliases": [ + "pensive" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ช", + "description": "sleepy face", + "category": "Smileys & Emotion", + "aliases": [ + "sleepy" + ], + "tags": [ + "tired" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿคค", + "description": "drooling face", + "category": "Smileys & Emotion", + "aliases": [ + "drooling_face" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿ˜ด", + "description": "sleeping face", + "category": "Smileys & Emotion", + "aliases": [ + "sleeping" + ], + "tags": [ + "zzz" + ], + "unicode_version": "6.1", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ท", + "description": "face with medical mask", + "category": "Smileys & Emotion", + "aliases": [ + "mask" + ], + "tags": [ + "sick", + "ill" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿค’", + "description": "face with thermometer", + "category": "Smileys & Emotion", + "aliases": [ + "face_with_thermometer" + ], + "tags": [ + "sick" + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿค•", + "description": "face with head-bandage", + "category": "Smileys & Emotion", + "aliases": [ + "face_with_head_bandage" + ], + "tags": [ + "hurt" + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿคข", + "description": "nauseated face", + "category": "Smileys & Emotion", + "aliases": [ + "nauseated_face" + ], + "tags": [ + "sick", + "barf", + "disgusted" + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿคฎ", + "description": "face vomiting", + "category": "Smileys & Emotion", + "aliases": [ + "vomiting_face" + ], + "tags": [ + "barf", + "sick" + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿคง", + "description": "sneezing face", + "category": "Smileys & Emotion", + "aliases": [ + "sneezing_face" + ], + "tags": [ + "achoo", + "sick" + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿฅต", + "description": "hot face", + "category": "Smileys & Emotion", + "aliases": [ + "hot_face" + ], + "tags": [ + "heat", + "sweating" + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฅถ", + "description": "cold face", + "category": "Smileys & Emotion", + "aliases": [ + "cold_face" + ], + "tags": [ + "freezing", + "ice" + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฅด", + "description": "woozy face", + "category": "Smileys & Emotion", + "aliases": [ + "woozy_face" + ], + "tags": [ + "groggy" + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ˜ต", + "description": "face with crossed-out eyes", + "category": "Smileys & Emotion", + "aliases": [ + "dizzy_face" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ตโ€๐Ÿ’ซ", + "description": "face with spiral eyes", + "category": "Smileys & Emotion", + "aliases": [ + "face_with_spiral_eyes" + ], + "tags": [ + + ], + "unicode_version": "13.1", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿคฏ", + "description": "exploding head", + "category": "Smileys & Emotion", + "aliases": [ + "exploding_head" + ], + "tags": [ + "mind", + "blown" + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿค ", + "description": "cowboy hat face", + "category": "Smileys & Emotion", + "aliases": [ + "cowboy_hat_face" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿฅณ", + "description": "partying face", + "category": "Smileys & Emotion", + "aliases": [ + "partying_face" + ], + "tags": [ + "celebration", + "birthday" + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฅธ", + "description": "disguised face", + "category": "Smileys & Emotion", + "aliases": [ + "disguised_face" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿ˜Ž", + "description": "smiling face with sunglasses", + "category": "Smileys & Emotion", + "aliases": [ + "sunglasses" + ], + "tags": [ + "cool" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿค“", + "description": "nerd face", + "category": "Smileys & Emotion", + "aliases": [ + "nerd_face" + ], + "tags": [ + "geek", + "glasses" + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿง", + "description": "face with monocle", + "category": "Smileys & Emotion", + "aliases": [ + "monocle_face" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ˜•", + "description": "confused face", + "category": "Smileys & Emotion", + "aliases": [ + "confused" + ], + "tags": [ + + ], + "unicode_version": "6.1", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿซค", + "description": "face with diagonal mouth", + "category": "Smileys & Emotion", + "aliases": [ + "face_with_diagonal_mouth" + ], + "tags": [ + "confused" + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐Ÿ˜Ÿ", + "description": "worried face", + "category": "Smileys & Emotion", + "aliases": [ + "worried" + ], + "tags": [ + "nervous" + ], + "unicode_version": "6.1", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ™", + "description": "slightly frowning face", + "category": "Smileys & Emotion", + "aliases": [ + "slightly_frowning_face" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "โ˜น๏ธ", + "description": "frowning face", + "category": "Smileys & Emotion", + "aliases": [ + "frowning_face" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ˜ฎ", + "description": "face with open mouth", + "category": "Smileys & Emotion", + "aliases": [ + "open_mouth" + ], + "tags": [ + "surprise", + "impressed", + "wow" + ], + "unicode_version": "6.1", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ฏ", + "description": "hushed face", + "category": "Smileys & Emotion", + "aliases": [ + "hushed" + ], + "tags": [ + "silence", + "speechless" + ], + "unicode_version": "6.1", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ฒ", + "description": "astonished face", + "category": "Smileys & Emotion", + "aliases": [ + "astonished" + ], + "tags": [ + "amazed", + "gasp" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ณ", + "description": "flushed face", + "category": "Smileys & Emotion", + "aliases": [ + "flushed" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฅบ", + "description": "pleading face", + "category": "Smileys & Emotion", + "aliases": [ + "pleading_face" + ], + "tags": [ + "puppy", + "eyes" + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฅน", + "description": "face holding back tears", + "category": "Smileys & Emotion", + "aliases": [ + "face_holding_back_tears" + ], + "tags": [ + "tears", + "gratitude" + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐Ÿ˜ฆ", + "description": "frowning face with open mouth", + "category": "Smileys & Emotion", + "aliases": [ + "frowning" + ], + "tags": [ + + ], + "unicode_version": "6.1", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ง", + "description": "anguished face", + "category": "Smileys & Emotion", + "aliases": [ + "anguished" + ], + "tags": [ + "stunned" + ], + "unicode_version": "6.1", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜จ", + "description": "fearful face", + "category": "Smileys & Emotion", + "aliases": [ + "fearful" + ], + "tags": [ + "scared", + "shocked", + "oops" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ฐ", + "description": "anxious face with sweat", + "category": "Smileys & Emotion", + "aliases": [ + "cold_sweat" + ], + "tags": [ + "nervous" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ฅ", + "description": "sad but relieved face", + "category": "Smileys & Emotion", + "aliases": [ + "disappointed_relieved" + ], + "tags": [ + "phew", + "sweat", + "nervous" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ข", + "description": "crying face", + "category": "Smileys & Emotion", + "aliases": [ + "cry" + ], + "tags": [ + "sad", + "tear" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ญ", + "description": "loudly crying face", + "category": "Smileys & Emotion", + "aliases": [ + "sob" + ], + "tags": [ + "sad", + "cry", + "bawling" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ฑ", + "description": "face screaming in fear", + "category": "Smileys & Emotion", + "aliases": [ + "scream" + ], + "tags": [ + "horror", + "shocked" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜–", + "description": "confounded face", + "category": "Smileys & Emotion", + "aliases": [ + "confounded" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ฃ", + "description": "persevering face", + "category": "Smileys & Emotion", + "aliases": [ + "persevere" + ], + "tags": [ + "struggling" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ž", + "description": "disappointed face", + "category": "Smileys & Emotion", + "aliases": [ + "disappointed" + ], + "tags": [ + "sad" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜“", + "description": "downcast face with sweat", + "category": "Smileys & Emotion", + "aliases": [ + "sweat" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ฉ", + "description": "weary face", + "category": "Smileys & Emotion", + "aliases": [ + "weary" + ], + "tags": [ + "tired" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ซ", + "description": "tired face", + "category": "Smileys & Emotion", + "aliases": [ + "tired_face" + ], + "tags": [ + "upset", + "whine" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฅฑ", + "description": "yawning face", + "category": "Smileys & Emotion", + "aliases": [ + "yawning_face" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿ˜ค", + "description": "face with steam from nose", + "category": "Smileys & Emotion", + "aliases": [ + "triumph" + ], + "tags": [ + "smug" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ก", + "description": "pouting face", + "category": "Smileys & Emotion", + "aliases": [ + "rage", + "pout" + ], + "tags": [ + "angry" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ ", + "description": "angry face", + "category": "Smileys & Emotion", + "aliases": [ + "angry" + ], + "tags": [ + "mad", + "annoyed" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿคฌ", + "description": "face with symbols on mouth", + "category": "Smileys & Emotion", + "aliases": [ + "cursing_face" + ], + "tags": [ + "foul" + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ˜ˆ", + "description": "smiling face with horns", + "category": "Smileys & Emotion", + "aliases": [ + "smiling_imp" + ], + "tags": [ + "devil", + "evil", + "horns" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘ฟ", + "description": "angry face with horns", + "category": "Smileys & Emotion", + "aliases": [ + "imp" + ], + "tags": [ + "angry", + "devil", + "evil", + "horns" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’€", + "description": "skull", + "category": "Smileys & Emotion", + "aliases": [ + "skull" + ], + "tags": [ + "dead", + "danger", + "poison" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โ˜ ๏ธ", + "description": "skull and crossbones", + "category": "Smileys & Emotion", + "aliases": [ + "skull_and_crossbones" + ], + "tags": [ + "danger", + "pirate" + ], + "unicode_version": "", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ’ฉ", + "description": "pile of poo", + "category": "Smileys & Emotion", + "aliases": [ + "hankey", + "poop", + "shit" + ], + "tags": [ + "crap" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿคก", + "description": "clown face", + "category": "Smileys & Emotion", + "aliases": [ + "clown_face" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿ‘น", + "description": "ogre", + "category": "Smileys & Emotion", + "aliases": [ + "japanese_ogre" + ], + "tags": [ + "monster" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘บ", + "description": "goblin", + "category": "Smileys & Emotion", + "aliases": [ + "japanese_goblin" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘ป", + "description": "ghost", + "category": "Smileys & Emotion", + "aliases": [ + "ghost" + ], + "tags": [ + "halloween" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘ฝ", + "description": "alien", + "category": "Smileys & Emotion", + "aliases": [ + "alien" + ], + "tags": [ + "ufo" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘พ", + "description": "alien monster", + "category": "Smileys & Emotion", + "aliases": [ + "space_invader" + ], + "tags": [ + "game", + "retro" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿค–", + "description": "robot", + "category": "Smileys & Emotion", + "aliases": [ + "robot" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ˜บ", + "description": "grinning cat", + "category": "Smileys & Emotion", + "aliases": [ + "smiley_cat" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ธ", + "description": "grinning cat with smiling eyes", + "category": "Smileys & Emotion", + "aliases": [ + "smile_cat" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜น", + "description": "cat with tears of joy", + "category": "Smileys & Emotion", + "aliases": [ + "joy_cat" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ป", + "description": "smiling cat with heart-eyes", + "category": "Smileys & Emotion", + "aliases": [ + "heart_eyes_cat" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ผ", + "description": "cat with wry smile", + "category": "Smileys & Emotion", + "aliases": [ + "smirk_cat" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ฝ", + "description": "kissing cat", + "category": "Smileys & Emotion", + "aliases": [ + "kissing_cat" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ™€", + "description": "weary cat", + "category": "Smileys & Emotion", + "aliases": [ + "scream_cat" + ], + "tags": [ + "horror" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜ฟ", + "description": "crying cat", + "category": "Smileys & Emotion", + "aliases": [ + "crying_cat_face" + ], + "tags": [ + "sad", + "tear" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜พ", + "description": "pouting cat", + "category": "Smileys & Emotion", + "aliases": [ + "pouting_cat" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ™ˆ", + "description": "see-no-evil monkey", + "category": "Smileys & Emotion", + "aliases": [ + "see_no_evil" + ], + "tags": [ + "monkey", + "blind", + "ignore" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ™‰", + "description": "hear-no-evil monkey", + "category": "Smileys & Emotion", + "aliases": [ + "hear_no_evil" + ], + "tags": [ + "monkey", + "deaf" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ™Š", + "description": "speak-no-evil monkey", + "category": "Smileys & Emotion", + "aliases": [ + "speak_no_evil" + ], + "tags": [ + "monkey", + "mute", + "hush" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’‹", + "description": "kiss mark", + "category": "Smileys & Emotion", + "aliases": [ + "kiss" + ], + "tags": [ + "lipstick" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’Œ", + "description": "love letter", + "category": "Smileys & Emotion", + "aliases": [ + "love_letter" + ], + "tags": [ + "email", + "envelope" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’˜", + "description": "heart with arrow", + "category": "Smileys & Emotion", + "aliases": [ + "cupid" + ], + "tags": [ + "love", + "heart" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’", + "description": "heart with ribbon", + "category": "Smileys & Emotion", + "aliases": [ + "gift_heart" + ], + "tags": [ + "chocolates" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’–", + "description": "sparkling heart", + "category": "Smileys & Emotion", + "aliases": [ + "sparkling_heart" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’—", + "description": "growing heart", + "category": "Smileys & Emotion", + "aliases": [ + "heartpulse" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’“", + "description": "beating heart", + "category": "Smileys & Emotion", + "aliases": [ + "heartbeat" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’ž", + "description": "revolving hearts", + "category": "Smileys & Emotion", + "aliases": [ + "revolving_hearts" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’•", + "description": "two hearts", + "category": "Smileys & Emotion", + "aliases": [ + "two_hearts" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’Ÿ", + "description": "heart decoration", + "category": "Smileys & Emotion", + "aliases": [ + "heart_decoration" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โฃ๏ธ", + "description": "heart exclamation", + "category": "Smileys & Emotion", + "aliases": [ + "heavy_heart_exclamation" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ’”", + "description": "broken heart", + "category": "Smileys & Emotion", + "aliases": [ + "broken_heart" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โค๏ธโ€๐Ÿ”ฅ", + "description": "heart on fire", + "category": "Smileys & Emotion", + "aliases": [ + "heart_on_fire" + ], + "tags": [ + + ], + "unicode_version": "13.1", + "ios_version": "14.0" + }, + { + "emoji": "โค๏ธโ€๐Ÿฉน", + "description": "mending heart", + "category": "Smileys & Emotion", + "aliases": [ + "mending_heart" + ], + "tags": [ + + ], + "unicode_version": "13.1", + "ios_version": "14.0" + }, + { + "emoji": "โค๏ธ", + "description": "red heart", + "category": "Smileys & Emotion", + "aliases": [ + "heart" + ], + "tags": [ + "love" + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿงก", + "description": "orange heart", + "category": "Smileys & Emotion", + "aliases": [ + "orange_heart" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ’›", + "description": "yellow heart", + "category": "Smileys & Emotion", + "aliases": [ + "yellow_heart" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’š", + "description": "green heart", + "category": "Smileys & Emotion", + "aliases": [ + "green_heart" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’™", + "description": "blue heart", + "category": "Smileys & Emotion", + "aliases": [ + "blue_heart" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’œ", + "description": "purple heart", + "category": "Smileys & Emotion", + "aliases": [ + "purple_heart" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸคŽ", + "description": "brown heart", + "category": "Smileys & Emotion", + "aliases": [ + "brown_heart" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿ–ค", + "description": "black heart", + "category": "Smileys & Emotion", + "aliases": [ + "black_heart" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿค", + "description": "white heart", + "category": "Smileys & Emotion", + "aliases": [ + "white_heart" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿ’ฏ", + "description": "hundred points", + "category": "Smileys & Emotion", + "aliases": [ + "100" + ], + "tags": [ + "score", + "perfect" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’ข", + "description": "anger symbol", + "category": "Smileys & Emotion", + "aliases": [ + "anger" + ], + "tags": [ + "angry" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’ฅ", + "description": "collision", + "category": "Smileys & Emotion", + "aliases": [ + "boom", + "collision" + ], + "tags": [ + "explode" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’ซ", + "description": "dizzy", + "category": "Smileys & Emotion", + "aliases": [ + "dizzy" + ], + "tags": [ + "star" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’ฆ", + "description": "sweat droplets", + "category": "Smileys & Emotion", + "aliases": [ + "sweat_drops" + ], + "tags": [ + "water", + "workout" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’จ", + "description": "dashing away", + "category": "Smileys & Emotion", + "aliases": [ + "dash" + ], + "tags": [ + "wind", + "blow", + "fast" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•ณ๏ธ", + "description": "hole", + "category": "Smileys & Emotion", + "aliases": [ + "hole" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ’ฃ", + "description": "bomb", + "category": "Smileys & Emotion", + "aliases": [ + "bomb" + ], + "tags": [ + "boom" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’ฌ", + "description": "speech balloon", + "category": "Smileys & Emotion", + "aliases": [ + "speech_balloon" + ], + "tags": [ + "comment" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘๏ธโ€๐Ÿ—จ๏ธ", + "description": "eye in speech bubble", + "category": "Smileys & Emotion", + "aliases": [ + "eye_speech_bubble" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ—จ๏ธ", + "description": "left speech bubble", + "category": "Smileys & Emotion", + "aliases": [ + "left_speech_bubble" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ—ฏ๏ธ", + "description": "right anger bubble", + "category": "Smileys & Emotion", + "aliases": [ + "right_anger_bubble" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ’ญ", + "description": "thought balloon", + "category": "Smileys & Emotion", + "aliases": [ + "thought_balloon" + ], + "tags": [ + "thinking" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’ค", + "description": "zzz", + "category": "Smileys & Emotion", + "aliases": [ + "zzz" + ], + "tags": [ + "sleeping" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘‹", + "description": "waving hand", + "category": "People & Body", + "aliases": [ + "wave" + ], + "tags": [ + "goodbye" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿคš", + "description": "raised back of hand", + "category": "People & Body", + "aliases": [ + "raised_back_of_hand" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ–๏ธ", + "description": "hand with fingers splayed", + "category": "People & Body", + "aliases": [ + "raised_hand_with_fingers_splayed" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1", + "skin_tones": true + }, + { + "emoji": "โœ‹", + "description": "raised hand", + "category": "People & Body", + "aliases": [ + "hand", + "raised_hand" + ], + "tags": [ + "highfive", + "stop" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ––", + "description": "vulcan salute", + "category": "People & Body", + "aliases": [ + "vulcan_salute" + ], + "tags": [ + "prosper", + "spock" + ], + "unicode_version": "7.0", + "ios_version": "8.3", + "skin_tones": true + }, + { + "emoji": "๐Ÿซฑ", + "description": "rightwards hand", + "category": "People & Body", + "aliases": [ + "rightwards_hand" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4", + "skin_tones": true + }, + { + "emoji": "๐Ÿซฒ", + "description": "leftwards hand", + "category": "People & Body", + "aliases": [ + "leftwards_hand" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4", + "skin_tones": true + }, + { + "emoji": "๐Ÿซณ", + "description": "palm down hand", + "category": "People & Body", + "aliases": [ + "palm_down_hand" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4", + "skin_tones": true + }, + { + "emoji": "๐Ÿซด", + "description": "palm up hand", + "category": "People & Body", + "aliases": [ + "palm_up_hand" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘Œ", + "description": "OK hand", + "category": "People & Body", + "aliases": [ + "ok_hand" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐ŸคŒ", + "description": "pinched fingers", + "category": "People & Body", + "aliases": [ + "pinched_fingers" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿค", + "description": "pinching hand", + "category": "People & Body", + "aliases": [ + "pinching_hand" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0", + "skin_tones": true + }, + { + "emoji": "โœŒ๏ธ", + "description": "victory hand", + "category": "People & Body", + "aliases": [ + "v" + ], + "tags": [ + "victory", + "peace" + ], + "unicode_version": "", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿคž", + "description": "crossed fingers", + "category": "People & Body", + "aliases": [ + "crossed_fingers" + ], + "tags": [ + "luck", + "hopeful" + ], + "unicode_version": "9.0", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿซฐ", + "description": "hand with index finger and thumb crossed", + "category": "People & Body", + "aliases": [ + "hand_with_index_finger_and_thumb_crossed" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4", + "skin_tones": true + }, + { + "emoji": "๐ŸคŸ", + "description": "love-you gesture", + "category": "People & Body", + "aliases": [ + "love_you_gesture" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿค˜", + "description": "sign of the horns", + "category": "People & Body", + "aliases": [ + "metal" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿค™", + "description": "call me hand", + "category": "People & Body", + "aliases": [ + "call_me_hand" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ˆ", + "description": "backhand index pointing left", + "category": "People & Body", + "aliases": [ + "point_left" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘‰", + "description": "backhand index pointing right", + "category": "People & Body", + "aliases": [ + "point_right" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘†", + "description": "backhand index pointing up", + "category": "People & Body", + "aliases": [ + "point_up_2" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ–•", + "description": "middle finger", + "category": "People & Body", + "aliases": [ + "middle_finger", + "fu" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘‡", + "description": "backhand index pointing down", + "category": "People & Body", + "aliases": [ + "point_down" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "โ˜๏ธ", + "description": "index pointing up", + "category": "People & Body", + "aliases": [ + "point_up" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿซต", + "description": "index pointing at the viewer", + "category": "People & Body", + "aliases": [ + "index_pointing_at_the_viewer" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘", + "description": "thumbs up", + "category": "People & Body", + "aliases": [ + "+1", + "thumbsup" + ], + "tags": [ + "approve", + "ok" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘Ž", + "description": "thumbs down", + "category": "People & Body", + "aliases": [ + "-1", + "thumbsdown" + ], + "tags": [ + "disapprove", + "bury" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "โœŠ", + "description": "raised fist", + "category": "People & Body", + "aliases": [ + "fist_raised", + "fist" + ], + "tags": [ + "power" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘Š", + "description": "oncoming fist", + "category": "People & Body", + "aliases": [ + "fist_oncoming", + "facepunch", + "punch" + ], + "tags": [ + "attack" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿค›", + "description": "left-facing fist", + "category": "People & Body", + "aliases": [ + "fist_left" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿคœ", + "description": "right-facing fist", + "category": "People & Body", + "aliases": [ + "fist_right" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘", + "description": "clapping hands", + "category": "People & Body", + "aliases": [ + "clap" + ], + "tags": [ + "praise", + "applause" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ™Œ", + "description": "raising hands", + "category": "People & Body", + "aliases": [ + "raised_hands" + ], + "tags": [ + "hooray" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿซถ", + "description": "heart hands", + "category": "People & Body", + "aliases": [ + "heart_hands" + ], + "tags": [ + "love" + ], + "unicode_version": "14.0", + "ios_version": "15.4", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘", + "description": "open hands", + "category": "People & Body", + "aliases": [ + "open_hands" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿคฒ", + "description": "palms up together", + "category": "People & Body", + "aliases": [ + "palms_up_together" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿค", + "description": "handshake", + "category": "People & Body", + "aliases": [ + "handshake" + ], + "tags": [ + "deal" + ], + "unicode_version": "9.0", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ™", + "description": "folded hands", + "category": "People & Body", + "aliases": [ + "pray" + ], + "tags": [ + "please", + "hope", + "wish" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "โœ๏ธ", + "description": "writing hand", + "category": "People & Body", + "aliases": [ + "writing_hand" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "9.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ’…", + "description": "nail polish", + "category": "People & Body", + "aliases": [ + "nail_care" + ], + "tags": [ + "beauty", + "manicure" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿคณ", + "description": "selfie", + "category": "People & Body", + "aliases": [ + "selfie" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ’ช", + "description": "flexed biceps", + "category": "People & Body", + "aliases": [ + "muscle" + ], + "tags": [ + "flex", + "bicep", + "strong", + "workout" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿฆพ", + "description": "mechanical arm", + "category": "People & Body", + "aliases": [ + "mechanical_arm" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿฆฟ", + "description": "mechanical leg", + "category": "People & Body", + "aliases": [ + "mechanical_leg" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿฆต", + "description": "leg", + "category": "People & Body", + "aliases": [ + "leg" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿฆถ", + "description": "foot", + "category": "People & Body", + "aliases": [ + "foot" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘‚", + "description": "ear", + "category": "People & Body", + "aliases": [ + "ear" + ], + "tags": [ + "hear", + "sound", + "listen" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿฆป", + "description": "ear with hearing aid", + "category": "People & Body", + "aliases": [ + "ear_with_hearing_aid" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ƒ", + "description": "nose", + "category": "People & Body", + "aliases": [ + "nose" + ], + "tags": [ + "smell" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿง ", + "description": "brain", + "category": "People & Body", + "aliases": [ + "brain" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿซ€", + "description": "anatomical heart", + "category": "People & Body", + "aliases": [ + "anatomical_heart" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿซ", + "description": "lungs", + "category": "People & Body", + "aliases": [ + "lungs" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿฆท", + "description": "tooth", + "category": "People & Body", + "aliases": [ + "tooth" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฆด", + "description": "bone", + "category": "People & Body", + "aliases": [ + "bone" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ‘€", + "description": "eyes", + "category": "People & Body", + "aliases": [ + "eyes" + ], + "tags": [ + "look", + "see", + "watch" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘๏ธ", + "description": "eye", + "category": "People & Body", + "aliases": [ + "eye" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ‘…", + "description": "tongue", + "category": "People & Body", + "aliases": [ + "tongue" + ], + "tags": [ + "taste" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘„", + "description": "mouth", + "category": "People & Body", + "aliases": [ + "lips" + ], + "tags": [ + "kiss" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿซฆ", + "description": "biting lip", + "category": "People & Body", + "aliases": [ + "biting_lip" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐Ÿ‘ถ", + "description": "baby", + "category": "People & Body", + "aliases": [ + "baby" + ], + "tags": [ + "child", + "newborn" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿง’", + "description": "child", + "category": "People & Body", + "aliases": [ + "child" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฆ", + "description": "boy", + "category": "People & Body", + "aliases": [ + "boy" + ], + "tags": [ + "child" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ง", + "description": "girl", + "category": "People & Body", + "aliases": [ + "girl" + ], + "tags": [ + "child" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘", + "description": "person", + "category": "People & Body", + "aliases": [ + "adult" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฑ", + "description": "person: blond hair", + "category": "People & Body", + "aliases": [ + "blond_haired_person" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จ", + "description": "man", + "category": "People & Body", + "aliases": [ + "man" + ], + "tags": [ + "mustache", + "father", + "dad" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿง”", + "description": "person: beard", + "category": "People & Body", + "aliases": [ + "bearded_person" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿง”โ€โ™‚๏ธ", + "description": "man: beard", + "category": "People & Body", + "aliases": [ + "man_beard" + ], + "tags": [ + + ], + "unicode_version": "13.1", + "ios_version": "14.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿง”โ€โ™€๏ธ", + "description": "woman: beard", + "category": "People & Body", + "aliases": [ + "woman_beard" + ], + "tags": [ + + ], + "unicode_version": "13.1", + "ios_version": "14.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿฆฐ", + "description": "man: red hair", + "category": "People & Body", + "aliases": [ + "red_haired_man" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿฆฑ", + "description": "man: curly hair", + "category": "People & Body", + "aliases": [ + "curly_haired_man" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿฆณ", + "description": "man: white hair", + "category": "People & Body", + "aliases": [ + "white_haired_man" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿฆฒ", + "description": "man: bald", + "category": "People & Body", + "aliases": [ + "bald_man" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉ", + "description": "woman", + "category": "People & Body", + "aliases": [ + "woman" + ], + "tags": [ + "girls" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿฆฐ", + "description": "woman: red hair", + "category": "People & Body", + "aliases": [ + "red_haired_woman" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€๐Ÿฆฐ", + "description": "person: red hair", + "category": "People & Body", + "aliases": [ + "person_red_hair" + ], + "tags": [ + + ], + "unicode_version": "12.1", + "ios_version": "13.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿฆฑ", + "description": "woman: curly hair", + "category": "People & Body", + "aliases": [ + "curly_haired_woman" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€๐Ÿฆฑ", + "description": "person: curly hair", + "category": "People & Body", + "aliases": [ + "person_curly_hair" + ], + "tags": [ + + ], + "unicode_version": "12.1", + "ios_version": "13.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿฆณ", + "description": "woman: white hair", + "category": "People & Body", + "aliases": [ + "white_haired_woman" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€๐Ÿฆณ", + "description": "person: white hair", + "category": "People & Body", + "aliases": [ + "person_white_hair" + ], + "tags": [ + + ], + "unicode_version": "12.1", + "ios_version": "13.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿฆฒ", + "description": "woman: bald", + "category": "People & Body", + "aliases": [ + "bald_woman" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€๐Ÿฆฒ", + "description": "person: bald", + "category": "People & Body", + "aliases": [ + "person_bald" + ], + "tags": [ + + ], + "unicode_version": "12.1", + "ios_version": "13.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฑโ€โ™€๏ธ", + "description": "woman: blond hair", + "category": "People & Body", + "aliases": [ + "blond_haired_woman", + "blonde_woman" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฑโ€โ™‚๏ธ", + "description": "man: blond hair", + "category": "People & Body", + "aliases": [ + "blond_haired_man" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿง“", + "description": "older person", + "category": "People & Body", + "aliases": [ + "older_adult" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ด", + "description": "old man", + "category": "People & Body", + "aliases": [ + "older_man" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ต", + "description": "old woman", + "category": "People & Body", + "aliases": [ + "older_woman" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ™", + "description": "person frowning", + "category": "People & Body", + "aliases": [ + "frowning_person" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ™โ€โ™‚๏ธ", + "description": "man frowning", + "category": "People & Body", + "aliases": [ + "frowning_man" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ™โ€โ™€๏ธ", + "description": "woman frowning", + "category": "People & Body", + "aliases": [ + "frowning_woman" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ™Ž", + "description": "person pouting", + "category": "People & Body", + "aliases": [ + "pouting_face" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ™Žโ€โ™‚๏ธ", + "description": "man pouting", + "category": "People & Body", + "aliases": [ + "pouting_man" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ™Žโ€โ™€๏ธ", + "description": "woman pouting", + "category": "People & Body", + "aliases": [ + "pouting_woman" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ™…", + "description": "person gesturing NO", + "category": "People & Body", + "aliases": [ + "no_good" + ], + "tags": [ + "stop", + "halt", + "denied" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ™…โ€โ™‚๏ธ", + "description": "man gesturing NO", + "category": "People & Body", + "aliases": [ + "no_good_man", + "ng_man" + ], + "tags": [ + "stop", + "halt", + "denied" + ], + "unicode_version": "6.0", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ™…โ€โ™€๏ธ", + "description": "woman gesturing NO", + "category": "People & Body", + "aliases": [ + "no_good_woman", + "ng_woman" + ], + "tags": [ + "stop", + "halt", + "denied" + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ™†", + "description": "person gesturing OK", + "category": "People & Body", + "aliases": [ + "ok_person" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ™†โ€โ™‚๏ธ", + "description": "man gesturing OK", + "category": "People & Body", + "aliases": [ + "ok_man" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ™†โ€โ™€๏ธ", + "description": "woman gesturing OK", + "category": "People & Body", + "aliases": [ + "ok_woman" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ’", + "description": "person tipping hand", + "category": "People & Body", + "aliases": [ + "tipping_hand_person", + "information_desk_person" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ’โ€โ™‚๏ธ", + "description": "man tipping hand", + "category": "People & Body", + "aliases": [ + "tipping_hand_man", + "sassy_man" + ], + "tags": [ + "information" + ], + "unicode_version": "6.0", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ’โ€โ™€๏ธ", + "description": "woman tipping hand", + "category": "People & Body", + "aliases": [ + "tipping_hand_woman", + "sassy_woman" + ], + "tags": [ + "information" + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ™‹", + "description": "person raising hand", + "category": "People & Body", + "aliases": [ + "raising_hand" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ™‹โ€โ™‚๏ธ", + "description": "man raising hand", + "category": "People & Body", + "aliases": [ + "raising_hand_man" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ™‹โ€โ™€๏ธ", + "description": "woman raising hand", + "category": "People & Body", + "aliases": [ + "raising_hand_woman" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿง", + "description": "deaf person", + "category": "People & Body", + "aliases": [ + "deaf_person" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿงโ€โ™‚๏ธ", + "description": "deaf man", + "category": "People & Body", + "aliases": [ + "deaf_man" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿงโ€โ™€๏ธ", + "description": "deaf woman", + "category": "People & Body", + "aliases": [ + "deaf_woman" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ™‡", + "description": "person bowing", + "category": "People & Body", + "aliases": [ + "bow" + ], + "tags": [ + "respect", + "thanks" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ™‡โ€โ™‚๏ธ", + "description": "man bowing", + "category": "People & Body", + "aliases": [ + "bowing_man" + ], + "tags": [ + "respect", + "thanks" + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ™‡โ€โ™€๏ธ", + "description": "woman bowing", + "category": "People & Body", + "aliases": [ + "bowing_woman" + ], + "tags": [ + "respect", + "thanks" + ], + "unicode_version": "6.0", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿคฆ", + "description": "person facepalming", + "category": "People & Body", + "aliases": [ + "facepalm" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿคฆโ€โ™‚๏ธ", + "description": "man facepalming", + "category": "People & Body", + "aliases": [ + "man_facepalming" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿคฆโ€โ™€๏ธ", + "description": "woman facepalming", + "category": "People & Body", + "aliases": [ + "woman_facepalming" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿคท", + "description": "person shrugging", + "category": "People & Body", + "aliases": [ + "shrug" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿคทโ€โ™‚๏ธ", + "description": "man shrugging", + "category": "People & Body", + "aliases": [ + "man_shrugging" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿคทโ€โ™€๏ธ", + "description": "woman shrugging", + "category": "People & Body", + "aliases": [ + "woman_shrugging" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€โš•๏ธ", + "description": "health worker", + "category": "People & Body", + "aliases": [ + "health_worker" + ], + "tags": [ + + ], + "unicode_version": "12.1", + "ios_version": "13.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€โš•๏ธ", + "description": "man health worker", + "category": "People & Body", + "aliases": [ + "man_health_worker" + ], + "tags": [ + "doctor", + "nurse" + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€โš•๏ธ", + "description": "woman health worker", + "category": "People & Body", + "aliases": [ + "woman_health_worker" + ], + "tags": [ + "doctor", + "nurse" + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€๐ŸŽ“", + "description": "student", + "category": "People & Body", + "aliases": [ + "student" + ], + "tags": [ + + ], + "unicode_version": "12.1", + "ios_version": "13.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€๐ŸŽ“", + "description": "man student", + "category": "People & Body", + "aliases": [ + "man_student" + ], + "tags": [ + "graduation" + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€๐ŸŽ“", + "description": "woman student", + "category": "People & Body", + "aliases": [ + "woman_student" + ], + "tags": [ + "graduation" + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€๐Ÿซ", + "description": "teacher", + "category": "People & Body", + "aliases": [ + "teacher" + ], + "tags": [ + + ], + "unicode_version": "12.1", + "ios_version": "13.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿซ", + "description": "man teacher", + "category": "People & Body", + "aliases": [ + "man_teacher" + ], + "tags": [ + "school", + "professor" + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿซ", + "description": "woman teacher", + "category": "People & Body", + "aliases": [ + "woman_teacher" + ], + "tags": [ + "school", + "professor" + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€โš–๏ธ", + "description": "judge", + "category": "People & Body", + "aliases": [ + "judge" + ], + "tags": [ + + ], + "unicode_version": "12.1", + "ios_version": "13.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€โš–๏ธ", + "description": "man judge", + "category": "People & Body", + "aliases": [ + "man_judge" + ], + "tags": [ + "justice" + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€โš–๏ธ", + "description": "woman judge", + "category": "People & Body", + "aliases": [ + "woman_judge" + ], + "tags": [ + "justice" + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€๐ŸŒพ", + "description": "farmer", + "category": "People & Body", + "aliases": [ + "farmer" + ], + "tags": [ + + ], + "unicode_version": "12.1", + "ios_version": "13.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€๐ŸŒพ", + "description": "man farmer", + "category": "People & Body", + "aliases": [ + "man_farmer" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€๐ŸŒพ", + "description": "woman farmer", + "category": "People & Body", + "aliases": [ + "woman_farmer" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€๐Ÿณ", + "description": "cook", + "category": "People & Body", + "aliases": [ + "cook" + ], + "tags": [ + + ], + "unicode_version": "12.1", + "ios_version": "13.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿณ", + "description": "man cook", + "category": "People & Body", + "aliases": [ + "man_cook" + ], + "tags": [ + "chef" + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿณ", + "description": "woman cook", + "category": "People & Body", + "aliases": [ + "woman_cook" + ], + "tags": [ + "chef" + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€๐Ÿ”ง", + "description": "mechanic", + "category": "People & Body", + "aliases": [ + "mechanic" + ], + "tags": [ + + ], + "unicode_version": "12.1", + "ios_version": "13.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿ”ง", + "description": "man mechanic", + "category": "People & Body", + "aliases": [ + "man_mechanic" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿ”ง", + "description": "woman mechanic", + "category": "People & Body", + "aliases": [ + "woman_mechanic" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€๐Ÿญ", + "description": "factory worker", + "category": "People & Body", + "aliases": [ + "factory_worker" + ], + "tags": [ + + ], + "unicode_version": "12.1", + "ios_version": "13.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿญ", + "description": "man factory worker", + "category": "People & Body", + "aliases": [ + "man_factory_worker" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿญ", + "description": "woman factory worker", + "category": "People & Body", + "aliases": [ + "woman_factory_worker" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€๐Ÿ’ผ", + "description": "office worker", + "category": "People & Body", + "aliases": [ + "office_worker" + ], + "tags": [ + + ], + "unicode_version": "12.1", + "ios_version": "13.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿ’ผ", + "description": "man office worker", + "category": "People & Body", + "aliases": [ + "man_office_worker" + ], + "tags": [ + "business" + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿ’ผ", + "description": "woman office worker", + "category": "People & Body", + "aliases": [ + "woman_office_worker" + ], + "tags": [ + "business" + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€๐Ÿ”ฌ", + "description": "scientist", + "category": "People & Body", + "aliases": [ + "scientist" + ], + "tags": [ + + ], + "unicode_version": "12.1", + "ios_version": "13.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿ”ฌ", + "description": "man scientist", + "category": "People & Body", + "aliases": [ + "man_scientist" + ], + "tags": [ + "research" + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿ”ฌ", + "description": "woman scientist", + "category": "People & Body", + "aliases": [ + "woman_scientist" + ], + "tags": [ + "research" + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€๐Ÿ’ป", + "description": "technologist", + "category": "People & Body", + "aliases": [ + "technologist" + ], + "tags": [ + + ], + "unicode_version": "12.1", + "ios_version": "13.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿ’ป", + "description": "man technologist", + "category": "People & Body", + "aliases": [ + "man_technologist" + ], + "tags": [ + "coder" + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿ’ป", + "description": "woman technologist", + "category": "People & Body", + "aliases": [ + "woman_technologist" + ], + "tags": [ + "coder" + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€๐ŸŽค", + "description": "singer", + "category": "People & Body", + "aliases": [ + "singer" + ], + "tags": [ + + ], + "unicode_version": "12.1", + "ios_version": "13.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€๐ŸŽค", + "description": "man singer", + "category": "People & Body", + "aliases": [ + "man_singer" + ], + "tags": [ + "rockstar" + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€๐ŸŽค", + "description": "woman singer", + "category": "People & Body", + "aliases": [ + "woman_singer" + ], + "tags": [ + "rockstar" + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€๐ŸŽจ", + "description": "artist", + "category": "People & Body", + "aliases": [ + "artist" + ], + "tags": [ + + ], + "unicode_version": "12.1", + "ios_version": "13.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€๐ŸŽจ", + "description": "man artist", + "category": "People & Body", + "aliases": [ + "man_artist" + ], + "tags": [ + "painter" + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€๐ŸŽจ", + "description": "woman artist", + "category": "People & Body", + "aliases": [ + "woman_artist" + ], + "tags": [ + "painter" + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€โœˆ๏ธ", + "description": "pilot", + "category": "People & Body", + "aliases": [ + "pilot" + ], + "tags": [ + + ], + "unicode_version": "12.1", + "ios_version": "13.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€โœˆ๏ธ", + "description": "man pilot", + "category": "People & Body", + "aliases": [ + "man_pilot" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€โœˆ๏ธ", + "description": "woman pilot", + "category": "People & Body", + "aliases": [ + "woman_pilot" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€๐Ÿš€", + "description": "astronaut", + "category": "People & Body", + "aliases": [ + "astronaut" + ], + "tags": [ + + ], + "unicode_version": "12.1", + "ios_version": "13.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿš€", + "description": "man astronaut", + "category": "People & Body", + "aliases": [ + "man_astronaut" + ], + "tags": [ + "space" + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿš€", + "description": "woman astronaut", + "category": "People & Body", + "aliases": [ + "woman_astronaut" + ], + "tags": [ + "space" + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€๐Ÿš’", + "description": "firefighter", + "category": "People & Body", + "aliases": [ + "firefighter" + ], + "tags": [ + + ], + "unicode_version": "12.1", + "ios_version": "13.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿš’", + "description": "man firefighter", + "category": "People & Body", + "aliases": [ + "man_firefighter" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿš’", + "description": "woman firefighter", + "category": "People & Body", + "aliases": [ + "woman_firefighter" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฎ", + "description": "police officer", + "category": "People & Body", + "aliases": [ + "police_officer", + "cop" + ], + "tags": [ + "law" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฎโ€โ™‚๏ธ", + "description": "man police officer", + "category": "People & Body", + "aliases": [ + "policeman" + ], + "tags": [ + "law", + "cop" + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฎโ€โ™€๏ธ", + "description": "woman police officer", + "category": "People & Body", + "aliases": [ + "policewoman" + ], + "tags": [ + "law", + "cop" + ], + "unicode_version": "6.0", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ•ต๏ธ", + "description": "detective", + "category": "People & Body", + "aliases": [ + "detective" + ], + "tags": [ + "sleuth" + ], + "unicode_version": "7.0", + "ios_version": "9.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ•ต๏ธโ€โ™‚๏ธ", + "description": "man detective", + "category": "People & Body", + "aliases": [ + "male_detective" + ], + "tags": [ + "sleuth" + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ•ต๏ธโ€โ™€๏ธ", + "description": "woman detective", + "category": "People & Body", + "aliases": [ + "female_detective" + ], + "tags": [ + "sleuth" + ], + "unicode_version": "6.0", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ’‚", + "description": "guard", + "category": "People & Body", + "aliases": [ + "guard" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ’‚โ€โ™‚๏ธ", + "description": "man guard", + "category": "People & Body", + "aliases": [ + "guardsman" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ’‚โ€โ™€๏ธ", + "description": "woman guard", + "category": "People & Body", + "aliases": [ + "guardswoman" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿฅท", + "description": "ninja", + "category": "People & Body", + "aliases": [ + "ninja" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ท", + "description": "construction worker", + "category": "People & Body", + "aliases": [ + "construction_worker" + ], + "tags": [ + "helmet" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ทโ€โ™‚๏ธ", + "description": "man construction worker", + "category": "People & Body", + "aliases": [ + "construction_worker_man" + ], + "tags": [ + "helmet" + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ทโ€โ™€๏ธ", + "description": "woman construction worker", + "category": "People & Body", + "aliases": [ + "construction_worker_woman" + ], + "tags": [ + "helmet" + ], + "unicode_version": "6.0", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿซ…", + "description": "person with crown", + "category": "People & Body", + "aliases": [ + "person_with_crown" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4", + "skin_tones": true + }, + { + "emoji": "๐Ÿคด", + "description": "prince", + "category": "People & Body", + "aliases": [ + "prince" + ], + "tags": [ + "crown", + "royal" + ], + "unicode_version": "9.0", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ธ", + "description": "princess", + "category": "People & Body", + "aliases": [ + "princess" + ], + "tags": [ + "crown", + "royal" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ณ", + "description": "person wearing turban", + "category": "People & Body", + "aliases": [ + "person_with_turban" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ณโ€โ™‚๏ธ", + "description": "man wearing turban", + "category": "People & Body", + "aliases": [ + "man_with_turban" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ณโ€โ™€๏ธ", + "description": "woman wearing turban", + "category": "People & Body", + "aliases": [ + "woman_with_turban" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฒ", + "description": "person with skullcap", + "category": "People & Body", + "aliases": [ + "man_with_gua_pi_mao" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿง•", + "description": "woman with headscarf", + "category": "People & Body", + "aliases": [ + "woman_with_headscarf" + ], + "tags": [ + "hijab" + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿคต", + "description": "person in tuxedo", + "category": "People & Body", + "aliases": [ + "person_in_tuxedo" + ], + "tags": [ + "groom", + "marriage", + "wedding" + ], + "unicode_version": "9.0", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿคตโ€โ™‚๏ธ", + "description": "man in tuxedo", + "category": "People & Body", + "aliases": [ + "man_in_tuxedo" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿคตโ€โ™€๏ธ", + "description": "woman in tuxedo", + "category": "People & Body", + "aliases": [ + "woman_in_tuxedo" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฐ", + "description": "person with veil", + "category": "People & Body", + "aliases": [ + "person_with_veil" + ], + "tags": [ + "marriage", + "wedding" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฐโ€โ™‚๏ธ", + "description": "man with veil", + "category": "People & Body", + "aliases": [ + "man_with_veil" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฐโ€โ™€๏ธ", + "description": "woman with veil", + "category": "People & Body", + "aliases": [ + "woman_with_veil", + "bride_with_veil" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿคฐ", + "description": "pregnant woman", + "category": "People & Body", + "aliases": [ + "pregnant_woman" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿซƒ", + "description": "pregnant man", + "category": "People & Body", + "aliases": [ + "pregnant_man" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4", + "skin_tones": true + }, + { + "emoji": "๐Ÿซ„", + "description": "pregnant person", + "category": "People & Body", + "aliases": [ + "pregnant_person" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4", + "skin_tones": true + }, + { + "emoji": "๐Ÿคฑ", + "description": "breast-feeding", + "category": "People & Body", + "aliases": [ + "breast_feeding" + ], + "tags": [ + "nursing" + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿผ", + "description": "woman feeding baby", + "category": "People & Body", + "aliases": [ + "woman_feeding_baby" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿผ", + "description": "man feeding baby", + "category": "People & Body", + "aliases": [ + "man_feeding_baby" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€๐Ÿผ", + "description": "person feeding baby", + "category": "People & Body", + "aliases": [ + "person_feeding_baby" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ผ", + "description": "baby angel", + "category": "People & Body", + "aliases": [ + "angel" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐ŸŽ…", + "description": "Santa Claus", + "category": "People & Body", + "aliases": [ + "santa" + ], + "tags": [ + "christmas" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿคถ", + "description": "Mrs. Claus", + "category": "People & Body", + "aliases": [ + "mrs_claus" + ], + "tags": [ + "santa" + ], + "unicode_version": "9.0", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€๐ŸŽ„", + "description": "mx claus", + "category": "People & Body", + "aliases": [ + "mx_claus" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿฆธ", + "description": "superhero", + "category": "People & Body", + "aliases": [ + "superhero" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿฆธโ€โ™‚๏ธ", + "description": "man superhero", + "category": "People & Body", + "aliases": [ + "superhero_man" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿฆธโ€โ™€๏ธ", + "description": "woman superhero", + "category": "People & Body", + "aliases": [ + "superhero_woman" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿฆน", + "description": "supervillain", + "category": "People & Body", + "aliases": [ + "supervillain" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿฆนโ€โ™‚๏ธ", + "description": "man supervillain", + "category": "People & Body", + "aliases": [ + "supervillain_man" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿฆนโ€โ™€๏ธ", + "description": "woman supervillain", + "category": "People & Body", + "aliases": [ + "supervillain_woman" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿง™", + "description": "mage", + "category": "People & Body", + "aliases": [ + "mage" + ], + "tags": [ + "wizard" + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿง™โ€โ™‚๏ธ", + "description": "man mage", + "category": "People & Body", + "aliases": [ + "mage_man" + ], + "tags": [ + "wizard" + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿง™โ€โ™€๏ธ", + "description": "woman mage", + "category": "People & Body", + "aliases": [ + "mage_woman" + ], + "tags": [ + "wizard" + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿงš", + "description": "fairy", + "category": "People & Body", + "aliases": [ + "fairy" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿงšโ€โ™‚๏ธ", + "description": "man fairy", + "category": "People & Body", + "aliases": [ + "fairy_man" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿงšโ€โ™€๏ธ", + "description": "woman fairy", + "category": "People & Body", + "aliases": [ + "fairy_woman" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿง›", + "description": "vampire", + "category": "People & Body", + "aliases": [ + "vampire" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿง›โ€โ™‚๏ธ", + "description": "man vampire", + "category": "People & Body", + "aliases": [ + "vampire_man" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿง›โ€โ™€๏ธ", + "description": "woman vampire", + "category": "People & Body", + "aliases": [ + "vampire_woman" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿงœ", + "description": "merperson", + "category": "People & Body", + "aliases": [ + "merperson" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿงœโ€โ™‚๏ธ", + "description": "merman", + "category": "People & Body", + "aliases": [ + "merman" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿงœโ€โ™€๏ธ", + "description": "mermaid", + "category": "People & Body", + "aliases": [ + "mermaid" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿง", + "description": "elf", + "category": "People & Body", + "aliases": [ + "elf" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿงโ€โ™‚๏ธ", + "description": "man elf", + "category": "People & Body", + "aliases": [ + "elf_man" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿงโ€โ™€๏ธ", + "description": "woman elf", + "category": "People & Body", + "aliases": [ + "elf_woman" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿงž", + "description": "genie", + "category": "People & Body", + "aliases": [ + "genie" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿงžโ€โ™‚๏ธ", + "description": "man genie", + "category": "People & Body", + "aliases": [ + "genie_man" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿงžโ€โ™€๏ธ", + "description": "woman genie", + "category": "People & Body", + "aliases": [ + "genie_woman" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐ŸงŸ", + "description": "zombie", + "category": "People & Body", + "aliases": [ + "zombie" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐ŸงŸโ€โ™‚๏ธ", + "description": "man zombie", + "category": "People & Body", + "aliases": [ + "zombie_man" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐ŸงŸโ€โ™€๏ธ", + "description": "woman zombie", + "category": "People & Body", + "aliases": [ + "zombie_woman" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐ŸงŒ", + "description": "troll", + "category": "People & Body", + "aliases": [ + "troll" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐Ÿ’†", + "description": "person getting massage", + "category": "People & Body", + "aliases": [ + "massage" + ], + "tags": [ + "spa" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ’†โ€โ™‚๏ธ", + "description": "man getting massage", + "category": "People & Body", + "aliases": [ + "massage_man" + ], + "tags": [ + "spa" + ], + "unicode_version": "6.0", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ’†โ€โ™€๏ธ", + "description": "woman getting massage", + "category": "People & Body", + "aliases": [ + "massage_woman" + ], + "tags": [ + "spa" + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ’‡", + "description": "person getting haircut", + "category": "People & Body", + "aliases": [ + "haircut" + ], + "tags": [ + "beauty" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ’‡โ€โ™‚๏ธ", + "description": "man getting haircut", + "category": "People & Body", + "aliases": [ + "haircut_man" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ’‡โ€โ™€๏ธ", + "description": "woman getting haircut", + "category": "People & Body", + "aliases": [ + "haircut_woman" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿšถ", + "description": "person walking", + "category": "People & Body", + "aliases": [ + "walking" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿšถโ€โ™‚๏ธ", + "description": "man walking", + "category": "People & Body", + "aliases": [ + "walking_man" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿšถโ€โ™€๏ธ", + "description": "woman walking", + "category": "People & Body", + "aliases": [ + "walking_woman" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿง", + "description": "person standing", + "category": "People & Body", + "aliases": [ + "standing_person" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿงโ€โ™‚๏ธ", + "description": "man standing", + "category": "People & Body", + "aliases": [ + "standing_man" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿงโ€โ™€๏ธ", + "description": "woman standing", + "category": "People & Body", + "aliases": [ + "standing_woman" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0", + "skin_tones": true + }, + { + "emoji": "๐ŸงŽ", + "description": "person kneeling", + "category": "People & Body", + "aliases": [ + "kneeling_person" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0", + "skin_tones": true + }, + { + "emoji": "๐ŸงŽโ€โ™‚๏ธ", + "description": "man kneeling", + "category": "People & Body", + "aliases": [ + "kneeling_man" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0", + "skin_tones": true + }, + { + "emoji": "๐ŸงŽโ€โ™€๏ธ", + "description": "woman kneeling", + "category": "People & Body", + "aliases": [ + "kneeling_woman" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€๐Ÿฆฏ", + "description": "person with white cane", + "category": "People & Body", + "aliases": [ + "person_with_probing_cane" + ], + "tags": [ + + ], + "unicode_version": "12.1", + "ios_version": "13.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿฆฏ", + "description": "man with white cane", + "category": "People & Body", + "aliases": [ + "man_with_probing_cane" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿฆฏ", + "description": "woman with white cane", + "category": "People & Body", + "aliases": [ + "woman_with_probing_cane" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€๐Ÿฆผ", + "description": "person in motorized wheelchair", + "category": "People & Body", + "aliases": [ + "person_in_motorized_wheelchair" + ], + "tags": [ + + ], + "unicode_version": "12.1", + "ios_version": "13.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿฆผ", + "description": "man in motorized wheelchair", + "category": "People & Body", + "aliases": [ + "man_in_motorized_wheelchair" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿฆผ", + "description": "woman in motorized wheelchair", + "category": "People & Body", + "aliases": [ + "woman_in_motorized_wheelchair" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€๐Ÿฆฝ", + "description": "person in manual wheelchair", + "category": "People & Body", + "aliases": [ + "person_in_manual_wheelchair" + ], + "tags": [ + + ], + "unicode_version": "12.1", + "ios_version": "13.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿฆฝ", + "description": "man in manual wheelchair", + "category": "People & Body", + "aliases": [ + "man_in_manual_wheelchair" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿฆฝ", + "description": "woman in manual wheelchair", + "category": "People & Body", + "aliases": [ + "woman_in_manual_wheelchair" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿƒ", + "description": "person running", + "category": "People & Body", + "aliases": [ + "runner", + "running" + ], + "tags": [ + "exercise", + "workout", + "marathon" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿƒโ€โ™‚๏ธ", + "description": "man running", + "category": "People & Body", + "aliases": [ + "running_man" + ], + "tags": [ + "exercise", + "workout", + "marathon" + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿƒโ€โ™€๏ธ", + "description": "woman running", + "category": "People & Body", + "aliases": [ + "running_woman" + ], + "tags": [ + "exercise", + "workout", + "marathon" + ], + "unicode_version": "6.0", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ’ƒ", + "description": "woman dancing", + "category": "People & Body", + "aliases": [ + "woman_dancing", + "dancer" + ], + "tags": [ + "dress" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ•บ", + "description": "man dancing", + "category": "People & Body", + "aliases": [ + "man_dancing" + ], + "tags": [ + "dancer" + ], + "unicode_version": "9.0", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿ•ด๏ธ", + "description": "person in suit levitating", + "category": "People & Body", + "aliases": [ + "business_suit_levitating" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฏ", + "description": "people with bunny ears", + "category": "People & Body", + "aliases": [ + "dancers" + ], + "tags": [ + "bunny" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘ฏโ€โ™‚๏ธ", + "description": "men with bunny ears", + "category": "People & Body", + "aliases": [ + "dancing_men" + ], + "tags": [ + "bunny" + ], + "unicode_version": "6.0", + "ios_version": "10.0" + }, + { + "emoji": "๐Ÿ‘ฏโ€โ™€๏ธ", + "description": "women with bunny ears", + "category": "People & Body", + "aliases": [ + "dancing_women" + ], + "tags": [ + "bunny" + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿง–", + "description": "person in steamy room", + "category": "People & Body", + "aliases": [ + "sauna_person" + ], + "tags": [ + "steamy" + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿง–โ€โ™‚๏ธ", + "description": "man in steamy room", + "category": "People & Body", + "aliases": [ + "sauna_man" + ], + "tags": [ + "steamy" + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿง–โ€โ™€๏ธ", + "description": "woman in steamy room", + "category": "People & Body", + "aliases": [ + "sauna_woman" + ], + "tags": [ + "steamy" + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿง—", + "description": "person climbing", + "category": "People & Body", + "aliases": [ + "climbing" + ], + "tags": [ + "bouldering" + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿง—โ€โ™‚๏ธ", + "description": "man climbing", + "category": "People & Body", + "aliases": [ + "climbing_man" + ], + "tags": [ + "bouldering" + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿง—โ€โ™€๏ธ", + "description": "woman climbing", + "category": "People & Body", + "aliases": [ + "climbing_woman" + ], + "tags": [ + "bouldering" + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿคบ", + "description": "person fencing", + "category": "People & Body", + "aliases": [ + "person_fencing" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿ‡", + "description": "horse racing", + "category": "People & Body", + "aliases": [ + "horse_racing" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "โ›ท๏ธ", + "description": "skier", + "category": "People & Body", + "aliases": [ + "skier" + ], + "tags": [ + + ], + "unicode_version": "5.2", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ‚", + "description": "snowboarder", + "category": "People & Body", + "aliases": [ + "snowboarder" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐ŸŒ๏ธ", + "description": "person golfing", + "category": "People & Body", + "aliases": [ + "golfing" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1", + "skin_tones": true + }, + { + "emoji": "๐ŸŒ๏ธโ€โ™‚๏ธ", + "description": "man golfing", + "category": "People & Body", + "aliases": [ + "golfing_man" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐ŸŒ๏ธโ€โ™€๏ธ", + "description": "woman golfing", + "category": "People & Body", + "aliases": [ + "golfing_woman" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ„", + "description": "person surfing", + "category": "People & Body", + "aliases": [ + "surfer" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ„โ€โ™‚๏ธ", + "description": "man surfing", + "category": "People & Body", + "aliases": [ + "surfing_man" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ„โ€โ™€๏ธ", + "description": "woman surfing", + "category": "People & Body", + "aliases": [ + "surfing_woman" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿšฃ", + "description": "person rowing boat", + "category": "People & Body", + "aliases": [ + "rowboat" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿšฃโ€โ™‚๏ธ", + "description": "man rowing boat", + "category": "People & Body", + "aliases": [ + "rowing_man" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿšฃโ€โ™€๏ธ", + "description": "woman rowing boat", + "category": "People & Body", + "aliases": [ + "rowing_woman" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "๐ŸŠ", + "description": "person swimming", + "category": "People & Body", + "aliases": [ + "swimmer" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐ŸŠโ€โ™‚๏ธ", + "description": "man swimming", + "category": "People & Body", + "aliases": [ + "swimming_man" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐ŸŠโ€โ™€๏ธ", + "description": "woman swimming", + "category": "People & Body", + "aliases": [ + "swimming_woman" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "โ›น๏ธ", + "description": "person bouncing ball", + "category": "People & Body", + "aliases": [ + "bouncing_ball_person" + ], + "tags": [ + "basketball" + ], + "unicode_version": "5.2", + "ios_version": "9.1", + "skin_tones": true + }, + { + "emoji": "โ›น๏ธโ€โ™‚๏ธ", + "description": "man bouncing ball", + "category": "People & Body", + "aliases": [ + "bouncing_ball_man", + "basketball_man" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "โ›น๏ธโ€โ™€๏ธ", + "description": "woman bouncing ball", + "category": "People & Body", + "aliases": [ + "bouncing_ball_woman", + "basketball_woman" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‹๏ธ", + "description": "person lifting weights", + "category": "People & Body", + "aliases": [ + "weight_lifting" + ], + "tags": [ + "gym", + "workout" + ], + "unicode_version": "7.0", + "ios_version": "9.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‹๏ธโ€โ™‚๏ธ", + "description": "man lifting weights", + "category": "People & Body", + "aliases": [ + "weight_lifting_man" + ], + "tags": [ + "gym", + "workout" + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‹๏ธโ€โ™€๏ธ", + "description": "woman lifting weights", + "category": "People & Body", + "aliases": [ + "weight_lifting_woman" + ], + "tags": [ + "gym", + "workout" + ], + "unicode_version": "6.0", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿšด", + "description": "person biking", + "category": "People & Body", + "aliases": [ + "bicyclist" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿšดโ€โ™‚๏ธ", + "description": "man biking", + "category": "People & Body", + "aliases": [ + "biking_man" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿšดโ€โ™€๏ธ", + "description": "woman biking", + "category": "People & Body", + "aliases": [ + "biking_woman" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿšต", + "description": "person mountain biking", + "category": "People & Body", + "aliases": [ + "mountain_bicyclist" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿšตโ€โ™‚๏ธ", + "description": "man mountain biking", + "category": "People & Body", + "aliases": [ + "mountain_biking_man" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿšตโ€โ™€๏ธ", + "description": "woman mountain biking", + "category": "People & Body", + "aliases": [ + "mountain_biking_woman" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "10.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿคธ", + "description": "person cartwheeling", + "category": "People & Body", + "aliases": [ + "cartwheeling" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿคธโ€โ™‚๏ธ", + "description": "man cartwheeling", + "category": "People & Body", + "aliases": [ + "man_cartwheeling" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿคธโ€โ™€๏ธ", + "description": "woman cartwheeling", + "category": "People & Body", + "aliases": [ + "woman_cartwheeling" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿคผ", + "description": "people wrestling", + "category": "People & Body", + "aliases": [ + "wrestling" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿคผโ€โ™‚๏ธ", + "description": "men wrestling", + "category": "People & Body", + "aliases": [ + "men_wrestling" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿคผโ€โ™€๏ธ", + "description": "women wrestling", + "category": "People & Body", + "aliases": [ + "women_wrestling" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿคฝ", + "description": "person playing water polo", + "category": "People & Body", + "aliases": [ + "water_polo" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿคฝโ€โ™‚๏ธ", + "description": "man playing water polo", + "category": "People & Body", + "aliases": [ + "man_playing_water_polo" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿคฝโ€โ™€๏ธ", + "description": "woman playing water polo", + "category": "People & Body", + "aliases": [ + "woman_playing_water_polo" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿคพ", + "description": "person playing handball", + "category": "People & Body", + "aliases": [ + "handball_person" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿคพโ€โ™‚๏ธ", + "description": "man playing handball", + "category": "People & Body", + "aliases": [ + "man_playing_handball" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿคพโ€โ™€๏ธ", + "description": "woman playing handball", + "category": "People & Body", + "aliases": [ + "woman_playing_handball" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿคน", + "description": "person juggling", + "category": "People & Body", + "aliases": [ + "juggling_person" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿคนโ€โ™‚๏ธ", + "description": "man juggling", + "category": "People & Body", + "aliases": [ + "man_juggling" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿคนโ€โ™€๏ธ", + "description": "woman juggling", + "category": "People & Body", + "aliases": [ + "woman_juggling" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2", + "skin_tones": true + }, + { + "emoji": "๐Ÿง˜", + "description": "person in lotus position", + "category": "People & Body", + "aliases": [ + "lotus_position" + ], + "tags": [ + "meditation" + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿง˜โ€โ™‚๏ธ", + "description": "man in lotus position", + "category": "People & Body", + "aliases": [ + "lotus_position_man" + ], + "tags": [ + "meditation" + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿง˜โ€โ™€๏ธ", + "description": "woman in lotus position", + "category": "People & Body", + "aliases": [ + "lotus_position_woman" + ], + "tags": [ + "meditation" + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ›€", + "description": "person taking bath", + "category": "People & Body", + "aliases": [ + "bath" + ], + "tags": [ + "shower" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ›Œ", + "description": "person in bed", + "category": "People & Body", + "aliases": [ + "sleeping_bed" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿง‘โ€๐Ÿคโ€๐Ÿง‘", + "description": "people holding hands", + "category": "People & Body", + "aliases": [ + "people_holding_hands" + ], + "tags": [ + "couple", + "date" + ], + "unicode_version": "12.0", + "ios_version": "13.0", + "skin_tones": false + }, + { + "emoji": "๐Ÿ‘ญ", + "description": "women holding hands", + "category": "People & Body", + "aliases": [ + "two_women_holding_hands" + ], + "tags": [ + "couple", + "date" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ซ", + "description": "woman and man holding hands", + "category": "People & Body", + "aliases": [ + "couple" + ], + "tags": [ + "date" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฌ", + "description": "men holding hands", + "category": "People & Body", + "aliases": [ + "two_men_holding_hands" + ], + "tags": [ + "couple", + "date" + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ’", + "description": "kiss", + "category": "People & Body", + "aliases": [ + "couplekiss" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ’‹โ€๐Ÿ‘จ", + "description": "kiss: woman, man", + "category": "People & Body", + "aliases": [ + "couplekiss_man_woman" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€โค๏ธโ€๐Ÿ’‹โ€๐Ÿ‘จ", + "description": "kiss: man, man", + "category": "People & Body", + "aliases": [ + "couplekiss_man_man" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ’‹โ€๐Ÿ‘ฉ", + "description": "kiss: woman, woman", + "category": "People & Body", + "aliases": [ + "couplekiss_woman_woman" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3", + "skin_tones": true + }, + { + "emoji": "๐Ÿ’‘", + "description": "couple with heart", + "category": "People & Body", + "aliases": [ + "couple_with_heart" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ‘จ", + "description": "couple with heart: woman, man", + "category": "People & Body", + "aliases": [ + "couple_with_heart_woman_man" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘จโ€โค๏ธโ€๐Ÿ‘จ", + "description": "couple with heart: man, man", + "category": "People & Body", + "aliases": [ + "couple_with_heart_man_man" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ‘ฉ", + "description": "couple with heart: woman, woman", + "category": "People & Body", + "aliases": [ + "couple_with_heart_woman_woman" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3", + "skin_tones": true + }, + { + "emoji": "๐Ÿ‘ช", + "description": "family", + "category": "People & Body", + "aliases": [ + "family" + ], + "tags": [ + "home", + "parents", + "child" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆ", + "description": "family: man, woman, boy", + "category": "People & Body", + "aliases": [ + "family_man_woman_boy" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ง", + "description": "family: man, woman, girl", + "category": "People & Body", + "aliases": [ + "family_man_woman_girl" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ", + "description": "family: man, woman, girl, boy", + "category": "People & Body", + "aliases": [ + "family_man_woman_girl_boy" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ", + "description": "family: man, woman, boy, boy", + "category": "People & Body", + "aliases": [ + "family_man_woman_boy_boy" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง", + "description": "family: man, woman, girl, girl", + "category": "People & Body", + "aliases": [ + "family_man_woman_girl_girl" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘ฆ", + "description": "family: man, man, boy", + "category": "People & Body", + "aliases": [ + "family_man_man_boy" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘ง", + "description": "family: man, man, girl", + "category": "People & Body", + "aliases": [ + "family_man_man_girl" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ฆ", + "description": "family: man, man, girl, boy", + "category": "People & Body", + "aliases": [ + "family_man_man_girl_boy" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ", + "description": "family: man, man, boy, boy", + "category": "People & Body", + "aliases": [ + "family_man_man_boy_boy" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง", + "description": "family: man, man, girl, girl", + "category": "People & Body", + "aliases": [ + "family_man_man_girl_girl" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆ", + "description": "family: woman, woman, boy", + "category": "People & Body", + "aliases": [ + "family_woman_woman_boy" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘ง", + "description": "family: woman, woman, girl", + "category": "People & Body", + "aliases": [ + "family_woman_woman_girl" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ", + "description": "family: woman, woman, girl, boy", + "category": "People & Body", + "aliases": [ + "family_woman_woman_girl_boy" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ", + "description": "family: woman, woman, boy, boy", + "category": "People & Body", + "aliases": [ + "family_woman_woman_boy_boy" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง", + "description": "family: woman, woman, girl, girl", + "category": "People & Body", + "aliases": [ + "family_woman_woman_girl_girl" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿ‘ฆ", + "description": "family: man, boy", + "category": "People & Body", + "aliases": [ + "family_man_boy" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "10.0" + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ", + "description": "family: man, boy, boy", + "category": "People & Body", + "aliases": [ + "family_man_boy_boy" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "10.0" + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿ‘ง", + "description": "family: man, girl", + "category": "People & Body", + "aliases": [ + "family_man_girl" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "10.0" + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ฆ", + "description": "family: man, girl, boy", + "category": "People & Body", + "aliases": [ + "family_man_girl_boy" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "10.0" + }, + { + "emoji": "๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง", + "description": "family: man, girl, girl", + "category": "People & Body", + "aliases": [ + "family_man_girl_girl" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "10.0" + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿ‘ฆ", + "description": "family: woman, boy", + "category": "People & Body", + "aliases": [ + "family_woman_boy" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "10.0" + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ", + "description": "family: woman, boy, boy", + "category": "People & Body", + "aliases": [ + "family_woman_boy_boy" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "10.0" + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿ‘ง", + "description": "family: woman, girl", + "category": "People & Body", + "aliases": [ + "family_woman_girl" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "10.0" + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ", + "description": "family: woman, girl, boy", + "category": "People & Body", + "aliases": [ + "family_woman_girl_boy" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "10.0" + }, + { + "emoji": "๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง", + "description": "family: woman, girl, girl", + "category": "People & Body", + "aliases": [ + "family_woman_girl_girl" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "10.0" + }, + { + "emoji": "๐Ÿ—ฃ๏ธ", + "description": "speaking head", + "category": "People & Body", + "aliases": [ + "speaking_head" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ‘ค", + "description": "bust in silhouette", + "category": "People & Body", + "aliases": [ + "bust_in_silhouette" + ], + "tags": [ + "user" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘ฅ", + "description": "busts in silhouette", + "category": "People & Body", + "aliases": [ + "busts_in_silhouette" + ], + "tags": [ + "users", + "group", + "team" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿซ‚", + "description": "people hugging", + "category": "People & Body", + "aliases": [ + "people_hugging" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿ‘ฃ", + "description": "footprints", + "category": "People & Body", + "aliases": [ + "footprints" + ], + "tags": [ + "feet", + "tracks" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿต", + "description": "monkey face", + "category": "Animals & Nature", + "aliases": [ + "monkey_face" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’", + "description": "monkey", + "category": "Animals & Nature", + "aliases": [ + "monkey" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฆ", + "description": "gorilla", + "category": "Animals & Nature", + "aliases": [ + "gorilla" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿฆง", + "description": "orangutan", + "category": "Animals & Nature", + "aliases": [ + "orangutan" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿถ", + "description": "dog face", + "category": "Animals & Nature", + "aliases": [ + "dog" + ], + "tags": [ + "pet" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•", + "description": "dog", + "category": "Animals & Nature", + "aliases": [ + "dog2" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฆฎ", + "description": "guide dog", + "category": "Animals & Nature", + "aliases": [ + "guide_dog" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿ•โ€๐Ÿฆบ", + "description": "service dog", + "category": "Animals & Nature", + "aliases": [ + "service_dog" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿฉ", + "description": "poodle", + "category": "Animals & Nature", + "aliases": [ + "poodle" + ], + "tags": [ + "dog" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿบ", + "description": "wolf", + "category": "Animals & Nature", + "aliases": [ + "wolf" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸฆŠ", + "description": "fox", + "category": "Animals & Nature", + "aliases": [ + "fox_face" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿฆ", + "description": "raccoon", + "category": "Animals & Nature", + "aliases": [ + "raccoon" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฑ", + "description": "cat face", + "category": "Animals & Nature", + "aliases": [ + "cat" + ], + "tags": [ + "pet" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿˆ", + "description": "cat", + "category": "Animals & Nature", + "aliases": [ + "cat2" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿˆโ€โฌ›", + "description": "black cat", + "category": "Animals & Nature", + "aliases": [ + "black_cat" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿฆ", + "description": "lion", + "category": "Animals & Nature", + "aliases": [ + "lion" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿฏ", + "description": "tiger face", + "category": "Animals & Nature", + "aliases": [ + "tiger" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ…", + "description": "tiger", + "category": "Animals & Nature", + "aliases": [ + "tiger2" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ†", + "description": "leopard", + "category": "Animals & Nature", + "aliases": [ + "leopard" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿด", + "description": "horse face", + "category": "Animals & Nature", + "aliases": [ + "horse" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽ", + "description": "horse", + "category": "Animals & Nature", + "aliases": [ + "racehorse" + ], + "tags": [ + "speed" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฆ„", + "description": "unicorn", + "category": "Animals & Nature", + "aliases": [ + "unicorn" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿฆ“", + "description": "zebra", + "category": "Animals & Nature", + "aliases": [ + "zebra" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐ŸฆŒ", + "description": "deer", + "category": "Animals & Nature", + "aliases": [ + "deer" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿฆฌ", + "description": "bison", + "category": "Animals & Nature", + "aliases": [ + "bison" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿฎ", + "description": "cow face", + "category": "Animals & Nature", + "aliases": [ + "cow" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‚", + "description": "ox", + "category": "Animals & Nature", + "aliases": [ + "ox" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿƒ", + "description": "water buffalo", + "category": "Animals & Nature", + "aliases": [ + "water_buffalo" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ„", + "description": "cow", + "category": "Animals & Nature", + "aliases": [ + "cow2" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿท", + "description": "pig face", + "category": "Animals & Nature", + "aliases": [ + "pig" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ–", + "description": "pig", + "category": "Animals & Nature", + "aliases": [ + "pig2" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ—", + "description": "boar", + "category": "Animals & Nature", + "aliases": [ + "boar" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฝ", + "description": "pig nose", + "category": "Animals & Nature", + "aliases": [ + "pig_nose" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ", + "description": "ram", + "category": "Animals & Nature", + "aliases": [ + "ram" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘", + "description": "ewe", + "category": "Animals & Nature", + "aliases": [ + "sheep" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ", + "description": "goat", + "category": "Animals & Nature", + "aliases": [ + "goat" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿช", + "description": "camel", + "category": "Animals & Nature", + "aliases": [ + "dromedary_camel" + ], + "tags": [ + "desert" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿซ", + "description": "two-hump camel", + "category": "Animals & Nature", + "aliases": [ + "camel" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฆ™", + "description": "llama", + "category": "Animals & Nature", + "aliases": [ + "llama" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฆ’", + "description": "giraffe", + "category": "Animals & Nature", + "aliases": [ + "giraffe" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ˜", + "description": "elephant", + "category": "Animals & Nature", + "aliases": [ + "elephant" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฆฃ", + "description": "mammoth", + "category": "Animals & Nature", + "aliases": [ + "mammoth" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿฆ", + "description": "rhinoceros", + "category": "Animals & Nature", + "aliases": [ + "rhinoceros" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿฆ›", + "description": "hippopotamus", + "category": "Animals & Nature", + "aliases": [ + "hippopotamus" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿญ", + "description": "mouse face", + "category": "Animals & Nature", + "aliases": [ + "mouse" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ", + "description": "mouse", + "category": "Animals & Nature", + "aliases": [ + "mouse2" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ€", + "description": "rat", + "category": "Animals & Nature", + "aliases": [ + "rat" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿน", + "description": "hamster", + "category": "Animals & Nature", + "aliases": [ + "hamster" + ], + "tags": [ + "pet" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฐ", + "description": "rabbit face", + "category": "Animals & Nature", + "aliases": [ + "rabbit" + ], + "tags": [ + "bunny" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‡", + "description": "rabbit", + "category": "Animals & Nature", + "aliases": [ + "rabbit2" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฟ๏ธ", + "description": "chipmunk", + "category": "Animals & Nature", + "aliases": [ + "chipmunk" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿฆซ", + "description": "beaver", + "category": "Animals & Nature", + "aliases": [ + "beaver" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿฆ”", + "description": "hedgehog", + "category": "Animals & Nature", + "aliases": [ + "hedgehog" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฆ‡", + "description": "bat", + "category": "Animals & Nature", + "aliases": [ + "bat" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿป", + "description": "bear", + "category": "Animals & Nature", + "aliases": [ + "bear" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿปโ€โ„๏ธ", + "description": "polar bear", + "category": "Animals & Nature", + "aliases": [ + "polar_bear" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿจ", + "description": "koala", + "category": "Animals & Nature", + "aliases": [ + "koala" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿผ", + "description": "panda", + "category": "Animals & Nature", + "aliases": [ + "panda_face" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฆฅ", + "description": "sloth", + "category": "Animals & Nature", + "aliases": [ + "sloth" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿฆฆ", + "description": "otter", + "category": "Animals & Nature", + "aliases": [ + "otter" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿฆจ", + "description": "skunk", + "category": "Animals & Nature", + "aliases": [ + "skunk" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿฆ˜", + "description": "kangaroo", + "category": "Animals & Nature", + "aliases": [ + "kangaroo" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฆก", + "description": "badger", + "category": "Animals & Nature", + "aliases": [ + "badger" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿพ", + "description": "paw prints", + "category": "Animals & Nature", + "aliases": [ + "feet", + "paw_prints" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฆƒ", + "description": "turkey", + "category": "Animals & Nature", + "aliases": [ + "turkey" + ], + "tags": [ + "thanksgiving" + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ”", + "description": "chicken", + "category": "Animals & Nature", + "aliases": [ + "chicken" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“", + "description": "rooster", + "category": "Animals & Nature", + "aliases": [ + "rooster" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฃ", + "description": "hatching chick", + "category": "Animals & Nature", + "aliases": [ + "hatching_chick" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿค", + "description": "baby chick", + "category": "Animals & Nature", + "aliases": [ + "baby_chick" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฅ", + "description": "front-facing baby chick", + "category": "Animals & Nature", + "aliases": [ + "hatched_chick" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฆ", + "description": "bird", + "category": "Animals & Nature", + "aliases": [ + "bird" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿง", + "description": "penguin", + "category": "Animals & Nature", + "aliases": [ + "penguin" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•Š๏ธ", + "description": "dove", + "category": "Animals & Nature", + "aliases": [ + "dove" + ], + "tags": [ + "peace" + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿฆ…", + "description": "eagle", + "category": "Animals & Nature", + "aliases": [ + "eagle" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿฆ†", + "description": "duck", + "category": "Animals & Nature", + "aliases": [ + "duck" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿฆข", + "description": "swan", + "category": "Animals & Nature", + "aliases": [ + "swan" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฆ‰", + "description": "owl", + "category": "Animals & Nature", + "aliases": [ + "owl" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿฆค", + "description": "dodo", + "category": "Animals & Nature", + "aliases": [ + "dodo" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿชถ", + "description": "feather", + "category": "Animals & Nature", + "aliases": [ + "feather" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿฆฉ", + "description": "flamingo", + "category": "Animals & Nature", + "aliases": [ + "flamingo" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿฆš", + "description": "peacock", + "category": "Animals & Nature", + "aliases": [ + "peacock" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฆœ", + "description": "parrot", + "category": "Animals & Nature", + "aliases": [ + "parrot" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿธ", + "description": "frog", + "category": "Animals & Nature", + "aliases": [ + "frog" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŠ", + "description": "crocodile", + "category": "Animals & Nature", + "aliases": [ + "crocodile" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿข", + "description": "turtle", + "category": "Animals & Nature", + "aliases": [ + "turtle" + ], + "tags": [ + "slow" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸฆŽ", + "description": "lizard", + "category": "Animals & Nature", + "aliases": [ + "lizard" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿ", + "description": "snake", + "category": "Animals & Nature", + "aliases": [ + "snake" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฒ", + "description": "dragon face", + "category": "Animals & Nature", + "aliases": [ + "dragon_face" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‰", + "description": "dragon", + "category": "Animals & Nature", + "aliases": [ + "dragon" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฆ•", + "description": "sauropod", + "category": "Animals & Nature", + "aliases": [ + "sauropod" + ], + "tags": [ + "dinosaur" + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฆ–", + "description": "T-Rex", + "category": "Animals & Nature", + "aliases": [ + "t-rex" + ], + "tags": [ + "dinosaur" + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿณ", + "description": "spouting whale", + "category": "Animals & Nature", + "aliases": [ + "whale" + ], + "tags": [ + "sea" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‹", + "description": "whale", + "category": "Animals & Nature", + "aliases": [ + "whale2" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฌ", + "description": "dolphin", + "category": "Animals & Nature", + "aliases": [ + "dolphin", + "flipper" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฆญ", + "description": "seal", + "category": "Animals & Nature", + "aliases": [ + "seal" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐ŸŸ", + "description": "fish", + "category": "Animals & Nature", + "aliases": [ + "fish" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ ", + "description": "tropical fish", + "category": "Animals & Nature", + "aliases": [ + "tropical_fish" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿก", + "description": "blowfish", + "category": "Animals & Nature", + "aliases": [ + "blowfish" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฆˆ", + "description": "shark", + "category": "Animals & Nature", + "aliases": [ + "shark" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿ™", + "description": "octopus", + "category": "Animals & Nature", + "aliases": [ + "octopus" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿš", + "description": "spiral shell", + "category": "Animals & Nature", + "aliases": [ + "shell" + ], + "tags": [ + "sea", + "beach" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿชธ", + "description": "coral", + "category": "Animals & Nature", + "aliases": [ + "coral" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐ŸŒ", + "description": "snail", + "category": "Animals & Nature", + "aliases": [ + "snail" + ], + "tags": [ + "slow" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฆ‹", + "description": "butterfly", + "category": "Animals & Nature", + "aliases": [ + "butterfly" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿ›", + "description": "bug", + "category": "Animals & Nature", + "aliases": [ + "bug" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿœ", + "description": "ant", + "category": "Animals & Nature", + "aliases": [ + "ant" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ", + "description": "honeybee", + "category": "Animals & Nature", + "aliases": [ + "bee", + "honeybee" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿชฒ", + "description": "beetle", + "category": "Animals & Nature", + "aliases": [ + "beetle" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿž", + "description": "lady beetle", + "category": "Animals & Nature", + "aliases": [ + "lady_beetle" + ], + "tags": [ + "bug" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฆ—", + "description": "cricket", + "category": "Animals & Nature", + "aliases": [ + "cricket" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿชณ", + "description": "cockroach", + "category": "Animals & Nature", + "aliases": [ + "cockroach" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿ•ท๏ธ", + "description": "spider", + "category": "Animals & Nature", + "aliases": [ + "spider" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ•ธ๏ธ", + "description": "spider web", + "category": "Animals & Nature", + "aliases": [ + "spider_web" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿฆ‚", + "description": "scorpion", + "category": "Animals & Nature", + "aliases": [ + "scorpion" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸฆŸ", + "description": "mosquito", + "category": "Animals & Nature", + "aliases": [ + "mosquito" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿชฐ", + "description": "fly", + "category": "Animals & Nature", + "aliases": [ + "fly" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿชฑ", + "description": "worm", + "category": "Animals & Nature", + "aliases": [ + "worm" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿฆ ", + "description": "microbe", + "category": "Animals & Nature", + "aliases": [ + "microbe" + ], + "tags": [ + "germ" + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ’", + "description": "bouquet", + "category": "Animals & Nature", + "aliases": [ + "bouquet" + ], + "tags": [ + "flowers" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒธ", + "description": "cherry blossom", + "category": "Animals & Nature", + "aliases": [ + "cherry_blossom" + ], + "tags": [ + "flower", + "spring" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’ฎ", + "description": "white flower", + "category": "Animals & Nature", + "aliases": [ + "white_flower" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿชท", + "description": "lotus", + "category": "Animals & Nature", + "aliases": [ + "lotus" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐Ÿต๏ธ", + "description": "rosette", + "category": "Animals & Nature", + "aliases": [ + "rosette" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŒน", + "description": "rose", + "category": "Animals & Nature", + "aliases": [ + "rose" + ], + "tags": [ + "flower" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฅ€", + "description": "wilted flower", + "category": "Animals & Nature", + "aliases": [ + "wilted_flower" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐ŸŒบ", + "description": "hibiscus", + "category": "Animals & Nature", + "aliases": [ + "hibiscus" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒป", + "description": "sunflower", + "category": "Animals & Nature", + "aliases": [ + "sunflower" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒผ", + "description": "blossom", + "category": "Animals & Nature", + "aliases": [ + "blossom" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒท", + "description": "tulip", + "category": "Animals & Nature", + "aliases": [ + "tulip" + ], + "tags": [ + "flower" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒฑ", + "description": "seedling", + "category": "Animals & Nature", + "aliases": [ + "seedling" + ], + "tags": [ + "plant" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿชด", + "description": "potted plant", + "category": "Animals & Nature", + "aliases": [ + "potted_plant" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐ŸŒฒ", + "description": "evergreen tree", + "category": "Animals & Nature", + "aliases": [ + "evergreen_tree" + ], + "tags": [ + "wood" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒณ", + "description": "deciduous tree", + "category": "Animals & Nature", + "aliases": [ + "deciduous_tree" + ], + "tags": [ + "wood" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒด", + "description": "palm tree", + "category": "Animals & Nature", + "aliases": [ + "palm_tree" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒต", + "description": "cactus", + "category": "Animals & Nature", + "aliases": [ + "cactus" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒพ", + "description": "sheaf of rice", + "category": "Animals & Nature", + "aliases": [ + "ear_of_rice" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒฟ", + "description": "herb", + "category": "Animals & Nature", + "aliases": [ + "herb" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โ˜˜๏ธ", + "description": "shamrock", + "category": "Animals & Nature", + "aliases": [ + "shamrock" + ], + "tags": [ + + ], + "unicode_version": "4.1", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ€", + "description": "four leaf clover", + "category": "Animals & Nature", + "aliases": [ + "four_leaf_clover" + ], + "tags": [ + "luck" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ", + "description": "maple leaf", + "category": "Animals & Nature", + "aliases": [ + "maple_leaf" + ], + "tags": [ + "canada" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‚", + "description": "fallen leaf", + "category": "Animals & Nature", + "aliases": [ + "fallen_leaf" + ], + "tags": [ + "autumn" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿƒ", + "description": "leaf fluttering in wind", + "category": "Animals & Nature", + "aliases": [ + "leaves" + ], + "tags": [ + "leaf" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿชน", + "description": "empty nest", + "category": "Animals & Nature", + "aliases": [ + "empty_nest" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐Ÿชบ", + "description": "nest with eggs", + "category": "Animals & Nature", + "aliases": [ + "nest_with_eggs" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐Ÿ‡", + "description": "grapes", + "category": "Food & Drink", + "aliases": [ + "grapes" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿˆ", + "description": "melon", + "category": "Food & Drink", + "aliases": [ + "melon" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‰", + "description": "watermelon", + "category": "Food & Drink", + "aliases": [ + "watermelon" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŠ", + "description": "tangerine", + "category": "Food & Drink", + "aliases": [ + "tangerine", + "orange", + "mandarin" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‹", + "description": "lemon", + "category": "Food & Drink", + "aliases": [ + "lemon" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒ", + "description": "banana", + "category": "Food & Drink", + "aliases": [ + "banana" + ], + "tags": [ + "fruit" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ", + "description": "pineapple", + "category": "Food & Drink", + "aliases": [ + "pineapple" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฅญ", + "description": "mango", + "category": "Food & Drink", + "aliases": [ + "mango" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐ŸŽ", + "description": "red apple", + "category": "Food & Drink", + "aliases": [ + "apple" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ", + "description": "green apple", + "category": "Food & Drink", + "aliases": [ + "green_apple" + ], + "tags": [ + "fruit" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ", + "description": "pear", + "category": "Food & Drink", + "aliases": [ + "pear" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘", + "description": "peach", + "category": "Food & Drink", + "aliases": [ + "peach" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’", + "description": "cherries", + "category": "Food & Drink", + "aliases": [ + "cherries" + ], + "tags": [ + "fruit" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“", + "description": "strawberry", + "category": "Food & Drink", + "aliases": [ + "strawberry" + ], + "tags": [ + "fruit" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿซ", + "description": "blueberries", + "category": "Food & Drink", + "aliases": [ + "blueberries" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿฅ", + "description": "kiwi fruit", + "category": "Food & Drink", + "aliases": [ + "kiwi_fruit" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿ…", + "description": "tomato", + "category": "Food & Drink", + "aliases": [ + "tomato" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿซ’", + "description": "olive", + "category": "Food & Drink", + "aliases": [ + "olive" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿฅฅ", + "description": "coconut", + "category": "Food & Drink", + "aliases": [ + "coconut" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฅ‘", + "description": "avocado", + "category": "Food & Drink", + "aliases": [ + "avocado" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿ†", + "description": "eggplant", + "category": "Food & Drink", + "aliases": [ + "eggplant" + ], + "tags": [ + "aubergine" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฅ”", + "description": "potato", + "category": "Food & Drink", + "aliases": [ + "potato" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿฅ•", + "description": "carrot", + "category": "Food & Drink", + "aliases": [ + "carrot" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐ŸŒฝ", + "description": "ear of corn", + "category": "Food & Drink", + "aliases": [ + "corn" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒถ๏ธ", + "description": "hot pepper", + "category": "Food & Drink", + "aliases": [ + "hot_pepper" + ], + "tags": [ + "spicy" + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿซ‘", + "description": "bell pepper", + "category": "Food & Drink", + "aliases": [ + "bell_pepper" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿฅ’", + "description": "cucumber", + "category": "Food & Drink", + "aliases": [ + "cucumber" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿฅฌ", + "description": "leafy green", + "category": "Food & Drink", + "aliases": [ + "leafy_green" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฅฆ", + "description": "broccoli", + "category": "Food & Drink", + "aliases": [ + "broccoli" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿง„", + "description": "garlic", + "category": "Food & Drink", + "aliases": [ + "garlic" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿง…", + "description": "onion", + "category": "Food & Drink", + "aliases": [ + "onion" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿ„", + "description": "mushroom", + "category": "Food & Drink", + "aliases": [ + "mushroom" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฅœ", + "description": "peanuts", + "category": "Food & Drink", + "aliases": [ + "peanuts" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿซ˜", + "description": "beans", + "category": "Food & Drink", + "aliases": [ + "beans" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐ŸŒฐ", + "description": "chestnut", + "category": "Food & Drink", + "aliases": [ + "chestnut" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿž", + "description": "bread", + "category": "Food & Drink", + "aliases": [ + "bread" + ], + "tags": [ + "toast" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฅ", + "description": "croissant", + "category": "Food & Drink", + "aliases": [ + "croissant" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿฅ–", + "description": "baguette bread", + "category": "Food & Drink", + "aliases": [ + "baguette_bread" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿซ“", + "description": "flatbread", + "category": "Food & Drink", + "aliases": [ + "flatbread" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿฅจ", + "description": "pretzel", + "category": "Food & Drink", + "aliases": [ + "pretzel" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฅฏ", + "description": "bagel", + "category": "Food & Drink", + "aliases": [ + "bagel" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฅž", + "description": "pancakes", + "category": "Food & Drink", + "aliases": [ + "pancakes" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿง‡", + "description": "waffle", + "category": "Food & Drink", + "aliases": [ + "waffle" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿง€", + "description": "cheese wedge", + "category": "Food & Drink", + "aliases": [ + "cheese" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ–", + "description": "meat on bone", + "category": "Food & Drink", + "aliases": [ + "meat_on_bone" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ—", + "description": "poultry leg", + "category": "Food & Drink", + "aliases": [ + "poultry_leg" + ], + "tags": [ + "meat", + "chicken" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฅฉ", + "description": "cut of meat", + "category": "Food & Drink", + "aliases": [ + "cut_of_meat" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฅ“", + "description": "bacon", + "category": "Food & Drink", + "aliases": [ + "bacon" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿ”", + "description": "hamburger", + "category": "Food & Drink", + "aliases": [ + "hamburger" + ], + "tags": [ + "burger" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŸ", + "description": "french fries", + "category": "Food & Drink", + "aliases": [ + "fries" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•", + "description": "pizza", + "category": "Food & Drink", + "aliases": [ + "pizza" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒญ", + "description": "hot dog", + "category": "Food & Drink", + "aliases": [ + "hotdog" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿฅช", + "description": "sandwich", + "category": "Food & Drink", + "aliases": [ + "sandwich" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐ŸŒฎ", + "description": "taco", + "category": "Food & Drink", + "aliases": [ + "taco" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŒฏ", + "description": "burrito", + "category": "Food & Drink", + "aliases": [ + "burrito" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿซ”", + "description": "tamale", + "category": "Food & Drink", + "aliases": [ + "tamale" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿฅ™", + "description": "stuffed flatbread", + "category": "Food & Drink", + "aliases": [ + "stuffed_flatbread" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿง†", + "description": "falafel", + "category": "Food & Drink", + "aliases": [ + "falafel" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿฅš", + "description": "egg", + "category": "Food & Drink", + "aliases": [ + "egg" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿณ", + "description": "cooking", + "category": "Food & Drink", + "aliases": [ + "fried_egg" + ], + "tags": [ + "breakfast" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฅ˜", + "description": "shallow pan of food", + "category": "Food & Drink", + "aliases": [ + "shallow_pan_of_food" + ], + "tags": [ + "paella", + "curry" + ], + "unicode_version": "", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿฒ", + "description": "pot of food", + "category": "Food & Drink", + "aliases": [ + "stew" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿซ•", + "description": "fondue", + "category": "Food & Drink", + "aliases": [ + "fondue" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿฅฃ", + "description": "bowl with spoon", + "category": "Food & Drink", + "aliases": [ + "bowl_with_spoon" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฅ—", + "description": "green salad", + "category": "Food & Drink", + "aliases": [ + "green_salad" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿฟ", + "description": "popcorn", + "category": "Food & Drink", + "aliases": [ + "popcorn" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿงˆ", + "description": "butter", + "category": "Food & Drink", + "aliases": [ + "butter" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿง‚", + "description": "salt", + "category": "Food & Drink", + "aliases": [ + "salt" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฅซ", + "description": "canned food", + "category": "Food & Drink", + "aliases": [ + "canned_food" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฑ", + "description": "bento box", + "category": "Food & Drink", + "aliases": [ + "bento" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ˜", + "description": "rice cracker", + "category": "Food & Drink", + "aliases": [ + "rice_cracker" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ™", + "description": "rice ball", + "category": "Food & Drink", + "aliases": [ + "rice_ball" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿš", + "description": "cooked rice", + "category": "Food & Drink", + "aliases": [ + "rice" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ›", + "description": "curry rice", + "category": "Food & Drink", + "aliases": [ + "curry" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿœ", + "description": "steaming bowl", + "category": "Food & Drink", + "aliases": [ + "ramen" + ], + "tags": [ + "noodle" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ", + "description": "spaghetti", + "category": "Food & Drink", + "aliases": [ + "spaghetti" + ], + "tags": [ + "pasta" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ ", + "description": "roasted sweet potato", + "category": "Food & Drink", + "aliases": [ + "sweet_potato" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿข", + "description": "oden", + "category": "Food & Drink", + "aliases": [ + "oden" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฃ", + "description": "sushi", + "category": "Food & Drink", + "aliases": [ + "sushi" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿค", + "description": "fried shrimp", + "category": "Food & Drink", + "aliases": [ + "fried_shrimp" + ], + "tags": [ + "tempura" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฅ", + "description": "fish cake with swirl", + "category": "Food & Drink", + "aliases": [ + "fish_cake" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฅฎ", + "description": "moon cake", + "category": "Food & Drink", + "aliases": [ + "moon_cake" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿก", + "description": "dango", + "category": "Food & Drink", + "aliases": [ + "dango" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸฅŸ", + "description": "dumpling", + "category": "Food & Drink", + "aliases": [ + "dumpling" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฅ ", + "description": "fortune cookie", + "category": "Food & Drink", + "aliases": [ + "fortune_cookie" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฅก", + "description": "takeout box", + "category": "Food & Drink", + "aliases": [ + "takeout_box" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฆ€", + "description": "crab", + "category": "Food & Drink", + "aliases": [ + "crab" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿฆž", + "description": "lobster", + "category": "Food & Drink", + "aliases": [ + "lobster" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฆ", + "description": "shrimp", + "category": "Food & Drink", + "aliases": [ + "shrimp" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿฆ‘", + "description": "squid", + "category": "Food & Drink", + "aliases": [ + "squid" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿฆช", + "description": "oyster", + "category": "Food & Drink", + "aliases": [ + "oyster" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿฆ", + "description": "soft ice cream", + "category": "Food & Drink", + "aliases": [ + "icecream" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿง", + "description": "shaved ice", + "category": "Food & Drink", + "aliases": [ + "shaved_ice" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿจ", + "description": "ice cream", + "category": "Food & Drink", + "aliases": [ + "ice_cream" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฉ", + "description": "doughnut", + "category": "Food & Drink", + "aliases": [ + "doughnut" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿช", + "description": "cookie", + "category": "Food & Drink", + "aliases": [ + "cookie" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽ‚", + "description": "birthday cake", + "category": "Food & Drink", + "aliases": [ + "birthday" + ], + "tags": [ + "party" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฐ", + "description": "shortcake", + "category": "Food & Drink", + "aliases": [ + "cake" + ], + "tags": [ + "dessert" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿง", + "description": "cupcake", + "category": "Food & Drink", + "aliases": [ + "cupcake" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฅง", + "description": "pie", + "category": "Food & Drink", + "aliases": [ + "pie" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿซ", + "description": "chocolate bar", + "category": "Food & Drink", + "aliases": [ + "chocolate_bar" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฌ", + "description": "candy", + "category": "Food & Drink", + "aliases": [ + "candy" + ], + "tags": [ + "sweet" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿญ", + "description": "lollipop", + "category": "Food & Drink", + "aliases": [ + "lollipop" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฎ", + "description": "custard", + "category": "Food & Drink", + "aliases": [ + "custard" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฏ", + "description": "honey pot", + "category": "Food & Drink", + "aliases": [ + "honey_pot" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿผ", + "description": "baby bottle", + "category": "Food & Drink", + "aliases": [ + "baby_bottle" + ], + "tags": [ + "milk" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฅ›", + "description": "glass of milk", + "category": "Food & Drink", + "aliases": [ + "milk_glass" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "โ˜•", + "description": "hot beverage", + "category": "Food & Drink", + "aliases": [ + "coffee" + ], + "tags": [ + "cafe", + "espresso" + ], + "unicode_version": "4.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿซ–", + "description": "teapot", + "category": "Food & Drink", + "aliases": [ + "teapot" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿต", + "description": "teacup without handle", + "category": "Food & Drink", + "aliases": [ + "tea" + ], + "tags": [ + "green", + "breakfast" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿถ", + "description": "sake", + "category": "Food & Drink", + "aliases": [ + "sake" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿพ", + "description": "bottle with popping cork", + "category": "Food & Drink", + "aliases": [ + "champagne" + ], + "tags": [ + "bottle", + "bubbly", + "celebration" + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿท", + "description": "wine glass", + "category": "Food & Drink", + "aliases": [ + "wine_glass" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿธ", + "description": "cocktail glass", + "category": "Food & Drink", + "aliases": [ + "cocktail" + ], + "tags": [ + "drink" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿน", + "description": "tropical drink", + "category": "Food & Drink", + "aliases": [ + "tropical_drink" + ], + "tags": [ + "summer", + "vacation" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿบ", + "description": "beer mug", + "category": "Food & Drink", + "aliases": [ + "beer" + ], + "tags": [ + "drink" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿป", + "description": "clinking beer mugs", + "category": "Food & Drink", + "aliases": [ + "beers" + ], + "tags": [ + "drinks" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฅ‚", + "description": "clinking glasses", + "category": "Food & Drink", + "aliases": [ + "clinking_glasses" + ], + "tags": [ + "cheers", + "toast" + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿฅƒ", + "description": "tumbler glass", + "category": "Food & Drink", + "aliases": [ + "tumbler_glass" + ], + "tags": [ + "whisky" + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿซ—", + "description": "pouring liquid", + "category": "Food & Drink", + "aliases": [ + "pouring_liquid" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐Ÿฅค", + "description": "cup with straw", + "category": "Food & Drink", + "aliases": [ + "cup_with_straw" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿง‹", + "description": "bubble tea", + "category": "Food & Drink", + "aliases": [ + "bubble_tea" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿงƒ", + "description": "beverage box", + "category": "Food & Drink", + "aliases": [ + "beverage_box" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿง‰", + "description": "mate", + "category": "Food & Drink", + "aliases": [ + "mate" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐ŸงŠ", + "description": "ice", + "category": "Food & Drink", + "aliases": [ + "ice_cube" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿฅข", + "description": "chopsticks", + "category": "Food & Drink", + "aliases": [ + "chopsticks" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฝ๏ธ", + "description": "fork and knife with plate", + "category": "Food & Drink", + "aliases": [ + "plate_with_cutlery" + ], + "tags": [ + "dining", + "dinner" + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿด", + "description": "fork and knife", + "category": "Food & Drink", + "aliases": [ + "fork_and_knife" + ], + "tags": [ + "cutlery" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฅ„", + "description": "spoon", + "category": "Food & Drink", + "aliases": [ + "spoon" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿ”ช", + "description": "kitchen knife", + "category": "Food & Drink", + "aliases": [ + "hocho", + "knife" + ], + "tags": [ + "cut", + "chop" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿซ™", + "description": "jar", + "category": "Food & Drink", + "aliases": [ + "jar" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐Ÿบ", + "description": "amphora", + "category": "Food & Drink", + "aliases": [ + "amphora" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŒ", + "description": "globe showing Europe-Africa", + "category": "Travel & Places", + "aliases": [ + "earth_africa" + ], + "tags": [ + "globe", + "world", + "international" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒŽ", + "description": "globe showing Americas", + "category": "Travel & Places", + "aliases": [ + "earth_americas" + ], + "tags": [ + "globe", + "world", + "international" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒ", + "description": "globe showing Asia-Australia", + "category": "Travel & Places", + "aliases": [ + "earth_asia" + ], + "tags": [ + "globe", + "world", + "international" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒ", + "description": "globe with meridians", + "category": "Travel & Places", + "aliases": [ + "globe_with_meridians" + ], + "tags": [ + "world", + "global", + "international" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ—บ๏ธ", + "description": "world map", + "category": "Travel & Places", + "aliases": [ + "world_map" + ], + "tags": [ + "travel" + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ—พ", + "description": "map of Japan", + "category": "Travel & Places", + "aliases": [ + "japan" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿงญ", + "description": "compass", + "category": "Travel & Places", + "aliases": [ + "compass" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ”๏ธ", + "description": "snow-capped mountain", + "category": "Travel & Places", + "aliases": [ + "mountain_snow" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "โ›ฐ๏ธ", + "description": "mountain", + "category": "Travel & Places", + "aliases": [ + "mountain" + ], + "tags": [ + + ], + "unicode_version": "5.2", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŒ‹", + "description": "volcano", + "category": "Travel & Places", + "aliases": [ + "volcano" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ—ป", + "description": "mount fuji", + "category": "Travel & Places", + "aliases": [ + "mount_fuji" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•๏ธ", + "description": "camping", + "category": "Travel & Places", + "aliases": [ + "camping" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ–๏ธ", + "description": "beach with umbrella", + "category": "Travel & Places", + "aliases": [ + "beach_umbrella" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿœ๏ธ", + "description": "desert", + "category": "Travel & Places", + "aliases": [ + "desert" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ๏ธ", + "description": "desert island", + "category": "Travel & Places", + "aliases": [ + "desert_island" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿž๏ธ", + "description": "national park", + "category": "Travel & Places", + "aliases": [ + "national_park" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŸ๏ธ", + "description": "stadium", + "category": "Travel & Places", + "aliases": [ + "stadium" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ›๏ธ", + "description": "classical building", + "category": "Travel & Places", + "aliases": [ + "classical_building" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ—๏ธ", + "description": "building construction", + "category": "Travel & Places", + "aliases": [ + "building_construction" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿงฑ", + "description": "brick", + "category": "Travel & Places", + "aliases": [ + "bricks" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿชจ", + "description": "rock", + "category": "Travel & Places", + "aliases": [ + "rock" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿชต", + "description": "wood", + "category": "Travel & Places", + "aliases": [ + "wood" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿ›–", + "description": "hut", + "category": "Travel & Places", + "aliases": [ + "hut" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿ˜๏ธ", + "description": "houses", + "category": "Travel & Places", + "aliases": [ + "houses" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿš๏ธ", + "description": "derelict house", + "category": "Travel & Places", + "aliases": [ + "derelict_house" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ ", + "description": "house", + "category": "Travel & Places", + "aliases": [ + "house" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿก", + "description": "house with garden", + "category": "Travel & Places", + "aliases": [ + "house_with_garden" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿข", + "description": "office building", + "category": "Travel & Places", + "aliases": [ + "office" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฃ", + "description": "Japanese post office", + "category": "Travel & Places", + "aliases": [ + "post_office" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿค", + "description": "post office", + "category": "Travel & Places", + "aliases": [ + "european_post_office" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฅ", + "description": "hospital", + "category": "Travel & Places", + "aliases": [ + "hospital" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฆ", + "description": "bank", + "category": "Travel & Places", + "aliases": [ + "bank" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿจ", + "description": "hotel", + "category": "Travel & Places", + "aliases": [ + "hotel" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฉ", + "description": "love hotel", + "category": "Travel & Places", + "aliases": [ + "love_hotel" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿช", + "description": "convenience store", + "category": "Travel & Places", + "aliases": [ + "convenience_store" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿซ", + "description": "school", + "category": "Travel & Places", + "aliases": [ + "school" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฌ", + "description": "department store", + "category": "Travel & Places", + "aliases": [ + "department_store" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿญ", + "description": "factory", + "category": "Travel & Places", + "aliases": [ + "factory" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฏ", + "description": "Japanese castle", + "category": "Travel & Places", + "aliases": [ + "japanese_castle" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฐ", + "description": "castle", + "category": "Travel & Places", + "aliases": [ + "european_castle" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’’", + "description": "wedding", + "category": "Travel & Places", + "aliases": [ + "wedding" + ], + "tags": [ + "marriage" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ—ผ", + "description": "Tokyo tower", + "category": "Travel & Places", + "aliases": [ + "tokyo_tower" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ—ฝ", + "description": "Statue of Liberty", + "category": "Travel & Places", + "aliases": [ + "statue_of_liberty" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โ›ช", + "description": "church", + "category": "Travel & Places", + "aliases": [ + "church" + ], + "tags": [ + + ], + "unicode_version": "5.2", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•Œ", + "description": "mosque", + "category": "Travel & Places", + "aliases": [ + "mosque" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ›•", + "description": "hindu temple", + "category": "Travel & Places", + "aliases": [ + "hindu_temple" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿ•", + "description": "synagogue", + "category": "Travel & Places", + "aliases": [ + "synagogue" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "โ›ฉ๏ธ", + "description": "shinto shrine", + "category": "Travel & Places", + "aliases": [ + "shinto_shrine" + ], + "tags": [ + + ], + "unicode_version": "5.2", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ•‹", + "description": "kaaba", + "category": "Travel & Places", + "aliases": [ + "kaaba" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "โ›ฒ", + "description": "fountain", + "category": "Travel & Places", + "aliases": [ + "fountain" + ], + "tags": [ + + ], + "unicode_version": "5.2", + "ios_version": "6.0" + }, + { + "emoji": "โ›บ", + "description": "tent", + "category": "Travel & Places", + "aliases": [ + "tent" + ], + "tags": [ + "camping" + ], + "unicode_version": "5.2", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒ", + "description": "foggy", + "category": "Travel & Places", + "aliases": [ + "foggy" + ], + "tags": [ + "karl" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒƒ", + "description": "night with stars", + "category": "Travel & Places", + "aliases": [ + "night_with_stars" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ™๏ธ", + "description": "cityscape", + "category": "Travel & Places", + "aliases": [ + "cityscape" + ], + "tags": [ + "skyline" + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŒ„", + "description": "sunrise over mountains", + "category": "Travel & Places", + "aliases": [ + "sunrise_over_mountains" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒ…", + "description": "sunrise", + "category": "Travel & Places", + "aliases": [ + "sunrise" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒ†", + "description": "cityscape at dusk", + "category": "Travel & Places", + "aliases": [ + "city_sunset" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒ‡", + "description": "sunset", + "category": "Travel & Places", + "aliases": [ + "city_sunrise" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒ‰", + "description": "bridge at night", + "category": "Travel & Places", + "aliases": [ + "bridge_at_night" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โ™จ๏ธ", + "description": "hot springs", + "category": "Travel & Places", + "aliases": [ + "hotsprings" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽ ", + "description": "carousel horse", + "category": "Travel & Places", + "aliases": [ + "carousel_horse" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ›", + "description": "playground slide", + "category": "Travel & Places", + "aliases": [ + "playground_slide" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐ŸŽก", + "description": "ferris wheel", + "category": "Travel & Places", + "aliases": [ + "ferris_wheel" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽข", + "description": "roller coaster", + "category": "Travel & Places", + "aliases": [ + "roller_coaster" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’ˆ", + "description": "barber pole", + "category": "Travel & Places", + "aliases": [ + "barber" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽช", + "description": "circus tent", + "category": "Travel & Places", + "aliases": [ + "circus_tent" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿš‚", + "description": "locomotive", + "category": "Travel & Places", + "aliases": [ + "steam_locomotive" + ], + "tags": [ + "train" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿšƒ", + "description": "railway car", + "category": "Travel & Places", + "aliases": [ + "railway_car" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿš„", + "description": "high-speed train", + "category": "Travel & Places", + "aliases": [ + "bullettrain_side" + ], + "tags": [ + "train" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿš…", + "description": "bullet train", + "category": "Travel & Places", + "aliases": [ + "bullettrain_front" + ], + "tags": [ + "train" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿš†", + "description": "train", + "category": "Travel & Places", + "aliases": [ + "train2" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿš‡", + "description": "metro", + "category": "Travel & Places", + "aliases": [ + "metro" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿšˆ", + "description": "light rail", + "category": "Travel & Places", + "aliases": [ + "light_rail" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿš‰", + "description": "station", + "category": "Travel & Places", + "aliases": [ + "station" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸšŠ", + "description": "tram", + "category": "Travel & Places", + "aliases": [ + "tram" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿš", + "description": "monorail", + "category": "Travel & Places", + "aliases": [ + "monorail" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿšž", + "description": "mountain railway", + "category": "Travel & Places", + "aliases": [ + "mountain_railway" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿš‹", + "description": "tram car", + "category": "Travel & Places", + "aliases": [ + "train" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸšŒ", + "description": "bus", + "category": "Travel & Places", + "aliases": [ + "bus" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿš", + "description": "oncoming bus", + "category": "Travel & Places", + "aliases": [ + "oncoming_bus" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸšŽ", + "description": "trolleybus", + "category": "Travel & Places", + "aliases": [ + "trolleybus" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿš", + "description": "minibus", + "category": "Travel & Places", + "aliases": [ + "minibus" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿš‘", + "description": "ambulance", + "category": "Travel & Places", + "aliases": [ + "ambulance" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿš’", + "description": "fire engine", + "category": "Travel & Places", + "aliases": [ + "fire_engine" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿš“", + "description": "police car", + "category": "Travel & Places", + "aliases": [ + "police_car" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿš”", + "description": "oncoming police car", + "category": "Travel & Places", + "aliases": [ + "oncoming_police_car" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿš•", + "description": "taxi", + "category": "Travel & Places", + "aliases": [ + "taxi" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿš–", + "description": "oncoming taxi", + "category": "Travel & Places", + "aliases": [ + "oncoming_taxi" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿš—", + "description": "automobile", + "category": "Travel & Places", + "aliases": [ + "car", + "red_car" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿš˜", + "description": "oncoming automobile", + "category": "Travel & Places", + "aliases": [ + "oncoming_automobile" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿš™", + "description": "sport utility vehicle", + "category": "Travel & Places", + "aliases": [ + "blue_car" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ›ป", + "description": "pickup truck", + "category": "Travel & Places", + "aliases": [ + "pickup_truck" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿšš", + "description": "delivery truck", + "category": "Travel & Places", + "aliases": [ + "truck" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿš›", + "description": "articulated lorry", + "category": "Travel & Places", + "aliases": [ + "articulated_lorry" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿšœ", + "description": "tractor", + "category": "Travel & Places", + "aliases": [ + "tractor" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽ๏ธ", + "description": "racing car", + "category": "Travel & Places", + "aliases": [ + "racing_car" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ๏ธ", + "description": "motorcycle", + "category": "Travel & Places", + "aliases": [ + "motorcycle" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ›ต", + "description": "motor scooter", + "category": "Travel & Places", + "aliases": [ + "motor_scooter" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿฆฝ", + "description": "manual wheelchair", + "category": "Travel & Places", + "aliases": [ + "manual_wheelchair" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿฆผ", + "description": "motorized wheelchair", + "category": "Travel & Places", + "aliases": [ + "motorized_wheelchair" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿ›บ", + "description": "auto rickshaw", + "category": "Travel & Places", + "aliases": [ + "auto_rickshaw" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿšฒ", + "description": "bicycle", + "category": "Travel & Places", + "aliases": [ + "bike" + ], + "tags": [ + "bicycle" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ›ด", + "description": "kick scooter", + "category": "Travel & Places", + "aliases": [ + "kick_scooter" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿ›น", + "description": "skateboard", + "category": "Travel & Places", + "aliases": [ + "skateboard" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ›ผ", + "description": "roller skate", + "category": "Travel & Places", + "aliases": [ + "roller_skate" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿš", + "description": "bus stop", + "category": "Travel & Places", + "aliases": [ + "busstop" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ›ฃ๏ธ", + "description": "motorway", + "category": "Travel & Places", + "aliases": [ + "motorway" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ›ค๏ธ", + "description": "railway track", + "category": "Travel & Places", + "aliases": [ + "railway_track" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ›ข๏ธ", + "description": "oil drum", + "category": "Travel & Places", + "aliases": [ + "oil_drum" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "โ›ฝ", + "description": "fuel pump", + "category": "Travel & Places", + "aliases": [ + "fuelpump" + ], + "tags": [ + + ], + "unicode_version": "5.2", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ›ž", + "description": "wheel", + "category": "Travel & Places", + "aliases": [ + "wheel" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐Ÿšจ", + "description": "police car light", + "category": "Travel & Places", + "aliases": [ + "rotating_light" + ], + "tags": [ + "911", + "emergency" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿšฅ", + "description": "horizontal traffic light", + "category": "Travel & Places", + "aliases": [ + "traffic_light" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿšฆ", + "description": "vertical traffic light", + "category": "Travel & Places", + "aliases": [ + "vertical_traffic_light" + ], + "tags": [ + "semaphore" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ›‘", + "description": "stop sign", + "category": "Travel & Places", + "aliases": [ + "stop_sign" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿšง", + "description": "construction", + "category": "Travel & Places", + "aliases": [ + "construction" + ], + "tags": [ + "wip" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โš“", + "description": "anchor", + "category": "Travel & Places", + "aliases": [ + "anchor" + ], + "tags": [ + "ship" + ], + "unicode_version": "4.1", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ›Ÿ", + "description": "ring buoy", + "category": "Travel & Places", + "aliases": [ + "ring_buoy" + ], + "tags": [ + "life preserver" + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "โ›ต", + "description": "sailboat", + "category": "Travel & Places", + "aliases": [ + "boat", + "sailboat" + ], + "tags": [ + + ], + "unicode_version": "5.2", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ›ถ", + "description": "canoe", + "category": "Travel & Places", + "aliases": [ + "canoe" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿšค", + "description": "speedboat", + "category": "Travel & Places", + "aliases": [ + "speedboat" + ], + "tags": [ + "ship" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ›ณ๏ธ", + "description": "passenger ship", + "category": "Travel & Places", + "aliases": [ + "passenger_ship" + ], + "tags": [ + "cruise" + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "โ›ด๏ธ", + "description": "ferry", + "category": "Travel & Places", + "aliases": [ + "ferry" + ], + "tags": [ + + ], + "unicode_version": "5.2", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ›ฅ๏ธ", + "description": "motor boat", + "category": "Travel & Places", + "aliases": [ + "motor_boat" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿšข", + "description": "ship", + "category": "Travel & Places", + "aliases": [ + "ship" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โœˆ๏ธ", + "description": "airplane", + "category": "Travel & Places", + "aliases": [ + "airplane" + ], + "tags": [ + "flight" + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ›ฉ๏ธ", + "description": "small airplane", + "category": "Travel & Places", + "aliases": [ + "small_airplane" + ], + "tags": [ + "flight" + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ›ซ", + "description": "airplane departure", + "category": "Travel & Places", + "aliases": [ + "flight_departure" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ›ฌ", + "description": "airplane arrival", + "category": "Travel & Places", + "aliases": [ + "flight_arrival" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿช‚", + "description": "parachute", + "category": "Travel & Places", + "aliases": [ + "parachute" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿ’บ", + "description": "seat", + "category": "Travel & Places", + "aliases": [ + "seat" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿš", + "description": "helicopter", + "category": "Travel & Places", + "aliases": [ + "helicopter" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸšŸ", + "description": "suspension railway", + "category": "Travel & Places", + "aliases": [ + "suspension_railway" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿš ", + "description": "mountain cableway", + "category": "Travel & Places", + "aliases": [ + "mountain_cableway" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿšก", + "description": "aerial tramway", + "category": "Travel & Places", + "aliases": [ + "aerial_tramway" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ›ฐ๏ธ", + "description": "satellite", + "category": "Travel & Places", + "aliases": [ + "artificial_satellite" + ], + "tags": [ + "orbit", + "space" + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿš€", + "description": "rocket", + "category": "Travel & Places", + "aliases": [ + "rocket" + ], + "tags": [ + "ship", + "launch" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ›ธ", + "description": "flying saucer", + "category": "Travel & Places", + "aliases": [ + "flying_saucer" + ], + "tags": [ + "ufo" + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ›Ž๏ธ", + "description": "bellhop bell", + "category": "Travel & Places", + "aliases": [ + "bellhop_bell" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿงณ", + "description": "luggage", + "category": "Travel & Places", + "aliases": [ + "luggage" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "โŒ›", + "description": "hourglass done", + "category": "Travel & Places", + "aliases": [ + "hourglass" + ], + "tags": [ + "time" + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โณ", + "description": "hourglass not done", + "category": "Travel & Places", + "aliases": [ + "hourglass_flowing_sand" + ], + "tags": [ + "time" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โŒš", + "description": "watch", + "category": "Travel & Places", + "aliases": [ + "watch" + ], + "tags": [ + "time" + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โฐ", + "description": "alarm clock", + "category": "Travel & Places", + "aliases": [ + "alarm_clock" + ], + "tags": [ + "morning" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โฑ๏ธ", + "description": "stopwatch", + "category": "Travel & Places", + "aliases": [ + "stopwatch" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.1" + }, + { + "emoji": "โฒ๏ธ", + "description": "timer clock", + "category": "Travel & Places", + "aliases": [ + "timer_clock" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ•ฐ๏ธ", + "description": "mantelpiece clock", + "category": "Travel & Places", + "aliases": [ + "mantelpiece_clock" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ•›", + "description": "twelve oโ€™clock", + "category": "Travel & Places", + "aliases": [ + "clock12" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•ง", + "description": "twelve-thirty", + "category": "Travel & Places", + "aliases": [ + "clock1230" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•", + "description": "one oโ€™clock", + "category": "Travel & Places", + "aliases": [ + "clock1" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•œ", + "description": "one-thirty", + "category": "Travel & Places", + "aliases": [ + "clock130" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•‘", + "description": "two oโ€™clock", + "category": "Travel & Places", + "aliases": [ + "clock2" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•", + "description": "two-thirty", + "category": "Travel & Places", + "aliases": [ + "clock230" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•’", + "description": "three oโ€™clock", + "category": "Travel & Places", + "aliases": [ + "clock3" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•ž", + "description": "three-thirty", + "category": "Travel & Places", + "aliases": [ + "clock330" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•“", + "description": "four oโ€™clock", + "category": "Travel & Places", + "aliases": [ + "clock4" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•Ÿ", + "description": "four-thirty", + "category": "Travel & Places", + "aliases": [ + "clock430" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•”", + "description": "five oโ€™clock", + "category": "Travel & Places", + "aliases": [ + "clock5" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ• ", + "description": "five-thirty", + "category": "Travel & Places", + "aliases": [ + "clock530" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ••", + "description": "six oโ€™clock", + "category": "Travel & Places", + "aliases": [ + "clock6" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•ก", + "description": "six-thirty", + "category": "Travel & Places", + "aliases": [ + "clock630" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•–", + "description": "seven oโ€™clock", + "category": "Travel & Places", + "aliases": [ + "clock7" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•ข", + "description": "seven-thirty", + "category": "Travel & Places", + "aliases": [ + "clock730" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•—", + "description": "eight oโ€™clock", + "category": "Travel & Places", + "aliases": [ + "clock8" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•ฃ", + "description": "eight-thirty", + "category": "Travel & Places", + "aliases": [ + "clock830" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•˜", + "description": "nine oโ€™clock", + "category": "Travel & Places", + "aliases": [ + "clock9" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•ค", + "description": "nine-thirty", + "category": "Travel & Places", + "aliases": [ + "clock930" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•™", + "description": "ten oโ€™clock", + "category": "Travel & Places", + "aliases": [ + "clock10" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•ฅ", + "description": "ten-thirty", + "category": "Travel & Places", + "aliases": [ + "clock1030" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•š", + "description": "eleven oโ€™clock", + "category": "Travel & Places", + "aliases": [ + "clock11" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•ฆ", + "description": "eleven-thirty", + "category": "Travel & Places", + "aliases": [ + "clock1130" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒ‘", + "description": "new moon", + "category": "Travel & Places", + "aliases": [ + "new_moon" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒ’", + "description": "waxing crescent moon", + "category": "Travel & Places", + "aliases": [ + "waxing_crescent_moon" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒ“", + "description": "first quarter moon", + "category": "Travel & Places", + "aliases": [ + "first_quarter_moon" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒ”", + "description": "waxing gibbous moon", + "category": "Travel & Places", + "aliases": [ + "moon", + "waxing_gibbous_moon" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒ•", + "description": "full moon", + "category": "Travel & Places", + "aliases": [ + "full_moon" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒ–", + "description": "waning gibbous moon", + "category": "Travel & Places", + "aliases": [ + "waning_gibbous_moon" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒ—", + "description": "last quarter moon", + "category": "Travel & Places", + "aliases": [ + "last_quarter_moon" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒ˜", + "description": "waning crescent moon", + "category": "Travel & Places", + "aliases": [ + "waning_crescent_moon" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒ™", + "description": "crescent moon", + "category": "Travel & Places", + "aliases": [ + "crescent_moon" + ], + "tags": [ + "night" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒš", + "description": "new moon face", + "category": "Travel & Places", + "aliases": [ + "new_moon_with_face" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒ›", + "description": "first quarter moon face", + "category": "Travel & Places", + "aliases": [ + "first_quarter_moon_with_face" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒœ", + "description": "last quarter moon face", + "category": "Travel & Places", + "aliases": [ + "last_quarter_moon_with_face" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒก๏ธ", + "description": "thermometer", + "category": "Travel & Places", + "aliases": [ + "thermometer" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "โ˜€๏ธ", + "description": "sun", + "category": "Travel & Places", + "aliases": [ + "sunny" + ], + "tags": [ + "weather" + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒ", + "description": "full moon face", + "category": "Travel & Places", + "aliases": [ + "full_moon_with_face" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒž", + "description": "sun with face", + "category": "Travel & Places", + "aliases": [ + "sun_with_face" + ], + "tags": [ + "summer" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿช", + "description": "ringed planet", + "category": "Travel & Places", + "aliases": [ + "ringed_planet" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "โญ", + "description": "star", + "category": "Travel & Places", + "aliases": [ + "star" + ], + "tags": [ + + ], + "unicode_version": "5.1", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒŸ", + "description": "glowing star", + "category": "Travel & Places", + "aliases": [ + "star2" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒ ", + "description": "shooting star", + "category": "Travel & Places", + "aliases": [ + "stars" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒŒ", + "description": "milky way", + "category": "Travel & Places", + "aliases": [ + "milky_way" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โ˜๏ธ", + "description": "cloud", + "category": "Travel & Places", + "aliases": [ + "cloud" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ›…", + "description": "sun behind cloud", + "category": "Travel & Places", + "aliases": [ + "partly_sunny" + ], + "tags": [ + "weather", + "cloud" + ], + "unicode_version": "5.2", + "ios_version": "6.0" + }, + { + "emoji": "โ›ˆ๏ธ", + "description": "cloud with lightning and rain", + "category": "Travel & Places", + "aliases": [ + "cloud_with_lightning_and_rain" + ], + "tags": [ + + ], + "unicode_version": "5.2", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŒค๏ธ", + "description": "sun behind small cloud", + "category": "Travel & Places", + "aliases": [ + "sun_behind_small_cloud" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŒฅ๏ธ", + "description": "sun behind large cloud", + "category": "Travel & Places", + "aliases": [ + "sun_behind_large_cloud" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŒฆ๏ธ", + "description": "sun behind rain cloud", + "category": "Travel & Places", + "aliases": [ + "sun_behind_rain_cloud" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŒง๏ธ", + "description": "cloud with rain", + "category": "Travel & Places", + "aliases": [ + "cloud_with_rain" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŒจ๏ธ", + "description": "cloud with snow", + "category": "Travel & Places", + "aliases": [ + "cloud_with_snow" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŒฉ๏ธ", + "description": "cloud with lightning", + "category": "Travel & Places", + "aliases": [ + "cloud_with_lightning" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŒช๏ธ", + "description": "tornado", + "category": "Travel & Places", + "aliases": [ + "tornado" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŒซ๏ธ", + "description": "fog", + "category": "Travel & Places", + "aliases": [ + "fog" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŒฌ๏ธ", + "description": "wind face", + "category": "Travel & Places", + "aliases": [ + "wind_face" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŒ€", + "description": "cyclone", + "category": "Travel & Places", + "aliases": [ + "cyclone" + ], + "tags": [ + "swirl" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒˆ", + "description": "rainbow", + "category": "Travel & Places", + "aliases": [ + "rainbow" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒ‚", + "description": "closed umbrella", + "category": "Travel & Places", + "aliases": [ + "closed_umbrella" + ], + "tags": [ + "weather", + "rain" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โ˜‚๏ธ", + "description": "umbrella", + "category": "Travel & Places", + "aliases": [ + "open_umbrella" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "9.1" + }, + { + "emoji": "โ˜”", + "description": "umbrella with rain drops", + "category": "Travel & Places", + "aliases": [ + "umbrella" + ], + "tags": [ + "rain", + "weather" + ], + "unicode_version": "4.0", + "ios_version": "6.0" + }, + { + "emoji": "โ›ฑ๏ธ", + "description": "umbrella on ground", + "category": "Travel & Places", + "aliases": [ + "parasol_on_ground" + ], + "tags": [ + "beach_umbrella" + ], + "unicode_version": "5.2", + "ios_version": "9.1" + }, + { + "emoji": "โšก", + "description": "high voltage", + "category": "Travel & Places", + "aliases": [ + "zap" + ], + "tags": [ + "lightning", + "thunder" + ], + "unicode_version": "4.0", + "ios_version": "6.0" + }, + { + "emoji": "โ„๏ธ", + "description": "snowflake", + "category": "Travel & Places", + "aliases": [ + "snowflake" + ], + "tags": [ + "winter", + "cold", + "weather" + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ˜ƒ๏ธ", + "description": "snowman", + "category": "Travel & Places", + "aliases": [ + "snowman_with_snow" + ], + "tags": [ + "winter", + "christmas" + ], + "unicode_version": "", + "ios_version": "9.1" + }, + { + "emoji": "โ›„", + "description": "snowman without snow", + "category": "Travel & Places", + "aliases": [ + "snowman" + ], + "tags": [ + "winter" + ], + "unicode_version": "5.2", + "ios_version": "6.0" + }, + { + "emoji": "โ˜„๏ธ", + "description": "comet", + "category": "Travel & Places", + "aliases": [ + "comet" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ”ฅ", + "description": "fire", + "category": "Travel & Places", + "aliases": [ + "fire" + ], + "tags": [ + "burn" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’ง", + "description": "droplet", + "category": "Travel & Places", + "aliases": [ + "droplet" + ], + "tags": [ + "water" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŒŠ", + "description": "water wave", + "category": "Travel & Places", + "aliases": [ + "ocean" + ], + "tags": [ + "sea" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽƒ", + "description": "jack-o-lantern", + "category": "Activities", + "aliases": [ + "jack_o_lantern" + ], + "tags": [ + "halloween" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽ„", + "description": "Christmas tree", + "category": "Activities", + "aliases": [ + "christmas_tree" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽ†", + "description": "fireworks", + "category": "Activities", + "aliases": [ + "fireworks" + ], + "tags": [ + "festival", + "celebration" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽ‡", + "description": "sparkler", + "category": "Activities", + "aliases": [ + "sparkler" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿงจ", + "description": "firecracker", + "category": "Activities", + "aliases": [ + "firecracker" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "โœจ", + "description": "sparkles", + "category": "Activities", + "aliases": [ + "sparkles" + ], + "tags": [ + "shiny" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽˆ", + "description": "balloon", + "category": "Activities", + "aliases": [ + "balloon" + ], + "tags": [ + "party", + "birthday" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽ‰", + "description": "party popper", + "category": "Activities", + "aliases": [ + "tada" + ], + "tags": [ + "hooray", + "party" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽŠ", + "description": "confetti ball", + "category": "Activities", + "aliases": [ + "confetti_ball" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽ‹", + "description": "tanabata tree", + "category": "Activities", + "aliases": [ + "tanabata_tree" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽ", + "description": "pine decoration", + "category": "Activities", + "aliases": [ + "bamboo" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽŽ", + "description": "Japanese dolls", + "category": "Activities", + "aliases": [ + "dolls" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽ", + "description": "carp streamer", + "category": "Activities", + "aliases": [ + "flags" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽ", + "description": "wind chime", + "category": "Activities", + "aliases": [ + "wind_chime" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽ‘", + "description": "moon viewing ceremony", + "category": "Activities", + "aliases": [ + "rice_scene" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿงง", + "description": "red envelope", + "category": "Activities", + "aliases": [ + "red_envelope" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐ŸŽ€", + "description": "ribbon", + "category": "Activities", + "aliases": [ + "ribbon" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽ", + "description": "wrapped gift", + "category": "Activities", + "aliases": [ + "gift" + ], + "tags": [ + "present", + "birthday", + "christmas" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽ—๏ธ", + "description": "reminder ribbon", + "category": "Activities", + "aliases": [ + "reminder_ribbon" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŽŸ๏ธ", + "description": "admission tickets", + "category": "Activities", + "aliases": [ + "tickets" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŽซ", + "description": "ticket", + "category": "Activities", + "aliases": [ + "ticket" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽ–๏ธ", + "description": "military medal", + "category": "Activities", + "aliases": [ + "medal_military" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ†", + "description": "trophy", + "category": "Activities", + "aliases": [ + "trophy" + ], + "tags": [ + "award", + "contest", + "winner" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ…", + "description": "sports medal", + "category": "Activities", + "aliases": [ + "medal_sports" + ], + "tags": [ + "gold", + "winner" + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿฅ‡", + "description": "1st place medal", + "category": "Activities", + "aliases": [ + "1st_place_medal" + ], + "tags": [ + "gold" + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿฅˆ", + "description": "2nd place medal", + "category": "Activities", + "aliases": [ + "2nd_place_medal" + ], + "tags": [ + "silver" + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿฅ‰", + "description": "3rd place medal", + "category": "Activities", + "aliases": [ + "3rd_place_medal" + ], + "tags": [ + "bronze" + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "โšฝ", + "description": "soccer ball", + "category": "Activities", + "aliases": [ + "soccer" + ], + "tags": [ + "sports" + ], + "unicode_version": "5.2", + "ios_version": "6.0" + }, + { + "emoji": "โšพ", + "description": "baseball", + "category": "Activities", + "aliases": [ + "baseball" + ], + "tags": [ + "sports" + ], + "unicode_version": "5.2", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸฅŽ", + "description": "softball", + "category": "Activities", + "aliases": [ + "softball" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ€", + "description": "basketball", + "category": "Activities", + "aliases": [ + "basketball" + ], + "tags": [ + "sports" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ", + "description": "volleyball", + "category": "Activities", + "aliases": [ + "volleyball" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿˆ", + "description": "american football", + "category": "Activities", + "aliases": [ + "football" + ], + "tags": [ + "sports" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‰", + "description": "rugby football", + "category": "Activities", + "aliases": [ + "rugby_football" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽพ", + "description": "tennis", + "category": "Activities", + "aliases": [ + "tennis" + ], + "tags": [ + "sports" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฅ", + "description": "flying disc", + "category": "Activities", + "aliases": [ + "flying_disc" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐ŸŽณ", + "description": "bowling", + "category": "Activities", + "aliases": [ + "bowling" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ", + "description": "cricket game", + "category": "Activities", + "aliases": [ + "cricket_game" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ‘", + "description": "field hockey", + "category": "Activities", + "aliases": [ + "field_hockey" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ’", + "description": "ice hockey", + "category": "Activities", + "aliases": [ + "ice_hockey" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿฅ", + "description": "lacrosse", + "category": "Activities", + "aliases": [ + "lacrosse" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ“", + "description": "ping pong", + "category": "Activities", + "aliases": [ + "ping_pong" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿธ", + "description": "badminton", + "category": "Activities", + "aliases": [ + "badminton" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸฅŠ", + "description": "boxing glove", + "category": "Activities", + "aliases": [ + "boxing_glove" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿฅ‹", + "description": "martial arts uniform", + "category": "Activities", + "aliases": [ + "martial_arts_uniform" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿฅ…", + "description": "goal net", + "category": "Activities", + "aliases": [ + "goal_net" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "โ›ณ", + "description": "flag in hole", + "category": "Activities", + "aliases": [ + "golf" + ], + "tags": [ + + ], + "unicode_version": "5.2", + "ios_version": "6.0" + }, + { + "emoji": "โ›ธ๏ธ", + "description": "ice skate", + "category": "Activities", + "aliases": [ + "ice_skate" + ], + "tags": [ + "skating" + ], + "unicode_version": "5.2", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŽฃ", + "description": "fishing pole", + "category": "Activities", + "aliases": [ + "fishing_pole_and_fish" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿคฟ", + "description": "diving mask", + "category": "Activities", + "aliases": [ + "diving_mask" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐ŸŽฝ", + "description": "running shirt", + "category": "Activities", + "aliases": [ + "running_shirt_with_sash" + ], + "tags": [ + "marathon" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽฟ", + "description": "skis", + "category": "Activities", + "aliases": [ + "ski" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ›ท", + "description": "sled", + "category": "Activities", + "aliases": [ + "sled" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐ŸฅŒ", + "description": "curling stone", + "category": "Activities", + "aliases": [ + "curling_stone" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐ŸŽฏ", + "description": "bullseye", + "category": "Activities", + "aliases": [ + "dart" + ], + "tags": [ + "target" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿช€", + "description": "yo-yo", + "category": "Activities", + "aliases": [ + "yo_yo" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿช", + "description": "kite", + "category": "Activities", + "aliases": [ + "kite" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐ŸŽฑ", + "description": "pool 8 ball", + "category": "Activities", + "aliases": [ + "8ball" + ], + "tags": [ + "pool", + "billiards" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”ฎ", + "description": "crystal ball", + "category": "Activities", + "aliases": [ + "crystal_ball" + ], + "tags": [ + "fortune" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿช„", + "description": "magic wand", + "category": "Activities", + "aliases": [ + "magic_wand" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿงฟ", + "description": "nazar amulet", + "category": "Activities", + "aliases": [ + "nazar_amulet" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿชฌ", + "description": "hamsa", + "category": "Activities", + "aliases": [ + "hamsa" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐ŸŽฎ", + "description": "video game", + "category": "Activities", + "aliases": [ + "video_game" + ], + "tags": [ + "play", + "controller", + "console" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•น๏ธ", + "description": "joystick", + "category": "Activities", + "aliases": [ + "joystick" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŽฐ", + "description": "slot machine", + "category": "Activities", + "aliases": [ + "slot_machine" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽฒ", + "description": "game die", + "category": "Activities", + "aliases": [ + "game_die" + ], + "tags": [ + "dice", + "gambling" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿงฉ", + "description": "puzzle piece", + "category": "Activities", + "aliases": [ + "jigsaw" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿงธ", + "description": "teddy bear", + "category": "Activities", + "aliases": [ + "teddy_bear" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿช…", + "description": "piรฑata", + "category": "Activities", + "aliases": [ + "pinata" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿชฉ", + "description": "mirror ball", + "category": "Activities", + "aliases": [ + "mirror_ball" + ], + "tags": [ + "disco", + "party" + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐Ÿช†", + "description": "nesting dolls", + "category": "Activities", + "aliases": [ + "nesting_dolls" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "โ™ ๏ธ", + "description": "spade suit", + "category": "Activities", + "aliases": [ + "spades" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ™ฅ๏ธ", + "description": "heart suit", + "category": "Activities", + "aliases": [ + "hearts" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ™ฆ๏ธ", + "description": "diamond suit", + "category": "Activities", + "aliases": [ + "diamonds" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ™ฃ๏ธ", + "description": "club suit", + "category": "Activities", + "aliases": [ + "clubs" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ™Ÿ๏ธ", + "description": "chess pawn", + "category": "Activities", + "aliases": [ + "chess_pawn" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿƒ", + "description": "joker", + "category": "Activities", + "aliases": [ + "black_joker" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ€„", + "description": "mahjong red dragon", + "category": "Activities", + "aliases": [ + "mahjong" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽด", + "description": "flower playing cards", + "category": "Activities", + "aliases": [ + "flower_playing_cards" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽญ", + "description": "performing arts", + "category": "Activities", + "aliases": [ + "performing_arts" + ], + "tags": [ + "theater", + "drama" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ–ผ๏ธ", + "description": "framed picture", + "category": "Activities", + "aliases": [ + "framed_picture" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŽจ", + "description": "artist palette", + "category": "Activities", + "aliases": [ + "art" + ], + "tags": [ + "design", + "paint" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿงต", + "description": "thread", + "category": "Activities", + "aliases": [ + "thread" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿชก", + "description": "sewing needle", + "category": "Activities", + "aliases": [ + "sewing_needle" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿงถ", + "description": "yarn", + "category": "Activities", + "aliases": [ + "yarn" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿชข", + "description": "knot", + "category": "Activities", + "aliases": [ + "knot" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿ‘“", + "description": "glasses", + "category": "Objects", + "aliases": [ + "eyeglasses" + ], + "tags": [ + "glasses" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•ถ๏ธ", + "description": "sunglasses", + "category": "Objects", + "aliases": [ + "dark_sunglasses" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿฅฝ", + "description": "goggles", + "category": "Objects", + "aliases": [ + "goggles" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฅผ", + "description": "lab coat", + "category": "Objects", + "aliases": [ + "lab_coat" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฆบ", + "description": "safety vest", + "category": "Objects", + "aliases": [ + "safety_vest" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿ‘”", + "description": "necktie", + "category": "Objects", + "aliases": [ + "necktie" + ], + "tags": [ + "shirt", + "formal" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘•", + "description": "t-shirt", + "category": "Objects", + "aliases": [ + "shirt", + "tshirt" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘–", + "description": "jeans", + "category": "Objects", + "aliases": [ + "jeans" + ], + "tags": [ + "pants" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿงฃ", + "description": "scarf", + "category": "Objects", + "aliases": [ + "scarf" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿงค", + "description": "gloves", + "category": "Objects", + "aliases": [ + "gloves" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿงฅ", + "description": "coat", + "category": "Objects", + "aliases": [ + "coat" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿงฆ", + "description": "socks", + "category": "Objects", + "aliases": [ + "socks" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ‘—", + "description": "dress", + "category": "Objects", + "aliases": [ + "dress" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘˜", + "description": "kimono", + "category": "Objects", + "aliases": [ + "kimono" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฅป", + "description": "sari", + "category": "Objects", + "aliases": [ + "sari" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿฉฑ", + "description": "one-piece swimsuit", + "category": "Objects", + "aliases": [ + "one_piece_swimsuit" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿฉฒ", + "description": "briefs", + "category": "Objects", + "aliases": [ + "swim_brief" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿฉณ", + "description": "shorts", + "category": "Objects", + "aliases": [ + "shorts" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿ‘™", + "description": "bikini", + "category": "Objects", + "aliases": [ + "bikini" + ], + "tags": [ + "beach" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘š", + "description": "womanโ€™s clothes", + "category": "Objects", + "aliases": [ + "womans_clothes" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘›", + "description": "purse", + "category": "Objects", + "aliases": [ + "purse" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘œ", + "description": "handbag", + "category": "Objects", + "aliases": [ + "handbag" + ], + "tags": [ + "bag" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘", + "description": "clutch bag", + "category": "Objects", + "aliases": [ + "pouch" + ], + "tags": [ + "bag" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ›๏ธ", + "description": "shopping bags", + "category": "Objects", + "aliases": [ + "shopping" + ], + "tags": [ + "bags" + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŽ’", + "description": "backpack", + "category": "Objects", + "aliases": [ + "school_satchel" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฉด", + "description": "thong sandal", + "category": "Objects", + "aliases": [ + "thong_sandal" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿ‘ž", + "description": "manโ€™s shoe", + "category": "Objects", + "aliases": [ + "mans_shoe", + "shoe" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘Ÿ", + "description": "running shoe", + "category": "Objects", + "aliases": [ + "athletic_shoe" + ], + "tags": [ + "sneaker", + "sport", + "running" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฅพ", + "description": "hiking boot", + "category": "Objects", + "aliases": [ + "hiking_boot" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿฅฟ", + "description": "flat shoe", + "category": "Objects", + "aliases": [ + "flat_shoe" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ‘ ", + "description": "high-heeled shoe", + "category": "Objects", + "aliases": [ + "high_heel" + ], + "tags": [ + "shoe" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘ก", + "description": "womanโ€™s sandal", + "category": "Objects", + "aliases": [ + "sandal" + ], + "tags": [ + "shoe" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฉฐ", + "description": "ballet shoes", + "category": "Objects", + "aliases": [ + "ballet_shoes" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿ‘ข", + "description": "womanโ€™s boot", + "category": "Objects", + "aliases": [ + "boot" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘‘", + "description": "crown", + "category": "Objects", + "aliases": [ + "crown" + ], + "tags": [ + "king", + "queen", + "royal" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‘’", + "description": "womanโ€™s hat", + "category": "Objects", + "aliases": [ + "womans_hat" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽฉ", + "description": "top hat", + "category": "Objects", + "aliases": [ + "tophat" + ], + "tags": [ + "hat", + "classy" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽ“", + "description": "graduation cap", + "category": "Objects", + "aliases": [ + "mortar_board" + ], + "tags": [ + "education", + "college", + "university", + "graduation" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿงข", + "description": "billed cap", + "category": "Objects", + "aliases": [ + "billed_cap" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿช–", + "description": "military helmet", + "category": "Objects", + "aliases": [ + "military_helmet" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "โ›‘๏ธ", + "description": "rescue workerโ€™s helmet", + "category": "Objects", + "aliases": [ + "rescue_worker_helmet" + ], + "tags": [ + + ], + "unicode_version": "5.2", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ“ฟ", + "description": "prayer beads", + "category": "Objects", + "aliases": [ + "prayer_beads" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ’„", + "description": "lipstick", + "category": "Objects", + "aliases": [ + "lipstick" + ], + "tags": [ + "makeup" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’", + "description": "ring", + "category": "Objects", + "aliases": [ + "ring" + ], + "tags": [ + "wedding", + "marriage", + "engaged" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’Ž", + "description": "gem stone", + "category": "Objects", + "aliases": [ + "gem" + ], + "tags": [ + "diamond" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”‡", + "description": "muted speaker", + "category": "Objects", + "aliases": [ + "mute" + ], + "tags": [ + "sound", + "volume" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”ˆ", + "description": "speaker low volume", + "category": "Objects", + "aliases": [ + "speaker" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”‰", + "description": "speaker medium volume", + "category": "Objects", + "aliases": [ + "sound" + ], + "tags": [ + "volume" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”Š", + "description": "speaker high volume", + "category": "Objects", + "aliases": [ + "loud_sound" + ], + "tags": [ + "volume" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ข", + "description": "loudspeaker", + "category": "Objects", + "aliases": [ + "loudspeaker" + ], + "tags": [ + "announcement" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ฃ", + "description": "megaphone", + "category": "Objects", + "aliases": [ + "mega" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ฏ", + "description": "postal horn", + "category": "Objects", + "aliases": [ + "postal_horn" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ””", + "description": "bell", + "category": "Objects", + "aliases": [ + "bell" + ], + "tags": [ + "sound", + "notification" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”•", + "description": "bell with slash", + "category": "Objects", + "aliases": [ + "no_bell" + ], + "tags": [ + "volume", + "off" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽผ", + "description": "musical score", + "category": "Objects", + "aliases": [ + "musical_score" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽต", + "description": "musical note", + "category": "Objects", + "aliases": [ + "musical_note" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽถ", + "description": "musical notes", + "category": "Objects", + "aliases": [ + "notes" + ], + "tags": [ + "music" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽ™๏ธ", + "description": "studio microphone", + "category": "Objects", + "aliases": [ + "studio_microphone" + ], + "tags": [ + "podcast" + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŽš๏ธ", + "description": "level slider", + "category": "Objects", + "aliases": [ + "level_slider" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŽ›๏ธ", + "description": "control knobs", + "category": "Objects", + "aliases": [ + "control_knobs" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŽค", + "description": "microphone", + "category": "Objects", + "aliases": [ + "microphone" + ], + "tags": [ + "sing" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽง", + "description": "headphone", + "category": "Objects", + "aliases": [ + "headphones" + ], + "tags": [ + "music", + "earphones" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ป", + "description": "radio", + "category": "Objects", + "aliases": [ + "radio" + ], + "tags": [ + "podcast" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽท", + "description": "saxophone", + "category": "Objects", + "aliases": [ + "saxophone" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿช—", + "description": "accordion", + "category": "Objects", + "aliases": [ + "accordion" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐ŸŽธ", + "description": "guitar", + "category": "Objects", + "aliases": [ + "guitar" + ], + "tags": [ + "rock" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽน", + "description": "musical keyboard", + "category": "Objects", + "aliases": [ + "musical_keyboard" + ], + "tags": [ + "piano" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽบ", + "description": "trumpet", + "category": "Objects", + "aliases": [ + "trumpet" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽป", + "description": "violin", + "category": "Objects", + "aliases": [ + "violin" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿช•", + "description": "banjo", + "category": "Objects", + "aliases": [ + "banjo" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿฅ", + "description": "drum", + "category": "Objects", + "aliases": [ + "drum" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿช˜", + "description": "long drum", + "category": "Objects", + "aliases": [ + "long_drum" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿ“ฑ", + "description": "mobile phone", + "category": "Objects", + "aliases": [ + "iphone" + ], + "tags": [ + "smartphone", + "mobile" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ฒ", + "description": "mobile phone with arrow", + "category": "Objects", + "aliases": [ + "calling" + ], + "tags": [ + "call", + "incoming" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โ˜Ž๏ธ", + "description": "telephone", + "category": "Objects", + "aliases": [ + "phone", + "telephone" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ž", + "description": "telephone receiver", + "category": "Objects", + "aliases": [ + "telephone_receiver" + ], + "tags": [ + "phone", + "call" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“Ÿ", + "description": "pager", + "category": "Objects", + "aliases": [ + "pager" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ ", + "description": "fax machine", + "category": "Objects", + "aliases": [ + "fax" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”‹", + "description": "battery", + "category": "Objects", + "aliases": [ + "battery" + ], + "tags": [ + "power" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿชซ", + "description": "low battery", + "category": "Objects", + "aliases": [ + "low_battery" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐Ÿ”Œ", + "description": "electric plug", + "category": "Objects", + "aliases": [ + "electric_plug" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’ป", + "description": "laptop", + "category": "Objects", + "aliases": [ + "computer" + ], + "tags": [ + "desktop", + "screen" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ–ฅ๏ธ", + "description": "desktop computer", + "category": "Objects", + "aliases": [ + "desktop_computer" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ–จ๏ธ", + "description": "printer", + "category": "Objects", + "aliases": [ + "printer" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "โŒจ๏ธ", + "description": "keyboard", + "category": "Objects", + "aliases": [ + "keyboard" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ–ฑ๏ธ", + "description": "computer mouse", + "category": "Objects", + "aliases": [ + "computer_mouse" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ–ฒ๏ธ", + "description": "trackball", + "category": "Objects", + "aliases": [ + "trackball" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ’ฝ", + "description": "computer disk", + "category": "Objects", + "aliases": [ + "minidisc" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’พ", + "description": "floppy disk", + "category": "Objects", + "aliases": [ + "floppy_disk" + ], + "tags": [ + "save" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’ฟ", + "description": "optical disk", + "category": "Objects", + "aliases": [ + "cd" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“€", + "description": "dvd", + "category": "Objects", + "aliases": [ + "dvd" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿงฎ", + "description": "abacus", + "category": "Objects", + "aliases": [ + "abacus" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐ŸŽฅ", + "description": "movie camera", + "category": "Objects", + "aliases": [ + "movie_camera" + ], + "tags": [ + "film", + "video" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽž๏ธ", + "description": "film frames", + "category": "Objects", + "aliases": [ + "film_strip" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ“ฝ๏ธ", + "description": "film projector", + "category": "Objects", + "aliases": [ + "film_projector" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐ŸŽฌ", + "description": "clapper board", + "category": "Objects", + "aliases": [ + "clapper" + ], + "tags": [ + "film" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“บ", + "description": "television", + "category": "Objects", + "aliases": [ + "tv" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ท", + "description": "camera", + "category": "Objects", + "aliases": [ + "camera" + ], + "tags": [ + "photo" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ธ", + "description": "camera with flash", + "category": "Objects", + "aliases": [ + "camera_flash" + ], + "tags": [ + "photo" + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ“น", + "description": "video camera", + "category": "Objects", + "aliases": [ + "video_camera" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ผ", + "description": "videocassette", + "category": "Objects", + "aliases": [ + "vhs" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”", + "description": "magnifying glass tilted left", + "category": "Objects", + "aliases": [ + "mag" + ], + "tags": [ + "search", + "zoom" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”Ž", + "description": "magnifying glass tilted right", + "category": "Objects", + "aliases": [ + "mag_right" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ•ฏ๏ธ", + "description": "candle", + "category": "Objects", + "aliases": [ + "candle" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ’ก", + "description": "light bulb", + "category": "Objects", + "aliases": [ + "bulb" + ], + "tags": [ + "idea", + "light" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”ฆ", + "description": "flashlight", + "category": "Objects", + "aliases": [ + "flashlight" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฎ", + "description": "red paper lantern", + "category": "Objects", + "aliases": [ + "izakaya_lantern", + "lantern" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿช”", + "description": "diya lamp", + "category": "Objects", + "aliases": [ + "diya_lamp" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿ“”", + "description": "notebook with decorative cover", + "category": "Objects", + "aliases": [ + "notebook_with_decorative_cover" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“•", + "description": "closed book", + "category": "Objects", + "aliases": [ + "closed_book" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“–", + "description": "open book", + "category": "Objects", + "aliases": [ + "book", + "open_book" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“—", + "description": "green book", + "category": "Objects", + "aliases": [ + "green_book" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“˜", + "description": "blue book", + "category": "Objects", + "aliases": [ + "blue_book" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“™", + "description": "orange book", + "category": "Objects", + "aliases": [ + "orange_book" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“š", + "description": "books", + "category": "Objects", + "aliases": [ + "books" + ], + "tags": [ + "library" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ““", + "description": "notebook", + "category": "Objects", + "aliases": [ + "notebook" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“’", + "description": "ledger", + "category": "Objects", + "aliases": [ + "ledger" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ƒ", + "description": "page with curl", + "category": "Objects", + "aliases": [ + "page_with_curl" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“œ", + "description": "scroll", + "category": "Objects", + "aliases": [ + "scroll" + ], + "tags": [ + "document" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“„", + "description": "page facing up", + "category": "Objects", + "aliases": [ + "page_facing_up" + ], + "tags": [ + "document" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ฐ", + "description": "newspaper", + "category": "Objects", + "aliases": [ + "newspaper" + ], + "tags": [ + "press" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ—ž๏ธ", + "description": "rolled-up newspaper", + "category": "Objects", + "aliases": [ + "newspaper_roll" + ], + "tags": [ + "press" + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ“‘", + "description": "bookmark tabs", + "category": "Objects", + "aliases": [ + "bookmark_tabs" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”–", + "description": "bookmark", + "category": "Objects", + "aliases": [ + "bookmark" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿท๏ธ", + "description": "label", + "category": "Objects", + "aliases": [ + "label" + ], + "tags": [ + "tag" + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ’ฐ", + "description": "money bag", + "category": "Objects", + "aliases": [ + "moneybag" + ], + "tags": [ + "dollar", + "cream" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿช™", + "description": "coin", + "category": "Objects", + "aliases": [ + "coin" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿ’ด", + "description": "yen banknote", + "category": "Objects", + "aliases": [ + "yen" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’ต", + "description": "dollar banknote", + "category": "Objects", + "aliases": [ + "dollar" + ], + "tags": [ + "money" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’ถ", + "description": "euro banknote", + "category": "Objects", + "aliases": [ + "euro" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’ท", + "description": "pound banknote", + "category": "Objects", + "aliases": [ + "pound" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’ธ", + "description": "money with wings", + "category": "Objects", + "aliases": [ + "money_with_wings" + ], + "tags": [ + "dollar" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’ณ", + "description": "credit card", + "category": "Objects", + "aliases": [ + "credit_card" + ], + "tags": [ + "subscription" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿงพ", + "description": "receipt", + "category": "Objects", + "aliases": [ + "receipt" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ’น", + "description": "chart increasing with yen", + "category": "Objects", + "aliases": [ + "chart" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โœ‰๏ธ", + "description": "envelope", + "category": "Objects", + "aliases": [ + "envelope" + ], + "tags": [ + "letter", + "email" + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ง", + "description": "e-mail", + "category": "Objects", + "aliases": [ + "email", + "e-mail" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“จ", + "description": "incoming envelope", + "category": "Objects", + "aliases": [ + "incoming_envelope" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ฉ", + "description": "envelope with arrow", + "category": "Objects", + "aliases": [ + "envelope_with_arrow" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ค", + "description": "outbox tray", + "category": "Objects", + "aliases": [ + "outbox_tray" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ฅ", + "description": "inbox tray", + "category": "Objects", + "aliases": [ + "inbox_tray" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ฆ", + "description": "package", + "category": "Objects", + "aliases": [ + "package" + ], + "tags": [ + "shipping" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ซ", + "description": "closed mailbox with raised flag", + "category": "Objects", + "aliases": [ + "mailbox" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ช", + "description": "closed mailbox with lowered flag", + "category": "Objects", + "aliases": [ + "mailbox_closed" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ฌ", + "description": "open mailbox with raised flag", + "category": "Objects", + "aliases": [ + "mailbox_with_mail" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ญ", + "description": "open mailbox with lowered flag", + "category": "Objects", + "aliases": [ + "mailbox_with_no_mail" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ฎ", + "description": "postbox", + "category": "Objects", + "aliases": [ + "postbox" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ—ณ๏ธ", + "description": "ballot box with ballot", + "category": "Objects", + "aliases": [ + "ballot_box" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "โœ๏ธ", + "description": "pencil", + "category": "Objects", + "aliases": [ + "pencil2" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โœ’๏ธ", + "description": "black nib", + "category": "Objects", + "aliases": [ + "black_nib" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ–‹๏ธ", + "description": "fountain pen", + "category": "Objects", + "aliases": [ + "fountain_pen" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ–Š๏ธ", + "description": "pen", + "category": "Objects", + "aliases": [ + "pen" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ–Œ๏ธ", + "description": "paintbrush", + "category": "Objects", + "aliases": [ + "paintbrush" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ–๏ธ", + "description": "crayon", + "category": "Objects", + "aliases": [ + "crayon" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ“", + "description": "memo", + "category": "Objects", + "aliases": [ + "memo", + "pencil" + ], + "tags": [ + "document", + "note" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’ผ", + "description": "briefcase", + "category": "Objects", + "aliases": [ + "briefcase" + ], + "tags": [ + "business" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“", + "description": "file folder", + "category": "Objects", + "aliases": [ + "file_folder" + ], + "tags": [ + "directory" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“‚", + "description": "open file folder", + "category": "Objects", + "aliases": [ + "open_file_folder" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ—‚๏ธ", + "description": "card index dividers", + "category": "Objects", + "aliases": [ + "card_index_dividers" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ“…", + "description": "calendar", + "category": "Objects", + "aliases": [ + "date" + ], + "tags": [ + "calendar", + "schedule" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“†", + "description": "tear-off calendar", + "category": "Objects", + "aliases": [ + "calendar" + ], + "tags": [ + "schedule" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ—’๏ธ", + "description": "spiral notepad", + "category": "Objects", + "aliases": [ + "spiral_notepad" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ—“๏ธ", + "description": "spiral calendar", + "category": "Objects", + "aliases": [ + "spiral_calendar" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ“‡", + "description": "card index", + "category": "Objects", + "aliases": [ + "card_index" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ˆ", + "description": "chart increasing", + "category": "Objects", + "aliases": [ + "chart_with_upwards_trend" + ], + "tags": [ + "graph", + "metrics" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“‰", + "description": "chart decreasing", + "category": "Objects", + "aliases": [ + "chart_with_downwards_trend" + ], + "tags": [ + "graph", + "metrics" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“Š", + "description": "bar chart", + "category": "Objects", + "aliases": [ + "bar_chart" + ], + "tags": [ + "stats", + "metrics" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“‹", + "description": "clipboard", + "category": "Objects", + "aliases": [ + "clipboard" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“Œ", + "description": "pushpin", + "category": "Objects", + "aliases": [ + "pushpin" + ], + "tags": [ + "location" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“", + "description": "round pushpin", + "category": "Objects", + "aliases": [ + "round_pushpin" + ], + "tags": [ + "location" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“Ž", + "description": "paperclip", + "category": "Objects", + "aliases": [ + "paperclip" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ–‡๏ธ", + "description": "linked paperclips", + "category": "Objects", + "aliases": [ + "paperclips" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ“", + "description": "straight ruler", + "category": "Objects", + "aliases": [ + "straight_ruler" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“", + "description": "triangular ruler", + "category": "Objects", + "aliases": [ + "triangular_ruler" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โœ‚๏ธ", + "description": "scissors", + "category": "Objects", + "aliases": [ + "scissors" + ], + "tags": [ + "cut" + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ—ƒ๏ธ", + "description": "card file box", + "category": "Objects", + "aliases": [ + "card_file_box" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ—„๏ธ", + "description": "file cabinet", + "category": "Objects", + "aliases": [ + "file_cabinet" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ—‘๏ธ", + "description": "wastebasket", + "category": "Objects", + "aliases": [ + "wastebasket" + ], + "tags": [ + "trash" + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ”’", + "description": "locked", + "category": "Objects", + "aliases": [ + "lock" + ], + "tags": [ + "security", + "private" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”“", + "description": "unlocked", + "category": "Objects", + "aliases": [ + "unlock" + ], + "tags": [ + "security" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”", + "description": "locked with pen", + "category": "Objects", + "aliases": [ + "lock_with_ink_pen" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”", + "description": "locked with key", + "category": "Objects", + "aliases": [ + "closed_lock_with_key" + ], + "tags": [ + "security" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”‘", + "description": "key", + "category": "Objects", + "aliases": [ + "key" + ], + "tags": [ + "lock", + "password" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ—๏ธ", + "description": "old key", + "category": "Objects", + "aliases": [ + "old_key" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ”จ", + "description": "hammer", + "category": "Objects", + "aliases": [ + "hammer" + ], + "tags": [ + "tool" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿช“", + "description": "axe", + "category": "Objects", + "aliases": [ + "axe" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "โ›๏ธ", + "description": "pick", + "category": "Objects", + "aliases": [ + "pick" + ], + "tags": [ + + ], + "unicode_version": "5.2", + "ios_version": "9.1" + }, + { + "emoji": "โš’๏ธ", + "description": "hammer and pick", + "category": "Objects", + "aliases": [ + "hammer_and_pick" + ], + "tags": [ + + ], + "unicode_version": "4.1", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ› ๏ธ", + "description": "hammer and wrench", + "category": "Objects", + "aliases": [ + "hammer_and_wrench" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ—ก๏ธ", + "description": "dagger", + "category": "Objects", + "aliases": [ + "dagger" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "โš”๏ธ", + "description": "crossed swords", + "category": "Objects", + "aliases": [ + "crossed_swords" + ], + "tags": [ + + ], + "unicode_version": "4.1", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ”ซ", + "description": "water pistol", + "category": "Objects", + "aliases": [ + "gun" + ], + "tags": [ + "shoot", + "weapon" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿชƒ", + "description": "boomerang", + "category": "Objects", + "aliases": [ + "boomerang" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿน", + "description": "bow and arrow", + "category": "Objects", + "aliases": [ + "bow_and_arrow" + ], + "tags": [ + "archery" + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ›ก๏ธ", + "description": "shield", + "category": "Objects", + "aliases": [ + "shield" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿชš", + "description": "carpentry saw", + "category": "Objects", + "aliases": [ + "carpentry_saw" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿ”ง", + "description": "wrench", + "category": "Objects", + "aliases": [ + "wrench" + ], + "tags": [ + "tool" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿช›", + "description": "screwdriver", + "category": "Objects", + "aliases": [ + "screwdriver" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿ”ฉ", + "description": "nut and bolt", + "category": "Objects", + "aliases": [ + "nut_and_bolt" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โš™๏ธ", + "description": "gear", + "category": "Objects", + "aliases": [ + "gear" + ], + "tags": [ + + ], + "unicode_version": "4.1", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ—œ๏ธ", + "description": "clamp", + "category": "Objects", + "aliases": [ + "clamp" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "โš–๏ธ", + "description": "balance scale", + "category": "Objects", + "aliases": [ + "balance_scale" + ], + "tags": [ + + ], + "unicode_version": "4.1", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿฆฏ", + "description": "white cane", + "category": "Objects", + "aliases": [ + "probing_cane" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿ”—", + "description": "link", + "category": "Objects", + "aliases": [ + "link" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โ›“๏ธ", + "description": "chains", + "category": "Objects", + "aliases": [ + "chains" + ], + "tags": [ + + ], + "unicode_version": "5.2", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿช", + "description": "hook", + "category": "Objects", + "aliases": [ + "hook" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿงฐ", + "description": "toolbox", + "category": "Objects", + "aliases": [ + "toolbox" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿงฒ", + "description": "magnet", + "category": "Objects", + "aliases": [ + "magnet" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿชœ", + "description": "ladder", + "category": "Objects", + "aliases": [ + "ladder" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "โš—๏ธ", + "description": "alembic", + "category": "Objects", + "aliases": [ + "alembic" + ], + "tags": [ + + ], + "unicode_version": "4.1", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿงช", + "description": "test tube", + "category": "Objects", + "aliases": [ + "test_tube" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿงซ", + "description": "petri dish", + "category": "Objects", + "aliases": [ + "petri_dish" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿงฌ", + "description": "dna", + "category": "Objects", + "aliases": [ + "dna" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ”ฌ", + "description": "microscope", + "category": "Objects", + "aliases": [ + "microscope" + ], + "tags": [ + "science", + "laboratory", + "investigate" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”ญ", + "description": "telescope", + "category": "Objects", + "aliases": [ + "telescope" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ก", + "description": "satellite antenna", + "category": "Objects", + "aliases": [ + "satellite" + ], + "tags": [ + "signal" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’‰", + "description": "syringe", + "category": "Objects", + "aliases": [ + "syringe" + ], + "tags": [ + "health", + "hospital", + "needle" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฉธ", + "description": "drop of blood", + "category": "Objects", + "aliases": [ + "drop_of_blood" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿ’Š", + "description": "pill", + "category": "Objects", + "aliases": [ + "pill" + ], + "tags": [ + "health", + "medicine" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿฉน", + "description": "adhesive bandage", + "category": "Objects", + "aliases": [ + "adhesive_bandage" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿฉผ", + "description": "crutch", + "category": "Objects", + "aliases": [ + "crutch" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐Ÿฉบ", + "description": "stethoscope", + "category": "Objects", + "aliases": [ + "stethoscope" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿฉป", + "description": "x-ray", + "category": "Objects", + "aliases": [ + "x_ray" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐Ÿšช", + "description": "door", + "category": "Objects", + "aliases": [ + "door" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ›—", + "description": "elevator", + "category": "Objects", + "aliases": [ + "elevator" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿชž", + "description": "mirror", + "category": "Objects", + "aliases": [ + "mirror" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐ŸชŸ", + "description": "window", + "category": "Objects", + "aliases": [ + "window" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿ›๏ธ", + "description": "bed", + "category": "Objects", + "aliases": [ + "bed" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ›‹๏ธ", + "description": "couch and lamp", + "category": "Objects", + "aliases": [ + "couch_and_lamp" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿช‘", + "description": "chair", + "category": "Objects", + "aliases": [ + "chair" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿšฝ", + "description": "toilet", + "category": "Objects", + "aliases": [ + "toilet" + ], + "tags": [ + "wc" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿช ", + "description": "plunger", + "category": "Objects", + "aliases": [ + "plunger" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿšฟ", + "description": "shower", + "category": "Objects", + "aliases": [ + "shower" + ], + "tags": [ + "bath" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ›", + "description": "bathtub", + "category": "Objects", + "aliases": [ + "bathtub" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿชค", + "description": "mouse trap", + "category": "Objects", + "aliases": [ + "mouse_trap" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿช’", + "description": "razor", + "category": "Objects", + "aliases": [ + "razor" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿงด", + "description": "lotion bottle", + "category": "Objects", + "aliases": [ + "lotion_bottle" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿงท", + "description": "safety pin", + "category": "Objects", + "aliases": [ + "safety_pin" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿงน", + "description": "broom", + "category": "Objects", + "aliases": [ + "broom" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿงบ", + "description": "basket", + "category": "Objects", + "aliases": [ + "basket" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿงป", + "description": "roll of paper", + "category": "Objects", + "aliases": [ + "roll_of_paper" + ], + "tags": [ + "toilet" + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿชฃ", + "description": "bucket", + "category": "Objects", + "aliases": [ + "bucket" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿงผ", + "description": "soap", + "category": "Objects", + "aliases": [ + "soap" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿซง", + "description": "bubbles", + "category": "Objects", + "aliases": [ + "bubbles" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐Ÿชฅ", + "description": "toothbrush", + "category": "Objects", + "aliases": [ + "toothbrush" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿงฝ", + "description": "sponge", + "category": "Objects", + "aliases": [ + "sponge" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿงฏ", + "description": "fire extinguisher", + "category": "Objects", + "aliases": [ + "fire_extinguisher" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ›’", + "description": "shopping cart", + "category": "Objects", + "aliases": [ + "shopping_cart" + ], + "tags": [ + + ], + "unicode_version": "9.0", + "ios_version": "10.2" + }, + { + "emoji": "๐Ÿšฌ", + "description": "cigarette", + "category": "Objects", + "aliases": [ + "smoking" + ], + "tags": [ + "cigarette" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โšฐ๏ธ", + "description": "coffin", + "category": "Objects", + "aliases": [ + "coffin" + ], + "tags": [ + "funeral" + ], + "unicode_version": "4.1", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿชฆ", + "description": "headstone", + "category": "Objects", + "aliases": [ + "headstone" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "โšฑ๏ธ", + "description": "funeral urn", + "category": "Objects", + "aliases": [ + "funeral_urn" + ], + "tags": [ + + ], + "unicode_version": "4.1", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ—ฟ", + "description": "moai", + "category": "Objects", + "aliases": [ + "moyai" + ], + "tags": [ + "stone" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿชง", + "description": "placard", + "category": "Objects", + "aliases": [ + "placard" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿชช", + "description": "identification card", + "category": "Objects", + "aliases": [ + "identification_card" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "๐Ÿง", + "description": "ATM sign", + "category": "Symbols", + "aliases": [ + "atm" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿšฎ", + "description": "litter in bin sign", + "category": "Symbols", + "aliases": [ + "put_litter_in_its_place" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿšฐ", + "description": "potable water", + "category": "Symbols", + "aliases": [ + "potable_water" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โ™ฟ", + "description": "wheelchair symbol", + "category": "Symbols", + "aliases": [ + "wheelchair" + ], + "tags": [ + "accessibility" + ], + "unicode_version": "4.1", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿšน", + "description": "menโ€™s room", + "category": "Symbols", + "aliases": [ + "mens" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿšบ", + "description": "womenโ€™s room", + "category": "Symbols", + "aliases": [ + "womens" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿšป", + "description": "restroom", + "category": "Symbols", + "aliases": [ + "restroom" + ], + "tags": [ + "toilet" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿšผ", + "description": "baby symbol", + "category": "Symbols", + "aliases": [ + "baby_symbol" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿšพ", + "description": "water closet", + "category": "Symbols", + "aliases": [ + "wc" + ], + "tags": [ + "toilet", + "restroom" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ›‚", + "description": "passport control", + "category": "Symbols", + "aliases": [ + "passport_control" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ›ƒ", + "description": "customs", + "category": "Symbols", + "aliases": [ + "customs" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ›„", + "description": "baggage claim", + "category": "Symbols", + "aliases": [ + "baggage_claim" + ], + "tags": [ + "airport" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ›…", + "description": "left luggage", + "category": "Symbols", + "aliases": [ + "left_luggage" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โš ๏ธ", + "description": "warning", + "category": "Symbols", + "aliases": [ + "warning" + ], + "tags": [ + "wip" + ], + "unicode_version": "4.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿšธ", + "description": "children crossing", + "category": "Symbols", + "aliases": [ + "children_crossing" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โ›”", + "description": "no entry", + "category": "Symbols", + "aliases": [ + "no_entry" + ], + "tags": [ + "limit" + ], + "unicode_version": "5.2", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿšซ", + "description": "prohibited", + "category": "Symbols", + "aliases": [ + "no_entry_sign" + ], + "tags": [ + "block", + "forbidden" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿšณ", + "description": "no bicycles", + "category": "Symbols", + "aliases": [ + "no_bicycles" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿšญ", + "description": "no smoking", + "category": "Symbols", + "aliases": [ + "no_smoking" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿšฏ", + "description": "no littering", + "category": "Symbols", + "aliases": [ + "do_not_litter" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿšฑ", + "description": "non-potable water", + "category": "Symbols", + "aliases": [ + "non-potable_water" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿšท", + "description": "no pedestrians", + "category": "Symbols", + "aliases": [ + "no_pedestrians" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ต", + "description": "no mobile phones", + "category": "Symbols", + "aliases": [ + "no_mobile_phones" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”ž", + "description": "no one under eighteen", + "category": "Symbols", + "aliases": [ + "underage" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โ˜ข๏ธ", + "description": "radioactive", + "category": "Symbols", + "aliases": [ + "radioactive" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "9.1" + }, + { + "emoji": "โ˜ฃ๏ธ", + "description": "biohazard", + "category": "Symbols", + "aliases": [ + "biohazard" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "9.1" + }, + { + "emoji": "โฌ†๏ธ", + "description": "up arrow", + "category": "Symbols", + "aliases": [ + "arrow_up" + ], + "tags": [ + + ], + "unicode_version": "4.0", + "ios_version": "6.0" + }, + { + "emoji": "โ†—๏ธ", + "description": "up-right arrow", + "category": "Symbols", + "aliases": [ + "arrow_upper_right" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โžก๏ธ", + "description": "right arrow", + "category": "Symbols", + "aliases": [ + "arrow_right" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ†˜๏ธ", + "description": "down-right arrow", + "category": "Symbols", + "aliases": [ + "arrow_lower_right" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โฌ‡๏ธ", + "description": "down arrow", + "category": "Symbols", + "aliases": [ + "arrow_down" + ], + "tags": [ + + ], + "unicode_version": "4.0", + "ios_version": "6.0" + }, + { + "emoji": "โ†™๏ธ", + "description": "down-left arrow", + "category": "Symbols", + "aliases": [ + "arrow_lower_left" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โฌ…๏ธ", + "description": "left arrow", + "category": "Symbols", + "aliases": [ + "arrow_left" + ], + "tags": [ + + ], + "unicode_version": "4.0", + "ios_version": "6.0" + }, + { + "emoji": "โ†–๏ธ", + "description": "up-left arrow", + "category": "Symbols", + "aliases": [ + "arrow_upper_left" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ†•๏ธ", + "description": "up-down arrow", + "category": "Symbols", + "aliases": [ + "arrow_up_down" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ†”๏ธ", + "description": "left-right arrow", + "category": "Symbols", + "aliases": [ + "left_right_arrow" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ†ฉ๏ธ", + "description": "right arrow curving left", + "category": "Symbols", + "aliases": [ + "leftwards_arrow_with_hook" + ], + "tags": [ + "return" + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ†ช๏ธ", + "description": "left arrow curving right", + "category": "Symbols", + "aliases": [ + "arrow_right_hook" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โคด๏ธ", + "description": "right arrow curving up", + "category": "Symbols", + "aliases": [ + "arrow_heading_up" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โคต๏ธ", + "description": "right arrow curving down", + "category": "Symbols", + "aliases": [ + "arrow_heading_down" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”ƒ", + "description": "clockwise vertical arrows", + "category": "Symbols", + "aliases": [ + "arrows_clockwise" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”„", + "description": "counterclockwise arrows button", + "category": "Symbols", + "aliases": [ + "arrows_counterclockwise" + ], + "tags": [ + "sync" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”™", + "description": "BACK arrow", + "category": "Symbols", + "aliases": [ + "back" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”š", + "description": "END arrow", + "category": "Symbols", + "aliases": [ + "end" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”›", + "description": "ON! arrow", + "category": "Symbols", + "aliases": [ + "on" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”œ", + "description": "SOON arrow", + "category": "Symbols", + "aliases": [ + "soon" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”", + "description": "TOP arrow", + "category": "Symbols", + "aliases": [ + "top" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ›", + "description": "place of worship", + "category": "Symbols", + "aliases": [ + "place_of_worship" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "โš›๏ธ", + "description": "atom symbol", + "category": "Symbols", + "aliases": [ + "atom_symbol" + ], + "tags": [ + + ], + "unicode_version": "4.1", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ•‰๏ธ", + "description": "om", + "category": "Symbols", + "aliases": [ + "om" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "โœก๏ธ", + "description": "star of David", + "category": "Symbols", + "aliases": [ + "star_of_david" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "9.1" + }, + { + "emoji": "โ˜ธ๏ธ", + "description": "wheel of dharma", + "category": "Symbols", + "aliases": [ + "wheel_of_dharma" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "9.1" + }, + { + "emoji": "โ˜ฏ๏ธ", + "description": "yin yang", + "category": "Symbols", + "aliases": [ + "yin_yang" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "9.1" + }, + { + "emoji": "โœ๏ธ", + "description": "latin cross", + "category": "Symbols", + "aliases": [ + "latin_cross" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "9.1" + }, + { + "emoji": "โ˜ฆ๏ธ", + "description": "orthodox cross", + "category": "Symbols", + "aliases": [ + "orthodox_cross" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "9.1" + }, + { + "emoji": "โ˜ช๏ธ", + "description": "star and crescent", + "category": "Symbols", + "aliases": [ + "star_and_crescent" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "9.1" + }, + { + "emoji": "โ˜ฎ๏ธ", + "description": "peace symbol", + "category": "Symbols", + "aliases": [ + "peace_symbol" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ•Ž", + "description": "menorah", + "category": "Symbols", + "aliases": [ + "menorah" + ], + "tags": [ + + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ”ฏ", + "description": "dotted six-pointed star", + "category": "Symbols", + "aliases": [ + "six_pointed_star" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โ™ˆ", + "description": "Aries", + "category": "Symbols", + "aliases": [ + "aries" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ™‰", + "description": "Taurus", + "category": "Symbols", + "aliases": [ + "taurus" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ™Š", + "description": "Gemini", + "category": "Symbols", + "aliases": [ + "gemini" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ™‹", + "description": "Cancer", + "category": "Symbols", + "aliases": [ + "cancer" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ™Œ", + "description": "Leo", + "category": "Symbols", + "aliases": [ + "leo" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ™", + "description": "Virgo", + "category": "Symbols", + "aliases": [ + "virgo" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ™Ž", + "description": "Libra", + "category": "Symbols", + "aliases": [ + "libra" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ™", + "description": "Scorpio", + "category": "Symbols", + "aliases": [ + "scorpius" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ™", + "description": "Sagittarius", + "category": "Symbols", + "aliases": [ + "sagittarius" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ™‘", + "description": "Capricorn", + "category": "Symbols", + "aliases": [ + "capricorn" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ™’", + "description": "Aquarius", + "category": "Symbols", + "aliases": [ + "aquarius" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ™“", + "description": "Pisces", + "category": "Symbols", + "aliases": [ + "pisces" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ›Ž", + "description": "Ophiuchus", + "category": "Symbols", + "aliases": [ + "ophiuchus" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”€", + "description": "shuffle tracks button", + "category": "Symbols", + "aliases": [ + "twisted_rightwards_arrows" + ], + "tags": [ + "shuffle" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”", + "description": "repeat button", + "category": "Symbols", + "aliases": [ + "repeat" + ], + "tags": [ + "loop" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”‚", + "description": "repeat single button", + "category": "Symbols", + "aliases": [ + "repeat_one" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โ–ถ๏ธ", + "description": "play button", + "category": "Symbols", + "aliases": [ + "arrow_forward" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โฉ", + "description": "fast-forward button", + "category": "Symbols", + "aliases": [ + "fast_forward" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โญ๏ธ", + "description": "next track button", + "category": "Symbols", + "aliases": [ + "next_track_button" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.1" + }, + { + "emoji": "โฏ๏ธ", + "description": "play or pause button", + "category": "Symbols", + "aliases": [ + "play_or_pause_button" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.1" + }, + { + "emoji": "โ—€๏ธ", + "description": "reverse button", + "category": "Symbols", + "aliases": [ + "arrow_backward" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โช", + "description": "fast reverse button", + "category": "Symbols", + "aliases": [ + "rewind" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โฎ๏ธ", + "description": "last track button", + "category": "Symbols", + "aliases": [ + "previous_track_button" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ”ผ", + "description": "upwards button", + "category": "Symbols", + "aliases": [ + "arrow_up_small" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โซ", + "description": "fast up button", + "category": "Symbols", + "aliases": [ + "arrow_double_up" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”ฝ", + "description": "downwards button", + "category": "Symbols", + "aliases": [ + "arrow_down_small" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โฌ", + "description": "fast down button", + "category": "Symbols", + "aliases": [ + "arrow_double_down" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โธ๏ธ", + "description": "pause button", + "category": "Symbols", + "aliases": [ + "pause_button" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "โน๏ธ", + "description": "stop button", + "category": "Symbols", + "aliases": [ + "stop_button" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "โบ๏ธ", + "description": "record button", + "category": "Symbols", + "aliases": [ + "record_button" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "โ๏ธ", + "description": "eject button", + "category": "Symbols", + "aliases": [ + "eject_button" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐ŸŽฆ", + "description": "cinema", + "category": "Symbols", + "aliases": [ + "cinema" + ], + "tags": [ + "film", + "movie" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”…", + "description": "dim button", + "category": "Symbols", + "aliases": [ + "low_brightness" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”†", + "description": "bright button", + "category": "Symbols", + "aliases": [ + "high_brightness" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ถ", + "description": "antenna bars", + "category": "Symbols", + "aliases": [ + "signal_strength" + ], + "tags": [ + "wifi" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ณ", + "description": "vibration mode", + "category": "Symbols", + "aliases": [ + "vibration_mode" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“ด", + "description": "mobile phone off", + "category": "Symbols", + "aliases": [ + "mobile_phone_off" + ], + "tags": [ + "mute", + "off" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โ™€๏ธ", + "description": "female sign", + "category": "Symbols", + "aliases": [ + "female_sign" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "โ™‚๏ธ", + "description": "male sign", + "category": "Symbols", + "aliases": [ + "male_sign" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "โšง๏ธ", + "description": "transgender symbol", + "category": "Symbols", + "aliases": [ + "transgender_symbol" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "โœ–๏ธ", + "description": "multiply", + "category": "Symbols", + "aliases": [ + "heavy_multiplication_x" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โž•", + "description": "plus", + "category": "Symbols", + "aliases": [ + "heavy_plus_sign" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โž–", + "description": "minus", + "category": "Symbols", + "aliases": [ + "heavy_minus_sign" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โž—", + "description": "divide", + "category": "Symbols", + "aliases": [ + "heavy_division_sign" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŸฐ", + "description": "heavy equals sign", + "category": "Symbols", + "aliases": [ + "heavy_equals_sign" + ], + "tags": [ + + ], + "unicode_version": "14.0", + "ios_version": "15.4" + }, + { + "emoji": "โ™พ๏ธ", + "description": "infinity", + "category": "Symbols", + "aliases": [ + "infinity" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "โ€ผ๏ธ", + "description": "double exclamation mark", + "category": "Symbols", + "aliases": [ + "bangbang" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ‰๏ธ", + "description": "exclamation question mark", + "category": "Symbols", + "aliases": [ + "interrobang" + ], + "tags": [ + + ], + "unicode_version": "3.0", + "ios_version": "6.0" + }, + { + "emoji": "โ“", + "description": "red question mark", + "category": "Symbols", + "aliases": [ + "question" + ], + "tags": [ + "confused" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โ”", + "description": "white question mark", + "category": "Symbols", + "aliases": [ + "grey_question" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โ•", + "description": "white exclamation mark", + "category": "Symbols", + "aliases": [ + "grey_exclamation" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โ—", + "description": "red exclamation mark", + "category": "Symbols", + "aliases": [ + "exclamation", + "heavy_exclamation_mark" + ], + "tags": [ + "bang" + ], + "unicode_version": "5.2", + "ios_version": "6.0" + }, + { + "emoji": "ใ€ฐ๏ธ", + "description": "wavy dash", + "category": "Symbols", + "aliases": [ + "wavy_dash" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’ฑ", + "description": "currency exchange", + "category": "Symbols", + "aliases": [ + "currency_exchange" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’ฒ", + "description": "heavy dollar sign", + "category": "Symbols", + "aliases": [ + "heavy_dollar_sign" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โš•๏ธ", + "description": "medical symbol", + "category": "Symbols", + "aliases": [ + "medical_symbol" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "โ™ป๏ธ", + "description": "recycling symbol", + "category": "Symbols", + "aliases": [ + "recycle" + ], + "tags": [ + "environment", + "green" + ], + "unicode_version": "3.2", + "ios_version": "6.0" + }, + { + "emoji": "โšœ๏ธ", + "description": "fleur-de-lis", + "category": "Symbols", + "aliases": [ + "fleur_de_lis" + ], + "tags": [ + + ], + "unicode_version": "4.1", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ”ฑ", + "description": "trident emblem", + "category": "Symbols", + "aliases": [ + "trident" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ“›", + "description": "name badge", + "category": "Symbols", + "aliases": [ + "name_badge" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”ฐ", + "description": "Japanese symbol for beginner", + "category": "Symbols", + "aliases": [ + "beginner" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โญ•", + "description": "hollow red circle", + "category": "Symbols", + "aliases": [ + "o" + ], + "tags": [ + + ], + "unicode_version": "5.2", + "ios_version": "6.0" + }, + { + "emoji": "โœ…", + "description": "check mark button", + "category": "Symbols", + "aliases": [ + "white_check_mark" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โ˜‘๏ธ", + "description": "check box with check", + "category": "Symbols", + "aliases": [ + "ballot_box_with_check" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โœ”๏ธ", + "description": "check mark", + "category": "Symbols", + "aliases": [ + "heavy_check_mark" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โŒ", + "description": "cross mark", + "category": "Symbols", + "aliases": [ + "x" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โŽ", + "description": "cross mark button", + "category": "Symbols", + "aliases": [ + "negative_squared_cross_mark" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โžฐ", + "description": "curly loop", + "category": "Symbols", + "aliases": [ + "curly_loop" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โžฟ", + "description": "double curly loop", + "category": "Symbols", + "aliases": [ + "loop" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "ใ€ฝ๏ธ", + "description": "part alternation mark", + "category": "Symbols", + "aliases": [ + "part_alternation_mark" + ], + "tags": [ + + ], + "unicode_version": "3.2", + "ios_version": "6.0" + }, + { + "emoji": "โœณ๏ธ", + "description": "eight-spoked asterisk", + "category": "Symbols", + "aliases": [ + "eight_spoked_asterisk" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โœด๏ธ", + "description": "eight-pointed star", + "category": "Symbols", + "aliases": [ + "eight_pointed_black_star" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ‡๏ธ", + "description": "sparkle", + "category": "Symbols", + "aliases": [ + "sparkle" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "ยฉ๏ธ", + "description": "copyright", + "category": "Symbols", + "aliases": [ + "copyright" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "ยฎ๏ธ", + "description": "registered", + "category": "Symbols", + "aliases": [ + "registered" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ„ข๏ธ", + "description": "trade mark", + "category": "Symbols", + "aliases": [ + "tm" + ], + "tags": [ + "trademark" + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "#๏ธโƒฃ", + "description": "keycap: #", + "category": "Symbols", + "aliases": [ + "hash" + ], + "tags": [ + "number" + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "*๏ธโƒฃ", + "description": "keycap: *", + "category": "Symbols", + "aliases": [ + "asterisk" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "9.1" + }, + { + "emoji": "0๏ธโƒฃ", + "description": "keycap: 0", + "category": "Symbols", + "aliases": [ + "zero" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "1๏ธโƒฃ", + "description": "keycap: 1", + "category": "Symbols", + "aliases": [ + "one" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "2๏ธโƒฃ", + "description": "keycap: 2", + "category": "Symbols", + "aliases": [ + "two" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "3๏ธโƒฃ", + "description": "keycap: 3", + "category": "Symbols", + "aliases": [ + "three" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "4๏ธโƒฃ", + "description": "keycap: 4", + "category": "Symbols", + "aliases": [ + "four" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "5๏ธโƒฃ", + "description": "keycap: 5", + "category": "Symbols", + "aliases": [ + "five" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "6๏ธโƒฃ", + "description": "keycap: 6", + "category": "Symbols", + "aliases": [ + "six" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "7๏ธโƒฃ", + "description": "keycap: 7", + "category": "Symbols", + "aliases": [ + "seven" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "8๏ธโƒฃ", + "description": "keycap: 8", + "category": "Symbols", + "aliases": [ + "eight" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "9๏ธโƒฃ", + "description": "keycap: 9", + "category": "Symbols", + "aliases": [ + "nine" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”Ÿ", + "description": "keycap: 10", + "category": "Symbols", + "aliases": [ + "keycap_ten" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ” ", + "description": "input latin uppercase", + "category": "Symbols", + "aliases": [ + "capital_abcd" + ], + "tags": [ + "letters" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”ก", + "description": "input latin lowercase", + "category": "Symbols", + "aliases": [ + "abcd" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”ข", + "description": "input numbers", + "category": "Symbols", + "aliases": [ + "1234" + ], + "tags": [ + "numbers" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”ฃ", + "description": "input symbols", + "category": "Symbols", + "aliases": [ + "symbols" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”ค", + "description": "input latin letters", + "category": "Symbols", + "aliases": [ + "abc" + ], + "tags": [ + "alphabet" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ…ฐ๏ธ", + "description": "A button (blood type)", + "category": "Symbols", + "aliases": [ + "a" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ†Ž", + "description": "AB button (blood type)", + "category": "Symbols", + "aliases": [ + "ab" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ…ฑ๏ธ", + "description": "B button (blood type)", + "category": "Symbols", + "aliases": [ + "b" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ†‘", + "description": "CL button", + "category": "Symbols", + "aliases": [ + "cl" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ†’", + "description": "COOL button", + "category": "Symbols", + "aliases": [ + "cool" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ†“", + "description": "FREE button", + "category": "Symbols", + "aliases": [ + "free" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โ„น๏ธ", + "description": "information", + "category": "Symbols", + "aliases": [ + "information_source" + ], + "tags": [ + + ], + "unicode_version": "3.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ†”", + "description": "ID button", + "category": "Symbols", + "aliases": [ + "id" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "โ“‚๏ธ", + "description": "circled M", + "category": "Symbols", + "aliases": [ + "m" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ†•", + "description": "NEW button", + "category": "Symbols", + "aliases": [ + "new" + ], + "tags": [ + "fresh" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ†–", + "description": "NG button", + "category": "Symbols", + "aliases": [ + "ng" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ…พ๏ธ", + "description": "O button (blood type)", + "category": "Symbols", + "aliases": [ + "o2" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ†—", + "description": "OK button", + "category": "Symbols", + "aliases": [ + "ok" + ], + "tags": [ + "yes" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ…ฟ๏ธ", + "description": "P button", + "category": "Symbols", + "aliases": [ + "parking" + ], + "tags": [ + + ], + "unicode_version": "5.2", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ†˜", + "description": "SOS button", + "category": "Symbols", + "aliases": [ + "sos" + ], + "tags": [ + "help", + "emergency" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ†™", + "description": "UP! button", + "category": "Symbols", + "aliases": [ + "up" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ†š", + "description": "VS button", + "category": "Symbols", + "aliases": [ + "vs" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿˆ", + "description": "Japanese โ€œhereโ€ button", + "category": "Symbols", + "aliases": [ + "koko" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿˆ‚๏ธ", + "description": "Japanese โ€œservice chargeโ€ button", + "category": "Symbols", + "aliases": [ + "sa" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿˆท๏ธ", + "description": "Japanese โ€œmonthly amountโ€ button", + "category": "Symbols", + "aliases": [ + "u6708" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿˆถ", + "description": "Japanese โ€œnot free of chargeโ€ button", + "category": "Symbols", + "aliases": [ + "u6709" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿˆฏ", + "description": "Japanese โ€œreservedโ€ button", + "category": "Symbols", + "aliases": [ + "u6307" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‰", + "description": "Japanese โ€œbargainโ€ button", + "category": "Symbols", + "aliases": [ + "ideograph_advantage" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿˆน", + "description": "Japanese โ€œdiscountโ€ button", + "category": "Symbols", + "aliases": [ + "u5272" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿˆš", + "description": "Japanese โ€œfree of chargeโ€ button", + "category": "Symbols", + "aliases": [ + "u7121" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿˆฒ", + "description": "Japanese โ€œprohibitedโ€ button", + "category": "Symbols", + "aliases": [ + "u7981" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‰‘", + "description": "Japanese โ€œacceptableโ€ button", + "category": "Symbols", + "aliases": [ + "accept" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿˆธ", + "description": "Japanese โ€œapplicationโ€ button", + "category": "Symbols", + "aliases": [ + "u7533" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿˆด", + "description": "Japanese โ€œpassing gradeโ€ button", + "category": "Symbols", + "aliases": [ + "u5408" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿˆณ", + "description": "Japanese โ€œvacancyโ€ button", + "category": "Symbols", + "aliases": [ + "u7a7a" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "ใŠ—๏ธ", + "description": "Japanese โ€œcongratulationsโ€ button", + "category": "Symbols", + "aliases": [ + "congratulations" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "ใŠ™๏ธ", + "description": "Japanese โ€œsecretโ€ button", + "category": "Symbols", + "aliases": [ + "secret" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿˆบ", + "description": "Japanese โ€œopen for businessโ€ button", + "category": "Symbols", + "aliases": [ + "u55b6" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿˆต", + "description": "Japanese โ€œno vacancyโ€ button", + "category": "Symbols", + "aliases": [ + "u6e80" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”ด", + "description": "red circle", + "category": "Symbols", + "aliases": [ + "red_circle" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŸ ", + "description": "orange circle", + "category": "Symbols", + "aliases": [ + "orange_circle" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐ŸŸก", + "description": "yellow circle", + "category": "Symbols", + "aliases": [ + "yellow_circle" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐ŸŸข", + "description": "green circle", + "category": "Symbols", + "aliases": [ + "green_circle" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐Ÿ”ต", + "description": "blue circle", + "category": "Symbols", + "aliases": [ + "large_blue_circle" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŸฃ", + "description": "purple circle", + "category": "Symbols", + "aliases": [ + "purple_circle" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐ŸŸค", + "description": "brown circle", + "category": "Symbols", + "aliases": [ + "brown_circle" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "โšซ", + "description": "black circle", + "category": "Symbols", + "aliases": [ + "black_circle" + ], + "tags": [ + + ], + "unicode_version": "4.1", + "ios_version": "6.0" + }, + { + "emoji": "โšช", + "description": "white circle", + "category": "Symbols", + "aliases": [ + "white_circle" + ], + "tags": [ + + ], + "unicode_version": "4.1", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŸฅ", + "description": "red square", + "category": "Symbols", + "aliases": [ + "red_square" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐ŸŸง", + "description": "orange square", + "category": "Symbols", + "aliases": [ + "orange_square" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐ŸŸจ", + "description": "yellow square", + "category": "Symbols", + "aliases": [ + "yellow_square" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐ŸŸฉ", + "description": "green square", + "category": "Symbols", + "aliases": [ + "green_square" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐ŸŸฆ", + "description": "blue square", + "category": "Symbols", + "aliases": [ + "blue_square" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐ŸŸช", + "description": "purple square", + "category": "Symbols", + "aliases": [ + "purple_square" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "๐ŸŸซ", + "description": "brown square", + "category": "Symbols", + "aliases": [ + "brown_square" + ], + "tags": [ + + ], + "unicode_version": "12.0", + "ios_version": "13.0" + }, + { + "emoji": "โฌ›", + "description": "black large square", + "category": "Symbols", + "aliases": [ + "black_large_square" + ], + "tags": [ + + ], + "unicode_version": "5.1", + "ios_version": "6.0" + }, + { + "emoji": "โฌœ", + "description": "white large square", + "category": "Symbols", + "aliases": [ + "white_large_square" + ], + "tags": [ + + ], + "unicode_version": "5.1", + "ios_version": "6.0" + }, + { + "emoji": "โ—ผ๏ธ", + "description": "black medium square", + "category": "Symbols", + "aliases": [ + "black_medium_square" + ], + "tags": [ + + ], + "unicode_version": "3.2", + "ios_version": "6.0" + }, + { + "emoji": "โ—ป๏ธ", + "description": "white medium square", + "category": "Symbols", + "aliases": [ + "white_medium_square" + ], + "tags": [ + + ], + "unicode_version": "3.2", + "ios_version": "6.0" + }, + { + "emoji": "โ—พ", + "description": "black medium-small square", + "category": "Symbols", + "aliases": [ + "black_medium_small_square" + ], + "tags": [ + + ], + "unicode_version": "3.2", + "ios_version": "6.0" + }, + { + "emoji": "โ—ฝ", + "description": "white medium-small square", + "category": "Symbols", + "aliases": [ + "white_medium_small_square" + ], + "tags": [ + + ], + "unicode_version": "3.2", + "ios_version": "6.0" + }, + { + "emoji": "โ–ช๏ธ", + "description": "black small square", + "category": "Symbols", + "aliases": [ + "black_small_square" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "โ–ซ๏ธ", + "description": "white small square", + "category": "Symbols", + "aliases": [ + "white_small_square" + ], + "tags": [ + + ], + "unicode_version": "", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”ถ", + "description": "large orange diamond", + "category": "Symbols", + "aliases": [ + "large_orange_diamond" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”ท", + "description": "large blue diamond", + "category": "Symbols", + "aliases": [ + "large_blue_diamond" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”ธ", + "description": "small orange diamond", + "category": "Symbols", + "aliases": [ + "small_orange_diamond" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”น", + "description": "small blue diamond", + "category": "Symbols", + "aliases": [ + "small_blue_diamond" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”บ", + "description": "red triangle pointed up", + "category": "Symbols", + "aliases": [ + "small_red_triangle" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”ป", + "description": "red triangle pointed down", + "category": "Symbols", + "aliases": [ + "small_red_triangle_down" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ’ ", + "description": "diamond with a dot", + "category": "Symbols", + "aliases": [ + "diamond_shape_with_a_dot_inside" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”˜", + "description": "radio button", + "category": "Symbols", + "aliases": [ + "radio_button" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”ณ", + "description": "white square button", + "category": "Symbols", + "aliases": [ + "white_square_button" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ”ฒ", + "description": "black square button", + "category": "Symbols", + "aliases": [ + "black_square_button" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ", + "description": "chequered flag", + "category": "Flags", + "aliases": [ + "checkered_flag" + ], + "tags": [ + "milestone", + "finish" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿšฉ", + "description": "triangular flag", + "category": "Flags", + "aliases": [ + "triangular_flag_on_post" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐ŸŽŒ", + "description": "crossed flags", + "category": "Flags", + "aliases": [ + "crossed_flags" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿด", + "description": "black flag", + "category": "Flags", + "aliases": [ + "black_flag" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿณ๏ธ", + "description": "white flag", + "category": "Flags", + "aliases": [ + "white_flag" + ], + "tags": [ + + ], + "unicode_version": "7.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿณ๏ธโ€๐ŸŒˆ", + "description": "rainbow flag", + "category": "Flags", + "aliases": [ + "rainbow_flag" + ], + "tags": [ + "pride" + ], + "unicode_version": "6.0", + "ios_version": "10.0" + }, + { + "emoji": "๐Ÿณ๏ธโ€โšง๏ธ", + "description": "transgender flag", + "category": "Flags", + "aliases": [ + "transgender_flag" + ], + "tags": [ + + ], + "unicode_version": "13.0", + "ios_version": "14.0" + }, + { + "emoji": "๐Ÿดโ€โ˜ ๏ธ", + "description": "pirate flag", + "category": "Flags", + "aliases": [ + "pirate_flag" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ‡ฆ๐Ÿ‡จ", + "description": "flag: Ascension Island", + "category": "Flags", + "aliases": [ + "ascension_island" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ‡ฆ๐Ÿ‡ฉ", + "description": "flag: Andorra", + "category": "Flags", + "aliases": [ + "andorra" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฆ๐Ÿ‡ช", + "description": "flag: United Arab Emirates", + "category": "Flags", + "aliases": [ + "united_arab_emirates" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฆ๐Ÿ‡ซ", + "description": "flag: Afghanistan", + "category": "Flags", + "aliases": [ + "afghanistan" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฆ๐Ÿ‡ฌ", + "description": "flag: Antigua & Barbuda", + "category": "Flags", + "aliases": [ + "antigua_barbuda" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฆ๐Ÿ‡ฎ", + "description": "flag: Anguilla", + "category": "Flags", + "aliases": [ + "anguilla" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฆ๐Ÿ‡ฑ", + "description": "flag: Albania", + "category": "Flags", + "aliases": [ + "albania" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฆ๐Ÿ‡ฒ", + "description": "flag: Armenia", + "category": "Flags", + "aliases": [ + "armenia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฆ๐Ÿ‡ด", + "description": "flag: Angola", + "category": "Flags", + "aliases": [ + "angola" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฆ๐Ÿ‡ถ", + "description": "flag: Antarctica", + "category": "Flags", + "aliases": [ + "antarctica" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ฆ๐Ÿ‡ท", + "description": "flag: Argentina", + "category": "Flags", + "aliases": [ + "argentina" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฆ๐Ÿ‡ธ", + "description": "flag: American Samoa", + "category": "Flags", + "aliases": [ + "american_samoa" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฆ๐Ÿ‡น", + "description": "flag: Austria", + "category": "Flags", + "aliases": [ + "austria" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฆ๐Ÿ‡บ", + "description": "flag: Australia", + "category": "Flags", + "aliases": [ + "australia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฆ๐Ÿ‡ผ", + "description": "flag: Aruba", + "category": "Flags", + "aliases": [ + "aruba" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฆ๐Ÿ‡ฝ", + "description": "flag: ร…land Islands", + "category": "Flags", + "aliases": [ + "aland_islands" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ฆ๐Ÿ‡ฟ", + "description": "flag: Azerbaijan", + "category": "Flags", + "aliases": [ + "azerbaijan" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ง๐Ÿ‡ฆ", + "description": "flag: Bosnia & Herzegovina", + "category": "Flags", + "aliases": [ + "bosnia_herzegovina" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ง๐Ÿ‡ง", + "description": "flag: Barbados", + "category": "Flags", + "aliases": [ + "barbados" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ง๐Ÿ‡ฉ", + "description": "flag: Bangladesh", + "category": "Flags", + "aliases": [ + "bangladesh" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ง๐Ÿ‡ช", + "description": "flag: Belgium", + "category": "Flags", + "aliases": [ + "belgium" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ง๐Ÿ‡ซ", + "description": "flag: Burkina Faso", + "category": "Flags", + "aliases": [ + "burkina_faso" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ง๐Ÿ‡ฌ", + "description": "flag: Bulgaria", + "category": "Flags", + "aliases": [ + "bulgaria" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ง๐Ÿ‡ญ", + "description": "flag: Bahrain", + "category": "Flags", + "aliases": [ + "bahrain" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ง๐Ÿ‡ฎ", + "description": "flag: Burundi", + "category": "Flags", + "aliases": [ + "burundi" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ง๐Ÿ‡ฏ", + "description": "flag: Benin", + "category": "Flags", + "aliases": [ + "benin" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ง๐Ÿ‡ฑ", + "description": "flag: St. Barthรฉlemy", + "category": "Flags", + "aliases": [ + "st_barthelemy" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ง๐Ÿ‡ฒ", + "description": "flag: Bermuda", + "category": "Flags", + "aliases": [ + "bermuda" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ง๐Ÿ‡ณ", + "description": "flag: Brunei", + "category": "Flags", + "aliases": [ + "brunei" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ง๐Ÿ‡ด", + "description": "flag: Bolivia", + "category": "Flags", + "aliases": [ + "bolivia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ง๐Ÿ‡ถ", + "description": "flag: Caribbean Netherlands", + "category": "Flags", + "aliases": [ + "caribbean_netherlands" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ง๐Ÿ‡ท", + "description": "flag: Brazil", + "category": "Flags", + "aliases": [ + "brazil" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ง๐Ÿ‡ธ", + "description": "flag: Bahamas", + "category": "Flags", + "aliases": [ + "bahamas" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ง๐Ÿ‡น", + "description": "flag: Bhutan", + "category": "Flags", + "aliases": [ + "bhutan" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ง๐Ÿ‡ป", + "description": "flag: Bouvet Island", + "category": "Flags", + "aliases": [ + "bouvet_island" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ‡ง๐Ÿ‡ผ", + "description": "flag: Botswana", + "category": "Flags", + "aliases": [ + "botswana" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ง๐Ÿ‡พ", + "description": "flag: Belarus", + "category": "Flags", + "aliases": [ + "belarus" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ง๐Ÿ‡ฟ", + "description": "flag: Belize", + "category": "Flags", + "aliases": [ + "belize" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡จ๐Ÿ‡ฆ", + "description": "flag: Canada", + "category": "Flags", + "aliases": [ + "canada" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡จ๐Ÿ‡จ", + "description": "flag: Cocos (Keeling) Islands", + "category": "Flags", + "aliases": [ + "cocos_islands" + ], + "tags": [ + "keeling" + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡จ๐Ÿ‡ฉ", + "description": "flag: Congo - Kinshasa", + "category": "Flags", + "aliases": [ + "congo_kinshasa" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡จ๐Ÿ‡ซ", + "description": "flag: Central African Republic", + "category": "Flags", + "aliases": [ + "central_african_republic" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡จ๐Ÿ‡ฌ", + "description": "flag: Congo - Brazzaville", + "category": "Flags", + "aliases": [ + "congo_brazzaville" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡จ๐Ÿ‡ญ", + "description": "flag: Switzerland", + "category": "Flags", + "aliases": [ + "switzerland" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡จ๐Ÿ‡ฎ", + "description": "flag: Cรดte dโ€™Ivoire", + "category": "Flags", + "aliases": [ + "cote_divoire" + ], + "tags": [ + "ivory" + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡จ๐Ÿ‡ฐ", + "description": "flag: Cook Islands", + "category": "Flags", + "aliases": [ + "cook_islands" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡จ๐Ÿ‡ฑ", + "description": "flag: Chile", + "category": "Flags", + "aliases": [ + "chile" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡จ๐Ÿ‡ฒ", + "description": "flag: Cameroon", + "category": "Flags", + "aliases": [ + "cameroon" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡จ๐Ÿ‡ณ", + "description": "flag: China", + "category": "Flags", + "aliases": [ + "cn" + ], + "tags": [ + "china" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‡จ๐Ÿ‡ด", + "description": "flag: Colombia", + "category": "Flags", + "aliases": [ + "colombia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡จ๐Ÿ‡ต", + "description": "flag: Clipperton Island", + "category": "Flags", + "aliases": [ + "clipperton_island" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ‡จ๐Ÿ‡ท", + "description": "flag: Costa Rica", + "category": "Flags", + "aliases": [ + "costa_rica" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡จ๐Ÿ‡บ", + "description": "flag: Cuba", + "category": "Flags", + "aliases": [ + "cuba" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡จ๐Ÿ‡ป", + "description": "flag: Cape Verde", + "category": "Flags", + "aliases": [ + "cape_verde" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡จ๐Ÿ‡ผ", + "description": "flag: Curaรงao", + "category": "Flags", + "aliases": [ + "curacao" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡จ๐Ÿ‡ฝ", + "description": "flag: Christmas Island", + "category": "Flags", + "aliases": [ + "christmas_island" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡จ๐Ÿ‡พ", + "description": "flag: Cyprus", + "category": "Flags", + "aliases": [ + "cyprus" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡จ๐Ÿ‡ฟ", + "description": "flag: Czechia", + "category": "Flags", + "aliases": [ + "czech_republic" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฉ๐Ÿ‡ช", + "description": "flag: Germany", + "category": "Flags", + "aliases": [ + "de" + ], + "tags": [ + "flag", + "germany" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‡ฉ๐Ÿ‡ฌ", + "description": "flag: Diego Garcia", + "category": "Flags", + "aliases": [ + "diego_garcia" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ‡ฉ๐Ÿ‡ฏ", + "description": "flag: Djibouti", + "category": "Flags", + "aliases": [ + "djibouti" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฉ๐Ÿ‡ฐ", + "description": "flag: Denmark", + "category": "Flags", + "aliases": [ + "denmark" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฉ๐Ÿ‡ฒ", + "description": "flag: Dominica", + "category": "Flags", + "aliases": [ + "dominica" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฉ๐Ÿ‡ด", + "description": "flag: Dominican Republic", + "category": "Flags", + "aliases": [ + "dominican_republic" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฉ๐Ÿ‡ฟ", + "description": "flag: Algeria", + "category": "Flags", + "aliases": [ + "algeria" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ช๐Ÿ‡ฆ", + "description": "flag: Ceuta & Melilla", + "category": "Flags", + "aliases": [ + "ceuta_melilla" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ‡ช๐Ÿ‡จ", + "description": "flag: Ecuador", + "category": "Flags", + "aliases": [ + "ecuador" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ช๐Ÿ‡ช", + "description": "flag: Estonia", + "category": "Flags", + "aliases": [ + "estonia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ช๐Ÿ‡ฌ", + "description": "flag: Egypt", + "category": "Flags", + "aliases": [ + "egypt" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ช๐Ÿ‡ญ", + "description": "flag: Western Sahara", + "category": "Flags", + "aliases": [ + "western_sahara" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ช๐Ÿ‡ท", + "description": "flag: Eritrea", + "category": "Flags", + "aliases": [ + "eritrea" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ช๐Ÿ‡ธ", + "description": "flag: Spain", + "category": "Flags", + "aliases": [ + "es" + ], + "tags": [ + "spain" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‡ช๐Ÿ‡น", + "description": "flag: Ethiopia", + "category": "Flags", + "aliases": [ + "ethiopia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ช๐Ÿ‡บ", + "description": "flag: European Union", + "category": "Flags", + "aliases": [ + "eu", + "european_union" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ซ๐Ÿ‡ฎ", + "description": "flag: Finland", + "category": "Flags", + "aliases": [ + "finland" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ซ๐Ÿ‡ฏ", + "description": "flag: Fiji", + "category": "Flags", + "aliases": [ + "fiji" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ซ๐Ÿ‡ฐ", + "description": "flag: Falkland Islands", + "category": "Flags", + "aliases": [ + "falkland_islands" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ซ๐Ÿ‡ฒ", + "description": "flag: Micronesia", + "category": "Flags", + "aliases": [ + "micronesia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ซ๐Ÿ‡ด", + "description": "flag: Faroe Islands", + "category": "Flags", + "aliases": [ + "faroe_islands" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ซ๐Ÿ‡ท", + "description": "flag: France", + "category": "Flags", + "aliases": [ + "fr" + ], + "tags": [ + "france", + "french" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‡ฌ๐Ÿ‡ฆ", + "description": "flag: Gabon", + "category": "Flags", + "aliases": [ + "gabon" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฌ๐Ÿ‡ง", + "description": "flag: United Kingdom", + "category": "Flags", + "aliases": [ + "gb", + "uk" + ], + "tags": [ + "flag", + "british" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‡ฌ๐Ÿ‡ฉ", + "description": "flag: Grenada", + "category": "Flags", + "aliases": [ + "grenada" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฌ๐Ÿ‡ช", + "description": "flag: Georgia", + "category": "Flags", + "aliases": [ + "georgia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฌ๐Ÿ‡ซ", + "description": "flag: French Guiana", + "category": "Flags", + "aliases": [ + "french_guiana" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฌ๐Ÿ‡ฌ", + "description": "flag: Guernsey", + "category": "Flags", + "aliases": [ + "guernsey" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ฌ๐Ÿ‡ญ", + "description": "flag: Ghana", + "category": "Flags", + "aliases": [ + "ghana" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฌ๐Ÿ‡ฎ", + "description": "flag: Gibraltar", + "category": "Flags", + "aliases": [ + "gibraltar" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฌ๐Ÿ‡ฑ", + "description": "flag: Greenland", + "category": "Flags", + "aliases": [ + "greenland" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ฌ๐Ÿ‡ฒ", + "description": "flag: Gambia", + "category": "Flags", + "aliases": [ + "gambia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฌ๐Ÿ‡ณ", + "description": "flag: Guinea", + "category": "Flags", + "aliases": [ + "guinea" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฌ๐Ÿ‡ต", + "description": "flag: Guadeloupe", + "category": "Flags", + "aliases": [ + "guadeloupe" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ฌ๐Ÿ‡ถ", + "description": "flag: Equatorial Guinea", + "category": "Flags", + "aliases": [ + "equatorial_guinea" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฌ๐Ÿ‡ท", + "description": "flag: Greece", + "category": "Flags", + "aliases": [ + "greece" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฌ๐Ÿ‡ธ", + "description": "flag: South Georgia & South Sandwich Islands", + "category": "Flags", + "aliases": [ + "south_georgia_south_sandwich_islands" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ฌ๐Ÿ‡น", + "description": "flag: Guatemala", + "category": "Flags", + "aliases": [ + "guatemala" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฌ๐Ÿ‡บ", + "description": "flag: Guam", + "category": "Flags", + "aliases": [ + "guam" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฌ๐Ÿ‡ผ", + "description": "flag: Guinea-Bissau", + "category": "Flags", + "aliases": [ + "guinea_bissau" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฌ๐Ÿ‡พ", + "description": "flag: Guyana", + "category": "Flags", + "aliases": [ + "guyana" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ญ๐Ÿ‡ฐ", + "description": "flag: Hong Kong SAR China", + "category": "Flags", + "aliases": [ + "hong_kong" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ญ๐Ÿ‡ฒ", + "description": "flag: Heard & McDonald Islands", + "category": "Flags", + "aliases": [ + "heard_mcdonald_islands" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ‡ญ๐Ÿ‡ณ", + "description": "flag: Honduras", + "category": "Flags", + "aliases": [ + "honduras" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ญ๐Ÿ‡ท", + "description": "flag: Croatia", + "category": "Flags", + "aliases": [ + "croatia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ญ๐Ÿ‡น", + "description": "flag: Haiti", + "category": "Flags", + "aliases": [ + "haiti" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ญ๐Ÿ‡บ", + "description": "flag: Hungary", + "category": "Flags", + "aliases": [ + "hungary" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฎ๐Ÿ‡จ", + "description": "flag: Canary Islands", + "category": "Flags", + "aliases": [ + "canary_islands" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ฎ๐Ÿ‡ฉ", + "description": "flag: Indonesia", + "category": "Flags", + "aliases": [ + "indonesia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฎ๐Ÿ‡ช", + "description": "flag: Ireland", + "category": "Flags", + "aliases": [ + "ireland" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฎ๐Ÿ‡ฑ", + "description": "flag: Israel", + "category": "Flags", + "aliases": [ + "israel" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฎ๐Ÿ‡ฒ", + "description": "flag: Isle of Man", + "category": "Flags", + "aliases": [ + "isle_of_man" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ฎ๐Ÿ‡ณ", + "description": "flag: India", + "category": "Flags", + "aliases": [ + "india" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฎ๐Ÿ‡ด", + "description": "flag: British Indian Ocean Territory", + "category": "Flags", + "aliases": [ + "british_indian_ocean_territory" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ฎ๐Ÿ‡ถ", + "description": "flag: Iraq", + "category": "Flags", + "aliases": [ + "iraq" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฎ๐Ÿ‡ท", + "description": "flag: Iran", + "category": "Flags", + "aliases": [ + "iran" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฎ๐Ÿ‡ธ", + "description": "flag: Iceland", + "category": "Flags", + "aliases": [ + "iceland" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฎ๐Ÿ‡น", + "description": "flag: Italy", + "category": "Flags", + "aliases": [ + "it" + ], + "tags": [ + "italy" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‡ฏ๐Ÿ‡ช", + "description": "flag: Jersey", + "category": "Flags", + "aliases": [ + "jersey" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ฏ๐Ÿ‡ฒ", + "description": "flag: Jamaica", + "category": "Flags", + "aliases": [ + "jamaica" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฏ๐Ÿ‡ด", + "description": "flag: Jordan", + "category": "Flags", + "aliases": [ + "jordan" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฏ๐Ÿ‡ต", + "description": "flag: Japan", + "category": "Flags", + "aliases": [ + "jp" + ], + "tags": [ + "japan" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‡ฐ๐Ÿ‡ช", + "description": "flag: Kenya", + "category": "Flags", + "aliases": [ + "kenya" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฐ๐Ÿ‡ฌ", + "description": "flag: Kyrgyzstan", + "category": "Flags", + "aliases": [ + "kyrgyzstan" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฐ๐Ÿ‡ญ", + "description": "flag: Cambodia", + "category": "Flags", + "aliases": [ + "cambodia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฐ๐Ÿ‡ฎ", + "description": "flag: Kiribati", + "category": "Flags", + "aliases": [ + "kiribati" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฐ๐Ÿ‡ฒ", + "description": "flag: Comoros", + "category": "Flags", + "aliases": [ + "comoros" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฐ๐Ÿ‡ณ", + "description": "flag: St. Kitts & Nevis", + "category": "Flags", + "aliases": [ + "st_kitts_nevis" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฐ๐Ÿ‡ต", + "description": "flag: North Korea", + "category": "Flags", + "aliases": [ + "north_korea" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฐ๐Ÿ‡ท", + "description": "flag: South Korea", + "category": "Flags", + "aliases": [ + "kr" + ], + "tags": [ + "korea" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‡ฐ๐Ÿ‡ผ", + "description": "flag: Kuwait", + "category": "Flags", + "aliases": [ + "kuwait" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฐ๐Ÿ‡พ", + "description": "flag: Cayman Islands", + "category": "Flags", + "aliases": [ + "cayman_islands" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฐ๐Ÿ‡ฟ", + "description": "flag: Kazakhstan", + "category": "Flags", + "aliases": [ + "kazakhstan" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฑ๐Ÿ‡ฆ", + "description": "flag: Laos", + "category": "Flags", + "aliases": [ + "laos" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฑ๐Ÿ‡ง", + "description": "flag: Lebanon", + "category": "Flags", + "aliases": [ + "lebanon" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฑ๐Ÿ‡จ", + "description": "flag: St. Lucia", + "category": "Flags", + "aliases": [ + "st_lucia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฑ๐Ÿ‡ฎ", + "description": "flag: Liechtenstein", + "category": "Flags", + "aliases": [ + "liechtenstein" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฑ๐Ÿ‡ฐ", + "description": "flag: Sri Lanka", + "category": "Flags", + "aliases": [ + "sri_lanka" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฑ๐Ÿ‡ท", + "description": "flag: Liberia", + "category": "Flags", + "aliases": [ + "liberia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฑ๐Ÿ‡ธ", + "description": "flag: Lesotho", + "category": "Flags", + "aliases": [ + "lesotho" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฑ๐Ÿ‡น", + "description": "flag: Lithuania", + "category": "Flags", + "aliases": [ + "lithuania" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฑ๐Ÿ‡บ", + "description": "flag: Luxembourg", + "category": "Flags", + "aliases": [ + "luxembourg" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฑ๐Ÿ‡ป", + "description": "flag: Latvia", + "category": "Flags", + "aliases": [ + "latvia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฑ๐Ÿ‡พ", + "description": "flag: Libya", + "category": "Flags", + "aliases": [ + "libya" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฒ๐Ÿ‡ฆ", + "description": "flag: Morocco", + "category": "Flags", + "aliases": [ + "morocco" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฒ๐Ÿ‡จ", + "description": "flag: Monaco", + "category": "Flags", + "aliases": [ + "monaco" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ฒ๐Ÿ‡ฉ", + "description": "flag: Moldova", + "category": "Flags", + "aliases": [ + "moldova" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฒ๐Ÿ‡ช", + "description": "flag: Montenegro", + "category": "Flags", + "aliases": [ + "montenegro" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฒ๐Ÿ‡ซ", + "description": "flag: St. Martin", + "category": "Flags", + "aliases": [ + "st_martin" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ‡ฒ๐Ÿ‡ฌ", + "description": "flag: Madagascar", + "category": "Flags", + "aliases": [ + "madagascar" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฒ๐Ÿ‡ญ", + "description": "flag: Marshall Islands", + "category": "Flags", + "aliases": [ + "marshall_islands" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ฒ๐Ÿ‡ฐ", + "description": "flag: North Macedonia", + "category": "Flags", + "aliases": [ + "macedonia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฒ๐Ÿ‡ฑ", + "description": "flag: Mali", + "category": "Flags", + "aliases": [ + "mali" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฒ๐Ÿ‡ฒ", + "description": "flag: Myanmar (Burma)", + "category": "Flags", + "aliases": [ + "myanmar" + ], + "tags": [ + "burma" + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฒ๐Ÿ‡ณ", + "description": "flag: Mongolia", + "category": "Flags", + "aliases": [ + "mongolia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฒ๐Ÿ‡ด", + "description": "flag: Macao SAR China", + "category": "Flags", + "aliases": [ + "macau" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฒ๐Ÿ‡ต", + "description": "flag: Northern Mariana Islands", + "category": "Flags", + "aliases": [ + "northern_mariana_islands" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฒ๐Ÿ‡ถ", + "description": "flag: Martinique", + "category": "Flags", + "aliases": [ + "martinique" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ฒ๐Ÿ‡ท", + "description": "flag: Mauritania", + "category": "Flags", + "aliases": [ + "mauritania" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฒ๐Ÿ‡ธ", + "description": "flag: Montserrat", + "category": "Flags", + "aliases": [ + "montserrat" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฒ๐Ÿ‡น", + "description": "flag: Malta", + "category": "Flags", + "aliases": [ + "malta" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฒ๐Ÿ‡บ", + "description": "flag: Mauritius", + "category": "Flags", + "aliases": [ + "mauritius" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ฒ๐Ÿ‡ป", + "description": "flag: Maldives", + "category": "Flags", + "aliases": [ + "maldives" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฒ๐Ÿ‡ผ", + "description": "flag: Malawi", + "category": "Flags", + "aliases": [ + "malawi" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฒ๐Ÿ‡ฝ", + "description": "flag: Mexico", + "category": "Flags", + "aliases": [ + "mexico" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฒ๐Ÿ‡พ", + "description": "flag: Malaysia", + "category": "Flags", + "aliases": [ + "malaysia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฒ๐Ÿ‡ฟ", + "description": "flag: Mozambique", + "category": "Flags", + "aliases": [ + "mozambique" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ณ๐Ÿ‡ฆ", + "description": "flag: Namibia", + "category": "Flags", + "aliases": [ + "namibia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ณ๐Ÿ‡จ", + "description": "flag: New Caledonia", + "category": "Flags", + "aliases": [ + "new_caledonia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ณ๐Ÿ‡ช", + "description": "flag: Niger", + "category": "Flags", + "aliases": [ + "niger" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ณ๐Ÿ‡ซ", + "description": "flag: Norfolk Island", + "category": "Flags", + "aliases": [ + "norfolk_island" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ณ๐Ÿ‡ฌ", + "description": "flag: Nigeria", + "category": "Flags", + "aliases": [ + "nigeria" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ณ๐Ÿ‡ฎ", + "description": "flag: Nicaragua", + "category": "Flags", + "aliases": [ + "nicaragua" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ณ๐Ÿ‡ฑ", + "description": "flag: Netherlands", + "category": "Flags", + "aliases": [ + "netherlands" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ณ๐Ÿ‡ด", + "description": "flag: Norway", + "category": "Flags", + "aliases": [ + "norway" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ณ๐Ÿ‡ต", + "description": "flag: Nepal", + "category": "Flags", + "aliases": [ + "nepal" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ณ๐Ÿ‡ท", + "description": "flag: Nauru", + "category": "Flags", + "aliases": [ + "nauru" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ณ๐Ÿ‡บ", + "description": "flag: Niue", + "category": "Flags", + "aliases": [ + "niue" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ณ๐Ÿ‡ฟ", + "description": "flag: New Zealand", + "category": "Flags", + "aliases": [ + "new_zealand" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ด๐Ÿ‡ฒ", + "description": "flag: Oman", + "category": "Flags", + "aliases": [ + "oman" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ต๐Ÿ‡ฆ", + "description": "flag: Panama", + "category": "Flags", + "aliases": [ + "panama" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ต๐Ÿ‡ช", + "description": "flag: Peru", + "category": "Flags", + "aliases": [ + "peru" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ต๐Ÿ‡ซ", + "description": "flag: French Polynesia", + "category": "Flags", + "aliases": [ + "french_polynesia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ต๐Ÿ‡ฌ", + "description": "flag: Papua New Guinea", + "category": "Flags", + "aliases": [ + "papua_new_guinea" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ต๐Ÿ‡ญ", + "description": "flag: Philippines", + "category": "Flags", + "aliases": [ + "philippines" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ต๐Ÿ‡ฐ", + "description": "flag: Pakistan", + "category": "Flags", + "aliases": [ + "pakistan" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ต๐Ÿ‡ฑ", + "description": "flag: Poland", + "category": "Flags", + "aliases": [ + "poland" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ต๐Ÿ‡ฒ", + "description": "flag: St. Pierre & Miquelon", + "category": "Flags", + "aliases": [ + "st_pierre_miquelon" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ต๐Ÿ‡ณ", + "description": "flag: Pitcairn Islands", + "category": "Flags", + "aliases": [ + "pitcairn_islands" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ต๐Ÿ‡ท", + "description": "flag: Puerto Rico", + "category": "Flags", + "aliases": [ + "puerto_rico" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ต๐Ÿ‡ธ", + "description": "flag: Palestinian Territories", + "category": "Flags", + "aliases": [ + "palestinian_territories" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ต๐Ÿ‡น", + "description": "flag: Portugal", + "category": "Flags", + "aliases": [ + "portugal" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ต๐Ÿ‡ผ", + "description": "flag: Palau", + "category": "Flags", + "aliases": [ + "palau" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ต๐Ÿ‡พ", + "description": "flag: Paraguay", + "category": "Flags", + "aliases": [ + "paraguay" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ถ๐Ÿ‡ฆ", + "description": "flag: Qatar", + "category": "Flags", + "aliases": [ + "qatar" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ท๐Ÿ‡ช", + "description": "flag: Rรฉunion", + "category": "Flags", + "aliases": [ + "reunion" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ท๐Ÿ‡ด", + "description": "flag: Romania", + "category": "Flags", + "aliases": [ + "romania" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ท๐Ÿ‡ธ", + "description": "flag: Serbia", + "category": "Flags", + "aliases": [ + "serbia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ท๐Ÿ‡บ", + "description": "flag: Russia", + "category": "Flags", + "aliases": [ + "ru" + ], + "tags": [ + "russia" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‡ท๐Ÿ‡ผ", + "description": "flag: Rwanda", + "category": "Flags", + "aliases": [ + "rwanda" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ธ๐Ÿ‡ฆ", + "description": "flag: Saudi Arabia", + "category": "Flags", + "aliases": [ + "saudi_arabia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ธ๐Ÿ‡ง", + "description": "flag: Solomon Islands", + "category": "Flags", + "aliases": [ + "solomon_islands" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ธ๐Ÿ‡จ", + "description": "flag: Seychelles", + "category": "Flags", + "aliases": [ + "seychelles" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ธ๐Ÿ‡ฉ", + "description": "flag: Sudan", + "category": "Flags", + "aliases": [ + "sudan" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ธ๐Ÿ‡ช", + "description": "flag: Sweden", + "category": "Flags", + "aliases": [ + "sweden" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ธ๐Ÿ‡ฌ", + "description": "flag: Singapore", + "category": "Flags", + "aliases": [ + "singapore" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ธ๐Ÿ‡ญ", + "description": "flag: St. Helena", + "category": "Flags", + "aliases": [ + "st_helena" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ธ๐Ÿ‡ฎ", + "description": "flag: Slovenia", + "category": "Flags", + "aliases": [ + "slovenia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ธ๐Ÿ‡ฏ", + "description": "flag: Svalbard & Jan Mayen", + "category": "Flags", + "aliases": [ + "svalbard_jan_mayen" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ‡ธ๐Ÿ‡ฐ", + "description": "flag: Slovakia", + "category": "Flags", + "aliases": [ + "slovakia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ธ๐Ÿ‡ฑ", + "description": "flag: Sierra Leone", + "category": "Flags", + "aliases": [ + "sierra_leone" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ธ๐Ÿ‡ฒ", + "description": "flag: San Marino", + "category": "Flags", + "aliases": [ + "san_marino" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ธ๐Ÿ‡ณ", + "description": "flag: Senegal", + "category": "Flags", + "aliases": [ + "senegal" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ธ๐Ÿ‡ด", + "description": "flag: Somalia", + "category": "Flags", + "aliases": [ + "somalia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ธ๐Ÿ‡ท", + "description": "flag: Suriname", + "category": "Flags", + "aliases": [ + "suriname" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ธ๐Ÿ‡ธ", + "description": "flag: South Sudan", + "category": "Flags", + "aliases": [ + "south_sudan" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ธ๐Ÿ‡น", + "description": "flag: Sรฃo Tomรฉ & Prรญncipe", + "category": "Flags", + "aliases": [ + "sao_tome_principe" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ธ๐Ÿ‡ป", + "description": "flag: El Salvador", + "category": "Flags", + "aliases": [ + "el_salvador" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ธ๐Ÿ‡ฝ", + "description": "flag: Sint Maarten", + "category": "Flags", + "aliases": [ + "sint_maarten" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ธ๐Ÿ‡พ", + "description": "flag: Syria", + "category": "Flags", + "aliases": [ + "syria" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ธ๐Ÿ‡ฟ", + "description": "flag: Eswatini", + "category": "Flags", + "aliases": [ + "swaziland" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡น๐Ÿ‡ฆ", + "description": "flag: Tristan da Cunha", + "category": "Flags", + "aliases": [ + "tristan_da_cunha" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ‡น๐Ÿ‡จ", + "description": "flag: Turks & Caicos Islands", + "category": "Flags", + "aliases": [ + "turks_caicos_islands" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡น๐Ÿ‡ฉ", + "description": "flag: Chad", + "category": "Flags", + "aliases": [ + "chad" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡น๐Ÿ‡ซ", + "description": "flag: French Southern Territories", + "category": "Flags", + "aliases": [ + "french_southern_territories" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡น๐Ÿ‡ฌ", + "description": "flag: Togo", + "category": "Flags", + "aliases": [ + "togo" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡น๐Ÿ‡ญ", + "description": "flag: Thailand", + "category": "Flags", + "aliases": [ + "thailand" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡น๐Ÿ‡ฏ", + "description": "flag: Tajikistan", + "category": "Flags", + "aliases": [ + "tajikistan" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡น๐Ÿ‡ฐ", + "description": "flag: Tokelau", + "category": "Flags", + "aliases": [ + "tokelau" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡น๐Ÿ‡ฑ", + "description": "flag: Timor-Leste", + "category": "Flags", + "aliases": [ + "timor_leste" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡น๐Ÿ‡ฒ", + "description": "flag: Turkmenistan", + "category": "Flags", + "aliases": [ + "turkmenistan" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡น๐Ÿ‡ณ", + "description": "flag: Tunisia", + "category": "Flags", + "aliases": [ + "tunisia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡น๐Ÿ‡ด", + "description": "flag: Tonga", + "category": "Flags", + "aliases": [ + "tonga" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡น๐Ÿ‡ท", + "description": "flag: Turkey", + "category": "Flags", + "aliases": [ + "tr" + ], + "tags": [ + "turkey" + ], + "unicode_version": "8.0", + "ios_version": "9.1" + }, + { + "emoji": "๐Ÿ‡น๐Ÿ‡น", + "description": "flag: Trinidad & Tobago", + "category": "Flags", + "aliases": [ + "trinidad_tobago" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡น๐Ÿ‡ป", + "description": "flag: Tuvalu", + "category": "Flags", + "aliases": [ + "tuvalu" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡น๐Ÿ‡ผ", + "description": "flag: Taiwan", + "category": "Flags", + "aliases": [ + "taiwan" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡น๐Ÿ‡ฟ", + "description": "flag: Tanzania", + "category": "Flags", + "aliases": [ + "tanzania" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡บ๐Ÿ‡ฆ", + "description": "flag: Ukraine", + "category": "Flags", + "aliases": [ + "ukraine" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡บ๐Ÿ‡ฌ", + "description": "flag: Uganda", + "category": "Flags", + "aliases": [ + "uganda" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡บ๐Ÿ‡ฒ", + "description": "flag: U.S. Outlying Islands", + "category": "Flags", + "aliases": [ + "us_outlying_islands" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ‡บ๐Ÿ‡ณ", + "description": "flag: United Nations", + "category": "Flags", + "aliases": [ + "united_nations" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿ‡บ๐Ÿ‡ธ", + "description": "flag: United States", + "category": "Flags", + "aliases": [ + "us" + ], + "tags": [ + "flag", + "united", + "america" + ], + "unicode_version": "6.0", + "ios_version": "6.0" + }, + { + "emoji": "๐Ÿ‡บ๐Ÿ‡พ", + "description": "flag: Uruguay", + "category": "Flags", + "aliases": [ + "uruguay" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡บ๐Ÿ‡ฟ", + "description": "flag: Uzbekistan", + "category": "Flags", + "aliases": [ + "uzbekistan" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ป๐Ÿ‡ฆ", + "description": "flag: Vatican City", + "category": "Flags", + "aliases": [ + "vatican_city" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ป๐Ÿ‡จ", + "description": "flag: St. Vincent & Grenadines", + "category": "Flags", + "aliases": [ + "st_vincent_grenadines" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ป๐Ÿ‡ช", + "description": "flag: Venezuela", + "category": "Flags", + "aliases": [ + "venezuela" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ป๐Ÿ‡ฌ", + "description": "flag: British Virgin Islands", + "category": "Flags", + "aliases": [ + "british_virgin_islands" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ป๐Ÿ‡ฎ", + "description": "flag: U.S. Virgin Islands", + "category": "Flags", + "aliases": [ + "us_virgin_islands" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ป๐Ÿ‡ณ", + "description": "flag: Vietnam", + "category": "Flags", + "aliases": [ + "vietnam" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ป๐Ÿ‡บ", + "description": "flag: Vanuatu", + "category": "Flags", + "aliases": [ + "vanuatu" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ผ๐Ÿ‡ซ", + "description": "flag: Wallis & Futuna", + "category": "Flags", + "aliases": [ + "wallis_futuna" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ผ๐Ÿ‡ธ", + "description": "flag: Samoa", + "category": "Flags", + "aliases": [ + "samoa" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฝ๐Ÿ‡ฐ", + "description": "flag: Kosovo", + "category": "Flags", + "aliases": [ + "kosovo" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡พ๐Ÿ‡ช", + "description": "flag: Yemen", + "category": "Flags", + "aliases": [ + "yemen" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡พ๐Ÿ‡น", + "description": "flag: Mayotte", + "category": "Flags", + "aliases": [ + "mayotte" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "9.0" + }, + { + "emoji": "๐Ÿ‡ฟ๐Ÿ‡ฆ", + "description": "flag: South Africa", + "category": "Flags", + "aliases": [ + "south_africa" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฟ๐Ÿ‡ฒ", + "description": "flag: Zambia", + "category": "Flags", + "aliases": [ + "zambia" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿ‡ฟ๐Ÿ‡ผ", + "description": "flag: Zimbabwe", + "category": "Flags", + "aliases": [ + "zimbabwe" + ], + "tags": [ + + ], + "unicode_version": "6.0", + "ios_version": "8.3" + }, + { + "emoji": "๐Ÿด๓ ง๓ ข๓ ฅ๓ ฎ๓ ง๓ ฟ", + "description": "flag: England", + "category": "Flags", + "aliases": [ + "england" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿด๓ ง๓ ข๓ ณ๓ ฃ๓ ด๓ ฟ", + "description": "flag: Scotland", + "category": "Flags", + "aliases": [ + "scotland" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + }, + { + "emoji": "๐Ÿด๓ ง๓ ข๓ ท๓ ฌ๓ ณ๓ ฟ", + "description": "flag: Wales", + "category": "Flags", + "aliases": [ + "wales" + ], + "tags": [ + + ], + "unicode_version": "11.0", + "ios_version": "12.1" + } +]; + +let sortedEmojis = emojis.sort((a, b) => { + if (b.emoji.length < a.emoji.length) { + return -1; + } +}); \ No newline at end of file diff --git a/assets/js/he.js b/assets/js/he.js new file mode 100755 index 0000000..da4a8ab --- /dev/null +++ b/assets/js/he.js @@ -0,0 +1,345 @@ +/*! https://mths.be/he v1.2.0 by @mathias | MIT license */ +;(function(root) { + + // Detect free variables `exports`. + var freeExports = typeof exports == 'object' && exports; + + // Detect free variable `module`. + var freeModule = typeof module == 'object' && module && + module.exports == freeExports && module; + + // Detect free variable `global`, from Node.js or Browserified code, + // and use it as `root`. + var freeGlobal = typeof global == 'object' && global; + if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) { + root = freeGlobal; + } + + /*--------------------------------------------------------------------------*/ + + // All astral symbols. + var regexAstralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; + // All ASCII symbols (not just printable ASCII) except those listed in the + // first column of the overrides table. + // https://html.spec.whatwg.org/multipage/syntax.html#table-charref-overrides + var regexAsciiWhitelist = /[\x01-\x7F]/g; + // All BMP symbols that are not ASCII newlines, printable ASCII symbols, or + // code points listed in the first column of the overrides table on + // https://html.spec.whatwg.org/multipage/syntax.html#table-charref-overrides. + var regexBmpWhitelist = /[\x01-\t\x0B\f\x0E-\x1F\x7F\x81\x8D\x8F\x90\x9D\xA0-\uFFFF]/g; + + var regexEncodeNonAscii = /<\u20D2|=\u20E5|>\u20D2|\u205F\u200A|\u219D\u0338|\u2202\u0338|\u2220\u20D2|\u2229\uFE00|\u222A\uFE00|\u223C\u20D2|\u223D\u0331|\u223E\u0333|\u2242\u0338|\u224B\u0338|\u224D\u20D2|\u224E\u0338|\u224F\u0338|\u2250\u0338|\u2261\u20E5|\u2264\u20D2|\u2265\u20D2|\u2266\u0338|\u2267\u0338|\u2268\uFE00|\u2269\uFE00|\u226A\u0338|\u226A\u20D2|\u226B\u0338|\u226B\u20D2|\u227F\u0338|\u2282\u20D2|\u2283\u20D2|\u228A\uFE00|\u228B\uFE00|\u228F\u0338|\u2290\u0338|\u2293\uFE00|\u2294\uFE00|\u22B4\u20D2|\u22B5\u20D2|\u22D8\u0338|\u22D9\u0338|\u22DA\uFE00|\u22DB\uFE00|\u22F5\u0338|\u22F9\u0338|\u2933\u0338|\u29CF\u0338|\u29D0\u0338|\u2A6D\u0338|\u2A70\u0338|\u2A7D\u0338|\u2A7E\u0338|\u2AA1\u0338|\u2AA2\u0338|\u2AAC\uFE00|\u2AAD\uFE00|\u2AAF\u0338|\u2AB0\u0338|\u2AC5\u0338|\u2AC6\u0338|\u2ACB\uFE00|\u2ACC\uFE00|\u2AFD\u20E5|[\xA0-\u0113\u0116-\u0122\u0124-\u012B\u012E-\u014D\u0150-\u017E\u0192\u01B5\u01F5\u0237\u02C6\u02C7\u02D8-\u02DD\u0311\u0391-\u03A1\u03A3-\u03A9\u03B1-\u03C9\u03D1\u03D2\u03D5\u03D6\u03DC\u03DD\u03F0\u03F1\u03F5\u03F6\u0401-\u040C\u040E-\u044F\u0451-\u045C\u045E\u045F\u2002-\u2005\u2007-\u2010\u2013-\u2016\u2018-\u201A\u201C-\u201E\u2020-\u2022\u2025\u2026\u2030-\u2035\u2039\u203A\u203E\u2041\u2043\u2044\u204F\u2057\u205F-\u2063\u20AC\u20DB\u20DC\u2102\u2105\u210A-\u2113\u2115-\u211E\u2122\u2124\u2127-\u2129\u212C\u212D\u212F-\u2131\u2133-\u2138\u2145-\u2148\u2153-\u215E\u2190-\u219B\u219D-\u21A7\u21A9-\u21AE\u21B0-\u21B3\u21B5-\u21B7\u21BA-\u21DB\u21DD\u21E4\u21E5\u21F5\u21FD-\u2205\u2207-\u2209\u220B\u220C\u220F-\u2214\u2216-\u2218\u221A\u221D-\u2238\u223A-\u2257\u2259\u225A\u225C\u225F-\u2262\u2264-\u228B\u228D-\u229B\u229D-\u22A5\u22A7-\u22B0\u22B2-\u22BB\u22BD-\u22DB\u22DE-\u22E3\u22E6-\u22F7\u22F9-\u22FE\u2305\u2306\u2308-\u2310\u2312\u2313\u2315\u2316\u231C-\u231F\u2322\u2323\u232D\u232E\u2336\u233D\u233F\u237C\u23B0\u23B1\u23B4-\u23B6\u23DC-\u23DF\u23E2\u23E7\u2423\u24C8\u2500\u2502\u250C\u2510\u2514\u2518\u251C\u2524\u252C\u2534\u253C\u2550-\u256C\u2580\u2584\u2588\u2591-\u2593\u25A1\u25AA\u25AB\u25AD\u25AE\u25B1\u25B3-\u25B5\u25B8\u25B9\u25BD-\u25BF\u25C2\u25C3\u25CA\u25CB\u25EC\u25EF\u25F8-\u25FC\u2605\u2606\u260E\u2640\u2642\u2660\u2663\u2665\u2666\u266A\u266D-\u266F\u2713\u2717\u2720\u2736\u2758\u2772\u2773\u27C8\u27C9\u27E6-\u27ED\u27F5-\u27FA\u27FC\u27FF\u2902-\u2905\u290C-\u2913\u2916\u2919-\u2920\u2923-\u292A\u2933\u2935-\u2939\u293C\u293D\u2945\u2948-\u294B\u294E-\u2976\u2978\u2979\u297B-\u297F\u2985\u2986\u298B-\u2996\u299A\u299C\u299D\u29A4-\u29B7\u29B9\u29BB\u29BC\u29BE-\u29C5\u29C9\u29CD-\u29D0\u29DC-\u29DE\u29E3-\u29E5\u29EB\u29F4\u29F6\u2A00-\u2A02\u2A04\u2A06\u2A0C\u2A0D\u2A10-\u2A17\u2A22-\u2A27\u2A29\u2A2A\u2A2D-\u2A31\u2A33-\u2A3C\u2A3F\u2A40\u2A42-\u2A4D\u2A50\u2A53-\u2A58\u2A5A-\u2A5D\u2A5F\u2A66\u2A6A\u2A6D-\u2A75\u2A77-\u2A9A\u2A9D-\u2AA2\u2AA4-\u2AB0\u2AB3-\u2AC8\u2ACB\u2ACC\u2ACF-\u2ADB\u2AE4\u2AE6-\u2AE9\u2AEB-\u2AF3\u2AFD\uFB00-\uFB04]|\uD835[\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDCCF\uDD04\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDD6B]/g; + var encodeMap = {'\xAD':'shy','\u200C':'zwnj','\u200D':'zwj','\u200E':'lrm','\u2063':'ic','\u2062':'it','\u2061':'af','\u200F':'rlm','\u200B':'ZeroWidthSpace','\u2060':'NoBreak','\u0311':'DownBreve','\u20DB':'tdot','\u20DC':'DotDot','\t':'Tab','\n':'NewLine','\u2008':'puncsp','\u205F':'MediumSpace','\u2009':'thinsp','\u200A':'hairsp','\u2004':'emsp13','\u2002':'ensp','\u2005':'emsp14','\u2003':'emsp','\u2007':'numsp','\xA0':'nbsp','\u205F\u200A':'ThickSpace','\u203E':'oline','_':'lowbar','\u2010':'dash','\u2013':'ndash','\u2014':'mdash','\u2015':'horbar',',':'comma',';':'semi','\u204F':'bsemi',':':'colon','\u2A74':'Colone','!':'excl','\xA1':'iexcl','?':'quest','\xBF':'iquest','.':'period','\u2025':'nldr','\u2026':'mldr','\xB7':'middot','\'':'apos','\u2018':'lsquo','\u2019':'rsquo','\u201A':'sbquo','\u2039':'lsaquo','\u203A':'rsaquo','"':'quot','\u201C':'ldquo','\u201D':'rdquo','\u201E':'bdquo','\xAB':'laquo','\xBB':'raquo','(':'lpar',')':'rpar','[':'lsqb',']':'rsqb','{':'lcub','}':'rcub','\u2308':'lceil','\u2309':'rceil','\u230A':'lfloor','\u230B':'rfloor','\u2985':'lopar','\u2986':'ropar','\u298B':'lbrke','\u298C':'rbrke','\u298D':'lbrkslu','\u298E':'rbrksld','\u298F':'lbrksld','\u2990':'rbrkslu','\u2991':'langd','\u2992':'rangd','\u2993':'lparlt','\u2994':'rpargt','\u2995':'gtlPar','\u2996':'ltrPar','\u27E6':'lobrk','\u27E7':'robrk','\u27E8':'lang','\u27E9':'rang','\u27EA':'Lang','\u27EB':'Rang','\u27EC':'loang','\u27ED':'roang','\u2772':'lbbrk','\u2773':'rbbrk','\u2016':'Vert','\xA7':'sect','\xB6':'para','@':'commat','*':'ast','/':'sol','undefined':null,'&':'amp','#':'num','%':'percnt','\u2030':'permil','\u2031':'pertenk','\u2020':'dagger','\u2021':'Dagger','\u2022':'bull','\u2043':'hybull','\u2032':'prime','\u2033':'Prime','\u2034':'tprime','\u2057':'qprime','\u2035':'bprime','\u2041':'caret','`':'grave','\xB4':'acute','\u02DC':'tilde','^':'Hat','\xAF':'macr','\u02D8':'breve','\u02D9':'dot','\xA8':'die','\u02DA':'ring','\u02DD':'dblac','\xB8':'cedil','\u02DB':'ogon','\u02C6':'circ','\u02C7':'caron','\xB0':'deg','\xA9':'copy','\xAE':'reg','\u2117':'copysr','\u2118':'wp','\u211E':'rx','\u2127':'mho','\u2129':'iiota','\u2190':'larr','\u219A':'nlarr','\u2192':'rarr','\u219B':'nrarr','\u2191':'uarr','\u2193':'darr','\u2194':'harr','\u21AE':'nharr','\u2195':'varr','\u2196':'nwarr','\u2197':'nearr','\u2198':'searr','\u2199':'swarr','\u219D':'rarrw','\u219D\u0338':'nrarrw','\u219E':'Larr','\u219F':'Uarr','\u21A0':'Rarr','\u21A1':'Darr','\u21A2':'larrtl','\u21A3':'rarrtl','\u21A4':'mapstoleft','\u21A5':'mapstoup','\u21A6':'map','\u21A7':'mapstodown','\u21A9':'larrhk','\u21AA':'rarrhk','\u21AB':'larrlp','\u21AC':'rarrlp','\u21AD':'harrw','\u21B0':'lsh','\u21B1':'rsh','\u21B2':'ldsh','\u21B3':'rdsh','\u21B5':'crarr','\u21B6':'cularr','\u21B7':'curarr','\u21BA':'olarr','\u21BB':'orarr','\u21BC':'lharu','\u21BD':'lhard','\u21BE':'uharr','\u21BF':'uharl','\u21C0':'rharu','\u21C1':'rhard','\u21C2':'dharr','\u21C3':'dharl','\u21C4':'rlarr','\u21C5':'udarr','\u21C6':'lrarr','\u21C7':'llarr','\u21C8':'uuarr','\u21C9':'rrarr','\u21CA':'ddarr','\u21CB':'lrhar','\u21CC':'rlhar','\u21D0':'lArr','\u21CD':'nlArr','\u21D1':'uArr','\u21D2':'rArr','\u21CF':'nrArr','\u21D3':'dArr','\u21D4':'iff','\u21CE':'nhArr','\u21D5':'vArr','\u21D6':'nwArr','\u21D7':'neArr','\u21D8':'seArr','\u21D9':'swArr','\u21DA':'lAarr','\u21DB':'rAarr','\u21DD':'zigrarr','\u21E4':'larrb','\u21E5':'rarrb','\u21F5':'duarr','\u21FD':'loarr','\u21FE':'roarr','\u21FF':'hoarr','\u2200':'forall','\u2201':'comp','\u2202':'part','\u2202\u0338':'npart','\u2203':'exist','\u2204':'nexist','\u2205':'empty','\u2207':'Del','\u2208':'in','\u2209':'notin','\u220B':'ni','\u220C':'notni','\u03F6':'bepsi','\u220F':'prod','\u2210':'coprod','\u2211':'sum','+':'plus','\xB1':'pm','\xF7':'div','\xD7':'times','<':'lt','\u226E':'nlt','<\u20D2':'nvlt','=':'equals','\u2260':'ne','=\u20E5':'bne','\u2A75':'Equal','>':'gt','\u226F':'ngt','>\u20D2':'nvgt','\xAC':'not','|':'vert','\xA6':'brvbar','\u2212':'minus','\u2213':'mp','\u2214':'plusdo','\u2044':'frasl','\u2216':'setmn','\u2217':'lowast','\u2218':'compfn','\u221A':'Sqrt','\u221D':'prop','\u221E':'infin','\u221F':'angrt','\u2220':'ang','\u2220\u20D2':'nang','\u2221':'angmsd','\u2222':'angsph','\u2223':'mid','\u2224':'nmid','\u2225':'par','\u2226':'npar','\u2227':'and','\u2228':'or','\u2229':'cap','\u2229\uFE00':'caps','\u222A':'cup','\u222A\uFE00':'cups','\u222B':'int','\u222C':'Int','\u222D':'tint','\u2A0C':'qint','\u222E':'oint','\u222F':'Conint','\u2230':'Cconint','\u2231':'cwint','\u2232':'cwconint','\u2233':'awconint','\u2234':'there4','\u2235':'becaus','\u2236':'ratio','\u2237':'Colon','\u2238':'minusd','\u223A':'mDDot','\u223B':'homtht','\u223C':'sim','\u2241':'nsim','\u223C\u20D2':'nvsim','\u223D':'bsim','\u223D\u0331':'race','\u223E':'ac','\u223E\u0333':'acE','\u223F':'acd','\u2240':'wr','\u2242':'esim','\u2242\u0338':'nesim','\u2243':'sime','\u2244':'nsime','\u2245':'cong','\u2247':'ncong','\u2246':'simne','\u2248':'ap','\u2249':'nap','\u224A':'ape','\u224B':'apid','\u224B\u0338':'napid','\u224C':'bcong','\u224D':'CupCap','\u226D':'NotCupCap','\u224D\u20D2':'nvap','\u224E':'bump','\u224E\u0338':'nbump','\u224F':'bumpe','\u224F\u0338':'nbumpe','\u2250':'doteq','\u2250\u0338':'nedot','\u2251':'eDot','\u2252':'efDot','\u2253':'erDot','\u2254':'colone','\u2255':'ecolon','\u2256':'ecir','\u2257':'cire','\u2259':'wedgeq','\u225A':'veeeq','\u225C':'trie','\u225F':'equest','\u2261':'equiv','\u2262':'nequiv','\u2261\u20E5':'bnequiv','\u2264':'le','\u2270':'nle','\u2264\u20D2':'nvle','\u2265':'ge','\u2271':'nge','\u2265\u20D2':'nvge','\u2266':'lE','\u2266\u0338':'nlE','\u2267':'gE','\u2267\u0338':'ngE','\u2268\uFE00':'lvnE','\u2268':'lnE','\u2269':'gnE','\u2269\uFE00':'gvnE','\u226A':'ll','\u226A\u0338':'nLtv','\u226A\u20D2':'nLt','\u226B':'gg','\u226B\u0338':'nGtv','\u226B\u20D2':'nGt','\u226C':'twixt','\u2272':'lsim','\u2274':'nlsim','\u2273':'gsim','\u2275':'ngsim','\u2276':'lg','\u2278':'ntlg','\u2277':'gl','\u2279':'ntgl','\u227A':'pr','\u2280':'npr','\u227B':'sc','\u2281':'nsc','\u227C':'prcue','\u22E0':'nprcue','\u227D':'sccue','\u22E1':'nsccue','\u227E':'prsim','\u227F':'scsim','\u227F\u0338':'NotSucceedsTilde','\u2282':'sub','\u2284':'nsub','\u2282\u20D2':'vnsub','\u2283':'sup','\u2285':'nsup','\u2283\u20D2':'vnsup','\u2286':'sube','\u2288':'nsube','\u2287':'supe','\u2289':'nsupe','\u228A\uFE00':'vsubne','\u228A':'subne','\u228B\uFE00':'vsupne','\u228B':'supne','\u228D':'cupdot','\u228E':'uplus','\u228F':'sqsub','\u228F\u0338':'NotSquareSubset','\u2290':'sqsup','\u2290\u0338':'NotSquareSuperset','\u2291':'sqsube','\u22E2':'nsqsube','\u2292':'sqsupe','\u22E3':'nsqsupe','\u2293':'sqcap','\u2293\uFE00':'sqcaps','\u2294':'sqcup','\u2294\uFE00':'sqcups','\u2295':'oplus','\u2296':'ominus','\u2297':'otimes','\u2298':'osol','\u2299':'odot','\u229A':'ocir','\u229B':'oast','\u229D':'odash','\u229E':'plusb','\u229F':'minusb','\u22A0':'timesb','\u22A1':'sdotb','\u22A2':'vdash','\u22AC':'nvdash','\u22A3':'dashv','\u22A4':'top','\u22A5':'bot','\u22A7':'models','\u22A8':'vDash','\u22AD':'nvDash','\u22A9':'Vdash','\u22AE':'nVdash','\u22AA':'Vvdash','\u22AB':'VDash','\u22AF':'nVDash','\u22B0':'prurel','\u22B2':'vltri','\u22EA':'nltri','\u22B3':'vrtri','\u22EB':'nrtri','\u22B4':'ltrie','\u22EC':'nltrie','\u22B4\u20D2':'nvltrie','\u22B5':'rtrie','\u22ED':'nrtrie','\u22B5\u20D2':'nvrtrie','\u22B6':'origof','\u22B7':'imof','\u22B8':'mumap','\u22B9':'hercon','\u22BA':'intcal','\u22BB':'veebar','\u22BD':'barvee','\u22BE':'angrtvb','\u22BF':'lrtri','\u22C0':'Wedge','\u22C1':'Vee','\u22C2':'xcap','\u22C3':'xcup','\u22C4':'diam','\u22C5':'sdot','\u22C6':'Star','\u22C7':'divonx','\u22C8':'bowtie','\u22C9':'ltimes','\u22CA':'rtimes','\u22CB':'lthree','\u22CC':'rthree','\u22CD':'bsime','\u22CE':'cuvee','\u22CF':'cuwed','\u22D0':'Sub','\u22D1':'Sup','\u22D2':'Cap','\u22D3':'Cup','\u22D4':'fork','\u22D5':'epar','\u22D6':'ltdot','\u22D7':'gtdot','\u22D8':'Ll','\u22D8\u0338':'nLl','\u22D9':'Gg','\u22D9\u0338':'nGg','\u22DA\uFE00':'lesg','\u22DA':'leg','\u22DB':'gel','\u22DB\uFE00':'gesl','\u22DE':'cuepr','\u22DF':'cuesc','\u22E6':'lnsim','\u22E7':'gnsim','\u22E8':'prnsim','\u22E9':'scnsim','\u22EE':'vellip','\u22EF':'ctdot','\u22F0':'utdot','\u22F1':'dtdot','\u22F2':'disin','\u22F3':'isinsv','\u22F4':'isins','\u22F5':'isindot','\u22F5\u0338':'notindot','\u22F6':'notinvc','\u22F7':'notinvb','\u22F9':'isinE','\u22F9\u0338':'notinE','\u22FA':'nisd','\u22FB':'xnis','\u22FC':'nis','\u22FD':'notnivc','\u22FE':'notnivb','\u2305':'barwed','\u2306':'Barwed','\u230C':'drcrop','\u230D':'dlcrop','\u230E':'urcrop','\u230F':'ulcrop','\u2310':'bnot','\u2312':'profline','\u2313':'profsurf','\u2315':'telrec','\u2316':'target','\u231C':'ulcorn','\u231D':'urcorn','\u231E':'dlcorn','\u231F':'drcorn','\u2322':'frown','\u2323':'smile','\u232D':'cylcty','\u232E':'profalar','\u2336':'topbot','\u233D':'ovbar','\u233F':'solbar','\u237C':'angzarr','\u23B0':'lmoust','\u23B1':'rmoust','\u23B4':'tbrk','\u23B5':'bbrk','\u23B6':'bbrktbrk','\u23DC':'OverParenthesis','\u23DD':'UnderParenthesis','\u23DE':'OverBrace','\u23DF':'UnderBrace','\u23E2':'trpezium','\u23E7':'elinters','\u2423':'blank','\u2500':'boxh','\u2502':'boxv','\u250C':'boxdr','\u2510':'boxdl','\u2514':'boxur','\u2518':'boxul','\u251C':'boxvr','\u2524':'boxvl','\u252C':'boxhd','\u2534':'boxhu','\u253C':'boxvh','\u2550':'boxH','\u2551':'boxV','\u2552':'boxdR','\u2553':'boxDr','\u2554':'boxDR','\u2555':'boxdL','\u2556':'boxDl','\u2557':'boxDL','\u2558':'boxuR','\u2559':'boxUr','\u255A':'boxUR','\u255B':'boxuL','\u255C':'boxUl','\u255D':'boxUL','\u255E':'boxvR','\u255F':'boxVr','\u2560':'boxVR','\u2561':'boxvL','\u2562':'boxVl','\u2563':'boxVL','\u2564':'boxHd','\u2565':'boxhD','\u2566':'boxHD','\u2567':'boxHu','\u2568':'boxhU','\u2569':'boxHU','\u256A':'boxvH','\u256B':'boxVh','\u256C':'boxVH','\u2580':'uhblk','\u2584':'lhblk','\u2588':'block','\u2591':'blk14','\u2592':'blk12','\u2593':'blk34','\u25A1':'squ','\u25AA':'squf','\u25AB':'EmptyVerySmallSquare','\u25AD':'rect','\u25AE':'marker','\u25B1':'fltns','\u25B3':'xutri','\u25B4':'utrif','\u25B5':'utri','\u25B8':'rtrif','\u25B9':'rtri','\u25BD':'xdtri','\u25BE':'dtrif','\u25BF':'dtri','\u25C2':'ltrif','\u25C3':'ltri','\u25CA':'loz','\u25CB':'cir','\u25EC':'tridot','\u25EF':'xcirc','\u25F8':'ultri','\u25F9':'urtri','\u25FA':'lltri','\u25FB':'EmptySmallSquare','\u25FC':'FilledSmallSquare','\u2605':'starf','\u2606':'star','\u260E':'phone','\u2640':'female','\u2642':'male','\u2660':'spades','\u2663':'clubs','\u2665':'hearts','\u2666':'diams','\u266A':'sung','\u2713':'check','\u2717':'cross','\u2720':'malt','\u2736':'sext','\u2758':'VerticalSeparator','\u27C8':'bsolhsub','\u27C9':'suphsol','\u27F5':'xlarr','\u27F6':'xrarr','\u27F7':'xharr','\u27F8':'xlArr','\u27F9':'xrArr','\u27FA':'xhArr','\u27FC':'xmap','\u27FF':'dzigrarr','\u2902':'nvlArr','\u2903':'nvrArr','\u2904':'nvHarr','\u2905':'Map','\u290C':'lbarr','\u290D':'rbarr','\u290E':'lBarr','\u290F':'rBarr','\u2910':'RBarr','\u2911':'DDotrahd','\u2912':'UpArrowBar','\u2913':'DownArrowBar','\u2916':'Rarrtl','\u2919':'latail','\u291A':'ratail','\u291B':'lAtail','\u291C':'rAtail','\u291D':'larrfs','\u291E':'rarrfs','\u291F':'larrbfs','\u2920':'rarrbfs','\u2923':'nwarhk','\u2924':'nearhk','\u2925':'searhk','\u2926':'swarhk','\u2927':'nwnear','\u2928':'toea','\u2929':'tosa','\u292A':'swnwar','\u2933':'rarrc','\u2933\u0338':'nrarrc','\u2935':'cudarrr','\u2936':'ldca','\u2937':'rdca','\u2938':'cudarrl','\u2939':'larrpl','\u293C':'curarrm','\u293D':'cularrp','\u2945':'rarrpl','\u2948':'harrcir','\u2949':'Uarrocir','\u294A':'lurdshar','\u294B':'ldrushar','\u294E':'LeftRightVector','\u294F':'RightUpDownVector','\u2950':'DownLeftRightVector','\u2951':'LeftUpDownVector','\u2952':'LeftVectorBar','\u2953':'RightVectorBar','\u2954':'RightUpVectorBar','\u2955':'RightDownVectorBar','\u2956':'DownLeftVectorBar','\u2957':'DownRightVectorBar','\u2958':'LeftUpVectorBar','\u2959':'LeftDownVectorBar','\u295A':'LeftTeeVector','\u295B':'RightTeeVector','\u295C':'RightUpTeeVector','\u295D':'RightDownTeeVector','\u295E':'DownLeftTeeVector','\u295F':'DownRightTeeVector','\u2960':'LeftUpTeeVector','\u2961':'LeftDownTeeVector','\u2962':'lHar','\u2963':'uHar','\u2964':'rHar','\u2965':'dHar','\u2966':'luruhar','\u2967':'ldrdhar','\u2968':'ruluhar','\u2969':'rdldhar','\u296A':'lharul','\u296B':'llhard','\u296C':'rharul','\u296D':'lrhard','\u296E':'udhar','\u296F':'duhar','\u2970':'RoundImplies','\u2971':'erarr','\u2972':'simrarr','\u2973':'larrsim','\u2974':'rarrsim','\u2975':'rarrap','\u2976':'ltlarr','\u2978':'gtrarr','\u2979':'subrarr','\u297B':'suplarr','\u297C':'lfisht','\u297D':'rfisht','\u297E':'ufisht','\u297F':'dfisht','\u299A':'vzigzag','\u299C':'vangrt','\u299D':'angrtvbd','\u29A4':'ange','\u29A5':'range','\u29A6':'dwangle','\u29A7':'uwangle','\u29A8':'angmsdaa','\u29A9':'angmsdab','\u29AA':'angmsdac','\u29AB':'angmsdad','\u29AC':'angmsdae','\u29AD':'angmsdaf','\u29AE':'angmsdag','\u29AF':'angmsdah','\u29B0':'bemptyv','\u29B1':'demptyv','\u29B2':'cemptyv','\u29B3':'raemptyv','\u29B4':'laemptyv','\u29B5':'ohbar','\u29B6':'omid','\u29B7':'opar','\u29B9':'operp','\u29BB':'olcross','\u29BC':'odsold','\u29BE':'olcir','\u29BF':'ofcir','\u29C0':'olt','\u29C1':'ogt','\u29C2':'cirscir','\u29C3':'cirE','\u29C4':'solb','\u29C5':'bsolb','\u29C9':'boxbox','\u29CD':'trisb','\u29CE':'rtriltri','\u29CF':'LeftTriangleBar','\u29CF\u0338':'NotLeftTriangleBar','\u29D0':'RightTriangleBar','\u29D0\u0338':'NotRightTriangleBar','\u29DC':'iinfin','\u29DD':'infintie','\u29DE':'nvinfin','\u29E3':'eparsl','\u29E4':'smeparsl','\u29E5':'eqvparsl','\u29EB':'lozf','\u29F4':'RuleDelayed','\u29F6':'dsol','\u2A00':'xodot','\u2A01':'xoplus','\u2A02':'xotime','\u2A04':'xuplus','\u2A06':'xsqcup','\u2A0D':'fpartint','\u2A10':'cirfnint','\u2A11':'awint','\u2A12':'rppolint','\u2A13':'scpolint','\u2A14':'npolint','\u2A15':'pointint','\u2A16':'quatint','\u2A17':'intlarhk','\u2A22':'pluscir','\u2A23':'plusacir','\u2A24':'simplus','\u2A25':'plusdu','\u2A26':'plussim','\u2A27':'plustwo','\u2A29':'mcomma','\u2A2A':'minusdu','\u2A2D':'loplus','\u2A2E':'roplus','\u2A2F':'Cross','\u2A30':'timesd','\u2A31':'timesbar','\u2A33':'smashp','\u2A34':'lotimes','\u2A35':'rotimes','\u2A36':'otimesas','\u2A37':'Otimes','\u2A38':'odiv','\u2A39':'triplus','\u2A3A':'triminus','\u2A3B':'tritime','\u2A3C':'iprod','\u2A3F':'amalg','\u2A40':'capdot','\u2A42':'ncup','\u2A43':'ncap','\u2A44':'capand','\u2A45':'cupor','\u2A46':'cupcap','\u2A47':'capcup','\u2A48':'cupbrcap','\u2A49':'capbrcup','\u2A4A':'cupcup','\u2A4B':'capcap','\u2A4C':'ccups','\u2A4D':'ccaps','\u2A50':'ccupssm','\u2A53':'And','\u2A54':'Or','\u2A55':'andand','\u2A56':'oror','\u2A57':'orslope','\u2A58':'andslope','\u2A5A':'andv','\u2A5B':'orv','\u2A5C':'andd','\u2A5D':'ord','\u2A5F':'wedbar','\u2A66':'sdote','\u2A6A':'simdot','\u2A6D':'congdot','\u2A6D\u0338':'ncongdot','\u2A6E':'easter','\u2A6F':'apacir','\u2A70':'apE','\u2A70\u0338':'napE','\u2A71':'eplus','\u2A72':'pluse','\u2A73':'Esim','\u2A77':'eDDot','\u2A78':'equivDD','\u2A79':'ltcir','\u2A7A':'gtcir','\u2A7B':'ltquest','\u2A7C':'gtquest','\u2A7D':'les','\u2A7D\u0338':'nles','\u2A7E':'ges','\u2A7E\u0338':'nges','\u2A7F':'lesdot','\u2A80':'gesdot','\u2A81':'lesdoto','\u2A82':'gesdoto','\u2A83':'lesdotor','\u2A84':'gesdotol','\u2A85':'lap','\u2A86':'gap','\u2A87':'lne','\u2A88':'gne','\u2A89':'lnap','\u2A8A':'gnap','\u2A8B':'lEg','\u2A8C':'gEl','\u2A8D':'lsime','\u2A8E':'gsime','\u2A8F':'lsimg','\u2A90':'gsiml','\u2A91':'lgE','\u2A92':'glE','\u2A93':'lesges','\u2A94':'gesles','\u2A95':'els','\u2A96':'egs','\u2A97':'elsdot','\u2A98':'egsdot','\u2A99':'el','\u2A9A':'eg','\u2A9D':'siml','\u2A9E':'simg','\u2A9F':'simlE','\u2AA0':'simgE','\u2AA1':'LessLess','\u2AA1\u0338':'NotNestedLessLess','\u2AA2':'GreaterGreater','\u2AA2\u0338':'NotNestedGreaterGreater','\u2AA4':'glj','\u2AA5':'gla','\u2AA6':'ltcc','\u2AA7':'gtcc','\u2AA8':'lescc','\u2AA9':'gescc','\u2AAA':'smt','\u2AAB':'lat','\u2AAC':'smte','\u2AAC\uFE00':'smtes','\u2AAD':'late','\u2AAD\uFE00':'lates','\u2AAE':'bumpE','\u2AAF':'pre','\u2AAF\u0338':'npre','\u2AB0':'sce','\u2AB0\u0338':'nsce','\u2AB3':'prE','\u2AB4':'scE','\u2AB5':'prnE','\u2AB6':'scnE','\u2AB7':'prap','\u2AB8':'scap','\u2AB9':'prnap','\u2ABA':'scnap','\u2ABB':'Pr','\u2ABC':'Sc','\u2ABD':'subdot','\u2ABE':'supdot','\u2ABF':'subplus','\u2AC0':'supplus','\u2AC1':'submult','\u2AC2':'supmult','\u2AC3':'subedot','\u2AC4':'supedot','\u2AC5':'subE','\u2AC5\u0338':'nsubE','\u2AC6':'supE','\u2AC6\u0338':'nsupE','\u2AC7':'subsim','\u2AC8':'supsim','\u2ACB\uFE00':'vsubnE','\u2ACB':'subnE','\u2ACC\uFE00':'vsupnE','\u2ACC':'supnE','\u2ACF':'csub','\u2AD0':'csup','\u2AD1':'csube','\u2AD2':'csupe','\u2AD3':'subsup','\u2AD4':'supsub','\u2AD5':'subsub','\u2AD6':'supsup','\u2AD7':'suphsub','\u2AD8':'supdsub','\u2AD9':'forkv','\u2ADA':'topfork','\u2ADB':'mlcp','\u2AE4':'Dashv','\u2AE6':'Vdashl','\u2AE7':'Barv','\u2AE8':'vBar','\u2AE9':'vBarv','\u2AEB':'Vbar','\u2AEC':'Not','\u2AED':'bNot','\u2AEE':'rnmid','\u2AEF':'cirmid','\u2AF0':'midcir','\u2AF1':'topcir','\u2AF2':'nhpar','\u2AF3':'parsim','\u2AFD':'parsl','\u2AFD\u20E5':'nparsl','\u266D':'flat','\u266E':'natur','\u266F':'sharp','\xA4':'curren','\xA2':'cent','$':'dollar','\xA3':'pound','\xA5':'yen','\u20AC':'euro','\xB9':'sup1','\xBD':'half','\u2153':'frac13','\xBC':'frac14','\u2155':'frac15','\u2159':'frac16','\u215B':'frac18','\xB2':'sup2','\u2154':'frac23','\u2156':'frac25','\xB3':'sup3','\xBE':'frac34','\u2157':'frac35','\u215C':'frac38','\u2158':'frac45','\u215A':'frac56','\u215D':'frac58','\u215E':'frac78','\uD835\uDCB6':'ascr','\uD835\uDD52':'aopf','\uD835\uDD1E':'afr','\uD835\uDD38':'Aopf','\uD835\uDD04':'Afr','\uD835\uDC9C':'Ascr','\xAA':'ordf','\xE1':'aacute','\xC1':'Aacute','\xE0':'agrave','\xC0':'Agrave','\u0103':'abreve','\u0102':'Abreve','\xE2':'acirc','\xC2':'Acirc','\xE5':'aring','\xC5':'angst','\xE4':'auml','\xC4':'Auml','\xE3':'atilde','\xC3':'Atilde','\u0105':'aogon','\u0104':'Aogon','\u0101':'amacr','\u0100':'Amacr','\xE6':'aelig','\xC6':'AElig','\uD835\uDCB7':'bscr','\uD835\uDD53':'bopf','\uD835\uDD1F':'bfr','\uD835\uDD39':'Bopf','\u212C':'Bscr','\uD835\uDD05':'Bfr','\uD835\uDD20':'cfr','\uD835\uDCB8':'cscr','\uD835\uDD54':'copf','\u212D':'Cfr','\uD835\uDC9E':'Cscr','\u2102':'Copf','\u0107':'cacute','\u0106':'Cacute','\u0109':'ccirc','\u0108':'Ccirc','\u010D':'ccaron','\u010C':'Ccaron','\u010B':'cdot','\u010A':'Cdot','\xE7':'ccedil','\xC7':'Ccedil','\u2105':'incare','\uD835\uDD21':'dfr','\u2146':'dd','\uD835\uDD55':'dopf','\uD835\uDCB9':'dscr','\uD835\uDC9F':'Dscr','\uD835\uDD07':'Dfr','\u2145':'DD','\uD835\uDD3B':'Dopf','\u010F':'dcaron','\u010E':'Dcaron','\u0111':'dstrok','\u0110':'Dstrok','\xF0':'eth','\xD0':'ETH','\u2147':'ee','\u212F':'escr','\uD835\uDD22':'efr','\uD835\uDD56':'eopf','\u2130':'Escr','\uD835\uDD08':'Efr','\uD835\uDD3C':'Eopf','\xE9':'eacute','\xC9':'Eacute','\xE8':'egrave','\xC8':'Egrave','\xEA':'ecirc','\xCA':'Ecirc','\u011B':'ecaron','\u011A':'Ecaron','\xEB':'euml','\xCB':'Euml','\u0117':'edot','\u0116':'Edot','\u0119':'eogon','\u0118':'Eogon','\u0113':'emacr','\u0112':'Emacr','\uD835\uDD23':'ffr','\uD835\uDD57':'fopf','\uD835\uDCBB':'fscr','\uD835\uDD09':'Ffr','\uD835\uDD3D':'Fopf','\u2131':'Fscr','\uFB00':'fflig','\uFB03':'ffilig','\uFB04':'ffllig','\uFB01':'filig','fj':'fjlig','\uFB02':'fllig','\u0192':'fnof','\u210A':'gscr','\uD835\uDD58':'gopf','\uD835\uDD24':'gfr','\uD835\uDCA2':'Gscr','\uD835\uDD3E':'Gopf','\uD835\uDD0A':'Gfr','\u01F5':'gacute','\u011F':'gbreve','\u011E':'Gbreve','\u011D':'gcirc','\u011C':'Gcirc','\u0121':'gdot','\u0120':'Gdot','\u0122':'Gcedil','\uD835\uDD25':'hfr','\u210E':'planckh','\uD835\uDCBD':'hscr','\uD835\uDD59':'hopf','\u210B':'Hscr','\u210C':'Hfr','\u210D':'Hopf','\u0125':'hcirc','\u0124':'Hcirc','\u210F':'hbar','\u0127':'hstrok','\u0126':'Hstrok','\uD835\uDD5A':'iopf','\uD835\uDD26':'ifr','\uD835\uDCBE':'iscr','\u2148':'ii','\uD835\uDD40':'Iopf','\u2110':'Iscr','\u2111':'Im','\xED':'iacute','\xCD':'Iacute','\xEC':'igrave','\xCC':'Igrave','\xEE':'icirc','\xCE':'Icirc','\xEF':'iuml','\xCF':'Iuml','\u0129':'itilde','\u0128':'Itilde','\u0130':'Idot','\u012F':'iogon','\u012E':'Iogon','\u012B':'imacr','\u012A':'Imacr','\u0133':'ijlig','\u0132':'IJlig','\u0131':'imath','\uD835\uDCBF':'jscr','\uD835\uDD5B':'jopf','\uD835\uDD27':'jfr','\uD835\uDCA5':'Jscr','\uD835\uDD0D':'Jfr','\uD835\uDD41':'Jopf','\u0135':'jcirc','\u0134':'Jcirc','\u0237':'jmath','\uD835\uDD5C':'kopf','\uD835\uDCC0':'kscr','\uD835\uDD28':'kfr','\uD835\uDCA6':'Kscr','\uD835\uDD42':'Kopf','\uD835\uDD0E':'Kfr','\u0137':'kcedil','\u0136':'Kcedil','\uD835\uDD29':'lfr','\uD835\uDCC1':'lscr','\u2113':'ell','\uD835\uDD5D':'lopf','\u2112':'Lscr','\uD835\uDD0F':'Lfr','\uD835\uDD43':'Lopf','\u013A':'lacute','\u0139':'Lacute','\u013E':'lcaron','\u013D':'Lcaron','\u013C':'lcedil','\u013B':'Lcedil','\u0142':'lstrok','\u0141':'Lstrok','\u0140':'lmidot','\u013F':'Lmidot','\uD835\uDD2A':'mfr','\uD835\uDD5E':'mopf','\uD835\uDCC2':'mscr','\uD835\uDD10':'Mfr','\uD835\uDD44':'Mopf','\u2133':'Mscr','\uD835\uDD2B':'nfr','\uD835\uDD5F':'nopf','\uD835\uDCC3':'nscr','\u2115':'Nopf','\uD835\uDCA9':'Nscr','\uD835\uDD11':'Nfr','\u0144':'nacute','\u0143':'Nacute','\u0148':'ncaron','\u0147':'Ncaron','\xF1':'ntilde','\xD1':'Ntilde','\u0146':'ncedil','\u0145':'Ncedil','\u2116':'numero','\u014B':'eng','\u014A':'ENG','\uD835\uDD60':'oopf','\uD835\uDD2C':'ofr','\u2134':'oscr','\uD835\uDCAA':'Oscr','\uD835\uDD12':'Ofr','\uD835\uDD46':'Oopf','\xBA':'ordm','\xF3':'oacute','\xD3':'Oacute','\xF2':'ograve','\xD2':'Ograve','\xF4':'ocirc','\xD4':'Ocirc','\xF6':'ouml','\xD6':'Ouml','\u0151':'odblac','\u0150':'Odblac','\xF5':'otilde','\xD5':'Otilde','\xF8':'oslash','\xD8':'Oslash','\u014D':'omacr','\u014C':'Omacr','\u0153':'oelig','\u0152':'OElig','\uD835\uDD2D':'pfr','\uD835\uDCC5':'pscr','\uD835\uDD61':'popf','\u2119':'Popf','\uD835\uDD13':'Pfr','\uD835\uDCAB':'Pscr','\uD835\uDD62':'qopf','\uD835\uDD2E':'qfr','\uD835\uDCC6':'qscr','\uD835\uDCAC':'Qscr','\uD835\uDD14':'Qfr','\u211A':'Qopf','\u0138':'kgreen','\uD835\uDD2F':'rfr','\uD835\uDD63':'ropf','\uD835\uDCC7':'rscr','\u211B':'Rscr','\u211C':'Re','\u211D':'Ropf','\u0155':'racute','\u0154':'Racute','\u0159':'rcaron','\u0158':'Rcaron','\u0157':'rcedil','\u0156':'Rcedil','\uD835\uDD64':'sopf','\uD835\uDCC8':'sscr','\uD835\uDD30':'sfr','\uD835\uDD4A':'Sopf','\uD835\uDD16':'Sfr','\uD835\uDCAE':'Sscr','\u24C8':'oS','\u015B':'sacute','\u015A':'Sacute','\u015D':'scirc','\u015C':'Scirc','\u0161':'scaron','\u0160':'Scaron','\u015F':'scedil','\u015E':'Scedil','\xDF':'szlig','\uD835\uDD31':'tfr','\uD835\uDCC9':'tscr','\uD835\uDD65':'topf','\uD835\uDCAF':'Tscr','\uD835\uDD17':'Tfr','\uD835\uDD4B':'Topf','\u0165':'tcaron','\u0164':'Tcaron','\u0163':'tcedil','\u0162':'Tcedil','\u2122':'trade','\u0167':'tstrok','\u0166':'Tstrok','\uD835\uDCCA':'uscr','\uD835\uDD66':'uopf','\uD835\uDD32':'ufr','\uD835\uDD4C':'Uopf','\uD835\uDD18':'Ufr','\uD835\uDCB0':'Uscr','\xFA':'uacute','\xDA':'Uacute','\xF9':'ugrave','\xD9':'Ugrave','\u016D':'ubreve','\u016C':'Ubreve','\xFB':'ucirc','\xDB':'Ucirc','\u016F':'uring','\u016E':'Uring','\xFC':'uuml','\xDC':'Uuml','\u0171':'udblac','\u0170':'Udblac','\u0169':'utilde','\u0168':'Utilde','\u0173':'uogon','\u0172':'Uogon','\u016B':'umacr','\u016A':'Umacr','\uD835\uDD33':'vfr','\uD835\uDD67':'vopf','\uD835\uDCCB':'vscr','\uD835\uDD19':'Vfr','\uD835\uDD4D':'Vopf','\uD835\uDCB1':'Vscr','\uD835\uDD68':'wopf','\uD835\uDCCC':'wscr','\uD835\uDD34':'wfr','\uD835\uDCB2':'Wscr','\uD835\uDD4E':'Wopf','\uD835\uDD1A':'Wfr','\u0175':'wcirc','\u0174':'Wcirc','\uD835\uDD35':'xfr','\uD835\uDCCD':'xscr','\uD835\uDD69':'xopf','\uD835\uDD4F':'Xopf','\uD835\uDD1B':'Xfr','\uD835\uDCB3':'Xscr','\uD835\uDD36':'yfr','\uD835\uDCCE':'yscr','\uD835\uDD6A':'yopf','\uD835\uDCB4':'Yscr','\uD835\uDD1C':'Yfr','\uD835\uDD50':'Yopf','\xFD':'yacute','\xDD':'Yacute','\u0177':'ycirc','\u0176':'Ycirc','\xFF':'yuml','\u0178':'Yuml','\uD835\uDCCF':'zscr','\uD835\uDD37':'zfr','\uD835\uDD6B':'zopf','\u2128':'Zfr','\u2124':'Zopf','\uD835\uDCB5':'Zscr','\u017A':'zacute','\u0179':'Zacute','\u017E':'zcaron','\u017D':'Zcaron','\u017C':'zdot','\u017B':'Zdot','\u01B5':'imped','\xFE':'thorn','\xDE':'THORN','\u0149':'napos','\u03B1':'alpha','\u0391':'Alpha','\u03B2':'beta','\u0392':'Beta','\u03B3':'gamma','\u0393':'Gamma','\u03B4':'delta','\u0394':'Delta','\u03B5':'epsi','\u03F5':'epsiv','\u0395':'Epsilon','\u03DD':'gammad','\u03DC':'Gammad','\u03B6':'zeta','\u0396':'Zeta','\u03B7':'eta','\u0397':'Eta','\u03B8':'theta','\u03D1':'thetav','\u0398':'Theta','\u03B9':'iota','\u0399':'Iota','\u03BA':'kappa','\u03F0':'kappav','\u039A':'Kappa','\u03BB':'lambda','\u039B':'Lambda','\u03BC':'mu','\xB5':'micro','\u039C':'Mu','\u03BD':'nu','\u039D':'Nu','\u03BE':'xi','\u039E':'Xi','\u03BF':'omicron','\u039F':'Omicron','\u03C0':'pi','\u03D6':'piv','\u03A0':'Pi','\u03C1':'rho','\u03F1':'rhov','\u03A1':'Rho','\u03C3':'sigma','\u03A3':'Sigma','\u03C2':'sigmaf','\u03C4':'tau','\u03A4':'Tau','\u03C5':'upsi','\u03A5':'Upsilon','\u03D2':'Upsi','\u03C6':'phi','\u03D5':'phiv','\u03A6':'Phi','\u03C7':'chi','\u03A7':'Chi','\u03C8':'psi','\u03A8':'Psi','\u03C9':'omega','\u03A9':'ohm','\u0430':'acy','\u0410':'Acy','\u0431':'bcy','\u0411':'Bcy','\u0432':'vcy','\u0412':'Vcy','\u0433':'gcy','\u0413':'Gcy','\u0453':'gjcy','\u0403':'GJcy','\u0434':'dcy','\u0414':'Dcy','\u0452':'djcy','\u0402':'DJcy','\u0435':'iecy','\u0415':'IEcy','\u0451':'iocy','\u0401':'IOcy','\u0454':'jukcy','\u0404':'Jukcy','\u0436':'zhcy','\u0416':'ZHcy','\u0437':'zcy','\u0417':'Zcy','\u0455':'dscy','\u0405':'DScy','\u0438':'icy','\u0418':'Icy','\u0456':'iukcy','\u0406':'Iukcy','\u0457':'yicy','\u0407':'YIcy','\u0439':'jcy','\u0419':'Jcy','\u0458':'jsercy','\u0408':'Jsercy','\u043A':'kcy','\u041A':'Kcy','\u045C':'kjcy','\u040C':'KJcy','\u043B':'lcy','\u041B':'Lcy','\u0459':'ljcy','\u0409':'LJcy','\u043C':'mcy','\u041C':'Mcy','\u043D':'ncy','\u041D':'Ncy','\u045A':'njcy','\u040A':'NJcy','\u043E':'ocy','\u041E':'Ocy','\u043F':'pcy','\u041F':'Pcy','\u0440':'rcy','\u0420':'Rcy','\u0441':'scy','\u0421':'Scy','\u0442':'tcy','\u0422':'Tcy','\u045B':'tshcy','\u040B':'TSHcy','\u0443':'ucy','\u0423':'Ucy','\u045E':'ubrcy','\u040E':'Ubrcy','\u0444':'fcy','\u0424':'Fcy','\u0445':'khcy','\u0425':'KHcy','\u0446':'tscy','\u0426':'TScy','\u0447':'chcy','\u0427':'CHcy','\u045F':'dzcy','\u040F':'DZcy','\u0448':'shcy','\u0428':'SHcy','\u0449':'shchcy','\u0429':'SHCHcy','\u044A':'hardcy','\u042A':'HARDcy','\u044B':'ycy','\u042B':'Ycy','\u044C':'softcy','\u042C':'SOFTcy','\u044D':'ecy','\u042D':'Ecy','\u044E':'yucy','\u042E':'YUcy','\u044F':'yacy','\u042F':'YAcy','\u2135':'aleph','\u2136':'beth','\u2137':'gimel','\u2138':'daleth'}; + + var regexEscape = /["&'<>`]/g; + var escapeMap = { + '"': '"', + '&': '&', + '\'': ''', + '<': '<', + // See https://mathiasbynens.be/notes/ambiguous-ampersands: in HTML, the + // following is not strictly necessary unless itโ€™s part of a tag or an + // unquoted attribute value. Weโ€™re only escaping it to support those + // situations, and for XML support. + '>': '>', + // In Internet Explorer โ‰ค 8, the backtick character can be used + // to break out of (un)quoted attribute values or HTML comments. + // See http://html5sec.org/#102, http://html5sec.org/#108, and + // http://html5sec.org/#133. + '`': '`' + }; + + var regexInvalidEntity = /&#(?:[xX][^a-fA-F0-9]|[^0-9xX])/; + var regexInvalidRawCodePoint = /[\0-\x08\x0B\x0E-\x1F\x7F-\x9F\uFDD0-\uFDEF\uFFFE\uFFFF]|[\uD83F\uD87F\uD8BF\uD8FF\uD93F\uD97F\uD9BF\uD9FF\uDA3F\uDA7F\uDABF\uDAFF\uDB3F\uDB7F\uDBBF\uDBFF][\uDFFE\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; + var regexDecode = /&(CounterClockwiseContourIntegral|DoubleLongLeftRightArrow|ClockwiseContourIntegral|NotNestedGreaterGreater|NotSquareSupersetEqual|DiacriticalDoubleAcute|NotRightTriangleEqual|NotSucceedsSlantEqual|NotPrecedesSlantEqual|CloseCurlyDoubleQuote|NegativeVeryThinSpace|DoubleContourIntegral|FilledVerySmallSquare|CapitalDifferentialD|OpenCurlyDoubleQuote|EmptyVerySmallSquare|NestedGreaterGreater|DoubleLongRightArrow|NotLeftTriangleEqual|NotGreaterSlantEqual|ReverseUpEquilibrium|DoubleLeftRightArrow|NotSquareSubsetEqual|NotDoubleVerticalBar|RightArrowLeftArrow|NotGreaterFullEqual|NotRightTriangleBar|SquareSupersetEqual|DownLeftRightVector|DoubleLongLeftArrow|leftrightsquigarrow|LeftArrowRightArrow|NegativeMediumSpace|blacktriangleright|RightDownVectorBar|PrecedesSlantEqual|RightDoubleBracket|SucceedsSlantEqual|NotLeftTriangleBar|RightTriangleEqual|SquareIntersection|RightDownTeeVector|ReverseEquilibrium|NegativeThickSpace|longleftrightarrow|Longleftrightarrow|LongLeftRightArrow|DownRightTeeVector|DownRightVectorBar|GreaterSlantEqual|SquareSubsetEqual|LeftDownVectorBar|LeftDoubleBracket|VerticalSeparator|rightleftharpoons|NotGreaterGreater|NotSquareSuperset|blacktriangleleft|blacktriangledown|NegativeThinSpace|LeftDownTeeVector|NotLessSlantEqual|leftrightharpoons|DoubleUpDownArrow|DoubleVerticalBar|LeftTriangleEqual|FilledSmallSquare|twoheadrightarrow|NotNestedLessLess|DownLeftTeeVector|DownLeftVectorBar|RightAngleBracket|NotTildeFullEqual|NotReverseElement|RightUpDownVector|DiacriticalTilde|NotSucceedsTilde|circlearrowright|NotPrecedesEqual|rightharpoondown|DoubleRightArrow|NotSucceedsEqual|NonBreakingSpace|NotRightTriangle|LessEqualGreater|RightUpTeeVector|LeftAngleBracket|GreaterFullEqual|DownArrowUpArrow|RightUpVectorBar|twoheadleftarrow|GreaterEqualLess|downharpoonright|RightTriangleBar|ntrianglerighteq|NotSupersetEqual|LeftUpDownVector|DiacriticalAcute|rightrightarrows|vartriangleright|UpArrowDownArrow|DiacriticalGrave|UnderParenthesis|EmptySmallSquare|LeftUpVectorBar|leftrightarrows|DownRightVector|downharpoonleft|trianglerighteq|ShortRightArrow|OverParenthesis|DoubleLeftArrow|DoubleDownArrow|NotSquareSubset|bigtriangledown|ntrianglelefteq|UpperRightArrow|curvearrowright|vartriangleleft|NotLeftTriangle|nleftrightarrow|LowerRightArrow|NotHumpDownHump|NotGreaterTilde|rightthreetimes|LeftUpTeeVector|NotGreaterEqual|straightepsilon|LeftTriangleBar|rightsquigarrow|ContourIntegral|rightleftarrows|CloseCurlyQuote|RightDownVector|LeftRightVector|nLeftrightarrow|leftharpoondown|circlearrowleft|SquareSuperset|OpenCurlyQuote|hookrightarrow|HorizontalLine|DiacriticalDot|NotLessGreater|ntriangleright|DoubleRightTee|InvisibleComma|InvisibleTimes|LowerLeftArrow|DownLeftVector|NotSubsetEqual|curvearrowleft|trianglelefteq|NotVerticalBar|TildeFullEqual|downdownarrows|NotGreaterLess|RightTeeVector|ZeroWidthSpace|looparrowright|LongRightArrow|doublebarwedge|ShortLeftArrow|ShortDownArrow|RightVectorBar|GreaterGreater|ReverseElement|rightharpoonup|LessSlantEqual|leftthreetimes|upharpoonright|rightarrowtail|LeftDownVector|Longrightarrow|NestedLessLess|UpperLeftArrow|nshortparallel|leftleftarrows|leftrightarrow|Leftrightarrow|LeftRightArrow|longrightarrow|upharpoonleft|RightArrowBar|ApplyFunction|LeftTeeVector|leftarrowtail|NotEqualTilde|varsubsetneqq|varsupsetneqq|RightTeeArrow|SucceedsEqual|SucceedsTilde|LeftVectorBar|SupersetEqual|hookleftarrow|DifferentialD|VerticalTilde|VeryThinSpace|blacktriangle|bigtriangleup|LessFullEqual|divideontimes|leftharpoonup|UpEquilibrium|ntriangleleft|RightTriangle|measuredangle|shortparallel|longleftarrow|Longleftarrow|LongLeftArrow|DoubleLeftTee|Poincareplane|PrecedesEqual|triangleright|DoubleUpArrow|RightUpVector|fallingdotseq|looparrowleft|PrecedesTilde|NotTildeEqual|NotTildeTilde|smallsetminus|Proportional|triangleleft|triangledown|UnderBracket|NotHumpEqual|exponentiale|ExponentialE|NotLessTilde|HilbertSpace|RightCeiling|blacklozenge|varsupsetneq|HumpDownHump|GreaterEqual|VerticalLine|LeftTeeArrow|NotLessEqual|DownTeeArrow|LeftTriangle|varsubsetneq|Intersection|NotCongruent|DownArrowBar|LeftUpVector|LeftArrowBar|risingdotseq|GreaterTilde|RoundImplies|SquareSubset|ShortUpArrow|NotSuperset|quaternions|precnapprox|backepsilon|preccurlyeq|OverBracket|blacksquare|MediumSpace|VerticalBar|circledcirc|circleddash|CircleMinus|CircleTimes|LessGreater|curlyeqprec|curlyeqsucc|diamondsuit|UpDownArrow|Updownarrow|RuleDelayed|Rrightarrow|updownarrow|RightVector|nRightarrow|nrightarrow|eqslantless|LeftCeiling|Equilibrium|SmallCircle|expectation|NotSucceeds|thickapprox|GreaterLess|SquareUnion|NotPrecedes|NotLessLess|straightphi|succnapprox|succcurlyeq|SubsetEqual|sqsupseteq|Proportion|Laplacetrf|ImaginaryI|supsetneqq|NotGreater|gtreqqless|NotElement|ThickSpace|TildeEqual|TildeTilde|Fouriertrf|rmoustache|EqualTilde|eqslantgtr|UnderBrace|LeftVector|UpArrowBar|nLeftarrow|nsubseteqq|subsetneqq|nsupseteqq|nleftarrow|succapprox|lessapprox|UpTeeArrow|upuparrows|curlywedge|lesseqqgtr|varepsilon|varnothing|RightFloor|complement|CirclePlus|sqsubseteq|Lleftarrow|circledast|RightArrow|Rightarrow|rightarrow|lmoustache|Bernoullis|precapprox|mapstoleft|mapstodown|longmapsto|dotsquare|downarrow|DoubleDot|nsubseteq|supsetneq|leftarrow|nsupseteq|subsetneq|ThinSpace|ngeqslant|subseteqq|HumpEqual|NotSubset|triangleq|NotCupCap|lesseqgtr|heartsuit|TripleDot|Leftarrow|Coproduct|Congruent|varpropto|complexes|gvertneqq|LeftArrow|LessTilde|supseteqq|MinusPlus|CircleDot|nleqslant|NotExists|gtreqless|nparallel|UnionPlus|LeftFloor|checkmark|CenterDot|centerdot|Mellintrf|gtrapprox|bigotimes|OverBrace|spadesuit|therefore|pitchfork|rationals|PlusMinus|Backslash|Therefore|DownBreve|backsimeq|backprime|DownArrow|nshortmid|Downarrow|lvertneqq|eqvparsl|imagline|imagpart|infintie|integers|Integral|intercal|LessLess|Uarrocir|intlarhk|sqsupset|angmsdaf|sqsubset|llcorner|vartheta|cupbrcap|lnapprox|Superset|SuchThat|succnsim|succneqq|angmsdag|biguplus|curlyvee|trpezium|Succeeds|NotTilde|bigwedge|angmsdah|angrtvbd|triminus|cwconint|fpartint|lrcorner|smeparsl|subseteq|urcorner|lurdshar|laemptyv|DDotrahd|approxeq|ldrushar|awconint|mapstoup|backcong|shortmid|triangle|geqslant|gesdotol|timesbar|circledR|circledS|setminus|multimap|naturals|scpolint|ncongdot|RightTee|boxminus|gnapprox|boxtimes|andslope|thicksim|angmsdaa|varsigma|cirfnint|rtriltri|angmsdab|rppolint|angmsdac|barwedge|drbkarow|clubsuit|thetasym|bsolhsub|capbrcup|dzigrarr|doteqdot|DotEqual|dotminus|UnderBar|NotEqual|realpart|otimesas|ulcorner|hksearow|hkswarow|parallel|PartialD|elinters|emptyset|plusacir|bbrktbrk|angmsdad|pointint|bigoplus|angmsdae|Precedes|bigsqcup|varkappa|notindot|supseteq|precneqq|precnsim|profalar|profline|profsurf|leqslant|lesdotor|raemptyv|subplus|notnivb|notnivc|subrarr|zigrarr|vzigzag|submult|subedot|Element|between|cirscir|larrbfs|larrsim|lotimes|lbrksld|lbrkslu|lozenge|ldrdhar|dbkarow|bigcirc|epsilon|simrarr|simplus|ltquest|Epsilon|luruhar|gtquest|maltese|npolint|eqcolon|npreceq|bigodot|ddagger|gtrless|bnequiv|harrcir|ddotseq|equivDD|backsim|demptyv|nsqsube|nsqsupe|Upsilon|nsubset|upsilon|minusdu|nsucceq|swarrow|nsupset|coloneq|searrow|boxplus|napprox|natural|asympeq|alefsym|congdot|nearrow|bigstar|diamond|supplus|tritime|LeftTee|nvinfin|triplus|NewLine|nvltrie|nvrtrie|nwarrow|nexists|Diamond|ruluhar|Implies|supmult|angzarr|suplarr|suphsub|questeq|because|digamma|Because|olcross|bemptyv|omicron|Omicron|rotimes|NoBreak|intprod|angrtvb|orderof|uwangle|suphsol|lesdoto|orslope|DownTee|realine|cudarrl|rdldhar|OverBar|supedot|lessdot|supdsub|topfork|succsim|rbrkslu|rbrksld|pertenk|cudarrr|isindot|planckh|lessgtr|pluscir|gesdoto|plussim|plustwo|lesssim|cularrp|rarrsim|Cayleys|notinva|notinvb|notinvc|UpArrow|Uparrow|uparrow|NotLess|dwangle|precsim|Product|curarrm|Cconint|dotplus|rarrbfs|ccupssm|Cedilla|cemptyv|notniva|quatint|frac35|frac38|frac45|frac56|frac58|frac78|tridot|xoplus|gacute|gammad|Gammad|lfisht|lfloor|bigcup|sqsupe|gbreve|Gbreve|lharul|sqsube|sqcups|Gcedil|apacir|llhard|lmidot|Lmidot|lmoust|andand|sqcaps|approx|Abreve|spades|circeq|tprime|divide|topcir|Assign|topbot|gesdot|divonx|xuplus|timesd|gesles|atilde|solbar|SOFTcy|loplus|timesb|lowast|lowbar|dlcorn|dlcrop|softcy|dollar|lparlt|thksim|lrhard|Atilde|lsaquo|smashp|bigvee|thinsp|wreath|bkarow|lsquor|lstrok|Lstrok|lthree|ltimes|ltlarr|DotDot|simdot|ltrPar|weierp|xsqcup|angmsd|sigmav|sigmaf|zeetrf|Zcaron|zcaron|mapsto|vsupne|thetav|cirmid|marker|mcomma|Zacute|vsubnE|there4|gtlPar|vsubne|bottom|gtrarr|SHCHcy|shchcy|midast|midcir|middot|minusb|minusd|gtrdot|bowtie|sfrown|mnplus|models|colone|seswar|Colone|mstpos|searhk|gtrsim|nacute|Nacute|boxbox|telrec|hairsp|Tcedil|nbumpe|scnsim|ncaron|Ncaron|ncedil|Ncedil|hamilt|Scedil|nearhk|hardcy|HARDcy|tcedil|Tcaron|commat|nequiv|nesear|tcaron|target|hearts|nexist|varrho|scedil|Scaron|scaron|hellip|Sacute|sacute|hercon|swnwar|compfn|rtimes|rthree|rsquor|rsaquo|zacute|wedgeq|homtht|barvee|barwed|Barwed|rpargt|horbar|conint|swarhk|roplus|nltrie|hslash|hstrok|Hstrok|rmoust|Conint|bprime|hybull|hyphen|iacute|Iacute|supsup|supsub|supsim|varphi|coprod|brvbar|agrave|Supset|supset|igrave|Igrave|notinE|Agrave|iiiint|iinfin|copysr|wedbar|Verbar|vangrt|becaus|incare|verbar|inodot|bullet|drcorn|intcal|drcrop|cularr|vellip|Utilde|bumpeq|cupcap|dstrok|Dstrok|CupCap|cupcup|cupdot|eacute|Eacute|supdot|iquest|easter|ecaron|Ecaron|ecolon|isinsv|utilde|itilde|Itilde|curarr|succeq|Bumpeq|cacute|ulcrop|nparsl|Cacute|nprcue|egrave|Egrave|nrarrc|nrarrw|subsup|subsub|nrtrie|jsercy|nsccue|Jsercy|kappav|kcedil|Kcedil|subsim|ulcorn|nsimeq|egsdot|veebar|kgreen|capand|elsdot|Subset|subset|curren|aacute|lacute|Lacute|emptyv|ntilde|Ntilde|lagran|lambda|Lambda|capcap|Ugrave|langle|subdot|emsp13|numero|emsp14|nvdash|nvDash|nVdash|nVDash|ugrave|ufisht|nvHarr|larrfs|nvlArr|larrhk|larrlp|larrpl|nvrArr|Udblac|nwarhk|larrtl|nwnear|oacute|Oacute|latail|lAtail|sstarf|lbrace|odblac|Odblac|lbrack|udblac|odsold|eparsl|lcaron|Lcaron|ograve|Ograve|lcedil|Lcedil|Aacute|ssmile|ssetmn|squarf|ldquor|capcup|ominus|cylcty|rharul|eqcirc|dagger|rfloor|rfisht|Dagger|daleth|equals|origof|capdot|equest|dcaron|Dcaron|rdquor|oslash|Oslash|otilde|Otilde|otimes|Otimes|urcrop|Ubreve|ubreve|Yacute|Uacute|uacute|Rcedil|rcedil|urcorn|parsim|Rcaron|Vdashl|rcaron|Tstrok|percnt|period|permil|Exists|yacute|rbrack|rbrace|phmmat|ccaron|Ccaron|planck|ccedil|plankv|tstrok|female|plusdo|plusdu|ffilig|plusmn|ffllig|Ccedil|rAtail|dfisht|bernou|ratail|Rarrtl|rarrtl|angsph|rarrpl|rarrlp|rarrhk|xwedge|xotime|forall|ForAll|Vvdash|vsupnE|preceq|bigcap|frac12|frac13|frac14|primes|rarrfs|prnsim|frac15|Square|frac16|square|lesdot|frac18|frac23|propto|prurel|rarrap|rangle|puncsp|frac25|Racute|qprime|racute|lesges|frac34|abreve|AElig|eqsim|utdot|setmn|urtri|Equal|Uring|seArr|uring|searr|dashv|Dashv|mumap|nabla|iogon|Iogon|sdote|sdotb|scsim|napid|napos|equiv|natur|Acirc|dblac|erarr|nbump|iprod|erDot|ucirc|awint|esdot|angrt|ncong|isinE|scnap|Scirc|scirc|ndash|isins|Ubrcy|nearr|neArr|isinv|nedot|ubrcy|acute|Ycirc|iukcy|Iukcy|xutri|nesim|caret|jcirc|Jcirc|caron|twixt|ddarr|sccue|exist|jmath|sbquo|ngeqq|angst|ccaps|lceil|ngsim|UpTee|delta|Delta|rtrif|nharr|nhArr|nhpar|rtrie|jukcy|Jukcy|kappa|rsquo|Kappa|nlarr|nlArr|TSHcy|rrarr|aogon|Aogon|fflig|xrarr|tshcy|ccirc|nleqq|filig|upsih|nless|dharl|nlsim|fjlig|ropar|nltri|dharr|robrk|roarr|fllig|fltns|roang|rnmid|subnE|subne|lAarr|trisb|Ccirc|acirc|ccups|blank|VDash|forkv|Vdash|langd|cedil|blk12|blk14|laquo|strns|diams|notin|vDash|larrb|blk34|block|disin|uplus|vdash|vBarv|aelig|starf|Wedge|check|xrArr|lates|lbarr|lBarr|notni|lbbrk|bcong|frasl|lbrke|frown|vrtri|vprop|vnsup|gamma|Gamma|wedge|xodot|bdquo|srarr|doteq|ldquo|boxdl|boxdL|gcirc|Gcirc|boxDl|boxDL|boxdr|boxdR|boxDr|TRADE|trade|rlhar|boxDR|vnsub|npart|vltri|rlarr|boxhd|boxhD|nprec|gescc|nrarr|nrArr|boxHd|boxHD|boxhu|boxhU|nrtri|boxHu|clubs|boxHU|times|colon|Colon|gimel|xlArr|Tilde|nsime|tilde|nsmid|nspar|THORN|thorn|xlarr|nsube|nsubE|thkap|xhArr|comma|nsucc|boxul|boxuL|nsupe|nsupE|gneqq|gnsim|boxUl|boxUL|grave|boxur|boxuR|boxUr|boxUR|lescc|angle|bepsi|boxvh|varpi|boxvH|numsp|Theta|gsime|gsiml|theta|boxVh|boxVH|boxvl|gtcir|gtdot|boxvL|boxVl|boxVL|crarr|cross|Cross|nvsim|boxvr|nwarr|nwArr|sqsup|dtdot|Uogon|lhard|lharu|dtrif|ocirc|Ocirc|lhblk|duarr|odash|sqsub|Hacek|sqcup|llarr|duhar|oelig|OElig|ofcir|boxvR|uogon|lltri|boxVr|csube|uuarr|ohbar|csupe|ctdot|olarr|olcir|harrw|oline|sqcap|omacr|Omacr|omega|Omega|boxVR|aleph|lneqq|lnsim|loang|loarr|rharu|lobrk|hcirc|operp|oplus|rhard|Hcirc|orarr|Union|order|ecirc|Ecirc|cuepr|szlig|cuesc|breve|reals|eDDot|Breve|hoarr|lopar|utrif|rdquo|Umacr|umacr|efDot|swArr|ultri|alpha|rceil|ovbar|swarr|Wcirc|wcirc|smtes|smile|bsemi|lrarr|aring|parsl|lrhar|bsime|uhblk|lrtri|cupor|Aring|uharr|uharl|slarr|rbrke|bsolb|lsime|rbbrk|RBarr|lsimg|phone|rBarr|rbarr|icirc|lsquo|Icirc|emacr|Emacr|ratio|simne|plusb|simlE|simgE|simeq|pluse|ltcir|ltdot|empty|xharr|xdtri|iexcl|Alpha|ltrie|rarrw|pound|ltrif|xcirc|bumpe|prcue|bumpE|asymp|amacr|cuvee|Sigma|sigma|iiint|udhar|iiota|ijlig|IJlig|supnE|imacr|Imacr|prime|Prime|image|prnap|eogon|Eogon|rarrc|mdash|mDDot|cuwed|imath|supne|imped|Amacr|udarr|prsim|micro|rarrb|cwint|raquo|infin|eplus|range|rangd|Ucirc|radic|minus|amalg|veeeq|rAarr|epsiv|ycirc|quest|sharp|quot|zwnj|Qscr|race|qscr|Qopf|qopf|qint|rang|Rang|Zscr|zscr|Zopf|zopf|rarr|rArr|Rarr|Pscr|pscr|prop|prod|prnE|prec|ZHcy|zhcy|prap|Zeta|zeta|Popf|popf|Zdot|plus|zdot|Yuml|yuml|phiv|YUcy|yucy|Yscr|yscr|perp|Yopf|yopf|part|para|YIcy|Ouml|rcub|yicy|YAcy|rdca|ouml|osol|Oscr|rdsh|yacy|real|oscr|xvee|andd|rect|andv|Xscr|oror|ordm|ordf|xscr|ange|aopf|Aopf|rHar|Xopf|opar|Oopf|xopf|xnis|rhov|oopf|omid|xmap|oint|apid|apos|ogon|ascr|Ascr|odot|odiv|xcup|xcap|ocir|oast|nvlt|nvle|nvgt|nvge|nvap|Wscr|wscr|auml|ntlg|ntgl|nsup|nsub|nsim|Nscr|nscr|nsce|Wopf|ring|npre|wopf|npar|Auml|Barv|bbrk|Nopf|nopf|nmid|nLtv|beta|ropf|Ropf|Beta|beth|nles|rpar|nleq|bnot|bNot|nldr|NJcy|rscr|Rscr|Vscr|vscr|rsqb|njcy|bopf|nisd|Bopf|rtri|Vopf|nGtv|ngtr|vopf|boxh|boxH|boxv|nges|ngeq|boxV|bscr|scap|Bscr|bsim|Vert|vert|bsol|bull|bump|caps|cdot|ncup|scnE|ncap|nbsp|napE|Cdot|cent|sdot|Vbar|nang|vBar|chcy|Mscr|mscr|sect|semi|CHcy|Mopf|mopf|sext|circ|cire|mldr|mlcp|cirE|comp|shcy|SHcy|vArr|varr|cong|copf|Copf|copy|COPY|malt|male|macr|lvnE|cscr|ltri|sime|ltcc|simg|Cscr|siml|csub|Uuml|lsqb|lsim|uuml|csup|Lscr|lscr|utri|smid|lpar|cups|smte|lozf|darr|Lopf|Uscr|solb|lopf|sopf|Sopf|lneq|uscr|spar|dArr|lnap|Darr|dash|Sqrt|LJcy|ljcy|lHar|dHar|Upsi|upsi|diam|lesg|djcy|DJcy|leqq|dopf|Dopf|dscr|Dscr|dscy|ldsh|ldca|squf|DScy|sscr|Sscr|dsol|lcub|late|star|Star|Uopf|Larr|lArr|larr|uopf|dtri|dzcy|sube|subE|Lang|lang|Kscr|kscr|Kopf|kopf|KJcy|kjcy|KHcy|khcy|DZcy|ecir|edot|eDot|Jscr|jscr|succ|Jopf|jopf|Edot|uHar|emsp|ensp|Iuml|iuml|eopf|isin|Iscr|iscr|Eopf|epar|sung|epsi|escr|sup1|sup2|sup3|Iota|iota|supe|supE|Iopf|iopf|IOcy|iocy|Escr|esim|Esim|imof|Uarr|QUOT|uArr|uarr|euml|IEcy|iecy|Idot|Euml|euro|excl|Hscr|hscr|Hopf|hopf|TScy|tscy|Tscr|hbar|tscr|flat|tbrk|fnof|hArr|harr|half|fopf|Fopf|tdot|gvnE|fork|trie|gtcc|fscr|Fscr|gdot|gsim|Gscr|gscr|Gopf|gopf|gneq|Gdot|tosa|gnap|Topf|topf|geqq|toea|GJcy|gjcy|tint|gesl|mid|Sfr|ggg|top|ges|gla|glE|glj|geq|gne|gEl|gel|gnE|Gcy|gcy|gap|Tfr|tfr|Tcy|tcy|Hat|Tau|Ffr|tau|Tab|hfr|Hfr|ffr|Fcy|fcy|icy|Icy|iff|ETH|eth|ifr|Ifr|Eta|eta|int|Int|Sup|sup|ucy|Ucy|Sum|sum|jcy|ENG|ufr|Ufr|eng|Jcy|jfr|els|ell|egs|Efr|efr|Jfr|uml|kcy|Kcy|Ecy|ecy|kfr|Kfr|lap|Sub|sub|lat|lcy|Lcy|leg|Dot|dot|lEg|leq|les|squ|div|die|lfr|Lfr|lgE|Dfr|dfr|Del|deg|Dcy|dcy|lne|lnE|sol|loz|smt|Cup|lrm|cup|lsh|Lsh|sim|shy|map|Map|mcy|Mcy|mfr|Mfr|mho|gfr|Gfr|sfr|cir|Chi|chi|nap|Cfr|vcy|Vcy|cfr|Scy|scy|ncy|Ncy|vee|Vee|Cap|cap|nfr|scE|sce|Nfr|nge|ngE|nGg|vfr|Vfr|ngt|bot|nGt|nis|niv|Rsh|rsh|nle|nlE|bne|Bfr|bfr|nLl|nlt|nLt|Bcy|bcy|not|Not|rlm|wfr|Wfr|npr|nsc|num|ocy|ast|Ocy|ofr|xfr|Xfr|Ofr|ogt|ohm|apE|olt|Rho|ape|rho|Rfr|rfr|ord|REG|ang|reg|orv|And|and|AMP|Rcy|amp|Afr|ycy|Ycy|yen|yfr|Yfr|rcy|par|pcy|Pcy|pfr|Pfr|phi|Phi|afr|Acy|acy|zcy|Zcy|piv|acE|acd|zfr|Zfr|pre|prE|psi|Psi|qfr|Qfr|zwj|Or|ge|Gg|gt|gg|el|oS|lt|Lt|LT|Re|lg|gl|eg|ne|Im|it|le|DD|wp|wr|nu|Nu|dd|lE|Sc|sc|pi|Pi|ee|af|ll|Ll|rx|gE|xi|pm|Xi|ic|pr|Pr|in|ni|mp|mu|ac|Mu|or|ap|Gt|GT|ii);|&(Aacute|Agrave|Atilde|Ccedil|Eacute|Egrave|Iacute|Igrave|Ntilde|Oacute|Ograve|Oslash|Otilde|Uacute|Ugrave|Yacute|aacute|agrave|atilde|brvbar|ccedil|curren|divide|eacute|egrave|frac12|frac14|frac34|iacute|igrave|iquest|middot|ntilde|oacute|ograve|oslash|otilde|plusmn|uacute|ugrave|yacute|AElig|Acirc|Aring|Ecirc|Icirc|Ocirc|THORN|Ucirc|acirc|acute|aelig|aring|cedil|ecirc|icirc|iexcl|laquo|micro|ocirc|pound|raquo|szlig|thorn|times|ucirc|Auml|COPY|Euml|Iuml|Ouml|QUOT|Uuml|auml|cent|copy|euml|iuml|macr|nbsp|ordf|ordm|ouml|para|quot|sect|sup1|sup2|sup3|uuml|yuml|AMP|ETH|REG|amp|deg|eth|not|reg|shy|uml|yen|GT|LT|gt|lt)(?!;)([=a-zA-Z0-9]?)|&#([0-9]+)(;?)|&#[xX]([a-fA-F0-9]+)(;?)|&([0-9a-zA-Z]+)/g; + var decodeMap = {'aacute':'\xE1','Aacute':'\xC1','abreve':'\u0103','Abreve':'\u0102','ac':'\u223E','acd':'\u223F','acE':'\u223E\u0333','acirc':'\xE2','Acirc':'\xC2','acute':'\xB4','acy':'\u0430','Acy':'\u0410','aelig':'\xE6','AElig':'\xC6','af':'\u2061','afr':'\uD835\uDD1E','Afr':'\uD835\uDD04','agrave':'\xE0','Agrave':'\xC0','alefsym':'\u2135','aleph':'\u2135','alpha':'\u03B1','Alpha':'\u0391','amacr':'\u0101','Amacr':'\u0100','amalg':'\u2A3F','amp':'&','AMP':'&','and':'\u2227','And':'\u2A53','andand':'\u2A55','andd':'\u2A5C','andslope':'\u2A58','andv':'\u2A5A','ang':'\u2220','ange':'\u29A4','angle':'\u2220','angmsd':'\u2221','angmsdaa':'\u29A8','angmsdab':'\u29A9','angmsdac':'\u29AA','angmsdad':'\u29AB','angmsdae':'\u29AC','angmsdaf':'\u29AD','angmsdag':'\u29AE','angmsdah':'\u29AF','angrt':'\u221F','angrtvb':'\u22BE','angrtvbd':'\u299D','angsph':'\u2222','angst':'\xC5','angzarr':'\u237C','aogon':'\u0105','Aogon':'\u0104','aopf':'\uD835\uDD52','Aopf':'\uD835\uDD38','ap':'\u2248','apacir':'\u2A6F','ape':'\u224A','apE':'\u2A70','apid':'\u224B','apos':'\'','ApplyFunction':'\u2061','approx':'\u2248','approxeq':'\u224A','aring':'\xE5','Aring':'\xC5','ascr':'\uD835\uDCB6','Ascr':'\uD835\uDC9C','Assign':'\u2254','ast':'*','asymp':'\u2248','asympeq':'\u224D','atilde':'\xE3','Atilde':'\xC3','auml':'\xE4','Auml':'\xC4','awconint':'\u2233','awint':'\u2A11','backcong':'\u224C','backepsilon':'\u03F6','backprime':'\u2035','backsim':'\u223D','backsimeq':'\u22CD','Backslash':'\u2216','Barv':'\u2AE7','barvee':'\u22BD','barwed':'\u2305','Barwed':'\u2306','barwedge':'\u2305','bbrk':'\u23B5','bbrktbrk':'\u23B6','bcong':'\u224C','bcy':'\u0431','Bcy':'\u0411','bdquo':'\u201E','becaus':'\u2235','because':'\u2235','Because':'\u2235','bemptyv':'\u29B0','bepsi':'\u03F6','bernou':'\u212C','Bernoullis':'\u212C','beta':'\u03B2','Beta':'\u0392','beth':'\u2136','between':'\u226C','bfr':'\uD835\uDD1F','Bfr':'\uD835\uDD05','bigcap':'\u22C2','bigcirc':'\u25EF','bigcup':'\u22C3','bigodot':'\u2A00','bigoplus':'\u2A01','bigotimes':'\u2A02','bigsqcup':'\u2A06','bigstar':'\u2605','bigtriangledown':'\u25BD','bigtriangleup':'\u25B3','biguplus':'\u2A04','bigvee':'\u22C1','bigwedge':'\u22C0','bkarow':'\u290D','blacklozenge':'\u29EB','blacksquare':'\u25AA','blacktriangle':'\u25B4','blacktriangledown':'\u25BE','blacktriangleleft':'\u25C2','blacktriangleright':'\u25B8','blank':'\u2423','blk12':'\u2592','blk14':'\u2591','blk34':'\u2593','block':'\u2588','bne':'=\u20E5','bnequiv':'\u2261\u20E5','bnot':'\u2310','bNot':'\u2AED','bopf':'\uD835\uDD53','Bopf':'\uD835\uDD39','bot':'\u22A5','bottom':'\u22A5','bowtie':'\u22C8','boxbox':'\u29C9','boxdl':'\u2510','boxdL':'\u2555','boxDl':'\u2556','boxDL':'\u2557','boxdr':'\u250C','boxdR':'\u2552','boxDr':'\u2553','boxDR':'\u2554','boxh':'\u2500','boxH':'\u2550','boxhd':'\u252C','boxhD':'\u2565','boxHd':'\u2564','boxHD':'\u2566','boxhu':'\u2534','boxhU':'\u2568','boxHu':'\u2567','boxHU':'\u2569','boxminus':'\u229F','boxplus':'\u229E','boxtimes':'\u22A0','boxul':'\u2518','boxuL':'\u255B','boxUl':'\u255C','boxUL':'\u255D','boxur':'\u2514','boxuR':'\u2558','boxUr':'\u2559','boxUR':'\u255A','boxv':'\u2502','boxV':'\u2551','boxvh':'\u253C','boxvH':'\u256A','boxVh':'\u256B','boxVH':'\u256C','boxvl':'\u2524','boxvL':'\u2561','boxVl':'\u2562','boxVL':'\u2563','boxvr':'\u251C','boxvR':'\u255E','boxVr':'\u255F','boxVR':'\u2560','bprime':'\u2035','breve':'\u02D8','Breve':'\u02D8','brvbar':'\xA6','bscr':'\uD835\uDCB7','Bscr':'\u212C','bsemi':'\u204F','bsim':'\u223D','bsime':'\u22CD','bsol':'\\','bsolb':'\u29C5','bsolhsub':'\u27C8','bull':'\u2022','bullet':'\u2022','bump':'\u224E','bumpe':'\u224F','bumpE':'\u2AAE','bumpeq':'\u224F','Bumpeq':'\u224E','cacute':'\u0107','Cacute':'\u0106','cap':'\u2229','Cap':'\u22D2','capand':'\u2A44','capbrcup':'\u2A49','capcap':'\u2A4B','capcup':'\u2A47','capdot':'\u2A40','CapitalDifferentialD':'\u2145','caps':'\u2229\uFE00','caret':'\u2041','caron':'\u02C7','Cayleys':'\u212D','ccaps':'\u2A4D','ccaron':'\u010D','Ccaron':'\u010C','ccedil':'\xE7','Ccedil':'\xC7','ccirc':'\u0109','Ccirc':'\u0108','Cconint':'\u2230','ccups':'\u2A4C','ccupssm':'\u2A50','cdot':'\u010B','Cdot':'\u010A','cedil':'\xB8','Cedilla':'\xB8','cemptyv':'\u29B2','cent':'\xA2','centerdot':'\xB7','CenterDot':'\xB7','cfr':'\uD835\uDD20','Cfr':'\u212D','chcy':'\u0447','CHcy':'\u0427','check':'\u2713','checkmark':'\u2713','chi':'\u03C7','Chi':'\u03A7','cir':'\u25CB','circ':'\u02C6','circeq':'\u2257','circlearrowleft':'\u21BA','circlearrowright':'\u21BB','circledast':'\u229B','circledcirc':'\u229A','circleddash':'\u229D','CircleDot':'\u2299','circledR':'\xAE','circledS':'\u24C8','CircleMinus':'\u2296','CirclePlus':'\u2295','CircleTimes':'\u2297','cire':'\u2257','cirE':'\u29C3','cirfnint':'\u2A10','cirmid':'\u2AEF','cirscir':'\u29C2','ClockwiseContourIntegral':'\u2232','CloseCurlyDoubleQuote':'\u201D','CloseCurlyQuote':'\u2019','clubs':'\u2663','clubsuit':'\u2663','colon':':','Colon':'\u2237','colone':'\u2254','Colone':'\u2A74','coloneq':'\u2254','comma':',','commat':'@','comp':'\u2201','compfn':'\u2218','complement':'\u2201','complexes':'\u2102','cong':'\u2245','congdot':'\u2A6D','Congruent':'\u2261','conint':'\u222E','Conint':'\u222F','ContourIntegral':'\u222E','copf':'\uD835\uDD54','Copf':'\u2102','coprod':'\u2210','Coproduct':'\u2210','copy':'\xA9','COPY':'\xA9','copysr':'\u2117','CounterClockwiseContourIntegral':'\u2233','crarr':'\u21B5','cross':'\u2717','Cross':'\u2A2F','cscr':'\uD835\uDCB8','Cscr':'\uD835\uDC9E','csub':'\u2ACF','csube':'\u2AD1','csup':'\u2AD0','csupe':'\u2AD2','ctdot':'\u22EF','cudarrl':'\u2938','cudarrr':'\u2935','cuepr':'\u22DE','cuesc':'\u22DF','cularr':'\u21B6','cularrp':'\u293D','cup':'\u222A','Cup':'\u22D3','cupbrcap':'\u2A48','cupcap':'\u2A46','CupCap':'\u224D','cupcup':'\u2A4A','cupdot':'\u228D','cupor':'\u2A45','cups':'\u222A\uFE00','curarr':'\u21B7','curarrm':'\u293C','curlyeqprec':'\u22DE','curlyeqsucc':'\u22DF','curlyvee':'\u22CE','curlywedge':'\u22CF','curren':'\xA4','curvearrowleft':'\u21B6','curvearrowright':'\u21B7','cuvee':'\u22CE','cuwed':'\u22CF','cwconint':'\u2232','cwint':'\u2231','cylcty':'\u232D','dagger':'\u2020','Dagger':'\u2021','daleth':'\u2138','darr':'\u2193','dArr':'\u21D3','Darr':'\u21A1','dash':'\u2010','dashv':'\u22A3','Dashv':'\u2AE4','dbkarow':'\u290F','dblac':'\u02DD','dcaron':'\u010F','Dcaron':'\u010E','dcy':'\u0434','Dcy':'\u0414','dd':'\u2146','DD':'\u2145','ddagger':'\u2021','ddarr':'\u21CA','DDotrahd':'\u2911','ddotseq':'\u2A77','deg':'\xB0','Del':'\u2207','delta':'\u03B4','Delta':'\u0394','demptyv':'\u29B1','dfisht':'\u297F','dfr':'\uD835\uDD21','Dfr':'\uD835\uDD07','dHar':'\u2965','dharl':'\u21C3','dharr':'\u21C2','DiacriticalAcute':'\xB4','DiacriticalDot':'\u02D9','DiacriticalDoubleAcute':'\u02DD','DiacriticalGrave':'`','DiacriticalTilde':'\u02DC','diam':'\u22C4','diamond':'\u22C4','Diamond':'\u22C4','diamondsuit':'\u2666','diams':'\u2666','die':'\xA8','DifferentialD':'\u2146','digamma':'\u03DD','disin':'\u22F2','div':'\xF7','divide':'\xF7','divideontimes':'\u22C7','divonx':'\u22C7','djcy':'\u0452','DJcy':'\u0402','dlcorn':'\u231E','dlcrop':'\u230D','dollar':'$','dopf':'\uD835\uDD55','Dopf':'\uD835\uDD3B','dot':'\u02D9','Dot':'\xA8','DotDot':'\u20DC','doteq':'\u2250','doteqdot':'\u2251','DotEqual':'\u2250','dotminus':'\u2238','dotplus':'\u2214','dotsquare':'\u22A1','doublebarwedge':'\u2306','DoubleContourIntegral':'\u222F','DoubleDot':'\xA8','DoubleDownArrow':'\u21D3','DoubleLeftArrow':'\u21D0','DoubleLeftRightArrow':'\u21D4','DoubleLeftTee':'\u2AE4','DoubleLongLeftArrow':'\u27F8','DoubleLongLeftRightArrow':'\u27FA','DoubleLongRightArrow':'\u27F9','DoubleRightArrow':'\u21D2','DoubleRightTee':'\u22A8','DoubleUpArrow':'\u21D1','DoubleUpDownArrow':'\u21D5','DoubleVerticalBar':'\u2225','downarrow':'\u2193','Downarrow':'\u21D3','DownArrow':'\u2193','DownArrowBar':'\u2913','DownArrowUpArrow':'\u21F5','DownBreve':'\u0311','downdownarrows':'\u21CA','downharpoonleft':'\u21C3','downharpoonright':'\u21C2','DownLeftRightVector':'\u2950','DownLeftTeeVector':'\u295E','DownLeftVector':'\u21BD','DownLeftVectorBar':'\u2956','DownRightTeeVector':'\u295F','DownRightVector':'\u21C1','DownRightVectorBar':'\u2957','DownTee':'\u22A4','DownTeeArrow':'\u21A7','drbkarow':'\u2910','drcorn':'\u231F','drcrop':'\u230C','dscr':'\uD835\uDCB9','Dscr':'\uD835\uDC9F','dscy':'\u0455','DScy':'\u0405','dsol':'\u29F6','dstrok':'\u0111','Dstrok':'\u0110','dtdot':'\u22F1','dtri':'\u25BF','dtrif':'\u25BE','duarr':'\u21F5','duhar':'\u296F','dwangle':'\u29A6','dzcy':'\u045F','DZcy':'\u040F','dzigrarr':'\u27FF','eacute':'\xE9','Eacute':'\xC9','easter':'\u2A6E','ecaron':'\u011B','Ecaron':'\u011A','ecir':'\u2256','ecirc':'\xEA','Ecirc':'\xCA','ecolon':'\u2255','ecy':'\u044D','Ecy':'\u042D','eDDot':'\u2A77','edot':'\u0117','eDot':'\u2251','Edot':'\u0116','ee':'\u2147','efDot':'\u2252','efr':'\uD835\uDD22','Efr':'\uD835\uDD08','eg':'\u2A9A','egrave':'\xE8','Egrave':'\xC8','egs':'\u2A96','egsdot':'\u2A98','el':'\u2A99','Element':'\u2208','elinters':'\u23E7','ell':'\u2113','els':'\u2A95','elsdot':'\u2A97','emacr':'\u0113','Emacr':'\u0112','empty':'\u2205','emptyset':'\u2205','EmptySmallSquare':'\u25FB','emptyv':'\u2205','EmptyVerySmallSquare':'\u25AB','emsp':'\u2003','emsp13':'\u2004','emsp14':'\u2005','eng':'\u014B','ENG':'\u014A','ensp':'\u2002','eogon':'\u0119','Eogon':'\u0118','eopf':'\uD835\uDD56','Eopf':'\uD835\uDD3C','epar':'\u22D5','eparsl':'\u29E3','eplus':'\u2A71','epsi':'\u03B5','epsilon':'\u03B5','Epsilon':'\u0395','epsiv':'\u03F5','eqcirc':'\u2256','eqcolon':'\u2255','eqsim':'\u2242','eqslantgtr':'\u2A96','eqslantless':'\u2A95','Equal':'\u2A75','equals':'=','EqualTilde':'\u2242','equest':'\u225F','Equilibrium':'\u21CC','equiv':'\u2261','equivDD':'\u2A78','eqvparsl':'\u29E5','erarr':'\u2971','erDot':'\u2253','escr':'\u212F','Escr':'\u2130','esdot':'\u2250','esim':'\u2242','Esim':'\u2A73','eta':'\u03B7','Eta':'\u0397','eth':'\xF0','ETH':'\xD0','euml':'\xEB','Euml':'\xCB','euro':'\u20AC','excl':'!','exist':'\u2203','Exists':'\u2203','expectation':'\u2130','exponentiale':'\u2147','ExponentialE':'\u2147','fallingdotseq':'\u2252','fcy':'\u0444','Fcy':'\u0424','female':'\u2640','ffilig':'\uFB03','fflig':'\uFB00','ffllig':'\uFB04','ffr':'\uD835\uDD23','Ffr':'\uD835\uDD09','filig':'\uFB01','FilledSmallSquare':'\u25FC','FilledVerySmallSquare':'\u25AA','fjlig':'fj','flat':'\u266D','fllig':'\uFB02','fltns':'\u25B1','fnof':'\u0192','fopf':'\uD835\uDD57','Fopf':'\uD835\uDD3D','forall':'\u2200','ForAll':'\u2200','fork':'\u22D4','forkv':'\u2AD9','Fouriertrf':'\u2131','fpartint':'\u2A0D','frac12':'\xBD','frac13':'\u2153','frac14':'\xBC','frac15':'\u2155','frac16':'\u2159','frac18':'\u215B','frac23':'\u2154','frac25':'\u2156','frac34':'\xBE','frac35':'\u2157','frac38':'\u215C','frac45':'\u2158','frac56':'\u215A','frac58':'\u215D','frac78':'\u215E','frasl':'\u2044','frown':'\u2322','fscr':'\uD835\uDCBB','Fscr':'\u2131','gacute':'\u01F5','gamma':'\u03B3','Gamma':'\u0393','gammad':'\u03DD','Gammad':'\u03DC','gap':'\u2A86','gbreve':'\u011F','Gbreve':'\u011E','Gcedil':'\u0122','gcirc':'\u011D','Gcirc':'\u011C','gcy':'\u0433','Gcy':'\u0413','gdot':'\u0121','Gdot':'\u0120','ge':'\u2265','gE':'\u2267','gel':'\u22DB','gEl':'\u2A8C','geq':'\u2265','geqq':'\u2267','geqslant':'\u2A7E','ges':'\u2A7E','gescc':'\u2AA9','gesdot':'\u2A80','gesdoto':'\u2A82','gesdotol':'\u2A84','gesl':'\u22DB\uFE00','gesles':'\u2A94','gfr':'\uD835\uDD24','Gfr':'\uD835\uDD0A','gg':'\u226B','Gg':'\u22D9','ggg':'\u22D9','gimel':'\u2137','gjcy':'\u0453','GJcy':'\u0403','gl':'\u2277','gla':'\u2AA5','glE':'\u2A92','glj':'\u2AA4','gnap':'\u2A8A','gnapprox':'\u2A8A','gne':'\u2A88','gnE':'\u2269','gneq':'\u2A88','gneqq':'\u2269','gnsim':'\u22E7','gopf':'\uD835\uDD58','Gopf':'\uD835\uDD3E','grave':'`','GreaterEqual':'\u2265','GreaterEqualLess':'\u22DB','GreaterFullEqual':'\u2267','GreaterGreater':'\u2AA2','GreaterLess':'\u2277','GreaterSlantEqual':'\u2A7E','GreaterTilde':'\u2273','gscr':'\u210A','Gscr':'\uD835\uDCA2','gsim':'\u2273','gsime':'\u2A8E','gsiml':'\u2A90','gt':'>','Gt':'\u226B','GT':'>','gtcc':'\u2AA7','gtcir':'\u2A7A','gtdot':'\u22D7','gtlPar':'\u2995','gtquest':'\u2A7C','gtrapprox':'\u2A86','gtrarr':'\u2978','gtrdot':'\u22D7','gtreqless':'\u22DB','gtreqqless':'\u2A8C','gtrless':'\u2277','gtrsim':'\u2273','gvertneqq':'\u2269\uFE00','gvnE':'\u2269\uFE00','Hacek':'\u02C7','hairsp':'\u200A','half':'\xBD','hamilt':'\u210B','hardcy':'\u044A','HARDcy':'\u042A','harr':'\u2194','hArr':'\u21D4','harrcir':'\u2948','harrw':'\u21AD','Hat':'^','hbar':'\u210F','hcirc':'\u0125','Hcirc':'\u0124','hearts':'\u2665','heartsuit':'\u2665','hellip':'\u2026','hercon':'\u22B9','hfr':'\uD835\uDD25','Hfr':'\u210C','HilbertSpace':'\u210B','hksearow':'\u2925','hkswarow':'\u2926','hoarr':'\u21FF','homtht':'\u223B','hookleftarrow':'\u21A9','hookrightarrow':'\u21AA','hopf':'\uD835\uDD59','Hopf':'\u210D','horbar':'\u2015','HorizontalLine':'\u2500','hscr':'\uD835\uDCBD','Hscr':'\u210B','hslash':'\u210F','hstrok':'\u0127','Hstrok':'\u0126','HumpDownHump':'\u224E','HumpEqual':'\u224F','hybull':'\u2043','hyphen':'\u2010','iacute':'\xED','Iacute':'\xCD','ic':'\u2063','icirc':'\xEE','Icirc':'\xCE','icy':'\u0438','Icy':'\u0418','Idot':'\u0130','iecy':'\u0435','IEcy':'\u0415','iexcl':'\xA1','iff':'\u21D4','ifr':'\uD835\uDD26','Ifr':'\u2111','igrave':'\xEC','Igrave':'\xCC','ii':'\u2148','iiiint':'\u2A0C','iiint':'\u222D','iinfin':'\u29DC','iiota':'\u2129','ijlig':'\u0133','IJlig':'\u0132','Im':'\u2111','imacr':'\u012B','Imacr':'\u012A','image':'\u2111','ImaginaryI':'\u2148','imagline':'\u2110','imagpart':'\u2111','imath':'\u0131','imof':'\u22B7','imped':'\u01B5','Implies':'\u21D2','in':'\u2208','incare':'\u2105','infin':'\u221E','infintie':'\u29DD','inodot':'\u0131','int':'\u222B','Int':'\u222C','intcal':'\u22BA','integers':'\u2124','Integral':'\u222B','intercal':'\u22BA','Intersection':'\u22C2','intlarhk':'\u2A17','intprod':'\u2A3C','InvisibleComma':'\u2063','InvisibleTimes':'\u2062','iocy':'\u0451','IOcy':'\u0401','iogon':'\u012F','Iogon':'\u012E','iopf':'\uD835\uDD5A','Iopf':'\uD835\uDD40','iota':'\u03B9','Iota':'\u0399','iprod':'\u2A3C','iquest':'\xBF','iscr':'\uD835\uDCBE','Iscr':'\u2110','isin':'\u2208','isindot':'\u22F5','isinE':'\u22F9','isins':'\u22F4','isinsv':'\u22F3','isinv':'\u2208','it':'\u2062','itilde':'\u0129','Itilde':'\u0128','iukcy':'\u0456','Iukcy':'\u0406','iuml':'\xEF','Iuml':'\xCF','jcirc':'\u0135','Jcirc':'\u0134','jcy':'\u0439','Jcy':'\u0419','jfr':'\uD835\uDD27','Jfr':'\uD835\uDD0D','jmath':'\u0237','jopf':'\uD835\uDD5B','Jopf':'\uD835\uDD41','jscr':'\uD835\uDCBF','Jscr':'\uD835\uDCA5','jsercy':'\u0458','Jsercy':'\u0408','jukcy':'\u0454','Jukcy':'\u0404','kappa':'\u03BA','Kappa':'\u039A','kappav':'\u03F0','kcedil':'\u0137','Kcedil':'\u0136','kcy':'\u043A','Kcy':'\u041A','kfr':'\uD835\uDD28','Kfr':'\uD835\uDD0E','kgreen':'\u0138','khcy':'\u0445','KHcy':'\u0425','kjcy':'\u045C','KJcy':'\u040C','kopf':'\uD835\uDD5C','Kopf':'\uD835\uDD42','kscr':'\uD835\uDCC0','Kscr':'\uD835\uDCA6','lAarr':'\u21DA','lacute':'\u013A','Lacute':'\u0139','laemptyv':'\u29B4','lagran':'\u2112','lambda':'\u03BB','Lambda':'\u039B','lang':'\u27E8','Lang':'\u27EA','langd':'\u2991','langle':'\u27E8','lap':'\u2A85','Laplacetrf':'\u2112','laquo':'\xAB','larr':'\u2190','lArr':'\u21D0','Larr':'\u219E','larrb':'\u21E4','larrbfs':'\u291F','larrfs':'\u291D','larrhk':'\u21A9','larrlp':'\u21AB','larrpl':'\u2939','larrsim':'\u2973','larrtl':'\u21A2','lat':'\u2AAB','latail':'\u2919','lAtail':'\u291B','late':'\u2AAD','lates':'\u2AAD\uFE00','lbarr':'\u290C','lBarr':'\u290E','lbbrk':'\u2772','lbrace':'{','lbrack':'[','lbrke':'\u298B','lbrksld':'\u298F','lbrkslu':'\u298D','lcaron':'\u013E','Lcaron':'\u013D','lcedil':'\u013C','Lcedil':'\u013B','lceil':'\u2308','lcub':'{','lcy':'\u043B','Lcy':'\u041B','ldca':'\u2936','ldquo':'\u201C','ldquor':'\u201E','ldrdhar':'\u2967','ldrushar':'\u294B','ldsh':'\u21B2','le':'\u2264','lE':'\u2266','LeftAngleBracket':'\u27E8','leftarrow':'\u2190','Leftarrow':'\u21D0','LeftArrow':'\u2190','LeftArrowBar':'\u21E4','LeftArrowRightArrow':'\u21C6','leftarrowtail':'\u21A2','LeftCeiling':'\u2308','LeftDoubleBracket':'\u27E6','LeftDownTeeVector':'\u2961','LeftDownVector':'\u21C3','LeftDownVectorBar':'\u2959','LeftFloor':'\u230A','leftharpoondown':'\u21BD','leftharpoonup':'\u21BC','leftleftarrows':'\u21C7','leftrightarrow':'\u2194','Leftrightarrow':'\u21D4','LeftRightArrow':'\u2194','leftrightarrows':'\u21C6','leftrightharpoons':'\u21CB','leftrightsquigarrow':'\u21AD','LeftRightVector':'\u294E','LeftTee':'\u22A3','LeftTeeArrow':'\u21A4','LeftTeeVector':'\u295A','leftthreetimes':'\u22CB','LeftTriangle':'\u22B2','LeftTriangleBar':'\u29CF','LeftTriangleEqual':'\u22B4','LeftUpDownVector':'\u2951','LeftUpTeeVector':'\u2960','LeftUpVector':'\u21BF','LeftUpVectorBar':'\u2958','LeftVector':'\u21BC','LeftVectorBar':'\u2952','leg':'\u22DA','lEg':'\u2A8B','leq':'\u2264','leqq':'\u2266','leqslant':'\u2A7D','les':'\u2A7D','lescc':'\u2AA8','lesdot':'\u2A7F','lesdoto':'\u2A81','lesdotor':'\u2A83','lesg':'\u22DA\uFE00','lesges':'\u2A93','lessapprox':'\u2A85','lessdot':'\u22D6','lesseqgtr':'\u22DA','lesseqqgtr':'\u2A8B','LessEqualGreater':'\u22DA','LessFullEqual':'\u2266','LessGreater':'\u2276','lessgtr':'\u2276','LessLess':'\u2AA1','lesssim':'\u2272','LessSlantEqual':'\u2A7D','LessTilde':'\u2272','lfisht':'\u297C','lfloor':'\u230A','lfr':'\uD835\uDD29','Lfr':'\uD835\uDD0F','lg':'\u2276','lgE':'\u2A91','lHar':'\u2962','lhard':'\u21BD','lharu':'\u21BC','lharul':'\u296A','lhblk':'\u2584','ljcy':'\u0459','LJcy':'\u0409','ll':'\u226A','Ll':'\u22D8','llarr':'\u21C7','llcorner':'\u231E','Lleftarrow':'\u21DA','llhard':'\u296B','lltri':'\u25FA','lmidot':'\u0140','Lmidot':'\u013F','lmoust':'\u23B0','lmoustache':'\u23B0','lnap':'\u2A89','lnapprox':'\u2A89','lne':'\u2A87','lnE':'\u2268','lneq':'\u2A87','lneqq':'\u2268','lnsim':'\u22E6','loang':'\u27EC','loarr':'\u21FD','lobrk':'\u27E6','longleftarrow':'\u27F5','Longleftarrow':'\u27F8','LongLeftArrow':'\u27F5','longleftrightarrow':'\u27F7','Longleftrightarrow':'\u27FA','LongLeftRightArrow':'\u27F7','longmapsto':'\u27FC','longrightarrow':'\u27F6','Longrightarrow':'\u27F9','LongRightArrow':'\u27F6','looparrowleft':'\u21AB','looparrowright':'\u21AC','lopar':'\u2985','lopf':'\uD835\uDD5D','Lopf':'\uD835\uDD43','loplus':'\u2A2D','lotimes':'\u2A34','lowast':'\u2217','lowbar':'_','LowerLeftArrow':'\u2199','LowerRightArrow':'\u2198','loz':'\u25CA','lozenge':'\u25CA','lozf':'\u29EB','lpar':'(','lparlt':'\u2993','lrarr':'\u21C6','lrcorner':'\u231F','lrhar':'\u21CB','lrhard':'\u296D','lrm':'\u200E','lrtri':'\u22BF','lsaquo':'\u2039','lscr':'\uD835\uDCC1','Lscr':'\u2112','lsh':'\u21B0','Lsh':'\u21B0','lsim':'\u2272','lsime':'\u2A8D','lsimg':'\u2A8F','lsqb':'[','lsquo':'\u2018','lsquor':'\u201A','lstrok':'\u0142','Lstrok':'\u0141','lt':'<','Lt':'\u226A','LT':'<','ltcc':'\u2AA6','ltcir':'\u2A79','ltdot':'\u22D6','lthree':'\u22CB','ltimes':'\u22C9','ltlarr':'\u2976','ltquest':'\u2A7B','ltri':'\u25C3','ltrie':'\u22B4','ltrif':'\u25C2','ltrPar':'\u2996','lurdshar':'\u294A','luruhar':'\u2966','lvertneqq':'\u2268\uFE00','lvnE':'\u2268\uFE00','macr':'\xAF','male':'\u2642','malt':'\u2720','maltese':'\u2720','map':'\u21A6','Map':'\u2905','mapsto':'\u21A6','mapstodown':'\u21A7','mapstoleft':'\u21A4','mapstoup':'\u21A5','marker':'\u25AE','mcomma':'\u2A29','mcy':'\u043C','Mcy':'\u041C','mdash':'\u2014','mDDot':'\u223A','measuredangle':'\u2221','MediumSpace':'\u205F','Mellintrf':'\u2133','mfr':'\uD835\uDD2A','Mfr':'\uD835\uDD10','mho':'\u2127','micro':'\xB5','mid':'\u2223','midast':'*','midcir':'\u2AF0','middot':'\xB7','minus':'\u2212','minusb':'\u229F','minusd':'\u2238','minusdu':'\u2A2A','MinusPlus':'\u2213','mlcp':'\u2ADB','mldr':'\u2026','mnplus':'\u2213','models':'\u22A7','mopf':'\uD835\uDD5E','Mopf':'\uD835\uDD44','mp':'\u2213','mscr':'\uD835\uDCC2','Mscr':'\u2133','mstpos':'\u223E','mu':'\u03BC','Mu':'\u039C','multimap':'\u22B8','mumap':'\u22B8','nabla':'\u2207','nacute':'\u0144','Nacute':'\u0143','nang':'\u2220\u20D2','nap':'\u2249','napE':'\u2A70\u0338','napid':'\u224B\u0338','napos':'\u0149','napprox':'\u2249','natur':'\u266E','natural':'\u266E','naturals':'\u2115','nbsp':'\xA0','nbump':'\u224E\u0338','nbumpe':'\u224F\u0338','ncap':'\u2A43','ncaron':'\u0148','Ncaron':'\u0147','ncedil':'\u0146','Ncedil':'\u0145','ncong':'\u2247','ncongdot':'\u2A6D\u0338','ncup':'\u2A42','ncy':'\u043D','Ncy':'\u041D','ndash':'\u2013','ne':'\u2260','nearhk':'\u2924','nearr':'\u2197','neArr':'\u21D7','nearrow':'\u2197','nedot':'\u2250\u0338','NegativeMediumSpace':'\u200B','NegativeThickSpace':'\u200B','NegativeThinSpace':'\u200B','NegativeVeryThinSpace':'\u200B','nequiv':'\u2262','nesear':'\u2928','nesim':'\u2242\u0338','NestedGreaterGreater':'\u226B','NestedLessLess':'\u226A','NewLine':'\n','nexist':'\u2204','nexists':'\u2204','nfr':'\uD835\uDD2B','Nfr':'\uD835\uDD11','nge':'\u2271','ngE':'\u2267\u0338','ngeq':'\u2271','ngeqq':'\u2267\u0338','ngeqslant':'\u2A7E\u0338','nges':'\u2A7E\u0338','nGg':'\u22D9\u0338','ngsim':'\u2275','ngt':'\u226F','nGt':'\u226B\u20D2','ngtr':'\u226F','nGtv':'\u226B\u0338','nharr':'\u21AE','nhArr':'\u21CE','nhpar':'\u2AF2','ni':'\u220B','nis':'\u22FC','nisd':'\u22FA','niv':'\u220B','njcy':'\u045A','NJcy':'\u040A','nlarr':'\u219A','nlArr':'\u21CD','nldr':'\u2025','nle':'\u2270','nlE':'\u2266\u0338','nleftarrow':'\u219A','nLeftarrow':'\u21CD','nleftrightarrow':'\u21AE','nLeftrightarrow':'\u21CE','nleq':'\u2270','nleqq':'\u2266\u0338','nleqslant':'\u2A7D\u0338','nles':'\u2A7D\u0338','nless':'\u226E','nLl':'\u22D8\u0338','nlsim':'\u2274','nlt':'\u226E','nLt':'\u226A\u20D2','nltri':'\u22EA','nltrie':'\u22EC','nLtv':'\u226A\u0338','nmid':'\u2224','NoBreak':'\u2060','NonBreakingSpace':'\xA0','nopf':'\uD835\uDD5F','Nopf':'\u2115','not':'\xAC','Not':'\u2AEC','NotCongruent':'\u2262','NotCupCap':'\u226D','NotDoubleVerticalBar':'\u2226','NotElement':'\u2209','NotEqual':'\u2260','NotEqualTilde':'\u2242\u0338','NotExists':'\u2204','NotGreater':'\u226F','NotGreaterEqual':'\u2271','NotGreaterFullEqual':'\u2267\u0338','NotGreaterGreater':'\u226B\u0338','NotGreaterLess':'\u2279','NotGreaterSlantEqual':'\u2A7E\u0338','NotGreaterTilde':'\u2275','NotHumpDownHump':'\u224E\u0338','NotHumpEqual':'\u224F\u0338','notin':'\u2209','notindot':'\u22F5\u0338','notinE':'\u22F9\u0338','notinva':'\u2209','notinvb':'\u22F7','notinvc':'\u22F6','NotLeftTriangle':'\u22EA','NotLeftTriangleBar':'\u29CF\u0338','NotLeftTriangleEqual':'\u22EC','NotLess':'\u226E','NotLessEqual':'\u2270','NotLessGreater':'\u2278','NotLessLess':'\u226A\u0338','NotLessSlantEqual':'\u2A7D\u0338','NotLessTilde':'\u2274','NotNestedGreaterGreater':'\u2AA2\u0338','NotNestedLessLess':'\u2AA1\u0338','notni':'\u220C','notniva':'\u220C','notnivb':'\u22FE','notnivc':'\u22FD','NotPrecedes':'\u2280','NotPrecedesEqual':'\u2AAF\u0338','NotPrecedesSlantEqual':'\u22E0','NotReverseElement':'\u220C','NotRightTriangle':'\u22EB','NotRightTriangleBar':'\u29D0\u0338','NotRightTriangleEqual':'\u22ED','NotSquareSubset':'\u228F\u0338','NotSquareSubsetEqual':'\u22E2','NotSquareSuperset':'\u2290\u0338','NotSquareSupersetEqual':'\u22E3','NotSubset':'\u2282\u20D2','NotSubsetEqual':'\u2288','NotSucceeds':'\u2281','NotSucceedsEqual':'\u2AB0\u0338','NotSucceedsSlantEqual':'\u22E1','NotSucceedsTilde':'\u227F\u0338','NotSuperset':'\u2283\u20D2','NotSupersetEqual':'\u2289','NotTilde':'\u2241','NotTildeEqual':'\u2244','NotTildeFullEqual':'\u2247','NotTildeTilde':'\u2249','NotVerticalBar':'\u2224','npar':'\u2226','nparallel':'\u2226','nparsl':'\u2AFD\u20E5','npart':'\u2202\u0338','npolint':'\u2A14','npr':'\u2280','nprcue':'\u22E0','npre':'\u2AAF\u0338','nprec':'\u2280','npreceq':'\u2AAF\u0338','nrarr':'\u219B','nrArr':'\u21CF','nrarrc':'\u2933\u0338','nrarrw':'\u219D\u0338','nrightarrow':'\u219B','nRightarrow':'\u21CF','nrtri':'\u22EB','nrtrie':'\u22ED','nsc':'\u2281','nsccue':'\u22E1','nsce':'\u2AB0\u0338','nscr':'\uD835\uDCC3','Nscr':'\uD835\uDCA9','nshortmid':'\u2224','nshortparallel':'\u2226','nsim':'\u2241','nsime':'\u2244','nsimeq':'\u2244','nsmid':'\u2224','nspar':'\u2226','nsqsube':'\u22E2','nsqsupe':'\u22E3','nsub':'\u2284','nsube':'\u2288','nsubE':'\u2AC5\u0338','nsubset':'\u2282\u20D2','nsubseteq':'\u2288','nsubseteqq':'\u2AC5\u0338','nsucc':'\u2281','nsucceq':'\u2AB0\u0338','nsup':'\u2285','nsupe':'\u2289','nsupE':'\u2AC6\u0338','nsupset':'\u2283\u20D2','nsupseteq':'\u2289','nsupseteqq':'\u2AC6\u0338','ntgl':'\u2279','ntilde':'\xF1','Ntilde':'\xD1','ntlg':'\u2278','ntriangleleft':'\u22EA','ntrianglelefteq':'\u22EC','ntriangleright':'\u22EB','ntrianglerighteq':'\u22ED','nu':'\u03BD','Nu':'\u039D','num':'#','numero':'\u2116','numsp':'\u2007','nvap':'\u224D\u20D2','nvdash':'\u22AC','nvDash':'\u22AD','nVdash':'\u22AE','nVDash':'\u22AF','nvge':'\u2265\u20D2','nvgt':'>\u20D2','nvHarr':'\u2904','nvinfin':'\u29DE','nvlArr':'\u2902','nvle':'\u2264\u20D2','nvlt':'<\u20D2','nvltrie':'\u22B4\u20D2','nvrArr':'\u2903','nvrtrie':'\u22B5\u20D2','nvsim':'\u223C\u20D2','nwarhk':'\u2923','nwarr':'\u2196','nwArr':'\u21D6','nwarrow':'\u2196','nwnear':'\u2927','oacute':'\xF3','Oacute':'\xD3','oast':'\u229B','ocir':'\u229A','ocirc':'\xF4','Ocirc':'\xD4','ocy':'\u043E','Ocy':'\u041E','odash':'\u229D','odblac':'\u0151','Odblac':'\u0150','odiv':'\u2A38','odot':'\u2299','odsold':'\u29BC','oelig':'\u0153','OElig':'\u0152','ofcir':'\u29BF','ofr':'\uD835\uDD2C','Ofr':'\uD835\uDD12','ogon':'\u02DB','ograve':'\xF2','Ograve':'\xD2','ogt':'\u29C1','ohbar':'\u29B5','ohm':'\u03A9','oint':'\u222E','olarr':'\u21BA','olcir':'\u29BE','olcross':'\u29BB','oline':'\u203E','olt':'\u29C0','omacr':'\u014D','Omacr':'\u014C','omega':'\u03C9','Omega':'\u03A9','omicron':'\u03BF','Omicron':'\u039F','omid':'\u29B6','ominus':'\u2296','oopf':'\uD835\uDD60','Oopf':'\uD835\uDD46','opar':'\u29B7','OpenCurlyDoubleQuote':'\u201C','OpenCurlyQuote':'\u2018','operp':'\u29B9','oplus':'\u2295','or':'\u2228','Or':'\u2A54','orarr':'\u21BB','ord':'\u2A5D','order':'\u2134','orderof':'\u2134','ordf':'\xAA','ordm':'\xBA','origof':'\u22B6','oror':'\u2A56','orslope':'\u2A57','orv':'\u2A5B','oS':'\u24C8','oscr':'\u2134','Oscr':'\uD835\uDCAA','oslash':'\xF8','Oslash':'\xD8','osol':'\u2298','otilde':'\xF5','Otilde':'\xD5','otimes':'\u2297','Otimes':'\u2A37','otimesas':'\u2A36','ouml':'\xF6','Ouml':'\xD6','ovbar':'\u233D','OverBar':'\u203E','OverBrace':'\u23DE','OverBracket':'\u23B4','OverParenthesis':'\u23DC','par':'\u2225','para':'\xB6','parallel':'\u2225','parsim':'\u2AF3','parsl':'\u2AFD','part':'\u2202','PartialD':'\u2202','pcy':'\u043F','Pcy':'\u041F','percnt':'%','period':'.','permil':'\u2030','perp':'\u22A5','pertenk':'\u2031','pfr':'\uD835\uDD2D','Pfr':'\uD835\uDD13','phi':'\u03C6','Phi':'\u03A6','phiv':'\u03D5','phmmat':'\u2133','phone':'\u260E','pi':'\u03C0','Pi':'\u03A0','pitchfork':'\u22D4','piv':'\u03D6','planck':'\u210F','planckh':'\u210E','plankv':'\u210F','plus':'+','plusacir':'\u2A23','plusb':'\u229E','pluscir':'\u2A22','plusdo':'\u2214','plusdu':'\u2A25','pluse':'\u2A72','PlusMinus':'\xB1','plusmn':'\xB1','plussim':'\u2A26','plustwo':'\u2A27','pm':'\xB1','Poincareplane':'\u210C','pointint':'\u2A15','popf':'\uD835\uDD61','Popf':'\u2119','pound':'\xA3','pr':'\u227A','Pr':'\u2ABB','prap':'\u2AB7','prcue':'\u227C','pre':'\u2AAF','prE':'\u2AB3','prec':'\u227A','precapprox':'\u2AB7','preccurlyeq':'\u227C','Precedes':'\u227A','PrecedesEqual':'\u2AAF','PrecedesSlantEqual':'\u227C','PrecedesTilde':'\u227E','preceq':'\u2AAF','precnapprox':'\u2AB9','precneqq':'\u2AB5','precnsim':'\u22E8','precsim':'\u227E','prime':'\u2032','Prime':'\u2033','primes':'\u2119','prnap':'\u2AB9','prnE':'\u2AB5','prnsim':'\u22E8','prod':'\u220F','Product':'\u220F','profalar':'\u232E','profline':'\u2312','profsurf':'\u2313','prop':'\u221D','Proportion':'\u2237','Proportional':'\u221D','propto':'\u221D','prsim':'\u227E','prurel':'\u22B0','pscr':'\uD835\uDCC5','Pscr':'\uD835\uDCAB','psi':'\u03C8','Psi':'\u03A8','puncsp':'\u2008','qfr':'\uD835\uDD2E','Qfr':'\uD835\uDD14','qint':'\u2A0C','qopf':'\uD835\uDD62','Qopf':'\u211A','qprime':'\u2057','qscr':'\uD835\uDCC6','Qscr':'\uD835\uDCAC','quaternions':'\u210D','quatint':'\u2A16','quest':'?','questeq':'\u225F','quot':'"','QUOT':'"','rAarr':'\u21DB','race':'\u223D\u0331','racute':'\u0155','Racute':'\u0154','radic':'\u221A','raemptyv':'\u29B3','rang':'\u27E9','Rang':'\u27EB','rangd':'\u2992','range':'\u29A5','rangle':'\u27E9','raquo':'\xBB','rarr':'\u2192','rArr':'\u21D2','Rarr':'\u21A0','rarrap':'\u2975','rarrb':'\u21E5','rarrbfs':'\u2920','rarrc':'\u2933','rarrfs':'\u291E','rarrhk':'\u21AA','rarrlp':'\u21AC','rarrpl':'\u2945','rarrsim':'\u2974','rarrtl':'\u21A3','Rarrtl':'\u2916','rarrw':'\u219D','ratail':'\u291A','rAtail':'\u291C','ratio':'\u2236','rationals':'\u211A','rbarr':'\u290D','rBarr':'\u290F','RBarr':'\u2910','rbbrk':'\u2773','rbrace':'}','rbrack':']','rbrke':'\u298C','rbrksld':'\u298E','rbrkslu':'\u2990','rcaron':'\u0159','Rcaron':'\u0158','rcedil':'\u0157','Rcedil':'\u0156','rceil':'\u2309','rcub':'}','rcy':'\u0440','Rcy':'\u0420','rdca':'\u2937','rdldhar':'\u2969','rdquo':'\u201D','rdquor':'\u201D','rdsh':'\u21B3','Re':'\u211C','real':'\u211C','realine':'\u211B','realpart':'\u211C','reals':'\u211D','rect':'\u25AD','reg':'\xAE','REG':'\xAE','ReverseElement':'\u220B','ReverseEquilibrium':'\u21CB','ReverseUpEquilibrium':'\u296F','rfisht':'\u297D','rfloor':'\u230B','rfr':'\uD835\uDD2F','Rfr':'\u211C','rHar':'\u2964','rhard':'\u21C1','rharu':'\u21C0','rharul':'\u296C','rho':'\u03C1','Rho':'\u03A1','rhov':'\u03F1','RightAngleBracket':'\u27E9','rightarrow':'\u2192','Rightarrow':'\u21D2','RightArrow':'\u2192','RightArrowBar':'\u21E5','RightArrowLeftArrow':'\u21C4','rightarrowtail':'\u21A3','RightCeiling':'\u2309','RightDoubleBracket':'\u27E7','RightDownTeeVector':'\u295D','RightDownVector':'\u21C2','RightDownVectorBar':'\u2955','RightFloor':'\u230B','rightharpoondown':'\u21C1','rightharpoonup':'\u21C0','rightleftarrows':'\u21C4','rightleftharpoons':'\u21CC','rightrightarrows':'\u21C9','rightsquigarrow':'\u219D','RightTee':'\u22A2','RightTeeArrow':'\u21A6','RightTeeVector':'\u295B','rightthreetimes':'\u22CC','RightTriangle':'\u22B3','RightTriangleBar':'\u29D0','RightTriangleEqual':'\u22B5','RightUpDownVector':'\u294F','RightUpTeeVector':'\u295C','RightUpVector':'\u21BE','RightUpVectorBar':'\u2954','RightVector':'\u21C0','RightVectorBar':'\u2953','ring':'\u02DA','risingdotseq':'\u2253','rlarr':'\u21C4','rlhar':'\u21CC','rlm':'\u200F','rmoust':'\u23B1','rmoustache':'\u23B1','rnmid':'\u2AEE','roang':'\u27ED','roarr':'\u21FE','robrk':'\u27E7','ropar':'\u2986','ropf':'\uD835\uDD63','Ropf':'\u211D','roplus':'\u2A2E','rotimes':'\u2A35','RoundImplies':'\u2970','rpar':')','rpargt':'\u2994','rppolint':'\u2A12','rrarr':'\u21C9','Rrightarrow':'\u21DB','rsaquo':'\u203A','rscr':'\uD835\uDCC7','Rscr':'\u211B','rsh':'\u21B1','Rsh':'\u21B1','rsqb':']','rsquo':'\u2019','rsquor':'\u2019','rthree':'\u22CC','rtimes':'\u22CA','rtri':'\u25B9','rtrie':'\u22B5','rtrif':'\u25B8','rtriltri':'\u29CE','RuleDelayed':'\u29F4','ruluhar':'\u2968','rx':'\u211E','sacute':'\u015B','Sacute':'\u015A','sbquo':'\u201A','sc':'\u227B','Sc':'\u2ABC','scap':'\u2AB8','scaron':'\u0161','Scaron':'\u0160','sccue':'\u227D','sce':'\u2AB0','scE':'\u2AB4','scedil':'\u015F','Scedil':'\u015E','scirc':'\u015D','Scirc':'\u015C','scnap':'\u2ABA','scnE':'\u2AB6','scnsim':'\u22E9','scpolint':'\u2A13','scsim':'\u227F','scy':'\u0441','Scy':'\u0421','sdot':'\u22C5','sdotb':'\u22A1','sdote':'\u2A66','searhk':'\u2925','searr':'\u2198','seArr':'\u21D8','searrow':'\u2198','sect':'\xA7','semi':';','seswar':'\u2929','setminus':'\u2216','setmn':'\u2216','sext':'\u2736','sfr':'\uD835\uDD30','Sfr':'\uD835\uDD16','sfrown':'\u2322','sharp':'\u266F','shchcy':'\u0449','SHCHcy':'\u0429','shcy':'\u0448','SHcy':'\u0428','ShortDownArrow':'\u2193','ShortLeftArrow':'\u2190','shortmid':'\u2223','shortparallel':'\u2225','ShortRightArrow':'\u2192','ShortUpArrow':'\u2191','shy':'\xAD','sigma':'\u03C3','Sigma':'\u03A3','sigmaf':'\u03C2','sigmav':'\u03C2','sim':'\u223C','simdot':'\u2A6A','sime':'\u2243','simeq':'\u2243','simg':'\u2A9E','simgE':'\u2AA0','siml':'\u2A9D','simlE':'\u2A9F','simne':'\u2246','simplus':'\u2A24','simrarr':'\u2972','slarr':'\u2190','SmallCircle':'\u2218','smallsetminus':'\u2216','smashp':'\u2A33','smeparsl':'\u29E4','smid':'\u2223','smile':'\u2323','smt':'\u2AAA','smte':'\u2AAC','smtes':'\u2AAC\uFE00','softcy':'\u044C','SOFTcy':'\u042C','sol':'/','solb':'\u29C4','solbar':'\u233F','sopf':'\uD835\uDD64','Sopf':'\uD835\uDD4A','spades':'\u2660','spadesuit':'\u2660','spar':'\u2225','sqcap':'\u2293','sqcaps':'\u2293\uFE00','sqcup':'\u2294','sqcups':'\u2294\uFE00','Sqrt':'\u221A','sqsub':'\u228F','sqsube':'\u2291','sqsubset':'\u228F','sqsubseteq':'\u2291','sqsup':'\u2290','sqsupe':'\u2292','sqsupset':'\u2290','sqsupseteq':'\u2292','squ':'\u25A1','square':'\u25A1','Square':'\u25A1','SquareIntersection':'\u2293','SquareSubset':'\u228F','SquareSubsetEqual':'\u2291','SquareSuperset':'\u2290','SquareSupersetEqual':'\u2292','SquareUnion':'\u2294','squarf':'\u25AA','squf':'\u25AA','srarr':'\u2192','sscr':'\uD835\uDCC8','Sscr':'\uD835\uDCAE','ssetmn':'\u2216','ssmile':'\u2323','sstarf':'\u22C6','star':'\u2606','Star':'\u22C6','starf':'\u2605','straightepsilon':'\u03F5','straightphi':'\u03D5','strns':'\xAF','sub':'\u2282','Sub':'\u22D0','subdot':'\u2ABD','sube':'\u2286','subE':'\u2AC5','subedot':'\u2AC3','submult':'\u2AC1','subne':'\u228A','subnE':'\u2ACB','subplus':'\u2ABF','subrarr':'\u2979','subset':'\u2282','Subset':'\u22D0','subseteq':'\u2286','subseteqq':'\u2AC5','SubsetEqual':'\u2286','subsetneq':'\u228A','subsetneqq':'\u2ACB','subsim':'\u2AC7','subsub':'\u2AD5','subsup':'\u2AD3','succ':'\u227B','succapprox':'\u2AB8','succcurlyeq':'\u227D','Succeeds':'\u227B','SucceedsEqual':'\u2AB0','SucceedsSlantEqual':'\u227D','SucceedsTilde':'\u227F','succeq':'\u2AB0','succnapprox':'\u2ABA','succneqq':'\u2AB6','succnsim':'\u22E9','succsim':'\u227F','SuchThat':'\u220B','sum':'\u2211','Sum':'\u2211','sung':'\u266A','sup':'\u2283','Sup':'\u22D1','sup1':'\xB9','sup2':'\xB2','sup3':'\xB3','supdot':'\u2ABE','supdsub':'\u2AD8','supe':'\u2287','supE':'\u2AC6','supedot':'\u2AC4','Superset':'\u2283','SupersetEqual':'\u2287','suphsol':'\u27C9','suphsub':'\u2AD7','suplarr':'\u297B','supmult':'\u2AC2','supne':'\u228B','supnE':'\u2ACC','supplus':'\u2AC0','supset':'\u2283','Supset':'\u22D1','supseteq':'\u2287','supseteqq':'\u2AC6','supsetneq':'\u228B','supsetneqq':'\u2ACC','supsim':'\u2AC8','supsub':'\u2AD4','supsup':'\u2AD6','swarhk':'\u2926','swarr':'\u2199','swArr':'\u21D9','swarrow':'\u2199','swnwar':'\u292A','szlig':'\xDF','Tab':'\t','target':'\u2316','tau':'\u03C4','Tau':'\u03A4','tbrk':'\u23B4','tcaron':'\u0165','Tcaron':'\u0164','tcedil':'\u0163','Tcedil':'\u0162','tcy':'\u0442','Tcy':'\u0422','tdot':'\u20DB','telrec':'\u2315','tfr':'\uD835\uDD31','Tfr':'\uD835\uDD17','there4':'\u2234','therefore':'\u2234','Therefore':'\u2234','theta':'\u03B8','Theta':'\u0398','thetasym':'\u03D1','thetav':'\u03D1','thickapprox':'\u2248','thicksim':'\u223C','ThickSpace':'\u205F\u200A','thinsp':'\u2009','ThinSpace':'\u2009','thkap':'\u2248','thksim':'\u223C','thorn':'\xFE','THORN':'\xDE','tilde':'\u02DC','Tilde':'\u223C','TildeEqual':'\u2243','TildeFullEqual':'\u2245','TildeTilde':'\u2248','times':'\xD7','timesb':'\u22A0','timesbar':'\u2A31','timesd':'\u2A30','tint':'\u222D','toea':'\u2928','top':'\u22A4','topbot':'\u2336','topcir':'\u2AF1','topf':'\uD835\uDD65','Topf':'\uD835\uDD4B','topfork':'\u2ADA','tosa':'\u2929','tprime':'\u2034','trade':'\u2122','TRADE':'\u2122','triangle':'\u25B5','triangledown':'\u25BF','triangleleft':'\u25C3','trianglelefteq':'\u22B4','triangleq':'\u225C','triangleright':'\u25B9','trianglerighteq':'\u22B5','tridot':'\u25EC','trie':'\u225C','triminus':'\u2A3A','TripleDot':'\u20DB','triplus':'\u2A39','trisb':'\u29CD','tritime':'\u2A3B','trpezium':'\u23E2','tscr':'\uD835\uDCC9','Tscr':'\uD835\uDCAF','tscy':'\u0446','TScy':'\u0426','tshcy':'\u045B','TSHcy':'\u040B','tstrok':'\u0167','Tstrok':'\u0166','twixt':'\u226C','twoheadleftarrow':'\u219E','twoheadrightarrow':'\u21A0','uacute':'\xFA','Uacute':'\xDA','uarr':'\u2191','uArr':'\u21D1','Uarr':'\u219F','Uarrocir':'\u2949','ubrcy':'\u045E','Ubrcy':'\u040E','ubreve':'\u016D','Ubreve':'\u016C','ucirc':'\xFB','Ucirc':'\xDB','ucy':'\u0443','Ucy':'\u0423','udarr':'\u21C5','udblac':'\u0171','Udblac':'\u0170','udhar':'\u296E','ufisht':'\u297E','ufr':'\uD835\uDD32','Ufr':'\uD835\uDD18','ugrave':'\xF9','Ugrave':'\xD9','uHar':'\u2963','uharl':'\u21BF','uharr':'\u21BE','uhblk':'\u2580','ulcorn':'\u231C','ulcorner':'\u231C','ulcrop':'\u230F','ultri':'\u25F8','umacr':'\u016B','Umacr':'\u016A','uml':'\xA8','UnderBar':'_','UnderBrace':'\u23DF','UnderBracket':'\u23B5','UnderParenthesis':'\u23DD','Union':'\u22C3','UnionPlus':'\u228E','uogon':'\u0173','Uogon':'\u0172','uopf':'\uD835\uDD66','Uopf':'\uD835\uDD4C','uparrow':'\u2191','Uparrow':'\u21D1','UpArrow':'\u2191','UpArrowBar':'\u2912','UpArrowDownArrow':'\u21C5','updownarrow':'\u2195','Updownarrow':'\u21D5','UpDownArrow':'\u2195','UpEquilibrium':'\u296E','upharpoonleft':'\u21BF','upharpoonright':'\u21BE','uplus':'\u228E','UpperLeftArrow':'\u2196','UpperRightArrow':'\u2197','upsi':'\u03C5','Upsi':'\u03D2','upsih':'\u03D2','upsilon':'\u03C5','Upsilon':'\u03A5','UpTee':'\u22A5','UpTeeArrow':'\u21A5','upuparrows':'\u21C8','urcorn':'\u231D','urcorner':'\u231D','urcrop':'\u230E','uring':'\u016F','Uring':'\u016E','urtri':'\u25F9','uscr':'\uD835\uDCCA','Uscr':'\uD835\uDCB0','utdot':'\u22F0','utilde':'\u0169','Utilde':'\u0168','utri':'\u25B5','utrif':'\u25B4','uuarr':'\u21C8','uuml':'\xFC','Uuml':'\xDC','uwangle':'\u29A7','vangrt':'\u299C','varepsilon':'\u03F5','varkappa':'\u03F0','varnothing':'\u2205','varphi':'\u03D5','varpi':'\u03D6','varpropto':'\u221D','varr':'\u2195','vArr':'\u21D5','varrho':'\u03F1','varsigma':'\u03C2','varsubsetneq':'\u228A\uFE00','varsubsetneqq':'\u2ACB\uFE00','varsupsetneq':'\u228B\uFE00','varsupsetneqq':'\u2ACC\uFE00','vartheta':'\u03D1','vartriangleleft':'\u22B2','vartriangleright':'\u22B3','vBar':'\u2AE8','Vbar':'\u2AEB','vBarv':'\u2AE9','vcy':'\u0432','Vcy':'\u0412','vdash':'\u22A2','vDash':'\u22A8','Vdash':'\u22A9','VDash':'\u22AB','Vdashl':'\u2AE6','vee':'\u2228','Vee':'\u22C1','veebar':'\u22BB','veeeq':'\u225A','vellip':'\u22EE','verbar':'|','Verbar':'\u2016','vert':'|','Vert':'\u2016','VerticalBar':'\u2223','VerticalLine':'|','VerticalSeparator':'\u2758','VerticalTilde':'\u2240','VeryThinSpace':'\u200A','vfr':'\uD835\uDD33','Vfr':'\uD835\uDD19','vltri':'\u22B2','vnsub':'\u2282\u20D2','vnsup':'\u2283\u20D2','vopf':'\uD835\uDD67','Vopf':'\uD835\uDD4D','vprop':'\u221D','vrtri':'\u22B3','vscr':'\uD835\uDCCB','Vscr':'\uD835\uDCB1','vsubne':'\u228A\uFE00','vsubnE':'\u2ACB\uFE00','vsupne':'\u228B\uFE00','vsupnE':'\u2ACC\uFE00','Vvdash':'\u22AA','vzigzag':'\u299A','wcirc':'\u0175','Wcirc':'\u0174','wedbar':'\u2A5F','wedge':'\u2227','Wedge':'\u22C0','wedgeq':'\u2259','weierp':'\u2118','wfr':'\uD835\uDD34','Wfr':'\uD835\uDD1A','wopf':'\uD835\uDD68','Wopf':'\uD835\uDD4E','wp':'\u2118','wr':'\u2240','wreath':'\u2240','wscr':'\uD835\uDCCC','Wscr':'\uD835\uDCB2','xcap':'\u22C2','xcirc':'\u25EF','xcup':'\u22C3','xdtri':'\u25BD','xfr':'\uD835\uDD35','Xfr':'\uD835\uDD1B','xharr':'\u27F7','xhArr':'\u27FA','xi':'\u03BE','Xi':'\u039E','xlarr':'\u27F5','xlArr':'\u27F8','xmap':'\u27FC','xnis':'\u22FB','xodot':'\u2A00','xopf':'\uD835\uDD69','Xopf':'\uD835\uDD4F','xoplus':'\u2A01','xotime':'\u2A02','xrarr':'\u27F6','xrArr':'\u27F9','xscr':'\uD835\uDCCD','Xscr':'\uD835\uDCB3','xsqcup':'\u2A06','xuplus':'\u2A04','xutri':'\u25B3','xvee':'\u22C1','xwedge':'\u22C0','yacute':'\xFD','Yacute':'\xDD','yacy':'\u044F','YAcy':'\u042F','ycirc':'\u0177','Ycirc':'\u0176','ycy':'\u044B','Ycy':'\u042B','yen':'\xA5','yfr':'\uD835\uDD36','Yfr':'\uD835\uDD1C','yicy':'\u0457','YIcy':'\u0407','yopf':'\uD835\uDD6A','Yopf':'\uD835\uDD50','yscr':'\uD835\uDCCE','Yscr':'\uD835\uDCB4','yucy':'\u044E','YUcy':'\u042E','yuml':'\xFF','Yuml':'\u0178','zacute':'\u017A','Zacute':'\u0179','zcaron':'\u017E','Zcaron':'\u017D','zcy':'\u0437','Zcy':'\u0417','zdot':'\u017C','Zdot':'\u017B','zeetrf':'\u2128','ZeroWidthSpace':'\u200B','zeta':'\u03B6','Zeta':'\u0396','zfr':'\uD835\uDD37','Zfr':'\u2128','zhcy':'\u0436','ZHcy':'\u0416','zigrarr':'\u21DD','zopf':'\uD835\uDD6B','Zopf':'\u2124','zscr':'\uD835\uDCCF','Zscr':'\uD835\uDCB5','zwj':'\u200D','zwnj':'\u200C'}; + var decodeMapLegacy = {'aacute':'\xE1','Aacute':'\xC1','acirc':'\xE2','Acirc':'\xC2','acute':'\xB4','aelig':'\xE6','AElig':'\xC6','agrave':'\xE0','Agrave':'\xC0','amp':'&','AMP':'&','aring':'\xE5','Aring':'\xC5','atilde':'\xE3','Atilde':'\xC3','auml':'\xE4','Auml':'\xC4','brvbar':'\xA6','ccedil':'\xE7','Ccedil':'\xC7','cedil':'\xB8','cent':'\xA2','copy':'\xA9','COPY':'\xA9','curren':'\xA4','deg':'\xB0','divide':'\xF7','eacute':'\xE9','Eacute':'\xC9','ecirc':'\xEA','Ecirc':'\xCA','egrave':'\xE8','Egrave':'\xC8','eth':'\xF0','ETH':'\xD0','euml':'\xEB','Euml':'\xCB','frac12':'\xBD','frac14':'\xBC','frac34':'\xBE','gt':'>','GT':'>','iacute':'\xED','Iacute':'\xCD','icirc':'\xEE','Icirc':'\xCE','iexcl':'\xA1','igrave':'\xEC','Igrave':'\xCC','iquest':'\xBF','iuml':'\xEF','Iuml':'\xCF','laquo':'\xAB','lt':'<','LT':'<','macr':'\xAF','micro':'\xB5','middot':'\xB7','nbsp':'\xA0','not':'\xAC','ntilde':'\xF1','Ntilde':'\xD1','oacute':'\xF3','Oacute':'\xD3','ocirc':'\xF4','Ocirc':'\xD4','ograve':'\xF2','Ograve':'\xD2','ordf':'\xAA','ordm':'\xBA','oslash':'\xF8','Oslash':'\xD8','otilde':'\xF5','Otilde':'\xD5','ouml':'\xF6','Ouml':'\xD6','para':'\xB6','plusmn':'\xB1','pound':'\xA3','quot':'"','QUOT':'"','raquo':'\xBB','reg':'\xAE','REG':'\xAE','sect':'\xA7','shy':'\xAD','sup1':'\xB9','sup2':'\xB2','sup3':'\xB3','szlig':'\xDF','thorn':'\xFE','THORN':'\xDE','times':'\xD7','uacute':'\xFA','Uacute':'\xDA','ucirc':'\xFB','Ucirc':'\xDB','ugrave':'\xF9','Ugrave':'\xD9','uml':'\xA8','uuml':'\xFC','Uuml':'\xDC','yacute':'\xFD','Yacute':'\xDD','yen':'\xA5','yuml':'\xFF'}; + var decodeMapNumeric = {'0':'\uFFFD','128':'\u20AC','130':'\u201A','131':'\u0192','132':'\u201E','133':'\u2026','134':'\u2020','135':'\u2021','136':'\u02C6','137':'\u2030','138':'\u0160','139':'\u2039','140':'\u0152','142':'\u017D','145':'\u2018','146':'\u2019','147':'\u201C','148':'\u201D','149':'\u2022','150':'\u2013','151':'\u2014','152':'\u02DC','153':'\u2122','154':'\u0161','155':'\u203A','156':'\u0153','158':'\u017E','159':'\u0178'}; + var invalidReferenceCodePoints = [1,2,3,4,5,6,7,8,11,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,64976,64977,64978,64979,64980,64981,64982,64983,64984,64985,64986,64987,64988,64989,64990,64991,64992,64993,64994,64995,64996,64997,64998,64999,65000,65001,65002,65003,65004,65005,65006,65007,65534,65535,131070,131071,196606,196607,262142,262143,327678,327679,393214,393215,458750,458751,524286,524287,589822,589823,655358,655359,720894,720895,786430,786431,851966,851967,917502,917503,983038,983039,1048574,1048575,1114110,1114111]; + + /*--------------------------------------------------------------------------*/ + + var stringFromCharCode = String.fromCharCode; + + var object = {}; + var hasOwnProperty = object.hasOwnProperty; + var has = function(object, propertyName) { + return hasOwnProperty.call(object, propertyName); + }; + + var contains = function(array, value) { + var index = -1; + var length = array.length; + while (++index < length) { + if (array[index] == value) { + return true; + } + } + return false; + }; + + var merge = function(options, defaults) { + if (!options) { + return defaults; + } + var result = {}; + var key; + for (key in defaults) { + // A `hasOwnProperty` check is not needed here, since only recognized + // option names are used anyway. Any others are ignored. + result[key] = has(options, key) ? options[key] : defaults[key]; + } + return result; + }; + + // Modified version of `ucs2encode`; see https://mths.be/punycode. + var codePointToSymbol = function(codePoint, strict) { + var output = ''; + if ((codePoint >= 0xD800 && codePoint <= 0xDFFF) || codePoint > 0x10FFFF) { + // See issue #4: + // โ€œOtherwise, if the number is in the range 0xD800 to 0xDFFF or is + // greater than 0x10FFFF, then this is a parse error. Return a U+FFFD + // REPLACEMENT CHARACTER.โ€ + if (strict) { + parseError('character reference outside the permissible Unicode range'); + } + return '\uFFFD'; + } + if (has(decodeMapNumeric, codePoint)) { + if (strict) { + parseError('disallowed character reference'); + } + return decodeMapNumeric[codePoint]; + } + if (strict && contains(invalidReferenceCodePoints, codePoint)) { + parseError('disallowed character reference'); + } + if (codePoint > 0xFFFF) { + codePoint -= 0x10000; + output += stringFromCharCode(codePoint >>> 10 & 0x3FF | 0xD800); + codePoint = 0xDC00 | codePoint & 0x3FF; + } + output += stringFromCharCode(codePoint); + return output; + }; + + var hexEscape = function(codePoint) { + return '&#x' + codePoint.toString(16).toUpperCase() + ';'; + }; + + var decEscape = function(codePoint) { + return '&#' + codePoint + ';'; + }; + + var parseError = function(message) { + throw Error('Parse error: ' + message); + }; + + /*--------------------------------------------------------------------------*/ + + var encode = function(string, options) { + options = merge(options, encode.options); + var strict = options.strict; + if (strict && regexInvalidRawCodePoint.test(string)) { + parseError('forbidden code point'); + } + var encodeEverything = options.encodeEverything; + var useNamedReferences = options.useNamedReferences; + var allowUnsafeSymbols = options.allowUnsafeSymbols; + var escapeCodePoint = options.decimal ? decEscape : hexEscape; + + var escapeBmpSymbol = function(symbol) { + return escapeCodePoint(symbol.charCodeAt(0)); + }; + + if (encodeEverything) { + // Encode ASCII symbols. + string = string.replace(regexAsciiWhitelist, function(symbol) { + // Use named references if requested & possible. + if (useNamedReferences && has(encodeMap, symbol)) { + return '&' + encodeMap[symbol] + ';'; + } + return escapeBmpSymbol(symbol); + }); + // Shorten a few escapes that represent two symbols, of which at least one + // is within the ASCII range. + if (useNamedReferences) { + string = string + .replace(/>\u20D2/g, '>⃒') + .replace(/<\u20D2/g, '<⃒') + .replace(/fj/g, 'fj'); + } + // Encode non-ASCII symbols. + if (useNamedReferences) { + // Encode non-ASCII symbols that can be replaced with a named reference. + string = string.replace(regexEncodeNonAscii, function(string) { + // Note: there is no need to check `has(encodeMap, string)` here. + return '&' + encodeMap[string] + ';'; + }); + } + // Note: any remaining non-ASCII symbols are handled outside of the `if`. + } else if (useNamedReferences) { + // Apply named character references. + // Encode `<>"'&` using named character references. + if (!allowUnsafeSymbols) { + string = string.replace(regexEscape, function(string) { + return '&' + encodeMap[string] + ';'; // no need to check `has()` here + }); + } + // Shorten escapes that represent two symbols, of which at least one is + // `<>"'&`. + string = string + .replace(/>\u20D2/g, '>⃒') + .replace(/<\u20D2/g, '<⃒'); + // Encode non-ASCII symbols that can be replaced with a named reference. + string = string.replace(regexEncodeNonAscii, function(string) { + // Note: there is no need to check `has(encodeMap, string)` here. + return '&' + encodeMap[string] + ';'; + }); + } else if (!allowUnsafeSymbols) { + // Encode `<>"'&` using hexadecimal escapes, now that theyโ€™re not handled + // using named character references. + string = string.replace(regexEscape, escapeBmpSymbol); + } + return string + // Encode astral symbols. + .replace(regexAstralSymbols, function($0) { + // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae + var high = $0.charCodeAt(0); + var low = $0.charCodeAt(1); + var codePoint = (high - 0xD800) * 0x400 + low - 0xDC00 + 0x10000; + return escapeCodePoint(codePoint); + }) + // Encode any remaining BMP symbols that are not printable ASCII symbols + // using a hexadecimal escape. + .replace(regexBmpWhitelist, escapeBmpSymbol); + }; + // Expose default options (so they can be overridden globally). + encode.options = { + 'allowUnsafeSymbols': false, + 'encodeEverything': false, + 'strict': false, + 'useNamedReferences': false, + 'decimal' : false + }; + + var decode = function(html, options) { + options = merge(options, decode.options); + var strict = options.strict; + if (strict && regexInvalidEntity.test(html)) { + parseError('malformed character reference'); + } + return html.replace(regexDecode, function($0, $1, $2, $3, $4, $5, $6, $7, $8) { + var codePoint; + var semicolon; + var decDigits; + var hexDigits; + var reference; + var next; + + if ($1) { + reference = $1; + // Note: there is no need to check `has(decodeMap, reference)`. + return decodeMap[reference]; + } + + if ($2) { + // Decode named character references without trailing `;`, e.g. `&`. + // This is only a parse error if it gets converted to `&`, or if it is + // followed by `=` in an attribute context. + reference = $2; + next = $3; + if (next && options.isAttributeValue) { + if (strict && next == '=') { + parseError('`&` did not start a character reference'); + } + return $0; + } else { + if (strict) { + parseError( + 'named character reference was not terminated by a semicolon' + ); + } + // Note: there is no need to check `has(decodeMapLegacy, reference)`. + return decodeMapLegacy[reference] + (next || ''); + } + } + + if ($4) { + // Decode decimal escapes, e.g. `𝌆`. + decDigits = $4; + semicolon = $5; + if (strict && !semicolon) { + parseError('character reference was not terminated by a semicolon'); + } + codePoint = parseInt(decDigits, 10); + return codePointToSymbol(codePoint, strict); + } + + if ($6) { + // Decode hexadecimal escapes, e.g. `𝌆`. + hexDigits = $6; + semicolon = $7; + if (strict && !semicolon) { + parseError('character reference was not terminated by a semicolon'); + } + codePoint = parseInt(hexDigits, 16); + return codePointToSymbol(codePoint, strict); + } + + // If weโ€™re still here, `if ($7)` is implied; itโ€™s an ambiguous + // ampersand for sure. https://mths.be/notes/ambiguous-ampersands + if (strict) { + parseError( + 'named character reference was not terminated by a semicolon' + ); + } + return $0; + }); + }; + // Expose default options (so they can be overridden globally). + decode.options = { + 'isAttributeValue': false, + 'strict': false + }; + + var escape = function(string) { + return string.replace(regexEscape, function($0) { + // Note: there is no need to check `has(escapeMap, $0)` here. + return escapeMap[$0]; + }); + }; + + /*--------------------------------------------------------------------------*/ + + var he = { + 'version': '1.2.0', + 'encode': encode, + 'decode': decode, + 'escape': escape, + 'unescape': decode + }; + + // Some AMD build optimizers, like r.js, check for specific condition patterns + // like the following: + if ( + typeof define == 'function' && + typeof define.amd == 'object' && + define.amd + ) { + define(function() { + return he; + }); + } else if (freeExports && !freeExports.nodeType) { + if (freeModule) { // in Node.js, io.js, or RingoJS v0.8.0+ + freeModule.exports = he; + } else { // in Narwhal or RingoJS v0.7.0- + for (var key in he) { + has(he, key) && (freeExports[key] = he[key]); + } + } + } else { // in Rhino or a web browser + root.he = he; + } + +}(this)); \ No newline at end of file diff --git a/assets/js/hl.js b/assets/js/hl.js new file mode 100755 index 0000000..43482e3 --- /dev/null +++ b/assets/js/hl.js @@ -0,0 +1,1198 @@ +/*! + Highlight.js v11.6.0 (git: bed790f3f3) + (c) 2006-2022 undefined and other contributors + License: BSD-3-Clause + */ +var hljs=function(){"use strict";var e={exports:{}};function n(e){ +return e instanceof Map?e.clear=e.delete=e.set=()=>{ +throw Error("map is read-only")}:e instanceof Set&&(e.add=e.clear=e.delete=()=>{ +throw Error("set is read-only") +}),Object.freeze(e),Object.getOwnPropertyNames(e).forEach((t=>{var a=e[t] +;"object"!=typeof a||Object.isFrozen(a)||n(a)})),e} +e.exports=n,e.exports.default=n;class t{constructor(e){ +void 0===e.data&&(e.data={}),this.data=e.data,this.isMatchIgnored=!1} +ignoreMatch(){this.isMatchIgnored=!0}}function a(e){ +return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'") +}function i(e,...n){const t=Object.create(null);for(const n in e)t[n]=e[n] +;return n.forEach((e=>{for(const n in e)t[n]=e[n]})),t} +const r=e=>!!e.scope||e.sublanguage&&e.language;class s{constructor(e,n){ +this.buffer="",this.classPrefix=n.classPrefix,e.walk(this)}addText(e){ +this.buffer+=a(e)}openNode(e){if(!r(e))return;let n="" +;n=e.sublanguage?"language-"+e.language:((e,{prefix:n})=>{if(e.includes(".")){ +const t=e.split(".") +;return[`${n}${t.shift()}`,...t.map(((e,n)=>`${e}${"_".repeat(n+1)}`))].join(" ") +}return`${n}${e}`})(e.scope,{prefix:this.classPrefix}),this.span(n)} +closeNode(e){r(e)&&(this.buffer+="")}value(){return this.buffer}span(e){ +this.buffer+=``}}const o=(e={})=>{const n={children:[]} +;return Object.assign(n,e),n};class l{constructor(){ +this.rootNode=o(),this.stack=[this.rootNode]}get top(){ +return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){ +this.top.children.push(e)}openNode(e){const n=o({scope:e}) +;this.add(n),this.stack.push(n)}closeNode(){ +if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){ +for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)} +walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,n){ +return"string"==typeof n?e.addText(n):n.children&&(e.openNode(n), +n.children.forEach((n=>this._walk(e,n))),e.closeNode(n)),e}static _collapse(e){ +"string"!=typeof e&&e.children&&(e.children.every((e=>"string"==typeof e))?e.children=[e.children.join("")]:e.children.forEach((e=>{ +l._collapse(e)})))}}class c extends l{constructor(e){super(),this.options=e} +addKeyword(e,n){""!==e&&(this.openNode(n),this.addText(e),this.closeNode())} +addText(e){""!==e&&this.add(e)}addSublanguage(e,n){const t=e.root +;t.sublanguage=!0,t.language=n,this.add(t)}toHTML(){ +return new s(this,this.options).value()}finalize(){return!0}}function d(e){ +return e?"string"==typeof e?e:e.source:null}function g(e){return m("(?=",e,")")} +function u(e){return m("(?:",e,")*")}function b(e){return m("(?:",e,")?")} +function m(...e){return e.map((e=>d(e))).join("")}function p(...e){const n=(e=>{ +const n=e[e.length-1] +;return"object"==typeof n&&n.constructor===Object?(e.splice(e.length-1,1),n):{} +})(e);return"("+(n.capture?"":"?:")+e.map((e=>d(e))).join("|")+")"} +function _(e){return RegExp(e.toString()+"|").exec("").length-1} +const h=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./ +;function f(e,{joinWith:n}){let t=0;return e.map((e=>{t+=1;const n=t +;let a=d(e),i="";for(;a.length>0;){const e=h.exec(a);if(!e){i+=a;break} +i+=a.substring(0,e.index), +a=a.substring(e.index+e[0].length),"\\"===e[0][0]&&e[1]?i+="\\"+(Number(e[1])+n):(i+=e[0], +"("===e[0]&&t++)}return i})).map((e=>`(${e})`)).join(n)} +const E="[a-zA-Z]\\w*",y="[a-zA-Z_]\\w*",w="\\b\\d+(\\.\\d+)?",N="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",v="\\b(0b[01]+)",O={ +begin:"\\\\[\\s\\S]",relevance:0},k={scope:"string",begin:"'",end:"'", +illegal:"\\n",contains:[O]},x={scope:"string",begin:'"',end:'"',illegal:"\\n", +contains:[O]},M=(e,n,t={})=>{const a=i({scope:"comment",begin:e,end:n, +contains:[]},t);a.contains.push({scope:"doctag", +begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)", +end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0}) +;const r=p("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/) +;return a.contains.push({begin:m(/[ ]+/,"(",r,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),a +},S=M("//","$"),A=M("/\\*","\\*/"),C=M("#","$");var T=Object.freeze({ +__proto__:null,MATCH_NOTHING_RE:/\b\B/,IDENT_RE:E,UNDERSCORE_IDENT_RE:y, +NUMBER_RE:w,C_NUMBER_RE:N,BINARY_NUMBER_RE:v, +RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~", +SHEBANG:(e={})=>{const n=/^#![ ]*\// +;return e.binary&&(e.begin=m(n,/.*\b/,e.binary,/\b.*/)),i({scope:"meta",begin:n, +end:/$/,relevance:0,"on:begin":(e,n)=>{0!==e.index&&n.ignoreMatch()}},e)}, +BACKSLASH_ESCAPE:O,APOS_STRING_MODE:k,QUOTE_STRING_MODE:x,PHRASAL_WORDS_MODE:{ +begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/ +},COMMENT:M,C_LINE_COMMENT_MODE:S,C_BLOCK_COMMENT_MODE:A,HASH_COMMENT_MODE:C, +NUMBER_MODE:{scope:"number",begin:w,relevance:0},C_NUMBER_MODE:{scope:"number", +begin:N,relevance:0},BINARY_NUMBER_MODE:{scope:"number",begin:v,relevance:0}, +REGEXP_MODE:{begin:/(?=\/[^/\n]*\/)/,contains:[{scope:"regexp",begin:/\//, +end:/\/[gimuy]*/,illegal:/\n/,contains:[O,{begin:/\[/,end:/\]/,relevance:0, +contains:[O]}]}]},TITLE_MODE:{scope:"title",begin:E,relevance:0}, +UNDERSCORE_TITLE_MODE:{scope:"title",begin:y,relevance:0},METHOD_GUARD:{ +begin:"\\.\\s*[a-zA-Z_]\\w*",relevance:0},END_SAME_AS_BEGIN:e=>Object.assign(e,{ +"on:begin":(e,n)=>{n.data._beginMatch=e[1]},"on:end":(e,n)=>{ +n.data._beginMatch!==e[1]&&n.ignoreMatch()}})});function R(e,n){ +"."===e.input[e.index-1]&&n.ignoreMatch()}function D(e,n){ +void 0!==e.className&&(e.scope=e.className,delete e.className)}function I(e,n){ +n&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)", +e.__beforeBegin=R,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords, +void 0===e.relevance&&(e.relevance=0))}function L(e,n){ +Array.isArray(e.illegal)&&(e.illegal=p(...e.illegal))}function B(e,n){ +if(e.match){ +if(e.begin||e.end)throw Error("begin & end are not supported with match") +;e.begin=e.match,delete e.match}}function $(e,n){ +void 0===e.relevance&&(e.relevance=1)}const z=(e,n)=>{if(!e.beforeMatch)return +;if(e.starts)throw Error("beforeMatch cannot be used with starts") +;const t=Object.assign({},e);Object.keys(e).forEach((n=>{delete e[n] +})),e.keywords=t.keywords,e.begin=m(t.beforeMatch,g(t.begin)),e.starts={ +relevance:0,contains:[Object.assign(t,{endsParent:!0})] +},e.relevance=0,delete t.beforeMatch +},F=["of","and","for","in","not","or","if","then","parent","list","value"] +;function U(e,n,t="keyword"){const a=Object.create(null) +;return"string"==typeof e?i(t,e.split(" ")):Array.isArray(e)?i(t,e):Object.keys(e).forEach((t=>{ +Object.assign(a,U(e[t],n,t))})),a;function i(e,t){ +n&&(t=t.map((e=>e.toLowerCase()))),t.forEach((n=>{const t=n.split("|") +;a[t[0]]=[e,j(t[0],t[1])]}))}}function j(e,n){ +return n?Number(n):(e=>F.includes(e.toLowerCase()))(e)?0:1}const P={},K=e=>{ +console.error(e)},H=(e,...n)=>{console.log("WARN: "+e,...n)},q=(e,n)=>{ +P[`${e}/${n}`]||(console.log(`Deprecated as of ${e}. ${n}`),P[`${e}/${n}`]=!0) +},Z=Error();function G(e,n,{key:t}){let a=0;const i=e[t],r={},s={} +;for(let e=1;e<=n.length;e++)s[e+a]=i[e],r[e+a]=!0,a+=_(n[e-1]) +;e[t]=s,e[t]._emit=r,e[t]._multi=!0}function W(e){(e=>{ +e.scope&&"object"==typeof e.scope&&null!==e.scope&&(e.beginScope=e.scope, +delete e.scope)})(e),"string"==typeof e.beginScope&&(e.beginScope={ +_wrap:e.beginScope}),"string"==typeof e.endScope&&(e.endScope={_wrap:e.endScope +}),(e=>{if(Array.isArray(e.begin)){ +if(e.skip||e.excludeBegin||e.returnBegin)throw K("skip, excludeBegin, returnBegin not compatible with beginScope: {}"), +Z +;if("object"!=typeof e.beginScope||null===e.beginScope)throw K("beginScope must be object"), +Z;G(e,e.begin,{key:"beginScope"}),e.begin=f(e.begin,{joinWith:""})}})(e),(e=>{ +if(Array.isArray(e.end)){ +if(e.skip||e.excludeEnd||e.returnEnd)throw K("skip, excludeEnd, returnEnd not compatible with endScope: {}"), +Z +;if("object"!=typeof e.endScope||null===e.endScope)throw K("endScope must be object"), +Z;G(e,e.end,{key:"endScope"}),e.end=f(e.end,{joinWith:""})}})(e)}function Q(e){ +function n(n,t){ +return RegExp(d(n),"m"+(e.case_insensitive?"i":"")+(e.unicodeRegex?"u":"")+(t?"g":"")) +}class t{constructor(){ +this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0} +addRule(e,n){ +n.position=this.position++,this.matchIndexes[this.matchAt]=n,this.regexes.push([n,e]), +this.matchAt+=_(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null) +;const e=this.regexes.map((e=>e[1]));this.matcherRe=n(f(e,{joinWith:"|" +}),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex +;const n=this.matcherRe.exec(e);if(!n)return null +;const t=n.findIndex(((e,n)=>n>0&&void 0!==e)),a=this.matchIndexes[t] +;return n.splice(0,t),Object.assign(n,a)}}class a{constructor(){ +this.rules=[],this.multiRegexes=[], +this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){ +if(this.multiRegexes[e])return this.multiRegexes[e];const n=new t +;return this.rules.slice(e).forEach((([e,t])=>n.addRule(e,t))), +n.compile(),this.multiRegexes[e]=n,n}resumingScanAtSamePosition(){ +return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(e,n){ +this.rules.push([e,n]),"begin"===n.type&&this.count++}exec(e){ +const n=this.getMatcher(this.regexIndex);n.lastIndex=this.lastIndex +;let t=n.exec(e) +;if(this.resumingScanAtSamePosition())if(t&&t.index===this.lastIndex);else{ +const n=this.getMatcher(0);n.lastIndex=this.lastIndex+1,t=n.exec(e)} +return t&&(this.regexIndex+=t.position+1, +this.regexIndex===this.count&&this.considerAll()),t}} +if(e.compilerExtensions||(e.compilerExtensions=[]), +e.contains&&e.contains.includes("self"))throw Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.") +;return e.classNameAliases=i(e.classNameAliases||{}),function t(r,s){const o=r +;if(r.isCompiled)return o +;[D,B,W,z].forEach((e=>e(r,s))),e.compilerExtensions.forEach((e=>e(r,s))), +r.__beforeBegin=null,[I,L,$].forEach((e=>e(r,s))),r.isCompiled=!0;let l=null +;return"object"==typeof r.keywords&&r.keywords.$pattern&&(r.keywords=Object.assign({},r.keywords), +l=r.keywords.$pattern, +delete r.keywords.$pattern),l=l||/\w+/,r.keywords&&(r.keywords=U(r.keywords,e.case_insensitive)), +o.keywordPatternRe=n(l,!0), +s&&(r.begin||(r.begin=/\B|\b/),o.beginRe=n(o.begin),r.end||r.endsWithParent||(r.end=/\B|\b/), +r.end&&(o.endRe=n(o.end)), +o.terminatorEnd=d(o.end)||"",r.endsWithParent&&s.terminatorEnd&&(o.terminatorEnd+=(r.end?"|":"")+s.terminatorEnd)), +r.illegal&&(o.illegalRe=n(r.illegal)), +r.contains||(r.contains=[]),r.contains=[].concat(...r.contains.map((e=>(e=>(e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map((n=>i(e,{ +variants:null},n)))),e.cachedVariants?e.cachedVariants:X(e)?i(e,{ +starts:e.starts?i(e.starts):null +}):Object.isFrozen(e)?i(e):e))("self"===e?r:e)))),r.contains.forEach((e=>{t(e,o) +})),r.starts&&t(r.starts,s),o.matcher=(e=>{const n=new a +;return e.contains.forEach((e=>n.addRule(e.begin,{rule:e,type:"begin" +}))),e.terminatorEnd&&n.addRule(e.terminatorEnd,{type:"end" +}),e.illegal&&n.addRule(e.illegal,{type:"illegal"}),n})(o),o}(e)}function X(e){ +return!!e&&(e.endsWithParent||X(e.starts))}class V extends Error{ +constructor(e,n){super(e),this.name="HTMLInjectionError",this.html=n}} +const J=a,Y=i,ee=Symbol("nomatch");var ne=(n=>{ +const a=Object.create(null),i=Object.create(null),r=[];let s=!0 +;const o="Could not find the language '{}', did you forget to load/include a language module?",l={ +disableAutodetect:!0,name:"Plain text",contains:[]};let d={ +ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i, +languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-", +cssSelector:"pre code",languages:null,__emitter:c};function _(e){ +return d.noHighlightRe.test(e)}function h(e,n,t){let a="",i="" +;"object"==typeof n?(a=e, +t=n.ignoreIllegals,i=n.language):(q("10.7.0","highlight(lang, code, ...args) has been deprecated."), +q("10.7.0","Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"), +i=e,a=n),void 0===t&&(t=!0);const r={code:a,language:i};x("before:highlight",r) +;const s=r.result?r.result:f(r.language,r.code,t) +;return s.code=r.code,x("after:highlight",s),s}function f(e,n,i,r){ +const l=Object.create(null);function c(){if(!k.keywords)return void M.addText(S) +;let e=0;k.keywordPatternRe.lastIndex=0;let n=k.keywordPatternRe.exec(S),t="" +;for(;n;){t+=S.substring(e,n.index) +;const i=w.case_insensitive?n[0].toLowerCase():n[0],r=(a=i,k.keywords[a]);if(r){ +const[e,a]=r +;if(M.addText(t),t="",l[i]=(l[i]||0)+1,l[i]<=7&&(A+=a),e.startsWith("_"))t+=n[0];else{ +const t=w.classNameAliases[e]||e;M.addKeyword(n[0],t)}}else t+=n[0] +;e=k.keywordPatternRe.lastIndex,n=k.keywordPatternRe.exec(S)}var a +;t+=S.substring(e),M.addText(t)}function g(){null!=k.subLanguage?(()=>{ +if(""===S)return;let e=null;if("string"==typeof k.subLanguage){ +if(!a[k.subLanguage])return void M.addText(S) +;e=f(k.subLanguage,S,!0,x[k.subLanguage]),x[k.subLanguage]=e._top +}else e=E(S,k.subLanguage.length?k.subLanguage:null) +;k.relevance>0&&(A+=e.relevance),M.addSublanguage(e._emitter,e.language) +})():c(),S=""}function u(e,n){let t=1;const a=n.length-1;for(;t<=a;){ +if(!e._emit[t]){t++;continue}const a=w.classNameAliases[e[t]]||e[t],i=n[t] +;a?M.addKeyword(i,a):(S=i,c(),S=""),t++}}function b(e,n){ +return e.scope&&"string"==typeof e.scope&&M.openNode(w.classNameAliases[e.scope]||e.scope), +e.beginScope&&(e.beginScope._wrap?(M.addKeyword(S,w.classNameAliases[e.beginScope._wrap]||e.beginScope._wrap), +S=""):e.beginScope._multi&&(u(e.beginScope,n),S="")),k=Object.create(e,{parent:{ +value:k}}),k}function m(e,n,a){let i=((e,n)=>{const t=e&&e.exec(n) +;return t&&0===t.index})(e.endRe,a);if(i){if(e["on:end"]){const a=new t(e) +;e["on:end"](n,a),a.isMatchIgnored&&(i=!1)}if(i){ +for(;e.endsParent&&e.parent;)e=e.parent;return e}} +if(e.endsWithParent)return m(e.parent,n,a)}function p(e){ +return 0===k.matcher.regexIndex?(S+=e[0],1):(R=!0,0)}function _(e){ +const t=e[0],a=n.substring(e.index),i=m(k,e,a);if(!i)return ee;const r=k +;k.endScope&&k.endScope._wrap?(g(), +M.addKeyword(t,k.endScope._wrap)):k.endScope&&k.endScope._multi?(g(), +u(k.endScope,e)):r.skip?S+=t:(r.returnEnd||r.excludeEnd||(S+=t), +g(),r.excludeEnd&&(S=t));do{ +k.scope&&M.closeNode(),k.skip||k.subLanguage||(A+=k.relevance),k=k.parent +}while(k!==i.parent);return i.starts&&b(i.starts,e),r.returnEnd?0:t.length} +let h={};function y(a,r){const o=r&&r[0];if(S+=a,null==o)return g(),0 +;if("begin"===h.type&&"end"===r.type&&h.index===r.index&&""===o){ +if(S+=n.slice(r.index,r.index+1),!s){const n=Error(`0 width match regex (${e})`) +;throw n.languageName=e,n.badRule=h.rule,n}return 1} +if(h=r,"begin"===r.type)return(e=>{ +const n=e[0],a=e.rule,i=new t(a),r=[a.__beforeBegin,a["on:begin"]] +;for(const t of r)if(t&&(t(e,i),i.isMatchIgnored))return p(n) +;return a.skip?S+=n:(a.excludeBegin&&(S+=n), +g(),a.returnBegin||a.excludeBegin||(S=n)),b(a,e),a.returnBegin?0:n.length})(r) +;if("illegal"===r.type&&!i){ +const e=Error('Illegal lexeme "'+o+'" for mode "'+(k.scope||"")+'"') +;throw e.mode=k,e}if("end"===r.type){const e=_(r);if(e!==ee)return e} +if("illegal"===r.type&&""===o)return 1 +;if(T>1e5&&T>3*r.index)throw Error("potential infinite loop, way more iterations than matches") +;return S+=o,o.length}const w=v(e) +;if(!w)throw K(o.replace("{}",e)),Error('Unknown language: "'+e+'"') +;const N=Q(w);let O="",k=r||N;const x={},M=new d.__emitter(d);(()=>{const e=[] +;for(let n=k;n!==w;n=n.parent)n.scope&&e.unshift(n.scope) +;e.forEach((e=>M.openNode(e)))})();let S="",A=0,C=0,T=0,R=!1;try{ +for(k.matcher.considerAll();;){ +T++,R?R=!1:k.matcher.considerAll(),k.matcher.lastIndex=C +;const e=k.matcher.exec(n);if(!e)break;const t=y(n.substring(C,e.index),e) +;C=e.index+t} +return y(n.substring(C)),M.closeAllNodes(),M.finalize(),O=M.toHTML(),{ +language:e,value:O,relevance:A,illegal:!1,_emitter:M,_top:k}}catch(t){ +if(t.message&&t.message.includes("Illegal"))return{language:e,value:J(n), +illegal:!0,relevance:0,_illegalBy:{message:t.message,index:C, +context:n.slice(C-100,C+100),mode:t.mode,resultSoFar:O},_emitter:M};if(s)return{ +language:e,value:J(n),illegal:!1,relevance:0,errorRaised:t,_emitter:M,_top:k} +;throw t}}function E(e,n){n=n||d.languages||Object.keys(a);const t=(e=>{ +const n={value:J(e),illegal:!1,relevance:0,_top:l,_emitter:new d.__emitter(d)} +;return n._emitter.addText(e),n})(e),i=n.filter(v).filter(k).map((n=>f(n,e,!1))) +;i.unshift(t);const r=i.sort(((e,n)=>{ +if(e.relevance!==n.relevance)return n.relevance-e.relevance +;if(e.language&&n.language){if(v(e.language).supersetOf===n.language)return 1 +;if(v(n.language).supersetOf===e.language)return-1}return 0})),[s,o]=r,c=s +;return c.secondBest=o,c}function y(e){let n=null;const t=(e=>{ +let n=e.className+" ";n+=e.parentNode?e.parentNode.className:"" +;const t=d.languageDetectRe.exec(n);if(t){const n=v(t[1]) +;return n||(H(o.replace("{}",t[1])), +H("Falling back to no-highlight mode for this block.",e)),n?t[1]:"no-highlight"} +return n.split(/\s+/).find((e=>_(e)||v(e)))})(e);if(_(t))return +;if(x("before:highlightElement",{el:e,language:t +}),e.children.length>0&&(d.ignoreUnescapedHTML||(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."), +console.warn("https://github.com/highlightjs/highlight.js/wiki/security"), +console.warn("The element with unescaped HTML:"), +console.warn(e)),d.throwUnescapedHTML))throw new V("One of your code blocks includes unescaped HTML.",e.innerHTML) +;n=e;const a=n.textContent,r=t?h(a,{language:t,ignoreIllegals:!0}):E(a) +;e.innerHTML=r.value,((e,n,t)=>{const a=n&&i[n]||t +;e.classList.add("hljs"),e.classList.add("language-"+a) +})(e,t,r.language),e.result={language:r.language,re:r.relevance, +relevance:r.relevance},r.secondBest&&(e.secondBest={ +language:r.secondBest.language,relevance:r.secondBest.relevance +}),x("after:highlightElement",{el:e,result:r,text:a})}let w=!1;function N(){ +"loading"!==document.readyState?document.querySelectorAll(d.cssSelector).forEach(y):w=!0 +}function v(e){return e=(e||"").toLowerCase(),a[e]||a[i[e]]} +function O(e,{languageName:n}){"string"==typeof e&&(e=[e]),e.forEach((e=>{ +i[e.toLowerCase()]=n}))}function k(e){const n=v(e) +;return n&&!n.disableAutodetect}function x(e,n){const t=e;r.forEach((e=>{ +e[t]&&e[t](n)}))} +"undefined"!=typeof window&&window.addEventListener&&window.addEventListener("DOMContentLoaded",(()=>{ +w&&N()}),!1),Object.assign(n,{highlight:h,highlightAuto:E,highlightAll:N, +highlightElement:y, +highlightBlock:e=>(q("10.7.0","highlightBlock will be removed entirely in v12.0"), +q("10.7.0","Please use highlightElement now."),y(e)),configure:e=>{d=Y(d,e)}, +initHighlighting:()=>{ +N(),q("10.6.0","initHighlighting() deprecated. Use highlightAll() now.")}, +initHighlightingOnLoad:()=>{ +N(),q("10.6.0","initHighlightingOnLoad() deprecated. Use highlightAll() now.") +},registerLanguage:(e,t)=>{let i=null;try{i=t(n)}catch(n){ +if(K("Language definition for '{}' could not be registered.".replace("{}",e)), +!s)throw n;K(n),i=l} +i.name||(i.name=e),a[e]=i,i.rawDefinition=t.bind(null,n),i.aliases&&O(i.aliases,{ +languageName:e})},unregisterLanguage:e=>{delete a[e] +;for(const n of Object.keys(i))i[n]===e&&delete i[n]}, +listLanguages:()=>Object.keys(a),getLanguage:v,registerAliases:O, +autoDetection:k,inherit:Y,addPlugin:e=>{(e=>{ +e["before:highlightBlock"]&&!e["before:highlightElement"]&&(e["before:highlightElement"]=n=>{ +e["before:highlightBlock"](Object.assign({block:n.el},n)) +}),e["after:highlightBlock"]&&!e["after:highlightElement"]&&(e["after:highlightElement"]=n=>{ +e["after:highlightBlock"](Object.assign({block:n.el},n))})})(e),r.push(e)} +}),n.debugMode=()=>{s=!1},n.safeMode=()=>{s=!0 +},n.versionString="11.6.0",n.regex={concat:m,lookahead:g,either:p,optional:b, +anyNumberOfTimes:u};for(const n in T)"object"==typeof T[n]&&e.exports(T[n]) +;return Object.assign(n,T),n})({});const te=e=>({IMPORTANT:{scope:"meta", +begin:"!important"},BLOCK_COMMENT:e.C_BLOCK_COMMENT_MODE,HEXCOLOR:{ +scope:"number",begin:/#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/}, +FUNCTION_DISPATCH:{className:"built_in",begin:/[\w-]+(?=\()/}, +ATTRIBUTE_SELECTOR_MODE:{scope:"selector-attr",begin:/\[/,end:/\]/,illegal:"$", +contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},CSS_NUMBER_MODE:{ +scope:"number", +begin:e.NUMBER_RE+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?", +relevance:0},CSS_VARIABLE:{className:"attr",begin:/--[A-Za-z][A-Za-z0-9_-]*/} +}),ae=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","main","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video"],ie=["any-hover","any-pointer","aspect-ratio","color","color-gamut","color-index","device-aspect-ratio","device-height","device-width","display-mode","forced-colors","grid","height","hover","inverted-colors","monochrome","orientation","overflow-block","overflow-inline","pointer","prefers-color-scheme","prefers-contrast","prefers-reduced-motion","prefers-reduced-transparency","resolution","scan","scripting","update","width","min-width","max-width","min-height","max-height"],re=["active","any-link","blank","checked","current","default","defined","dir","disabled","drop","empty","enabled","first","first-child","first-of-type","fullscreen","future","focus","focus-visible","focus-within","has","host","host-context","hover","indeterminate","in-range","invalid","is","lang","last-child","last-of-type","left","link","local-link","not","nth-child","nth-col","nth-last-child","nth-last-col","nth-last-of-type","nth-of-type","only-child","only-of-type","optional","out-of-range","past","placeholder-shown","read-only","read-write","required","right","root","scope","target","target-within","user-invalid","valid","visited","where"],se=["after","backdrop","before","cue","cue-region","first-letter","first-line","grammar-error","marker","part","placeholder","selection","slotted","spelling-error"],oe=["align-content","align-items","align-self","all","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","backface-visibility","background","background-attachment","background-blend-mode","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","block-size","border","border-block","border-block-color","border-block-end","border-block-end-color","border-block-end-style","border-block-end-width","border-block-start","border-block-start-color","border-block-start-style","border-block-start-width","border-block-style","border-block-width","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-inline","border-inline-color","border-inline-end","border-inline-end-color","border-inline-end-style","border-inline-end-width","border-inline-start","border-inline-start-color","border-inline-start-style","border-inline-start-width","border-inline-style","border-inline-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","caret-color","clear","clip","clip-path","clip-rule","color","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","contain","content","content-visibility","counter-increment","counter-reset","cue","cue-after","cue-before","cursor","direction","display","empty-cells","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","flow","font","font-display","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-smoothing","font-stretch","font-style","font-synthesis","font-variant","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-variation-settings","font-weight","gap","glyph-orientation-vertical","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-gap","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inline-size","isolation","justify-content","left","letter-spacing","line-break","line-height","list-style","list-style-image","list-style-position","list-style-type","margin","margin-block","margin-block-end","margin-block-start","margin-bottom","margin-inline","margin-inline-end","margin-inline-start","margin-left","margin-right","margin-top","marks","mask","mask-border","mask-border-mode","mask-border-outset","mask-border-repeat","mask-border-slice","mask-border-source","mask-border-width","mask-clip","mask-composite","mask-image","mask-mode","mask-origin","mask-position","mask-repeat","mask-size","mask-type","max-block-size","max-height","max-inline-size","max-width","min-block-size","min-height","min-inline-size","min-width","mix-blend-mode","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-block","padding-block-end","padding-block-start","padding-bottom","padding-inline","padding-inline-end","padding-inline-start","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","pause","pause-after","pause-before","perspective","perspective-origin","pointer-events","position","quotes","resize","rest","rest-after","rest-before","right","row-gap","scroll-margin","scroll-margin-block","scroll-margin-block-end","scroll-margin-block-start","scroll-margin-bottom","scroll-margin-inline","scroll-margin-inline-end","scroll-margin-inline-start","scroll-margin-left","scroll-margin-right","scroll-margin-top","scroll-padding","scroll-padding-block","scroll-padding-block-end","scroll-padding-block-start","scroll-padding-bottom","scroll-padding-inline","scroll-padding-inline-end","scroll-padding-inline-start","scroll-padding-left","scroll-padding-right","scroll-padding-top","scroll-snap-align","scroll-snap-stop","scroll-snap-type","scrollbar-color","scrollbar-gutter","scrollbar-width","shape-image-threshold","shape-margin","shape-outside","speak","speak-as","src","tab-size","table-layout","text-align","text-align-all","text-align-last","text-combine-upright","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-indent","text-justify","text-orientation","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-box","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","writing-mode","z-index"].reverse(),le=re.concat(se) +;var ce="\\.([0-9](_*[0-9])*)",de="[0-9a-fA-F](_*[0-9a-fA-F])*",ge={ +className:"number",variants:[{ +begin:`(\\b([0-9](_*[0-9])*)((${ce})|\\.)?|(${ce}))[eE][+-]?([0-9](_*[0-9])*)[fFdD]?\\b` +},{begin:`\\b([0-9](_*[0-9])*)((${ce})[fFdD]?\\b|\\.([fFdD]\\b)?)`},{ +begin:`(${ce})[fFdD]?\\b`},{begin:"\\b([0-9](_*[0-9])*)[fFdD]\\b"},{ +begin:`\\b0[xX]((${de})\\.?|(${de})?\\.(${de}))[pP][+-]?([0-9](_*[0-9])*)[fFdD]?\\b` +},{begin:"\\b(0|[1-9](_*[0-9])*)[lL]?\\b"},{begin:`\\b0[xX](${de})[lL]?\\b`},{ +begin:"\\b0(_*[0-7])*[lL]?\\b"},{begin:"\\b0[bB][01](_*[01])*[lL]?\\b"}], +relevance:0};function ue(e,n,t){return-1===t?"":e.replace(n,(a=>ue(e,n,t-1)))} +const be="[A-Za-z$_][0-9A-Za-z$_]*",me=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],pe=["true","false","null","undefined","NaN","Infinity"],_e=["Object","Function","Boolean","Symbol","Math","Date","Number","BigInt","String","RegExp","Array","Float32Array","Float64Array","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Int32Array","Uint16Array","Uint32Array","BigInt64Array","BigUint64Array","Set","Map","WeakSet","WeakMap","ArrayBuffer","SharedArrayBuffer","Atomics","DataView","JSON","Promise","Generator","GeneratorFunction","AsyncFunction","Reflect","Proxy","Intl","WebAssembly"],he=["Error","EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"],fe=["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],Ee=["arguments","this","super","console","window","document","localStorage","module","global"],ye=[].concat(fe,_e,he) +;function we(e){const n=e.regex,t=be,a={begin:/<[A-Za-z0-9\\._:-]+/, +end:/\/[A-Za-z0-9\\._:-]+>|\/>/,isTrulyOpeningTag:(e,n)=>{ +const t=e[0].length+e.index,a=e.input[t] +;if("<"===a||","===a)return void n.ignoreMatch();let i +;">"===a&&(((e,{after:n})=>{const t="",k={ +match:[/const|var|let/,/\s+/,t,/\s*/,/=\s*/,/(async\s*)?/,n.lookahead(O)], +keywords:"async",className:{1:"keyword",3:"title.function"},contains:[_]} +;return{name:"Javascript",aliases:["js","jsx","mjs","cjs"],keywords:i,exports:{ +PARAMS_CONTAINS:p,CLASS_REFERENCE:f},illegal:/#(?![$_A-z])/, +contains:[e.SHEBANG({label:"shebang",binary:"node",relevance:5}),{ +label:"use_strict",className:"meta",relevance:10, +begin:/^\s*['"]use (strict|asm)['"]/ +},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,c,d,g,u,o,f,{className:"attr", +begin:t+n.lookahead(":"),relevance:0},k,{ +begin:"("+e.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*", +keywords:"return throw case",relevance:0,contains:[u,e.REGEXP_MODE,{ +className:"function",begin:O,returnBegin:!0,end:"\\s*=>",contains:[{ +className:"params",variants:[{begin:e.UNDERSCORE_IDENT_RE,relevance:0},{ +className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0, +excludeEnd:!0,keywords:i,contains:p}]}]},{begin:/,/,relevance:0},{match:/\s+/, +relevance:0},{variants:[{begin:"<>",end:""},{ +match:/<[A-Za-z0-9\\._:-]+\s*\/>/},{begin:a.begin, +"on:begin":a.isTrulyOpeningTag,end:a.end}],subLanguage:"xml",contains:[{ +begin:a.begin,end:a.end,skip:!0,contains:["self"]}]}]},E,{ +beginKeywords:"while if switch catch for"},{ +begin:"\\b(?!function)"+e.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{", +returnBegin:!0,label:"func.def",contains:[_,e.inherit(e.TITLE_MODE,{begin:t, +className:"title.function"})]},{match:/\.\.\./,relevance:0},N,{match:"\\$"+t, +relevance:0},{match:[/\bconstructor(?=\s*\()/],className:{1:"title.function"}, +contains:[_]},y,{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/, +className:"variable.constant"},h,v,{match:/\$[(.]/}]}} +const Ne=e=>m(/\b/,e,/\w$/.test(e)?/\b/:/\B/),ve=["Protocol","Type"].map(Ne),Oe=["init","self"].map(Ne),ke=["Any","Self"],xe=["actor","any","associatedtype","async","await",/as\?/,/as!/,"as","break","case","catch","class","continue","convenience","default","defer","deinit","didSet","distributed","do","dynamic","else","enum","extension","fallthrough",/fileprivate\(set\)/,"fileprivate","final","for","func","get","guard","if","import","indirect","infix",/init\?/,/init!/,"inout",/internal\(set\)/,"internal","in","is","isolated","nonisolated","lazy","let","mutating","nonmutating",/open\(set\)/,"open","operator","optional","override","postfix","precedencegroup","prefix",/private\(set\)/,"private","protocol",/public\(set\)/,"public","repeat","required","rethrows","return","set","some","static","struct","subscript","super","switch","throws","throw",/try\?/,/try!/,"try","typealias",/unowned\(safe\)/,/unowned\(unsafe\)/,"unowned","var","weak","where","while","willSet"],Me=["false","nil","true"],Se=["assignment","associativity","higherThan","left","lowerThan","none","right"],Ae=["#colorLiteral","#column","#dsohandle","#else","#elseif","#endif","#error","#file","#fileID","#fileLiteral","#filePath","#function","#if","#imageLiteral","#keyPath","#line","#selector","#sourceLocation","#warn_unqualified_access","#warning"],Ce=["abs","all","any","assert","assertionFailure","debugPrint","dump","fatalError","getVaList","isKnownUniquelyReferenced","max","min","numericCast","pointwiseMax","pointwiseMin","precondition","preconditionFailure","print","readLine","repeatElement","sequence","stride","swap","swift_unboxFromSwiftValueWithType","transcode","type","unsafeBitCast","unsafeDowncast","withExtendedLifetime","withUnsafeMutablePointer","withUnsafePointer","withVaList","withoutActuallyEscaping","zip"],Te=p(/[/=\-+!*%<>&|^~?]/,/[\u00A1-\u00A7]/,/[\u00A9\u00AB]/,/[\u00AC\u00AE]/,/[\u00B0\u00B1]/,/[\u00B6\u00BB\u00BF\u00D7\u00F7]/,/[\u2016-\u2017]/,/[\u2020-\u2027]/,/[\u2030-\u203E]/,/[\u2041-\u2053]/,/[\u2055-\u205E]/,/[\u2190-\u23FF]/,/[\u2500-\u2775]/,/[\u2794-\u2BFF]/,/[\u2E00-\u2E7F]/,/[\u3001-\u3003]/,/[\u3008-\u3020]/,/[\u3030]/),Re=p(Te,/[\u0300-\u036F]/,/[\u1DC0-\u1DFF]/,/[\u20D0-\u20FF]/,/[\uFE00-\uFE0F]/,/[\uFE20-\uFE2F]/),De=m(Te,Re,"*"),Ie=p(/[a-zA-Z_]/,/[\u00A8\u00AA\u00AD\u00AF\u00B2-\u00B5\u00B7-\u00BA]/,/[\u00BC-\u00BE\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]/,/[\u0100-\u02FF\u0370-\u167F\u1681-\u180D\u180F-\u1DBF]/,/[\u1E00-\u1FFF]/,/[\u200B-\u200D\u202A-\u202E\u203F-\u2040\u2054\u2060-\u206F]/,/[\u2070-\u20CF\u2100-\u218F\u2460-\u24FF\u2776-\u2793]/,/[\u2C00-\u2DFF\u2E80-\u2FFF]/,/[\u3004-\u3007\u3021-\u302F\u3031-\u303F\u3040-\uD7FF]/,/[\uF900-\uFD3D\uFD40-\uFDCF\uFDF0-\uFE1F\uFE30-\uFE44]/,/[\uFE47-\uFEFE\uFF00-\uFFFD]/),Le=p(Ie,/\d/,/[\u0300-\u036F\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]/),Be=m(Ie,Le,"*"),$e=m(/[A-Z]/,Le,"*"),ze=["autoclosure",m(/convention\(/,p("swift","block","c"),/\)/),"discardableResult","dynamicCallable","dynamicMemberLookup","escaping","frozen","GKInspectable","IBAction","IBDesignable","IBInspectable","IBOutlet","IBSegueAction","inlinable","main","nonobjc","NSApplicationMain","NSCopying","NSManaged",m(/objc\(/,Be,/\)/),"objc","objcMembers","propertyWrapper","requires_stored_property_inits","resultBuilder","testable","UIApplicationMain","unknown","usableFromInline"],Fe=["iOS","iOSApplicationExtension","macOS","macOSApplicationExtension","macCatalyst","macCatalystApplicationExtension","watchOS","watchOSApplicationExtension","tvOS","tvOSApplicationExtension","swift"] +;var Ue=Object.freeze({__proto__:null,grmr_bash:e=>{const n=e.regex,t={},a={ +begin:/\$\{/,end:/\}/,contains:["self",{begin:/:-/,contains:[t]}]} +;Object.assign(t,{className:"variable",variants:[{ +begin:n.concat(/\$[\w\d#@][\w\d_]*/,"(?![\\w\\d])(?![$])")},a]});const i={ +className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]},r={ +begin:/<<-?\s*(?=\w+)/,starts:{contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/, +end:/(\w+)/,className:"string"})]}},s={className:"string",begin:/"/,end:/"/, +contains:[e.BACKSLASH_ESCAPE,t,i]};i.contains.push(s);const o={begin:/\$\(\(/, +end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,t] +},l=e.SHEBANG({binary:"(fish|bash|zsh|sh|csh|ksh|tcsh|dash|scsh)",relevance:10 +}),c={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0, +contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{ +name:"Bash",aliases:["sh"],keywords:{$pattern:/\b[a-z][a-z0-9._-]+\b/, +keyword:["if","then","else","elif","fi","for","while","in","do","done","case","esac","function"], +literal:["true","false"], +built_in:["break","cd","continue","eval","exec","exit","export","getopts","hash","pwd","readonly","return","shift","test","times","trap","umask","unset","alias","bind","builtin","caller","command","declare","echo","enable","help","let","local","logout","mapfile","printf","read","readarray","source","type","typeset","ulimit","unalias","set","shopt","autoload","bg","bindkey","bye","cap","chdir","clone","comparguments","compcall","compctl","compdescribe","compfiles","compgroups","compquote","comptags","comptry","compvalues","dirs","disable","disown","echotc","echoti","emulate","fc","fg","float","functions","getcap","getln","history","integer","jobs","kill","limit","log","noglob","popd","print","pushd","pushln","rehash","sched","setcap","setopt","stat","suspend","ttyctl","unfunction","unhash","unlimit","unsetopt","vared","wait","whence","where","which","zcompile","zformat","zftp","zle","zmodload","zparseopts","zprof","zpty","zregexparse","zsocket","zstyle","ztcp","chcon","chgrp","chown","chmod","cp","dd","df","dir","dircolors","ln","ls","mkdir","mkfifo","mknod","mktemp","mv","realpath","rm","rmdir","shred","sync","touch","truncate","vdir","b2sum","base32","base64","cat","cksum","comm","csplit","cut","expand","fmt","fold","head","join","md5sum","nl","numfmt","od","paste","ptx","pr","sha1sum","sha224sum","sha256sum","sha384sum","sha512sum","shuf","sort","split","sum","tac","tail","tr","tsort","unexpand","uniq","wc","arch","basename","chroot","date","dirname","du","echo","env","expr","factor","groups","hostid","id","link","logname","nice","nohup","nproc","pathchk","pinky","printenv","printf","pwd","readlink","runcon","seq","sleep","stat","stdbuf","stty","tee","test","timeout","tty","uname","unlink","uptime","users","who","whoami","yes"] +},contains:[l,e.SHEBANG(),c,o,e.HASH_COMMENT_MODE,r,{match:/(\/[a-z._-]+)+/},s,{ +className:"",begin:/\\"/},{className:"string",begin:/'/,end:/'/},t]}}, +grmr_c:e=>{const n=e.regex,t=e.COMMENT("//","$",{contains:[{begin:/\\\n/}] +}),a="[a-zA-Z_]\\w*::",i="(decltype\\(auto\\)|"+n.optional(a)+"[a-zA-Z_]\\w*"+n.optional("<[^<>]+>")+")",r={ +className:"type",variants:[{begin:"\\b[a-z\\d_]*_t\\b"},{ +match:/\batomic_[a-z]{3,6}\b/}]},s={className:"string",variants:[{ +begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{ +begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)", +end:"'",illegal:"."},e.END_SAME_AS_BEGIN({ +begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},o={ +className:"number",variants:[{begin:"\\b(0b[01']+)"},{ +begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)" +},{ +begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)" +}],relevance:0},l={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{ +keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include" +},contains:[{begin:/\\\n/,relevance:0},e.inherit(s,{className:"string"}),{ +className:"string",begin:/<.*?>/},t,e.C_BLOCK_COMMENT_MODE]},c={ +className:"title",begin:n.optional(a)+e.IDENT_RE,relevance:0 +},d=n.optional(a)+e.IDENT_RE+"\\s*\\(",g={ +keyword:["asm","auto","break","case","continue","default","do","else","enum","extern","for","fortran","goto","if","inline","register","restrict","return","sizeof","struct","switch","typedef","union","volatile","while","_Alignas","_Alignof","_Atomic","_Generic","_Noreturn","_Static_assert","_Thread_local","alignas","alignof","noreturn","static_assert","thread_local","_Pragma"], +type:["float","double","signed","unsigned","int","short","long","char","void","_Bool","_Complex","_Imaginary","_Decimal32","_Decimal64","_Decimal128","const","static","complex","bool","imaginary"], +literal:"true false NULL", +built_in:"std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr" +},u=[l,r,t,e.C_BLOCK_COMMENT_MODE,o,s],b={variants:[{begin:/=/,end:/;/},{ +begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}], +keywords:g,contains:u.concat([{begin:/\(/,end:/\)/,keywords:g, +contains:u.concat(["self"]),relevance:0}]),relevance:0},m={ +begin:"("+i+"[\\*&\\s]+)+"+d,returnBegin:!0,end:/[{;=]/,excludeEnd:!0, +keywords:g,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:"decltype\\(auto\\)", +keywords:g,relevance:0},{begin:d,returnBegin:!0,contains:[e.inherit(c,{ +className:"title.function"})],relevance:0},{relevance:0,match:/,/},{ +className:"params",begin:/\(/,end:/\)/,keywords:g,relevance:0, +contains:[t,e.C_BLOCK_COMMENT_MODE,s,o,r,{begin:/\(/,end:/\)/,keywords:g, +relevance:0,contains:["self",t,e.C_BLOCK_COMMENT_MODE,s,o,r]}] +},r,t,e.C_BLOCK_COMMENT_MODE,l]};return{name:"C",aliases:["h"],keywords:g, +disableAutodetect:!0,illegal:"=]/,contains:[{ +beginKeywords:"final class struct"},e.TITLE_MODE]}]),exports:{preprocessor:l, +strings:s,keywords:g}}},grmr_cpp:e=>{const n=e.regex,t=e.COMMENT("//","$",{ +contains:[{begin:/\\\n/}] +}),a="[a-zA-Z_]\\w*::",i="(?!struct)(decltype\\(auto\\)|"+n.optional(a)+"[a-zA-Z_]\\w*"+n.optional("<[^<>]+>")+")",r={ +className:"type",begin:"\\b[a-z\\d_]*_t\\b"},s={className:"string",variants:[{ +begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{ +begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)", +end:"'",illegal:"."},e.END_SAME_AS_BEGIN({ +begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},o={ +className:"number",variants:[{begin:"\\b(0b[01']+)"},{ +begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)" +},{ +begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)" +}],relevance:0},l={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{ +keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include" +},contains:[{begin:/\\\n/,relevance:0},e.inherit(s,{className:"string"}),{ +className:"string",begin:/<.*?>/},t,e.C_BLOCK_COMMENT_MODE]},c={ +className:"title",begin:n.optional(a)+e.IDENT_RE,relevance:0 +},d=n.optional(a)+e.IDENT_RE+"\\s*\\(",g={ +type:["bool","char","char16_t","char32_t","char8_t","double","float","int","long","short","void","wchar_t","unsigned","signed","const","static"], +keyword:["alignas","alignof","and","and_eq","asm","atomic_cancel","atomic_commit","atomic_noexcept","auto","bitand","bitor","break","case","catch","class","co_await","co_return","co_yield","compl","concept","const_cast|10","consteval","constexpr","constinit","continue","decltype","default","delete","do","dynamic_cast|10","else","enum","explicit","export","extern","false","final","for","friend","goto","if","import","inline","module","mutable","namespace","new","noexcept","not","not_eq","nullptr","operator","or","or_eq","override","private","protected","public","reflexpr","register","reinterpret_cast|10","requires","return","sizeof","static_assert","static_cast|10","struct","switch","synchronized","template","this","thread_local","throw","transaction_safe","transaction_safe_dynamic","true","try","typedef","typeid","typename","union","using","virtual","volatile","while","xor","xor_eq"], +literal:["NULL","false","nullopt","nullptr","true"],built_in:["_Pragma"], +_type_hints:["any","auto_ptr","barrier","binary_semaphore","bitset","complex","condition_variable","condition_variable_any","counting_semaphore","deque","false_type","future","imaginary","initializer_list","istringstream","jthread","latch","lock_guard","multimap","multiset","mutex","optional","ostringstream","packaged_task","pair","promise","priority_queue","queue","recursive_mutex","recursive_timed_mutex","scoped_lock","set","shared_future","shared_lock","shared_mutex","shared_timed_mutex","shared_ptr","stack","string_view","stringstream","timed_mutex","thread","true_type","tuple","unique_lock","unique_ptr","unordered_map","unordered_multimap","unordered_multiset","unordered_set","variant","vector","weak_ptr","wstring","wstring_view"] +},u={className:"function.dispatch",relevance:0,keywords:{ +_hint:["abort","abs","acos","apply","as_const","asin","atan","atan2","calloc","ceil","cerr","cin","clog","cos","cosh","cout","declval","endl","exchange","exit","exp","fabs","floor","fmod","forward","fprintf","fputs","free","frexp","fscanf","future","invoke","isalnum","isalpha","iscntrl","isdigit","isgraph","islower","isprint","ispunct","isspace","isupper","isxdigit","labs","launder","ldexp","log","log10","make_pair","make_shared","make_shared_for_overwrite","make_tuple","make_unique","malloc","memchr","memcmp","memcpy","memset","modf","move","pow","printf","putchar","puts","realloc","scanf","sin","sinh","snprintf","sprintf","sqrt","sscanf","std","stderr","stdin","stdout","strcat","strchr","strcmp","strcpy","strcspn","strlen","strncat","strncmp","strncpy","strpbrk","strrchr","strspn","strstr","swap","tan","tanh","terminate","to_underlying","tolower","toupper","vfprintf","visit","vprintf","vsprintf"] +}, +begin:n.concat(/\b/,/(?!decltype)/,/(?!if)/,/(?!for)/,/(?!switch)/,/(?!while)/,e.IDENT_RE,n.lookahead(/(<[^<>]+>|)\s*\(/)) +},b=[u,l,r,t,e.C_BLOCK_COMMENT_MODE,o,s],m={variants:[{begin:/=/,end:/;/},{ +begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}], +keywords:g,contains:b.concat([{begin:/\(/,end:/\)/,keywords:g, +contains:b.concat(["self"]),relevance:0}]),relevance:0},p={className:"function", +begin:"("+i+"[\\*&\\s]+)+"+d,returnBegin:!0,end:/[{;=]/,excludeEnd:!0, +keywords:g,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:"decltype\\(auto\\)", +keywords:g,relevance:0},{begin:d,returnBegin:!0,contains:[c],relevance:0},{ +begin:/::/,relevance:0},{begin:/:/,endsWithParent:!0,contains:[s,o]},{ +relevance:0,match:/,/},{className:"params",begin:/\(/,end:/\)/,keywords:g, +relevance:0,contains:[t,e.C_BLOCK_COMMENT_MODE,s,o,r,{begin:/\(/,end:/\)/, +keywords:g,relevance:0,contains:["self",t,e.C_BLOCK_COMMENT_MODE,s,o,r]}] +},r,t,e.C_BLOCK_COMMENT_MODE,l]};return{name:"C++", +aliases:["cc","c++","h++","hpp","hh","hxx","cxx"],keywords:g,illegal:"",keywords:g,contains:["self",r]},{begin:e.IDENT_RE+"::",keywords:g},{ +match:[/\b(?:enum(?:\s+(?:class|struct))?|class|struct|union)/,/\s+/,/\w+/], +className:{1:"keyword",3:"title.class"}}])}},grmr_csharp:e=>{const n={ +keyword:["abstract","as","base","break","case","catch","class","const","continue","do","else","event","explicit","extern","finally","fixed","for","foreach","goto","if","implicit","in","interface","internal","is","lock","namespace","new","operator","out","override","params","private","protected","public","readonly","record","ref","return","scoped","sealed","sizeof","stackalloc","static","struct","switch","this","throw","try","typeof","unchecked","unsafe","using","virtual","void","volatile","while"].concat(["add","alias","and","ascending","async","await","by","descending","equals","from","get","global","group","init","into","join","let","nameof","not","notnull","on","or","orderby","partial","remove","select","set","unmanaged","value|0","var","when","where","with","yield"]), +built_in:["bool","byte","char","decimal","delegate","double","dynamic","enum","float","int","long","nint","nuint","object","sbyte","short","string","ulong","uint","ushort"], +literal:["default","false","null","true"]},t=e.inherit(e.TITLE_MODE,{ +begin:"[a-zA-Z](\\.?\\w)*"}),a={className:"number",variants:[{ +begin:"\\b(0b[01']+)"},{ +begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{ +begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)" +}],relevance:0},i={className:"string",begin:'@"',end:'"',contains:[{begin:'""'}] +},r=e.inherit(i,{illegal:/\n/}),s={className:"subst",begin:/\{/,end:/\}/, +keywords:n},o=e.inherit(s,{illegal:/\n/}),l={className:"string",begin:/\$"/, +end:'"',illegal:/\n/,contains:[{begin:/\{\{/},{begin:/\}\}/ +},e.BACKSLASH_ESCAPE,o]},c={className:"string",begin:/\$@"/,end:'"',contains:[{ +begin:/\{\{/},{begin:/\}\}/},{begin:'""'},s]},d=e.inherit(c,{illegal:/\n/, +contains:[{begin:/\{\{/},{begin:/\}\}/},{begin:'""'},o]}) +;s.contains=[c,l,i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.C_BLOCK_COMMENT_MODE], +o.contains=[d,l,r,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.inherit(e.C_BLOCK_COMMENT_MODE,{ +illegal:/\n/})];const g={variants:[c,l,i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE] +},u={begin:"<",end:">",contains:[{beginKeywords:"in out"},t] +},b=e.IDENT_RE+"(<"+e.IDENT_RE+"(\\s*,\\s*"+e.IDENT_RE+")*>)?(\\[\\])?",m={ +begin:"@"+e.IDENT_RE,relevance:0};return{name:"C#",aliases:["cs","c#"], +keywords:n,illegal:/::/,contains:[e.COMMENT("///","$",{returnBegin:!0, +contains:[{className:"doctag",variants:[{begin:"///",relevance:0},{ +begin:"\x3c!--|--\x3e"},{begin:""}]}] +}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"meta",begin:"#", +end:"$",keywords:{ +keyword:"if else elif endif define undef warning error line region endregion pragma checksum" +}},g,a,{beginKeywords:"class interface",relevance:0,end:/[{;=]/, +illegal:/[^\s:,]/,contains:[{beginKeywords:"where class" +},t,u,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{beginKeywords:"namespace", +relevance:0,end:/[{;=]/,illegal:/[^\s:]/, +contains:[t,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{ +beginKeywords:"record",relevance:0,end:/[{;=]/,illegal:/[^\s:]/, +contains:[t,u,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"meta", +begin:"^\\s*\\[(?=[\\w])",excludeBegin:!0,end:"\\]",excludeEnd:!0,contains:[{ +className:"string",begin:/"/,end:/"/}]},{ +beginKeywords:"new return throw await else",relevance:0},{className:"function", +begin:"("+b+"\\s+)+"+e.IDENT_RE+"\\s*(<[^=]+>\\s*)?\\(",returnBegin:!0, +end:/\s*[{;=]/,excludeEnd:!0,keywords:n,contains:[{ +beginKeywords:"public private protected static internal protected abstract async extern override unsafe virtual new sealed partial", +relevance:0},{begin:e.IDENT_RE+"\\s*(<[^=]+>\\s*)?\\(",returnBegin:!0, +contains:[e.TITLE_MODE,u],relevance:0},{match:/\(\)/},{className:"params", +begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:n,relevance:0, +contains:[g,a,e.C_BLOCK_COMMENT_MODE] +},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},m]}},grmr_css:e=>{ +const n=e.regex,t=te(e),a=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE];return{ +name:"CSS",case_insensitive:!0,illegal:/[=|'\$]/,keywords:{ +keyframePosition:"from to"},classNameAliases:{keyframePosition:"selector-tag"}, +contains:[t.BLOCK_COMMENT,{begin:/-(webkit|moz|ms|o)-(?=[a-z])/ +},t.CSS_NUMBER_MODE,{className:"selector-id",begin:/#[A-Za-z0-9_-]+/,relevance:0 +},{className:"selector-class",begin:"\\.[a-zA-Z-][a-zA-Z0-9_-]*",relevance:0 +},t.ATTRIBUTE_SELECTOR_MODE,{className:"selector-pseudo",variants:[{ +begin:":("+re.join("|")+")"},{begin:":(:)?("+se.join("|")+")"}] +},t.CSS_VARIABLE,{className:"attribute",begin:"\\b("+oe.join("|")+")\\b"},{ +begin:/:/,end:/[;}{]/, +contains:[t.BLOCK_COMMENT,t.HEXCOLOR,t.IMPORTANT,t.CSS_NUMBER_MODE,...a,{ +begin:/(url|data-uri)\(/,end:/\)/,relevance:0,keywords:{built_in:"url data-uri" +},contains:[...a,{className:"string",begin:/[^)]/,endsWithParent:!0, +excludeEnd:!0}]},t.FUNCTION_DISPATCH]},{begin:n.lookahead(/@/),end:"[{;]", +relevance:0,illegal:/:/,contains:[{className:"keyword",begin:/@-?\w[\w]*(-\w+)*/ +},{begin:/\s/,endsWithParent:!0,excludeEnd:!0,relevance:0,keywords:{ +$pattern:/[a-z-]+/,keyword:"and or not only",attribute:ie.join(" ")},contains:[{ +begin:/[a-z-]+(?=:)/,className:"attribute"},...a,t.CSS_NUMBER_MODE]}]},{ +className:"selector-tag",begin:"\\b("+ae.join("|")+")\\b"}]}},grmr_diff:e=>{ +const n=e.regex;return{name:"Diff",aliases:["patch"],contains:[{ +className:"meta",relevance:10, +match:n.either(/^@@ +-\d+,\d+ +\+\d+,\d+ +@@/,/^\*\*\* +\d+,\d+ +\*\*\*\*$/,/^--- +\d+,\d+ +----$/) +},{className:"comment",variants:[{ +begin:n.either(/Index: /,/^index/,/={3,}/,/^-{3}/,/^\*{3} /,/^\+{3}/,/^diff --git/), +end:/$/},{match:/^\*{15}$/}]},{className:"addition",begin:/^\+/,end:/$/},{ +className:"deletion",begin:/^-/,end:/$/},{className:"addition",begin:/^!/, +end:/$/}]}},grmr_go:e=>{const n={ +keyword:["break","case","chan","const","continue","default","defer","else","fallthrough","for","func","go","goto","if","import","interface","map","package","range","return","select","struct","switch","type","var"], +type:["bool","byte","complex64","complex128","error","float32","float64","int8","int16","int32","int64","string","uint8","uint16","uint32","uint64","int","uint","uintptr","rune"], +literal:["true","false","iota","nil"], +built_in:["append","cap","close","complex","copy","imag","len","make","new","panic","print","println","real","recover","delete"] +};return{name:"Go",aliases:["golang"],keywords:n,illegal:"{const n=e.regex;return{name:"GraphQL",aliases:["gql"], +case_insensitive:!0,disableAutodetect:!1,keywords:{ +keyword:["query","mutation","subscription","type","input","schema","directive","interface","union","scalar","fragment","enum","on"], +literal:["true","false","null"]}, +contains:[e.HASH_COMMENT_MODE,e.QUOTE_STRING_MODE,e.NUMBER_MODE,{ +scope:"punctuation",match:/[.]{3}/,relevance:0},{scope:"punctuation", +begin:/[\!\(\)\:\=\[\]\{\|\}]{1}/,relevance:0},{scope:"variable",begin:/\$/, +end:/\W/,excludeEnd:!0,relevance:0},{scope:"meta",match:/@\w+/,excludeEnd:!0},{ +scope:"symbol",begin:n.concat(/[_A-Za-z][_0-9A-Za-z]*/,n.lookahead(/\s*:/)), +relevance:0}],illegal:[/[;<']/,/BEGIN/]}},grmr_ini:e=>{const n=e.regex,t={ +className:"number",relevance:0,variants:[{begin:/([+-]+)?[\d]+_[\d_]+/},{ +begin:e.NUMBER_RE}]},a=e.COMMENT();a.variants=[{begin:/;/,end:/$/},{begin:/#/, +end:/$/}];const i={className:"variable",variants:[{begin:/\$[\w\d"][\w\d_]*/},{ +begin:/\$\{(.*?)\}/}]},r={className:"literal", +begin:/\bon|off|true|false|yes|no\b/},s={className:"string", +contains:[e.BACKSLASH_ESCAPE],variants:[{begin:"'''",end:"'''",relevance:10},{ +begin:'"""',end:'"""',relevance:10},{begin:'"',end:'"'},{begin:"'",end:"'"}] +},o={begin:/\[/,end:/\]/,contains:[a,r,i,s,t,"self"],relevance:0 +},l=n.either(/[A-Za-z0-9_-]+/,/"(\\"|[^"])*"/,/'[^']*'/);return{ +name:"TOML, also INI",aliases:["toml"],case_insensitive:!0,illegal:/\S/, +contains:[a,{className:"section",begin:/\[+/,end:/\]+/},{ +begin:n.concat(l,"(\\s*\\.\\s*",l,")*",n.lookahead(/\s*=\s*[^#\s]/)), +className:"attr",starts:{end:/$/,contains:[a,o,r,i,s,t]}}]}},grmr_java:e=>{ +const n=e.regex,t="[\xc0-\u02b8a-zA-Z_$][\xc0-\u02b8a-zA-Z_$0-9]*",a=t+ue("(?:<"+t+"~~~(?:\\s*,\\s*"+t+"~~~)*>)?",/~~~/g,2),i={ +keyword:["synchronized","abstract","private","var","static","if","const ","for","while","strictfp","finally","protected","import","native","final","void","enum","else","break","transient","catch","instanceof","volatile","case","assert","package","default","public","try","switch","continue","throws","protected","public","private","module","requires","exports","do","sealed"], +literal:["false","true","null"], +type:["char","boolean","long","float","int","byte","short","double"], +built_in:["super","this"]},r={className:"meta",begin:"@"+t,contains:[{ +begin:/\(/,end:/\)/,contains:["self"]}]},s={className:"params",begin:/\(/, +end:/\)/,keywords:i,relevance:0,contains:[e.C_BLOCK_COMMENT_MODE],endsParent:!0} +;return{name:"Java",aliases:["jsp"],keywords:i,illegal:/<\/|#/, +contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{begin:/\w+@/, +relevance:0},{className:"doctag",begin:"@[A-Za-z]+"}]}),{ +begin:/import java\.[a-z]+\./,keywords:"import",relevance:2 +},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{begin:/"""/,end:/"""/, +className:"string",contains:[e.BACKSLASH_ESCAPE] +},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{ +match:[/\b(?:class|interface|enum|extends|implements|new)/,/\s+/,t],className:{ +1:"keyword",3:"title.class"}},{match:/non-sealed/,scope:"keyword"},{ +begin:[n.concat(/(?!else)/,t),/\s+/,t,/\s+/,/=(?!=)/],className:{1:"type", +3:"variable",5:"operator"}},{begin:[/record/,/\s+/,t],className:{1:"keyword", +3:"title.class"},contains:[s,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{ +beginKeywords:"new throw return else",relevance:0},{ +begin:["(?:"+a+"\\s+)",e.UNDERSCORE_IDENT_RE,/\s*(?=\()/],className:{ +2:"title.function"},keywords:i,contains:[{className:"params",begin:/\(/, +end:/\)/,keywords:i,relevance:0, +contains:[r,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,ge,e.C_BLOCK_COMMENT_MODE] +},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},ge,r]}},grmr_javascript:we, +grmr_json:e=>{const n=["true","false","null"],t={scope:"literal", +beginKeywords:n.join(" ")};return{name:"JSON",keywords:{literal:n},contains:[{ +className:"attr",begin:/"(\\.|[^\\"\r\n])*"(?=\s*:)/,relevance:1.01},{ +match:/[{}[\],:]/,className:"punctuation",relevance:0 +},e.QUOTE_STRING_MODE,t,e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE], +illegal:"\\S"}},grmr_kotlin:e=>{const n={ +keyword:"abstract as val var vararg get set class object open private protected public noinline crossinline dynamic final enum if else do while for when throw try catch finally import package is in fun override companion reified inline lateinit init interface annotation data sealed internal infix operator out by constructor super tailrec where const inner suspend typealias external expect actual", +built_in:"Byte Short Char Int Long Boolean Float Double Void Unit Nothing", +literal:"true false null"},t={className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"@" +},a={className:"subst",begin:/\$\{/,end:/\}/,contains:[e.C_NUMBER_MODE]},i={ +className:"variable",begin:"\\$"+e.UNDERSCORE_IDENT_RE},r={className:"string", +variants:[{begin:'"""',end:'"""(?=[^"])',contains:[i,a]},{begin:"'",end:"'", +illegal:/\n/,contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"',illegal:/\n/, +contains:[e.BACKSLASH_ESCAPE,i,a]}]};a.contains.push(r);const s={ +className:"meta", +begin:"@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*"+e.UNDERSCORE_IDENT_RE+")?" +},o={className:"meta",begin:"@"+e.UNDERSCORE_IDENT_RE,contains:[{begin:/\(/, +end:/\)/,contains:[e.inherit(r,{className:"string"}),"self"]}] +},l=ge,c=e.COMMENT("/\\*","\\*/",{contains:[e.C_BLOCK_COMMENT_MODE]}),d={ +variants:[{className:"type",begin:e.UNDERSCORE_IDENT_RE},{begin:/\(/,end:/\)/, +contains:[]}]},g=d;return g.variants[1].contains=[d],d.variants[1].contains=[g], +{name:"Kotlin",aliases:["kt","kts"],keywords:n, +contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{className:"doctag", +begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,c,{className:"keyword", +begin:/\b(break|continue|return|this)\b/,starts:{contains:[{className:"symbol", +begin:/@\w+/}]}},t,s,o,{className:"function",beginKeywords:"fun",end:"[(]|$", +returnBegin:!0,excludeEnd:!0,keywords:n,relevance:5,contains:[{ +begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0, +contains:[e.UNDERSCORE_TITLE_MODE]},{className:"type",begin://, +keywords:"reified",relevance:0},{className:"params",begin:/\(/,end:/\)/, +endsParent:!0,keywords:n,relevance:0,contains:[{begin:/:/,end:/[=,\/]/, +endsWithParent:!0,contains:[d,e.C_LINE_COMMENT_MODE,c],relevance:0 +},e.C_LINE_COMMENT_MODE,c,s,o,r,e.C_NUMBER_MODE]},c]},{ +begin:[/class|interface|trait/,/\s+/,e.UNDERSCORE_IDENT_RE],beginScope:{ +3:"title.class"},keywords:"class interface trait",end:/[:\{(]|$/,excludeEnd:!0, +illegal:"extends implements",contains:[{ +beginKeywords:"public protected internal private constructor" +},e.UNDERSCORE_TITLE_MODE,{className:"type",begin://,excludeBegin:!0, +excludeEnd:!0,relevance:0},{className:"type",begin:/[,:]\s*/,end:/[<\(,){\s]|$/, +excludeBegin:!0,returnEnd:!0},s,o]},r,{className:"meta",begin:"^#!/usr/bin/env", +end:"$",illegal:"\n"},l]}},grmr_less:e=>{ +const n=te(e),t=le,a="([\\w-]+|@\\{[\\w-]+\\})",i=[],r=[],s=e=>({ +className:"string",begin:"~?"+e+".*?"+e}),o=(e,n,t)=>({className:e,begin:n, +relevance:t}),l={$pattern:/[a-z-]+/,keyword:"and or not only", +attribute:ie.join(" ")},c={begin:"\\(",end:"\\)",contains:r,keywords:l, +relevance:0} +;r.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,s("'"),s('"'),n.CSS_NUMBER_MODE,{ +begin:"(url|data-uri)\\(",starts:{className:"string",end:"[\\)\\n]", +excludeEnd:!0} +},n.HEXCOLOR,c,o("variable","@@?[\\w-]+",10),o("variable","@\\{[\\w-]+\\}"),o("built_in","~?`[^`]*?`"),{ +className:"attribute",begin:"[\\w-]+\\s*:",end:":",returnBegin:!0,excludeEnd:!0 +},n.IMPORTANT,{beginKeywords:"and not"},n.FUNCTION_DISPATCH);const d=r.concat({ +begin:/\{/,end:/\}/,contains:i}),g={beginKeywords:"when",endsWithParent:!0, +contains:[{beginKeywords:"and not"}].concat(r)},u={begin:a+"\\s*:", +returnBegin:!0,end:/[;}]/,relevance:0,contains:[{begin:/-(webkit|moz|ms|o)-/ +},n.CSS_VARIABLE,{className:"attribute",begin:"\\b("+oe.join("|")+")\\b", +end:/(?=:)/,starts:{endsWithParent:!0,illegal:"[<=$]",relevance:0,contains:r}}] +},b={className:"keyword", +begin:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b", +starts:{end:"[;{}]",keywords:l,returnEnd:!0,contains:r,relevance:0}},m={ +className:"variable",variants:[{begin:"@[\\w-]+\\s*:",relevance:15},{ +begin:"@[\\w-]+"}],starts:{end:"[;}]",returnEnd:!0,contains:d}},p={variants:[{ +begin:"[\\.#:&\\[>]",end:"[;{}]"},{begin:a,end:/\{/}],returnBegin:!0, +returnEnd:!0,illegal:"[<='$\"]",relevance:0, +contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,g,o("keyword","all\\b"),o("variable","@\\{[\\w-]+\\}"),{ +begin:"\\b("+ae.join("|")+")\\b",className:"selector-tag" +},n.CSS_NUMBER_MODE,o("selector-tag",a,0),o("selector-id","#"+a),o("selector-class","\\."+a,0),o("selector-tag","&",0),n.ATTRIBUTE_SELECTOR_MODE,{ +className:"selector-pseudo",begin:":("+re.join("|")+")"},{ +className:"selector-pseudo",begin:":(:)?("+se.join("|")+")"},{begin:/\(/, +end:/\)/,relevance:0,contains:d},{begin:"!important"},n.FUNCTION_DISPATCH]},_={ +begin:`[\\w-]+:(:)?(${t.join("|")})`,returnBegin:!0,contains:[p]} +;return i.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,b,m,_,u,p,g,n.FUNCTION_DISPATCH), +{name:"Less",case_insensitive:!0,illegal:"[=>'/<($\"]",contains:i}}, +grmr_lua:e=>{const n="\\[=*\\[",t="\\]=*\\]",a={begin:n,end:t,contains:["self"] +},i=[e.COMMENT("--(?!\\[=*\\[)","$"),e.COMMENT("--\\[=*\\[",t,{contains:[a], +relevance:10})];return{name:"Lua",keywords:{$pattern:e.UNDERSCORE_IDENT_RE, +literal:"true false nil", +keyword:"and break do else elseif end for goto if in local not or repeat return then until while", +built_in:"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall arg self coroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove" +},contains:i.concat([{className:"function",beginKeywords:"function",end:"\\)", +contains:[e.inherit(e.TITLE_MODE,{ +begin:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),{className:"params", +begin:"\\(",endsWithParent:!0,contains:i}].concat(i) +},e.C_NUMBER_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"string", +begin:n,end:t,contains:[a],relevance:5}])}},grmr_makefile:e=>{const n={ +className:"variable",variants:[{begin:"\\$\\("+e.UNDERSCORE_IDENT_RE+"\\)", +contains:[e.BACKSLASH_ESCAPE]},{begin:/\$[@%{ +const n=e.regex,t=n.concat(/[\p{L}_]/u,n.optional(/[\p{L}0-9_.-]*:/u),/[\p{L}0-9_.-]*/u),a={ +className:"symbol",begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},i={begin:/\s/, +contains:[{className:"keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}] +},r=e.inherit(i,{begin:/\(/,end:/\)/}),s=e.inherit(e.APOS_STRING_MODE,{ +className:"string"}),o=e.inherit(e.QUOTE_STRING_MODE,{className:"string"}),l={ +endsWithParent:!0,illegal:/`]+/}]}]}]};return{ +name:"HTML, XML", +aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"], +case_insensitive:!0,unicodeRegex:!0,contains:[{className:"meta",begin://,relevance:10,contains:[i,o,s,r,{begin:/\[/,end:/\]/,contains:[{ +className:"meta",begin://,contains:[i,r,o,s]}]}] +},e.COMMENT(//,{relevance:10}),{begin://, +relevance:10},a,{className:"meta",end:/\?>/,variants:[{begin:/<\?xml/, +relevance:10,contains:[o]},{begin:/<\?[a-z][a-z0-9]+/}]},{className:"tag", +begin:/)/,end:/>/,keywords:{name:"style"},contains:[l],starts:{ +end:/<\/style>/,returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag", +begin:/)/,end:/>/,keywords:{name:"script"},contains:[l],starts:{ +end:/<\/script>/,returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{ +className:"tag",begin:/<>|<\/>/},{className:"tag", +begin:n.concat(//,/>/,/\s/)))), +end:/\/?>/,contains:[{className:"name",begin:t,relevance:0,starts:l}]},{ +className:"tag",begin:n.concat(/<\//,n.lookahead(n.concat(t,/>/))),contains:[{ +className:"name",begin:t,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]} +},grmr_markdown:e=>{const n={begin:/<\/?[A-Za-z_]/,end:">",subLanguage:"xml", +relevance:0},t={variants:[{begin:/\[.+?\]\[.*?\]/,relevance:0},{ +begin:/\[.+?\]\(((data|javascript|mailto):|(?:http|ftp)s?:\/\/).*?\)/, +relevance:2},{ +begin:e.regex.concat(/\[.+?\]\(/,/[A-Za-z][A-Za-z0-9+.-]*/,/:\/\/.*?\)/), +relevance:2},{begin:/\[.+?\]\([./?&#].*?\)/,relevance:1},{ +begin:/\[.*?\]\(.*?\)/,relevance:0}],returnBegin:!0,contains:[{match:/\[(?=\])/ +},{className:"string",relevance:0,begin:"\\[",end:"\\]",excludeBegin:!0, +returnEnd:!0},{className:"link",relevance:0,begin:"\\]\\(",end:"\\)", +excludeBegin:!0,excludeEnd:!0},{className:"symbol",relevance:0,begin:"\\]\\[", +end:"\\]",excludeBegin:!0,excludeEnd:!0}]},a={className:"strong",contains:[], +variants:[{begin:/_{2}/,end:/_{2}/},{begin:/\*{2}/,end:/\*{2}/}]},i={ +className:"emphasis",contains:[],variants:[{begin:/\*(?!\*)/,end:/\*/},{ +begin:/_(?!_)/,end:/_/,relevance:0}]},r=e.inherit(a,{contains:[] +}),s=e.inherit(i,{contains:[]});a.contains.push(s),i.contains.push(r) +;let o=[n,t];return[a,i,r,s].forEach((e=>{e.contains=e.contains.concat(o) +})),o=o.concat(a,i),{name:"Markdown",aliases:["md","mkdown","mkd"],contains:[{ +className:"section",variants:[{begin:"^#{1,6}",end:"$",contains:o},{ +begin:"(?=^.+?\\n[=-]{2,}$)",contains:[{begin:"^[=-]*$"},{begin:"^",end:"\\n", +contains:o}]}]},n,{className:"bullet",begin:"^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)", +end:"\\s+",excludeEnd:!0},a,i,{className:"quote",begin:"^>\\s+",contains:o, +end:"$"},{className:"code",variants:[{begin:"(`{3,})[^`](.|\\n)*?\\1`*[ ]*"},{ +begin:"(~{3,})[^~](.|\\n)*?\\1~*[ ]*"},{begin:"```",end:"```+[ ]*$"},{ +begin:"~~~",end:"~~~+[ ]*$"},{begin:"`.+?`"},{begin:"(?=^( {4}|\\t))", +contains:[{begin:"^( {4}|\\t)",end:"(\\n)$"}],relevance:0}]},{ +begin:"^[-\\*]{3,}",end:"$"},t,{begin:/^\[[^\n]+\]:/,returnBegin:!0,contains:[{ +className:"symbol",begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0},{ +className:"link",begin:/:\s*/,end:/$/,excludeBegin:!0}]}]}},grmr_objectivec:e=>{ +const n=/[a-zA-Z@][a-zA-Z0-9_]*/,t={$pattern:n, +keyword:["@interface","@class","@protocol","@implementation"]};return{ +name:"Objective-C",aliases:["mm","objc","obj-c","obj-c++","objective-c++"], +keywords:{"variable.language":["this","super"],$pattern:n, +keyword:["while","export","sizeof","typedef","const","struct","for","union","volatile","static","mutable","if","do","return","goto","enum","else","break","extern","asm","case","default","register","explicit","typename","switch","continue","inline","readonly","assign","readwrite","self","@synchronized","id","typeof","nonatomic","IBOutlet","IBAction","strong","weak","copy","in","out","inout","bycopy","byref","oneway","__strong","__weak","__block","__autoreleasing","@private","@protected","@public","@try","@property","@end","@throw","@catch","@finally","@autoreleasepool","@synthesize","@dynamic","@selector","@optional","@required","@encode","@package","@import","@defs","@compatibility_alias","__bridge","__bridge_transfer","__bridge_retained","__bridge_retain","__covariant","__contravariant","__kindof","_Nonnull","_Nullable","_Null_unspecified","__FUNCTION__","__PRETTY_FUNCTION__","__attribute__","getter","setter","retain","unsafe_unretained","nonnull","nullable","null_unspecified","null_resettable","class","instancetype","NS_DESIGNATED_INITIALIZER","NS_UNAVAILABLE","NS_REQUIRES_SUPER","NS_RETURNS_INNER_POINTER","NS_INLINE","NS_AVAILABLE","NS_DEPRECATED","NS_ENUM","NS_OPTIONS","NS_SWIFT_UNAVAILABLE","NS_ASSUME_NONNULL_BEGIN","NS_ASSUME_NONNULL_END","NS_REFINED_FOR_SWIFT","NS_SWIFT_NAME","NS_SWIFT_NOTHROW","NS_DURING","NS_HANDLER","NS_ENDHANDLER","NS_VALUERETURN","NS_VOIDRETURN"], +literal:["false","true","FALSE","TRUE","nil","YES","NO","NULL"], +built_in:["dispatch_once_t","dispatch_queue_t","dispatch_sync","dispatch_async","dispatch_once"], +type:["int","float","char","unsigned","signed","short","long","double","wchar_t","unichar","void","bool","BOOL","id|0","_Bool"] +},illegal:"/,end:/$/,illegal:"\\n" +},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"class", +begin:"("+t.keyword.join("|")+")\\b",end:/(\{|$)/,excludeEnd:!0,keywords:t, +contains:[e.UNDERSCORE_TITLE_MODE]},{begin:"\\."+e.UNDERSCORE_IDENT_RE, +relevance:0}]}},grmr_perl:e=>{const n=e.regex,t=/[dualxmsipngr]{0,12}/,a={ +$pattern:/[\w.]+/, +keyword:"abs accept alarm and atan2 bind binmode bless break caller chdir chmod chomp chop chown chr chroot close closedir connect continue cos crypt dbmclose dbmopen defined delete die do dump each else elsif endgrent endhostent endnetent endprotoent endpwent endservent eof eval exec exists exit exp fcntl fileno flock for foreach fork format formline getc getgrent getgrgid getgrnam gethostbyaddr gethostbyname gethostent getlogin getnetbyaddr getnetbyname getnetent getpeername getpgrp getpriority getprotobyname getprotobynumber getprotoent getpwent getpwnam getpwuid getservbyname getservbyport getservent getsockname getsockopt given glob gmtime goto grep gt hex if index int ioctl join keys kill last lc lcfirst length link listen local localtime log lstat lt ma map mkdir msgctl msgget msgrcv msgsnd my ne next no not oct open opendir or ord our pack package pipe pop pos print printf prototype push q|0 qq quotemeta qw qx rand read readdir readline readlink readpipe recv redo ref rename require reset return reverse rewinddir rindex rmdir say scalar seek seekdir select semctl semget semop send setgrent sethostent setnetent setpgrp setpriority setprotoent setpwent setservent setsockopt shift shmctl shmget shmread shmwrite shutdown sin sleep socket socketpair sort splice split sprintf sqrt srand stat state study sub substr symlink syscall sysopen sysread sysseek system syswrite tell telldir tie tied time times tr truncate uc ucfirst umask undef unless unlink unpack unshift untie until use utime values vec wait waitpid wantarray warn when while write x|0 xor y|0" +},i={className:"subst",begin:"[$@]\\{",end:"\\}",keywords:a},r={begin:/->\{/, +end:/\}/},s={variants:[{begin:/\$\d/},{ +begin:n.concat(/[$%@](\^\w\b|#\w+(::\w+)*|\{\w+\}|\w+(::\w*)*)/,"(?![A-Za-z])(?![@$%])") +},{begin:/[$%@][^\s\w{]/,relevance:0}] +},o=[e.BACKSLASH_ESCAPE,i,s],l=[/!/,/\//,/\|/,/\?/,/'/,/"/,/#/],c=(e,a,i="\\1")=>{ +const r="\\1"===i?i:n.concat(i,a) +;return n.concat(n.concat("(?:",e,")"),a,/(?:\\.|[^\\\/])*?/,r,/(?:\\.|[^\\\/])*?/,i,t) +},d=(e,a,i)=>n.concat(n.concat("(?:",e,")"),a,/(?:\\.|[^\\\/])*?/,i,t),g=[s,e.HASH_COMMENT_MODE,e.COMMENT(/^=\w/,/=cut/,{ +endsWithParent:!0}),r,{className:"string",contains:o,variants:[{ +begin:"q[qwxr]?\\s*\\(",end:"\\)",relevance:5},{begin:"q[qwxr]?\\s*\\[", +end:"\\]",relevance:5},{begin:"q[qwxr]?\\s*\\{",end:"\\}",relevance:5},{ +begin:"q[qwxr]?\\s*\\|",end:"\\|",relevance:5},{begin:"q[qwxr]?\\s*<",end:">", +relevance:5},{begin:"qw\\s+q",end:"q",relevance:5},{begin:"'",end:"'", +contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"'},{begin:"`",end:"`", +contains:[e.BACKSLASH_ESCAPE]},{begin:/\{\w+\}/,relevance:0},{ +begin:"-?\\w+\\s*=>",relevance:0}]},{className:"number", +begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b", +relevance:0},{ +begin:"(\\/\\/|"+e.RE_STARTERS_RE+"|\\b(split|return|print|reverse|grep)\\b)\\s*", +keywords:"split return print reverse grep",relevance:0, +contains:[e.HASH_COMMENT_MODE,{className:"regexp",variants:[{ +begin:c("s|tr|y",n.either(...l,{capture:!0}))},{begin:c("s|tr|y","\\(","\\)")},{ +begin:c("s|tr|y","\\[","\\]")},{begin:c("s|tr|y","\\{","\\}")}],relevance:2},{ +className:"regexp",variants:[{begin:/(m|qr)\/\//,relevance:0},{ +begin:d("(?:m|qr)?",/\//,/\//)},{begin:d("m|qr",n.either(...l,{capture:!0 +}),/\1/)},{begin:d("m|qr",/\(/,/\)/)},{begin:d("m|qr",/\[/,/\]/)},{ +begin:d("m|qr",/\{/,/\}/)}]}]},{className:"function",beginKeywords:"sub", +end:"(\\s*\\(.*?\\))?[;{]",excludeEnd:!0,relevance:5,contains:[e.TITLE_MODE]},{ +begin:"-\\w\\b",relevance:0},{begin:"^__DATA__$",end:"^__END__$", +subLanguage:"mojolicious",contains:[{begin:"^@@.*",end:"$",className:"comment"}] +}];return i.contains=g,r.contains=g,{name:"Perl",aliases:["pl","pm"],keywords:a, +contains:g}},grmr_php:e=>{ +const n=e.regex,t=/(?![A-Za-z0-9])(?![$])/,a=n.concat(/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/,t),i=n.concat(/(\\?[A-Z][a-z0-9_\x7f-\xff]+|\\?[A-Z]+(?=[A-Z][a-z0-9_\x7f-\xff])){1,}/,t),r={ +scope:"variable",match:"\\$+"+a},s={scope:"subst",variants:[{begin:/\$\w+/},{ +begin:/\{\$/,end:/\}/}]},o=e.inherit(e.APOS_STRING_MODE,{illegal:null +}),l="[ \t\n]",c={scope:"string",variants:[e.inherit(e.QUOTE_STRING_MODE,{ +illegal:null,contains:e.QUOTE_STRING_MODE.contains.concat(s) +}),o,e.END_SAME_AS_BEGIN({begin:/<<<[ \t]*(\w+)\n/,end:/[ \t]*(\w+)\b/, +contains:e.QUOTE_STRING_MODE.contains.concat(s)})]},d={scope:"number", +variants:[{begin:"\\b0[bB][01]+(?:_[01]+)*\\b"},{ +begin:"\\b0[oO][0-7]+(?:_[0-7]+)*\\b"},{ +begin:"\\b0[xX][\\da-fA-F]+(?:_[\\da-fA-F]+)*\\b"},{ +begin:"(?:\\b\\d+(?:_\\d+)*(\\.(?:\\d+(?:_\\d+)*))?|\\B\\.\\d+)(?:[eE][+-]?\\d+)?" +}],relevance:0 +},g=["false","null","true"],u=["__CLASS__","__DIR__","__FILE__","__FUNCTION__","__COMPILER_HALT_OFFSET__","__LINE__","__METHOD__","__NAMESPACE__","__TRAIT__","die","echo","exit","include","include_once","print","require","require_once","array","abstract","and","as","binary","bool","boolean","break","callable","case","catch","class","clone","const","continue","declare","default","do","double","else","elseif","empty","enddeclare","endfor","endforeach","endif","endswitch","endwhile","enum","eval","extends","final","finally","float","for","foreach","from","global","goto","if","implements","instanceof","insteadof","int","integer","interface","isset","iterable","list","match|0","mixed","new","never","object","or","private","protected","public","readonly","real","return","string","switch","throw","trait","try","unset","use","var","void","while","xor","yield"],b=["Error|0","AppendIterator","ArgumentCountError","ArithmeticError","ArrayIterator","ArrayObject","AssertionError","BadFunctionCallException","BadMethodCallException","CachingIterator","CallbackFilterIterator","CompileError","Countable","DirectoryIterator","DivisionByZeroError","DomainException","EmptyIterator","ErrorException","Exception","FilesystemIterator","FilterIterator","GlobIterator","InfiniteIterator","InvalidArgumentException","IteratorIterator","LengthException","LimitIterator","LogicException","MultipleIterator","NoRewindIterator","OutOfBoundsException","OutOfRangeException","OuterIterator","OverflowException","ParentIterator","ParseError","RangeException","RecursiveArrayIterator","RecursiveCachingIterator","RecursiveCallbackFilterIterator","RecursiveDirectoryIterator","RecursiveFilterIterator","RecursiveIterator","RecursiveIteratorIterator","RecursiveRegexIterator","RecursiveTreeIterator","RegexIterator","RuntimeException","SeekableIterator","SplDoublyLinkedList","SplFileInfo","SplFileObject","SplFixedArray","SplHeap","SplMaxHeap","SplMinHeap","SplObjectStorage","SplObserver","SplPriorityQueue","SplQueue","SplStack","SplSubject","SplTempFileObject","TypeError","UnderflowException","UnexpectedValueException","UnhandledMatchError","ArrayAccess","BackedEnum","Closure","Fiber","Generator","Iterator","IteratorAggregate","Serializable","Stringable","Throwable","Traversable","UnitEnum","WeakReference","WeakMap","Directory","__PHP_Incomplete_Class","parent","php_user_filter","self","static","stdClass"],m={ +keyword:u,literal:(e=>{const n=[];return e.forEach((e=>{ +n.push(e),e.toLowerCase()===e?n.push(e.toUpperCase()):n.push(e.toLowerCase()) +})),n})(g),built_in:b},p=e=>e.map((e=>e.replace(/\|\d+$/,""))),_={variants:[{ +match:[/new/,n.concat(l,"+"),n.concat("(?!",p(b).join("\\b|"),"\\b)"),i],scope:{ +1:"keyword",4:"title.class"}}]},h=n.concat(a,"\\b(?!\\()"),f={variants:[{ +match:[n.concat(/::/,n.lookahead(/(?!class\b)/)),h],scope:{2:"variable.constant" +}},{match:[/::/,/class/],scope:{2:"variable.language"}},{ +match:[i,n.concat(/::/,n.lookahead(/(?!class\b)/)),h],scope:{1:"title.class", +3:"variable.constant"}},{match:[i,n.concat("::",n.lookahead(/(?!class\b)/))], +scope:{1:"title.class"}},{match:[i,/::/,/class/],scope:{1:"title.class", +3:"variable.language"}}]},E={scope:"attr", +match:n.concat(a,n.lookahead(":"),n.lookahead(/(?!::)/))},y={relevance:0, +begin:/\(/,end:/\)/,keywords:m,contains:[E,r,f,e.C_BLOCK_COMMENT_MODE,c,d,_] +},w={relevance:0, +match:[/\b/,n.concat("(?!fn\\b|function\\b|",p(u).join("\\b|"),"|",p(b).join("\\b|"),"\\b)"),a,n.concat(l,"*"),n.lookahead(/(?=\()/)], +scope:{3:"title.function.invoke"},contains:[y]};y.contains.push(w) +;const N=[E,f,e.C_BLOCK_COMMENT_MODE,c,d,_];return{case_insensitive:!1, +keywords:m,contains:[{begin:n.concat(/#\[\s*/,i),beginScope:"meta",end:/]/, +endScope:"meta",keywords:{literal:g,keyword:["new","array"]},contains:[{ +begin:/\[/,end:/]/,keywords:{literal:g,keyword:["new","array"]}, +contains:["self",...N]},...N,{scope:"meta",match:i}] +},e.HASH_COMMENT_MODE,e.COMMENT("//","$"),e.COMMENT("/\\*","\\*/",{contains:[{ +scope:"doctag",match:"@[A-Za-z]+"}]}),{match:/__halt_compiler\(\);/, +keywords:"__halt_compiler",starts:{scope:"comment",end:e.MATCH_NOTHING_RE, +contains:[{match:/\?>/,scope:"meta",endsParent:!0}]}},{scope:"meta",variants:[{ +begin:/<\?php/,relevance:10},{begin:/<\?=/},{begin:/<\?/,relevance:.1},{ +begin:/\?>/}]},{scope:"variable.language",match:/\$this\b/},r,w,f,{ +match:[/const/,/\s/,a],scope:{1:"keyword",3:"variable.constant"}},_,{ +scope:"function",relevance:0,beginKeywords:"fn function",end:/[;{]/, +excludeEnd:!0,illegal:"[$%\\[]",contains:[{beginKeywords:"use" +},e.UNDERSCORE_TITLE_MODE,{begin:"=>",endsParent:!0},{scope:"params", +begin:"\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0,keywords:m, +contains:["self",r,f,e.C_BLOCK_COMMENT_MODE,c,d]}]},{scope:"class",variants:[{ +beginKeywords:"enum",illegal:/[($"]/},{beginKeywords:"class interface trait", +illegal:/[:($"]/}],relevance:0,end:/\{/,excludeEnd:!0,contains:[{ +beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{ +beginKeywords:"namespace",relevance:0,end:";",illegal:/[.']/, +contains:[e.inherit(e.UNDERSCORE_TITLE_MODE,{scope:"title.class"})]},{ +beginKeywords:"use",relevance:0,end:";",contains:[{ +match:/\b(as|const|function)\b/,scope:"keyword"},e.UNDERSCORE_TITLE_MODE]},c,d]} +},grmr_php_template:e=>({name:"PHP template",subLanguage:"xml",contains:[{ +begin:/<\?(php|=)?/,end:/\?>/,subLanguage:"php",contains:[{begin:"/\\*", +end:"\\*/",skip:!0},{begin:'b"',end:'"',skip:!0},{begin:"b'",end:"'",skip:!0 +},e.inherit(e.APOS_STRING_MODE,{illegal:null,className:null,contains:null, +skip:!0}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null,className:null, +contains:null,skip:!0})]}]}),grmr_plaintext:e=>({name:"Plain text", +aliases:["text","txt"],disableAutodetect:!0}),grmr_python:e=>{ +const n=e.regex,t=/[\p{XID_Start}_]\p{XID_Continue}*/u,a=["and","as","assert","async","await","break","case","class","continue","def","del","elif","else","except","finally","for","from","global","if","import","in","is","lambda","match","nonlocal|10","not","or","pass","raise","return","try","while","with","yield"],i={ +$pattern:/[A-Za-z]\w+|__\w+__/,keyword:a, +built_in:["__import__","abs","all","any","ascii","bin","bool","breakpoint","bytearray","bytes","callable","chr","classmethod","compile","complex","delattr","dict","dir","divmod","enumerate","eval","exec","filter","float","format","frozenset","getattr","globals","hasattr","hash","help","hex","id","input","int","isinstance","issubclass","iter","len","list","locals","map","max","memoryview","min","next","object","oct","open","ord","pow","print","property","range","repr","reversed","round","set","setattr","slice","sorted","staticmethod","str","sum","super","tuple","type","vars","zip"], +literal:["__debug__","Ellipsis","False","None","NotImplemented","True"], +type:["Any","Callable","Coroutine","Dict","List","Literal","Generic","Optional","Sequence","Set","Tuple","Type","Union"] +},r={className:"meta",begin:/^(>>>|\.\.\.) /},s={className:"subst",begin:/\{/, +end:/\}/,keywords:i,illegal:/#/},o={begin:/\{\{/,relevance:0},l={ +className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{ +begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?'''/,end:/'''/, +contains:[e.BACKSLASH_ESCAPE,r],relevance:10},{ +begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?"""/,end:/"""/, +contains:[e.BACKSLASH_ESCAPE,r],relevance:10},{ +begin:/([fF][rR]|[rR][fF]|[fF])'''/,end:/'''/, +contains:[e.BACKSLASH_ESCAPE,r,o,s]},{begin:/([fF][rR]|[rR][fF]|[fF])"""/, +end:/"""/,contains:[e.BACKSLASH_ESCAPE,r,o,s]},{begin:/([uU]|[rR])'/,end:/'/, +relevance:10},{begin:/([uU]|[rR])"/,end:/"/,relevance:10},{ +begin:/([bB]|[bB][rR]|[rR][bB])'/,end:/'/},{begin:/([bB]|[bB][rR]|[rR][bB])"/, +end:/"/},{begin:/([fF][rR]|[rR][fF]|[fF])'/,end:/'/, +contains:[e.BACKSLASH_ESCAPE,o,s]},{begin:/([fF][rR]|[rR][fF]|[fF])"/,end:/"/, +contains:[e.BACKSLASH_ESCAPE,o,s]},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE] +},c="[0-9](_?[0-9])*",d=`(\\b(${c}))?\\.(${c})|\\b(${c})\\.`,g="\\b|"+a.join("|"),u={ +className:"number",relevance:0,variants:[{ +begin:`(\\b(${c})|(${d}))[eE][+-]?(${c})[jJ]?(?=${g})`},{begin:`(${d})[jJ]?`},{ +begin:`\\b([1-9](_?[0-9])*|0+(_?0)*)[lLjJ]?(?=${g})`},{ +begin:`\\b0[bB](_?[01])+[lL]?(?=${g})`},{begin:`\\b0[oO](_?[0-7])+[lL]?(?=${g})` +},{begin:`\\b0[xX](_?[0-9a-fA-F])+[lL]?(?=${g})`},{begin:`\\b(${c})[jJ](?=${g})` +}]},b={className:"comment",begin:n.lookahead(/# type:/),end:/$/,keywords:i, +contains:[{begin:/# type:/},{begin:/#/,end:/\b\B/,endsWithParent:!0}]},m={ +className:"params",variants:[{className:"",begin:/\(\s*\)/,skip:!0},{begin:/\(/, +end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:i, +contains:["self",r,u,l,e.HASH_COMMENT_MODE]}]};return s.contains=[l,u,r],{ +name:"Python",aliases:["py","gyp","ipython"],unicodeRegex:!0,keywords:i, +illegal:/(<\/|->|\?)|=>/,contains:[r,u,{begin:/\bself\b/},{beginKeywords:"if", +relevance:0},l,b,e.HASH_COMMENT_MODE,{match:[/\bdef/,/\s+/,t],scope:{ +1:"keyword",3:"title.function"},contains:[m]},{variants:[{ +match:[/\bclass/,/\s+/,t,/\s*/,/\(\s*/,t,/\s*\)/]},{match:[/\bclass/,/\s+/,t]}], +scope:{1:"keyword",3:"title.class",6:"title.class.inherited"}},{ +className:"meta",begin:/^[\t ]*@/,end:/(?=#)|$/,contains:[u,m,l]}]}}, +grmr_python_repl:e=>({aliases:["pycon"],contains:[{className:"meta.prompt", +starts:{end:/ |$/,starts:{end:"$",subLanguage:"python"}},variants:[{ +begin:/^>>>(?=[ ]|$)/},{begin:/^\.\.\.(?=[ ]|$)/}]}]}),grmr_r:e=>{ +const n=e.regex,t=/(?:(?:[a-zA-Z]|\.[._a-zA-Z])[._a-zA-Z0-9]*)|\.(?!\d)/,a=n.either(/0[xX][0-9a-fA-F]+\.[0-9a-fA-F]*[pP][+-]?\d+i?/,/0[xX][0-9a-fA-F]+(?:[pP][+-]?\d+)?[Li]?/,/(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?[Li]?/),i=/[=!<>:]=|\|\||&&|:::?|<-|<<-|->>|->|\|>|[-+*\/?!$&|:<=>@^~]|\*\*/,r=n.either(/[()]/,/[{}]/,/\[\[/,/[[\]]/,/\\/,/,/) +;return{name:"R",keywords:{$pattern:t, +keyword:"function if in break next repeat else for while", +literal:"NULL NA TRUE FALSE Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10", +built_in:"LETTERS letters month.abb month.name pi T F abs acos acosh all any anyNA Arg as.call as.character as.complex as.double as.environment as.integer as.logical as.null.default as.numeric as.raw asin asinh atan atanh attr attributes baseenv browser c call ceiling class Conj cos cosh cospi cummax cummin cumprod cumsum digamma dim dimnames emptyenv exp expression floor forceAndCall gamma gc.time globalenv Im interactive invisible is.array is.atomic is.call is.character is.complex is.double is.environment is.expression is.finite is.function is.infinite is.integer is.language is.list is.logical is.matrix is.na is.name is.nan is.null is.numeric is.object is.pairlist is.raw is.recursive is.single is.symbol lazyLoadDBfetch length lgamma list log max min missing Mod names nargs nzchar oldClass on.exit pos.to.env proc.time prod quote range Re rep retracemem return round seq_along seq_len seq.int sign signif sin sinh sinpi sqrt standardGeneric substitute sum switch tan tanh tanpi tracemem trigamma trunc unclass untracemem UseMethod xtfrm" +},contains:[e.COMMENT(/#'/,/$/,{contains:[{scope:"doctag",match:/@examples/, +starts:{end:n.lookahead(n.either(/\n^#'\s*(?=@[a-zA-Z]+)/,/\n^(?!#')/)), +endsParent:!0}},{scope:"doctag",begin:"@param",end:/$/,contains:[{ +scope:"variable",variants:[{match:t},{match:/`(?:\\.|[^`\\])+`/}],endsParent:!0 +}]},{scope:"doctag",match:/@[a-zA-Z]+/},{scope:"keyword",match:/\\[a-zA-Z]+/}] +}),e.HASH_COMMENT_MODE,{scope:"string",contains:[e.BACKSLASH_ESCAPE], +variants:[e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\(/,end:/\)(-*)"/ +}),e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\{/,end:/\}(-*)"/ +}),e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\[/,end:/\](-*)"/ +}),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\(/,end:/\)(-*)'/ +}),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\{/,end:/\}(-*)'/ +}),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\[/,end:/\](-*)'/}),{begin:'"',end:'"', +relevance:0},{begin:"'",end:"'",relevance:0}]},{relevance:0,variants:[{scope:{ +1:"operator",2:"number"},match:[i,a]},{scope:{1:"operator",2:"number"}, +match:[/%[^%]*%/,a]},{scope:{1:"punctuation",2:"number"},match:[r,a]},{scope:{ +2:"number"},match:[/[^a-zA-Z0-9._]|^/,a]}]},{scope:{3:"operator"}, +match:[t,/\s+/,/<-/,/\s+/]},{scope:"operator",relevance:0,variants:[{match:i},{ +match:/%[^%]*%/}]},{scope:"punctuation",relevance:0,match:r},{begin:"`",end:"`", +contains:[{begin:/\\./}]}]}},grmr_ruby:e=>{ +const n=e.regex,t="([a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?)",a=n.either(/\b([A-Z]+[a-z0-9]+)+/,/\b([A-Z]+[a-z0-9]+)+[A-Z]+/),i=n.concat(a,/(::\w+)*/),r={ +"variable.constant":["__FILE__","__LINE__"], +"variable.language":["self","super"], +keyword:["alias","and","attr_accessor","attr_reader","attr_writer","begin","BEGIN","break","case","class","defined","do","else","elsif","end","END","ensure","for","if","in","include","module","next","not","or","redo","require","rescue","retry","return","then","undef","unless","until","when","while","yield"], +built_in:["proc","lambda"],literal:["true","false","nil"]},s={ +className:"doctag",begin:"@[A-Za-z]+"},o={begin:"#<",end:">" +},l=[e.COMMENT("#","$",{contains:[s]}),e.COMMENT("^=begin","^=end",{ +contains:[s],relevance:10}),e.COMMENT("^__END__",e.MATCH_NOTHING_RE)],c={ +className:"subst",begin:/#\{/,end:/\}/,keywords:r},d={className:"string", +contains:[e.BACKSLASH_ESCAPE,c],variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/ +},{begin:/`/,end:/`/},{begin:/%[qQwWx]?\(/,end:/\)/},{begin:/%[qQwWx]?\[/, +end:/\]/},{begin:/%[qQwWx]?\{/,end:/\}/},{begin:/%[qQwWx]?/},{ +begin:/%[qQwWx]?\//,end:/\//},{begin:/%[qQwWx]?%/,end:/%/},{begin:/%[qQwWx]?-/, +end:/-/},{begin:/%[qQwWx]?\|/,end:/\|/},{begin:/\B\?(\\\d{1,3})/},{ +begin:/\B\?(\\x[A-Fa-f0-9]{1,2})/},{begin:/\B\?(\\u\{?[A-Fa-f0-9]{1,6}\}?)/},{ +begin:/\B\?(\\M-\\C-|\\M-\\c|\\c\\M-|\\M-|\\C-\\M-)[\x20-\x7e]/},{ +begin:/\B\?\\(c|C-)[\x20-\x7e]/},{begin:/\B\?\\?\S/},{ +begin:n.concat(/<<[-~]?'?/,n.lookahead(/(\w+)(?=\W)[^\n]*\n(?:[^\n]*\n)*?\s*\1\b/)), +contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/, +contains:[e.BACKSLASH_ESCAPE,c]})]}]},g="[0-9](_?[0-9])*",u={className:"number", +relevance:0,variants:[{ +begin:`\\b([1-9](_?[0-9])*|0)(\\.(${g}))?([eE][+-]?(${g})|r)?i?\\b`},{ +begin:"\\b0[dD][0-9](_?[0-9])*r?i?\\b"},{begin:"\\b0[bB][0-1](_?[0-1])*r?i?\\b" +},{begin:"\\b0[oO][0-7](_?[0-7])*r?i?\\b"},{ +begin:"\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*r?i?\\b"},{ +begin:"\\b0(_?[0-7])+r?i?\\b"}]},b={variants:[{match:/\(\)/},{ +className:"params",begin:/\(/,end:/(?=\))/,excludeBegin:!0,endsParent:!0, +keywords:r}]},m=[d,{variants:[{match:[/class\s+/,i,/\s+<\s+/,i]},{ +match:[/class\s+/,i]}],scope:{2:"title.class",4:"title.class.inherited"}, +keywords:r},{relevance:0,match:[i,/\.new[ (]/],scope:{1:"title.class"}},{ +relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/,className:"variable.constant"},{ +match:[/def/,/\s+/,t],scope:{1:"keyword",3:"title.function"},contains:[b]},{ +begin:e.IDENT_RE+"::"},{className:"symbol", +begin:e.UNDERSCORE_IDENT_RE+"(!|\\?)?:",relevance:0},{className:"symbol", +begin:":(?!\\s)",contains:[d,{begin:t}],relevance:0},u,{className:"variable", +begin:"(\\$\\W)|((\\$|@@?)(\\w+))(?=[^@$?])(?![A-Za-z])(?![@$?'])"},{ +className:"params",begin:/\|/,end:/\|/,excludeBegin:!0,excludeEnd:!0, +relevance:0,keywords:r},{begin:"("+e.RE_STARTERS_RE+"|unless)\\s*", +keywords:"unless",contains:[{className:"regexp",contains:[e.BACKSLASH_ESCAPE,c], +illegal:/\n/,variants:[{begin:"/",end:"/[a-z]*"},{begin:/%r\{/,end:/\}[a-z]*/},{ +begin:"%r\\(",end:"\\)[a-z]*"},{begin:"%r!",end:"![a-z]*"},{begin:"%r\\[", +end:"\\][a-z]*"}]}].concat(o,l),relevance:0}].concat(o,l) +;c.contains=m,b.contains=m;const p=[{begin:/^\s*=>/,starts:{end:"$",contains:m} +},{className:"meta.prompt", +begin:"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+[>*]|(\\w+-)?\\d+\\.\\d+\\.\\d+(p\\d+)?[^\\d][^>]+>)(?=[ ])", +starts:{end:"$",keywords:r,contains:m}}];return l.unshift(o),{name:"Ruby", +aliases:["rb","gemspec","podspec","thor","irb"],keywords:r,illegal:/\/\*/, +contains:[e.SHEBANG({binary:"ruby"})].concat(p).concat(l).concat(m)}}, +grmr_rust:e=>{const n=e.regex,t={className:"title.function.invoke",relevance:0, +begin:n.concat(/\b/,/(?!let\b)/,e.IDENT_RE,n.lookahead(/\s*\(/)) +},a="([ui](8|16|32|64|128|size)|f(32|64))?",i=["drop ","Copy","Send","Sized","Sync","Drop","Fn","FnMut","FnOnce","ToOwned","Clone","Debug","PartialEq","PartialOrd","Eq","Ord","AsRef","AsMut","Into","From","Default","Iterator","Extend","IntoIterator","DoubleEndedIterator","ExactSizeIterator","SliceConcatExt","ToString","assert!","assert_eq!","bitflags!","bytes!","cfg!","col!","concat!","concat_idents!","debug_assert!","debug_assert_eq!","env!","panic!","file!","format!","format_args!","include_bytes!","include_str!","line!","local_data_key!","module_path!","option_env!","print!","println!","select!","stringify!","try!","unimplemented!","unreachable!","vec!","write!","writeln!","macro_rules!","assert_ne!","debug_assert_ne!"],r=["i8","i16","i32","i64","i128","isize","u8","u16","u32","u64","u128","usize","f32","f64","str","char","bool","Box","Option","Result","String","Vec"] +;return{name:"Rust",aliases:["rs"],keywords:{$pattern:e.IDENT_RE+"!?",type:r, +keyword:["abstract","as","async","await","become","box","break","const","continue","crate","do","dyn","else","enum","extern","false","final","fn","for","if","impl","in","let","loop","macro","match","mod","move","mut","override","priv","pub","ref","return","self","Self","static","struct","super","trait","true","try","type","typeof","unsafe","unsized","use","virtual","where","while","yield"], +literal:["true","false","Some","None","Ok","Err"],built_in:i},illegal:""},t]}}, +grmr_scss:e=>{const n=te(e),t=se,a=re,i="@[a-z-]+",r={className:"variable", +begin:"(\\$[a-zA-Z-][a-zA-Z0-9_-]*)\\b",relevance:0};return{name:"SCSS", +case_insensitive:!0,illegal:"[=/|']", +contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n.CSS_NUMBER_MODE,{ +className:"selector-id",begin:"#[A-Za-z0-9_-]+",relevance:0},{ +className:"selector-class",begin:"\\.[A-Za-z0-9_-]+",relevance:0 +},n.ATTRIBUTE_SELECTOR_MODE,{className:"selector-tag", +begin:"\\b("+ae.join("|")+")\\b",relevance:0},{className:"selector-pseudo", +begin:":("+a.join("|")+")"},{className:"selector-pseudo", +begin:":(:)?("+t.join("|")+")"},r,{begin:/\(/,end:/\)/, +contains:[n.CSS_NUMBER_MODE]},n.CSS_VARIABLE,{className:"attribute", +begin:"\\b("+oe.join("|")+")\\b"},{ +begin:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b" +},{begin:/:/,end:/[;}{]/,relevance:0, +contains:[n.BLOCK_COMMENT,r,n.HEXCOLOR,n.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,n.IMPORTANT,n.FUNCTION_DISPATCH] +},{begin:"@(page|font-face)",keywords:{$pattern:i,keyword:"@page @font-face"}},{ +begin:"@",end:"[{;]",returnBegin:!0,keywords:{$pattern:/[a-z-]+/, +keyword:"and or not only",attribute:ie.join(" ")},contains:[{begin:i, +className:"keyword"},{begin:/[a-z-]+(?=:)/,className:"attribute" +},r,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,n.HEXCOLOR,n.CSS_NUMBER_MODE] +},n.FUNCTION_DISPATCH]}},grmr_shell:e=>({name:"Shell Session", +aliases:["console","shellsession"],contains:[{className:"meta.prompt", +begin:/^\s{0,3}[/~\w\d[\]()@-]*[>%$#][ ]?/,starts:{end:/[^\\](?=\s*$)/, +subLanguage:"bash"}}]}),grmr_sql:e=>{ +const n=e.regex,t=e.COMMENT("--","$"),a=["true","false","unknown"],i=["bigint","binary","blob","boolean","char","character","clob","date","dec","decfloat","decimal","float","int","integer","interval","nchar","nclob","national","numeric","real","row","smallint","time","timestamp","varchar","varying","varbinary"],r=["abs","acos","array_agg","asin","atan","avg","cast","ceil","ceiling","coalesce","corr","cos","cosh","count","covar_pop","covar_samp","cume_dist","dense_rank","deref","element","exp","extract","first_value","floor","json_array","json_arrayagg","json_exists","json_object","json_objectagg","json_query","json_table","json_table_primitive","json_value","lag","last_value","lead","listagg","ln","log","log10","lower","max","min","mod","nth_value","ntile","nullif","percent_rank","percentile_cont","percentile_disc","position","position_regex","power","rank","regr_avgx","regr_avgy","regr_count","regr_intercept","regr_r2","regr_slope","regr_sxx","regr_sxy","regr_syy","row_number","sin","sinh","sqrt","stddev_pop","stddev_samp","substring","substring_regex","sum","tan","tanh","translate","translate_regex","treat","trim","trim_array","unnest","upper","value_of","var_pop","var_samp","width_bucket"],s=["create table","insert into","primary key","foreign key","not null","alter table","add constraint","grouping sets","on overflow","character set","respect nulls","ignore nulls","nulls first","nulls last","depth first","breadth first"],o=r,l=["abs","acos","all","allocate","alter","and","any","are","array","array_agg","array_max_cardinality","as","asensitive","asin","asymmetric","at","atan","atomic","authorization","avg","begin","begin_frame","begin_partition","between","bigint","binary","blob","boolean","both","by","call","called","cardinality","cascaded","case","cast","ceil","ceiling","char","char_length","character","character_length","check","classifier","clob","close","coalesce","collate","collect","column","commit","condition","connect","constraint","contains","convert","copy","corr","corresponding","cos","cosh","count","covar_pop","covar_samp","create","cross","cube","cume_dist","current","current_catalog","current_date","current_default_transform_group","current_path","current_role","current_row","current_schema","current_time","current_timestamp","current_path","current_role","current_transform_group_for_type","current_user","cursor","cycle","date","day","deallocate","dec","decimal","decfloat","declare","default","define","delete","dense_rank","deref","describe","deterministic","disconnect","distinct","double","drop","dynamic","each","element","else","empty","end","end_frame","end_partition","end-exec","equals","escape","every","except","exec","execute","exists","exp","external","extract","false","fetch","filter","first_value","float","floor","for","foreign","frame_row","free","from","full","function","fusion","get","global","grant","group","grouping","groups","having","hold","hour","identity","in","indicator","initial","inner","inout","insensitive","insert","int","integer","intersect","intersection","interval","into","is","join","json_array","json_arrayagg","json_exists","json_object","json_objectagg","json_query","json_table","json_table_primitive","json_value","lag","language","large","last_value","lateral","lead","leading","left","like","like_regex","listagg","ln","local","localtime","localtimestamp","log","log10","lower","match","match_number","match_recognize","matches","max","member","merge","method","min","minute","mod","modifies","module","month","multiset","national","natural","nchar","nclob","new","no","none","normalize","not","nth_value","ntile","null","nullif","numeric","octet_length","occurrences_regex","of","offset","old","omit","on","one","only","open","or","order","out","outer","over","overlaps","overlay","parameter","partition","pattern","per","percent","percent_rank","percentile_cont","percentile_disc","period","portion","position","position_regex","power","precedes","precision","prepare","primary","procedure","ptf","range","rank","reads","real","recursive","ref","references","referencing","regr_avgx","regr_avgy","regr_count","regr_intercept","regr_r2","regr_slope","regr_sxx","regr_sxy","regr_syy","release","result","return","returns","revoke","right","rollback","rollup","row","row_number","rows","running","savepoint","scope","scroll","search","second","seek","select","sensitive","session_user","set","show","similar","sin","sinh","skip","smallint","some","specific","specifictype","sql","sqlexception","sqlstate","sqlwarning","sqrt","start","static","stddev_pop","stddev_samp","submultiset","subset","substring","substring_regex","succeeds","sum","symmetric","system","system_time","system_user","table","tablesample","tan","tanh","then","time","timestamp","timezone_hour","timezone_minute","to","trailing","translate","translate_regex","translation","treat","trigger","trim","trim_array","true","truncate","uescape","union","unique","unknown","unnest","update","upper","user","using","value","values","value_of","var_pop","var_samp","varbinary","varchar","varying","versioning","when","whenever","where","width_bucket","window","with","within","without","year","add","asc","collation","desc","final","first","last","view"].filter((e=>!r.includes(e))),c={ +begin:n.concat(/\b/,n.either(...o),/\s*\(/),relevance:0,keywords:{built_in:o}} +;return{name:"SQL",case_insensitive:!0,illegal:/[{}]|<\//,keywords:{ +$pattern:/\b[\w\.]+/,keyword:((e,{exceptions:n,when:t}={})=>{const a=t +;return n=n||[],e.map((e=>e.match(/\|\d+$/)||n.includes(e)?e:a(e)?e+"|0":e)) +})(l,{when:e=>e.length<3}),literal:a,type:i, +built_in:["current_catalog","current_date","current_default_transform_group","current_path","current_role","current_schema","current_transform_group_for_type","current_user","session_user","system_time","system_user","current_time","localtime","current_timestamp","localtimestamp"] +},contains:[{begin:n.either(...s),relevance:0,keywords:{$pattern:/[\w\.]+/, +keyword:l.concat(s),literal:a,type:i}},{className:"type", +begin:n.either("double precision","large object","with timezone","without timezone") +},c,{className:"variable",begin:/@[a-z0-9]+/},{className:"string",variants:[{ +begin:/'/,end:/'/,contains:[{begin:/''/}]}]},{begin:/"/,end:/"/,contains:[{ +begin:/""/}]},e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE,t,{className:"operator", +begin:/[-+*/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?/,relevance:0}]}}, +grmr_swift:e=>{const n={match:/\s+/,relevance:0},t=e.COMMENT("/\\*","\\*/",{ +contains:["self"]}),a=[e.C_LINE_COMMENT_MODE,t],i={match:[/\./,p(...ve,...Oe)], +className:{2:"keyword"}},r={match:m(/\./,p(...xe)),relevance:0 +},s=xe.filter((e=>"string"==typeof e)).concat(["_|0"]),o={variants:[{ +className:"keyword", +match:p(...xe.filter((e=>"string"!=typeof e)).concat(ke).map(Ne),...Oe)}]},l={ +$pattern:p(/\b\w+/,/#\w+/),keyword:s.concat(Ae),literal:Me},c=[i,r,o],d=[{ +match:m(/\./,p(...Ce)),relevance:0},{className:"built_in", +match:m(/\b/,p(...Ce),/(?=\()/)}],u={match:/->/,relevance:0},b=[u,{ +className:"operator",relevance:0,variants:[{match:De},{match:`\\.(\\.|${Re})+`}] +}],_="([0-9a-fA-F]_*)+",h={className:"number",relevance:0,variants:[{ +match:"\\b(([0-9]_*)+)(\\.(([0-9]_*)+))?([eE][+-]?(([0-9]_*)+))?\\b"},{ +match:`\\b0x(${_})(\\.(${_}))?([pP][+-]?(([0-9]_*)+))?\\b`},{ +match:/\b0o([0-7]_*)+\b/},{match:/\b0b([01]_*)+\b/}]},f=(e="")=>({ +className:"subst",variants:[{match:m(/\\/,e,/[0\\tnr"']/)},{ +match:m(/\\/,e,/u\{[0-9a-fA-F]{1,8}\}/)}]}),E=(e="")=>({className:"subst", +match:m(/\\/,e,/[\t ]*(?:[\r\n]|\r\n)/)}),y=(e="")=>({className:"subst", +label:"interpol",begin:m(/\\/,e,/\(/),end:/\)/}),w=(e="")=>({begin:m(e,/"""/), +end:m(/"""/,e),contains:[f(e),E(e),y(e)]}),N=(e="")=>({begin:m(e,/"/), +end:m(/"/,e),contains:[f(e),y(e)]}),v={className:"string", +variants:[w(),w("#"),w("##"),w("###"),N(),N("#"),N("##"),N("###")]},O={ +match:m(/`/,Be,/`/)},k=[O,{className:"variable",match:/\$\d+/},{ +className:"variable",match:`\\$${Le}+`}],x=[{match:/(@|#(un)?)available/, +className:"keyword",starts:{contains:[{begin:/\(/,end:/\)/,keywords:Fe, +contains:[...b,h,v]}]}},{className:"keyword",match:m(/@/,p(...ze))},{ +className:"meta",match:m(/@/,Be)}],M={match:g(/\b[A-Z]/),relevance:0,contains:[{ +className:"type", +match:m(/(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)/,Le,"+") +},{className:"type",match:$e,relevance:0},{match:/[?!]+/,relevance:0},{ +match:/\.\.\./,relevance:0},{match:m(/\s+&\s+/,g($e)),relevance:0}]},S={ +begin://,keywords:l,contains:[...a,...c,...x,u,M]};M.contains.push(S) +;const A={begin:/\(/,end:/\)/,relevance:0,keywords:l,contains:["self",{ +match:m(Be,/\s*:/),keywords:"_|0",relevance:0 +},...a,...c,...d,...b,h,v,...k,...x,M]},C={begin://,contains:[...a,M] +},T={begin:/\(/,end:/\)/,keywords:l,contains:[{ +begin:p(g(m(Be,/\s*:/)),g(m(Be,/\s+/,Be,/\s*:/))),end:/:/,relevance:0, +contains:[{className:"keyword",match:/\b_\b/},{className:"params",match:Be}] +},...a,...c,...b,h,v,...x,M,A],endsParent:!0,illegal:/["']/},R={ +match:[/func/,/\s+/,p(O.match,Be,De)],className:{1:"keyword",3:"title.function" +},contains:[C,T,n],illegal:[/\[/,/%/]},D={ +match:[/\b(?:subscript|init[?!]?)/,/\s*(?=[<(])/],className:{1:"keyword"}, +contains:[C,T,n],illegal:/\[|%/},I={match:[/operator/,/\s+/,De],className:{ +1:"keyword",3:"title"}},L={begin:[/precedencegroup/,/\s+/,$e],className:{ +1:"keyword",3:"title"},contains:[M],keywords:[...Se,...Me],end:/}/} +;for(const e of v.variants){const n=e.contains.find((e=>"interpol"===e.label)) +;n.keywords=l;const t=[...c,...d,...b,h,v,...k];n.contains=[...t,{begin:/\(/, +end:/\)/,contains:["self",...t]}]}return{name:"Swift",keywords:l, +contains:[...a,R,D,{beginKeywords:"struct protocol class extension enum actor", +end:"\\{",excludeEnd:!0,keywords:l,contains:[e.inherit(e.TITLE_MODE,{ +className:"title.class",begin:/[A-Za-z$_][\u00C0-\u02B80-9A-Za-z$_]*/}),...c] +},I,L,{beginKeywords:"import",end:/$/,contains:[...a],relevance:0 +},...c,...d,...b,h,v,...k,...x,M,A]}},grmr_typescript:e=>{ +const n=we(e),t=["any","void","number","boolean","string","object","never","symbol","bigint","unknown"],a={ +beginKeywords:"namespace",end:/\{/,excludeEnd:!0, +contains:[n.exports.CLASS_REFERENCE]},i={beginKeywords:"interface",end:/\{/, +excludeEnd:!0,keywords:{keyword:"interface extends",built_in:t}, +contains:[n.exports.CLASS_REFERENCE]},r={$pattern:be, +keyword:me.concat(["type","namespace","interface","public","private","protected","implements","declare","abstract","readonly","enum","override"]), +literal:pe,built_in:ye.concat(t),"variable.language":Ee},s={className:"meta", +begin:"@[A-Za-z$_][0-9A-Za-z$_]*"},o=(e,n,t)=>{ +const a=e.contains.findIndex((e=>e.label===n)) +;if(-1===a)throw Error("can not find mode to replace");e.contains.splice(a,1,t)} +;return Object.assign(n.keywords,r), +n.exports.PARAMS_CONTAINS.push(s),n.contains=n.contains.concat([s,a,i]), +o(n,"shebang",e.SHEBANG()),o(n,"use_strict",{className:"meta",relevance:10, +begin:/^\s*['"]use strict['"]/ +}),n.contains.find((e=>"func.def"===e.label)).relevance=0,Object.assign(n,{ +name:"TypeScript",aliases:["ts","tsx"]}),n},grmr_vbnet:e=>{ +const n=e.regex,t=/\d{1,2}\/\d{1,2}\/\d{4}/,a=/\d{4}-\d{1,2}-\d{1,2}/,i=/(\d|1[012])(:\d+){0,2} *(AM|PM)/,r=/\d{1,2}(:\d{1,2}){1,2}/,s={ +className:"literal",variants:[{begin:n.concat(/# */,n.either(a,t),/ *#/)},{ +begin:n.concat(/# */,r,/ *#/)},{begin:n.concat(/# */,i,/ *#/)},{ +begin:n.concat(/# */,n.either(a,t),/ +/,n.either(i,r),/ *#/)}] +},o=e.COMMENT(/'''/,/$/,{contains:[{className:"doctag",begin:/<\/?/,end:/>/}] +}),l=e.COMMENT(null,/$/,{variants:[{begin:/'/},{begin:/([\t ]|^)REM(?=\s)/}]}) +;return{name:"Visual Basic .NET",aliases:["vb"],case_insensitive:!0, +classNameAliases:{label:"symbol"},keywords:{ +keyword:"addhandler alias aggregate ansi as async assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into iterator join key let lib loop me mid module mustinherit mustoverride mybase myclass namespace narrowing new next notinheritable notoverridable of off on operator option optional order overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly yield", +built_in:"addressof and andalso await directcast gettype getxmlnamespace is isfalse isnot istrue like mod nameof new not or orelse trycast typeof xor cbool cbyte cchar cdate cdbl cdec cint clng cobj csbyte cshort csng cstr cuint culng cushort", +type:"boolean byte char date decimal double integer long object sbyte short single string uinteger ulong ushort", +literal:"true false nothing"}, +illegal:"//|\\{|\\}|endif|gosub|variant|wend|^\\$ ",contains:[{ +className:"string",begin:/"(""|[^/n])"C\b/},{className:"string",begin:/"/, +end:/"/,illegal:/\n/,contains:[{begin:/""/}]},s,{className:"number",relevance:0, +variants:[{begin:/\b\d[\d_]*((\.[\d_]+(E[+-]?[\d_]+)?)|(E[+-]?[\d_]+))[RFD@!#]?/ +},{begin:/\b\d[\d_]*((U?[SIL])|[%&])?/},{begin:/&H[\dA-F_]+((U?[SIL])|[%&])?/},{ +begin:/&O[0-7_]+((U?[SIL])|[%&])?/},{begin:/&B[01_]+((U?[SIL])|[%&])?/}]},{ +className:"label",begin:/^\w+:/},o,l,{className:"meta", +begin:/[\t ]*#(const|disable|else|elseif|enable|end|externalsource|if|region)\b/, +end:/$/,keywords:{ +keyword:"const disable else elseif enable end externalsource if region then"}, +contains:[l]}]}},grmr_wasm:e=>{e.regex;const n=e.COMMENT(/\(;/,/;\)/) +;return n.contains.push("self"),{name:"WebAssembly",keywords:{$pattern:/[\w.]+/, +keyword:["anyfunc","block","br","br_if","br_table","call","call_indirect","data","drop","elem","else","end","export","func","global.get","global.set","local.get","local.set","local.tee","get_global","get_local","global","if","import","local","loop","memory","memory.grow","memory.size","module","mut","nop","offset","param","result","return","select","set_global","set_local","start","table","tee_local","then","type","unreachable"] +},contains:[e.COMMENT(/;;/,/$/),n,{match:[/(?:offset|align)/,/\s*/,/=/], +className:{1:"keyword",3:"operator"}},{className:"variable",begin:/\$[\w_]+/},{ +match:/(\((?!;)|\))+/,className:"punctuation",relevance:0},{ +begin:[/(?:func|call|call_indirect)/,/\s+/,/\$[^\s)]+/],className:{1:"keyword", +3:"title.function"}},e.QUOTE_STRING_MODE,{match:/(i32|i64|f32|f64)(?!\.)/, +className:"type"},{className:"keyword", +match:/\b(f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|nearest|neg?|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|store(?:8|16|32)?|sqrt|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))\b/ +},{className:"number",relevance:0, +match:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/ +}]}},grmr_yaml:e=>{ +const n="true false yes no null",t="[\\w#;/?:@&=+$,.~*'()[\\]]+",a={ +className:"string",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/ +},{begin:/\S+/}],contains:[e.BACKSLASH_ESCAPE,{className:"template-variable", +variants:[{begin:/\{\{/,end:/\}\}/},{begin:/%\{/,end:/\}/}]}]},i=e.inherit(a,{ +variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/[^\s,{}[\]]+/}]}),r={ +end:",",endsWithParent:!0,excludeEnd:!0,keywords:n,relevance:0},s={begin:/\{/, +end:/\}/,contains:[r],illegal:"\\n",relevance:0},o={begin:"\\[",end:"\\]", +contains:[r],illegal:"\\n",relevance:0},l=[{className:"attr",variants:[{ +begin:"\\w[\\w :\\/.-]*:(?=[ \t]|$)"},{begin:'"\\w[\\w :\\/.-]*":(?=[ \t]|$)'},{ +begin:"'\\w[\\w :\\/.-]*':(?=[ \t]|$)"}]},{className:"meta",begin:"^---\\s*$", +relevance:10},{className:"string", +begin:"[\\|>]([1-9]?[+-])?[ ]*\\n( +)[^ ][^\\n]*\\n(\\2[^\\n]+\\n?)*"},{ +begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0, +relevance:0},{className:"type",begin:"!\\w+!"+t},{className:"type", +begin:"!<"+t+">"},{className:"type",begin:"!"+t},{className:"type",begin:"!!"+t +},{className:"meta",begin:"&"+e.UNDERSCORE_IDENT_RE+"$"},{className:"meta", +begin:"\\*"+e.UNDERSCORE_IDENT_RE+"$"},{className:"bullet",begin:"-(?=[ ]|$)", +relevance:0},e.HASH_COMMENT_MODE,{beginKeywords:n,keywords:{literal:n}},{ +className:"number", +begin:"\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b" +},{className:"number",begin:e.C_NUMBER_RE+"\\b",relevance:0},s,o,a],c=[...l] +;return c.pop(),c.push(i),r.contains=c,{name:"YAML",case_insensitive:!0, +aliases:["yml"],contains:l}}});const je=ne;for(const e of Object.keys(Ue)){ +const n=e.replace("grmr_","").replace("_","-");je.registerLanguage(n,Ue[e])} +return je}() +;"object"==typeof exports&&"undefined"!=typeof module&&(module.exports=hljs); \ No newline at end of file diff --git a/assets/js/janus.js b/assets/js/janus.js new file mode 100755 index 0000000..a5585ed --- /dev/null +++ b/assets/js/janus.js @@ -0,0 +1,3646 @@ +"use strict"; + +/* + The MIT License (MIT) + + Copyright (c) 2016 Meetecho + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + */ + +// List of sessions +Janus.sessions = {}; + +Janus.isExtensionEnabled = function() { + if(navigator.mediaDevices && navigator.mediaDevices.getDisplayMedia) { + // No need for the extension, getDisplayMedia is supported + return true; + } + if(window.navigator.userAgent.match('Chrome')) { + var chromever = parseInt(window.navigator.userAgent.match(/Chrome\/(.*) /)[1], 10); + var maxver = 33; + if(window.navigator.userAgent.match('Linux')) + maxver = 35; // "known" crash in chrome 34 and 35 on linux + if(chromever >= 26 && chromever <= maxver) { + // Older versions of Chrome don't support this extension-based approach, so lie + return true; + } + return Janus.extension.isInstalled(); + } else { + // Firefox and others, no need for the extension (but this doesn't mean it will work) + return true; + } +}; + +var defaultExtension = { + // Screensharing Chrome Extension ID + extensionId: 'hapfgfdkleiggjjpfpenajgdnfckjpaj', + isInstalled: function() { return document.querySelector('#janus-extension-installed') !== null; }, + getScreen: function (callback) { + var pending = window.setTimeout(function () { + var error = new Error('NavigatorUserMediaError'); + error.name = 'The required Chrome extension is not installed: click here to install it. (NOTE: this will need you to refresh the page)'; + return callback(error); + }, 1000); + this.cache[pending] = callback; + window.postMessage({ type: 'janusGetScreen', id: pending }, '*'); + }, + init: function () { + var cache = {}; + this.cache = cache; + // Wait for events from the Chrome Extension + window.addEventListener('message', function (event) { + if(event.origin != window.location.origin) + return; + if(event.data.type == 'janusGotScreen' && cache[event.data.id]) { + var callback = cache[event.data.id]; + delete cache[event.data.id]; + + if (event.data.sourceId === '') { + // user canceled + var error = new Error('NavigatorUserMediaError'); + error.name = 'You cancelled the request for permission, giving up...'; + callback(error); + } else { + callback(null, event.data.sourceId); + } + } else if (event.data.type == 'janusGetScreenPending') { + console.log('clearing ', event.data.id); + window.clearTimeout(event.data.id); + } + }); + } +}; + +Janus.useDefaultDependencies = function (deps) { + var f = (deps && deps.fetch) || fetch; + var p = (deps && deps.Promise) || Promise; + var socketCls = (deps && deps.WebSocket) || WebSocket; + + return { + newWebSocket: function(server, proto) { return new socketCls(server, proto); }, + extension: (deps && deps.extension) || defaultExtension, + isArray: function(arr) { return Array.isArray(arr); }, + webRTCAdapter: (deps && deps.adapter) || adapter, + httpAPICall: function(url, options) { + var fetchOptions = { + method: options.verb, + headers: { + 'Accept': 'application/json, text/plain, */*' + }, + cache: 'no-cache' + }; + if(options.verb === "POST") { + fetchOptions.headers['Content-Type'] = 'application/json'; + } + if(options.withCredentials !== undefined) { + fetchOptions.credentials = options.withCredentials === true ? 'include' : (options.withCredentials ? options.withCredentials : 'omit'); + } + if(options.body) { + fetchOptions.body = JSON.stringify(options.body); + } + + var fetching = f(url, fetchOptions).catch(function(error) { + return p.reject({message: 'Probably a network error, is the server down?', error: error}); + }); + + /* + * fetch() does not natively support timeouts. + * Work around this by starting a timeout manually, and racing it agains the fetch() to see which thing resolves first. + */ + + if(options.timeout) { + var timeout = new p(function(resolve, reject) { + var timerId = setTimeout(function() { + clearTimeout(timerId); + return reject({message: 'Request timed out', timeout: options.timeout}); + }, options.timeout); + }); + fetching = p.race([fetching, timeout]); + } + + fetching.then(function(response) { + if(response.ok) { + if(typeof(options.success) === typeof(Janus.noop)) { + return response.json().then(function(parsed) { + try { + options.success(parsed); + } catch(error) { + Janus.error('Unhandled httpAPICall success callback error', error); + } + }, function(error) { + return p.reject({message: 'Failed to parse response body', error: error, response: response}); + }); + } + } + else { + return p.reject({message: 'API call failed', response: response}); + } + }).catch(function(error) { + if(typeof(options.error) === typeof(Janus.noop)) { + options.error(error.message || '<< internal error >>', error); + } + }); + + return fetching; + } + } +}; + +Janus.useOldDependencies = function (deps) { + var jq = (deps && deps.jQuery) || jQuery; + var socketCls = (deps && deps.WebSocket) || WebSocket; + return { + newWebSocket: function(server, proto) { return new socketCls(server, proto); }, + isArray: function(arr) { return jq.isArray(arr); }, + extension: (deps && deps.extension) || defaultExtension, + webRTCAdapter: (deps && deps.adapter) || adapter, + httpAPICall: function(url, options) { + var payload = options.body !== undefined ? { + contentType: 'application/json', + data: JSON.stringify(options.body) + } : {}; + var credentials = options.withCredentials !== undefined ? {xhrFields: {withCredentials: options.withCredentials}} : {}; + + return jq.ajax(jq.extend(payload, credentials, { + url: url, + type: options.verb, + cache: false, + dataType: 'json', + async: options.async, + timeout: options.timeout, + success: function(result) { + if(typeof(options.success) === typeof(Janus.noop)) { + options.success(result); + } + }, + error: function(xhr, status, err) { + if(typeof(options.error) === typeof(Janus.noop)) { + options.error(status, err); + } + } + })); + } + }; +}; + +Janus.noop = function() {}; + +Janus.dataChanDefaultLabel = "JanusDataChannel"; + +// Note: in the future we may want to change this, e.g., as was +// attempted in https://github.com/meetecho/janus-gateway/issues/1670 +Janus.endOfCandidates = null; + +// Stop all tracks from a given stream +Janus.stopAllTracks = function(stream) { + try { + // Try a MediaStreamTrack.stop() for each track + var tracks = stream.getTracks(); + for(var mst of tracks) { + Janus.log(mst); + if(mst) { + mst.stop(); + } + } + } catch(e) { + // Do nothing if this fails + } +} + +// Initialization +Janus.init = function(options) { + options = options || {}; + options.callback = (typeof options.callback == "function") ? options.callback : Janus.noop; + if(Janus.initDone) { + // Already initialized + options.callback(); + } else { + if(typeof console.log == "undefined") { + console.log = function() {}; + } + // Console logging (all debugging disabled by default) + Janus.trace = Janus.noop; + Janus.debug = Janus.noop; + Janus.vdebug = Janus.noop; + Janus.log = Janus.noop; + Janus.warn = Janus.noop; + Janus.error = Janus.noop; + if(options.debug === true || options.debug === "all") { + // Enable all debugging levels + Janus.trace = console.trace.bind(console); + Janus.debug = console.debug.bind(console); + Janus.vdebug = console.debug.bind(console); + Janus.log = console.log.bind(console); + Janus.warn = console.warn.bind(console); + Janus.error = console.error.bind(console); + } else if(Array.isArray(options.debug)) { + for(var d of options.debug) { + switch(d) { + case "trace": + Janus.trace = console.trace.bind(console); + break; + case "debug": + Janus.debug = console.debug.bind(console); + break; + case "vdebug": + Janus.vdebug = console.debug.bind(console); + break; + case "log": + Janus.log = console.log.bind(console); + break; + case "warn": + Janus.warn = console.warn.bind(console); + break; + case "error": + Janus.error = console.error.bind(console); + break; + default: + console.error("Unknown debugging option '" + d + "' (supported: 'trace', 'debug', 'vdebug', 'log', warn', 'error')"); + break; + } + } + } + Janus.log("Initializing library"); + + var usedDependencies = options.dependencies || Janus.useDefaultDependencies(); + Janus.isArray = usedDependencies.isArray; + Janus.webRTCAdapter = usedDependencies.webRTCAdapter; + Janus.httpAPICall = usedDependencies.httpAPICall; + Janus.newWebSocket = usedDependencies.newWebSocket; + Janus.extension = usedDependencies.extension; + Janus.extension.init(); + + // Helper method to enumerate devices + Janus.listDevices = function(callback, config) { + callback = (typeof callback == "function") ? callback : Janus.noop; + if (config == null) config = { audio: true, video: true }; + if(Janus.isGetUserMediaAvailable()) { + navigator.mediaDevices.getUserMedia(config) + .then(function(stream) { + navigator.mediaDevices.enumerateDevices().then(function(devices) { + Janus.debug(devices); + callback(devices); + // Get rid of the now useless stream + Janus.stopAllTracks(stream) + }); + }) + .catch(function(err) { + Janus.error(err); + callback([]); + }); + } else { + Janus.warn("navigator.mediaDevices unavailable"); + callback([]); + } + }; + // Helper methods to attach/reattach a stream to a video element (previously part of adapter.js) + Janus.attachMediaStream = function(element, stream) { + try { + element.srcObject = stream; + } catch (e) { + try { + element.src = URL.createObjectURL(stream); + } catch (e) { + Janus.error("Error attaching stream to element"); + } + } + }; + Janus.reattachMediaStream = function(to, from) { + try { + to.srcObject = from.srcObject; + } catch (e) { + try { + to.src = from.src; + } catch (e) { + Janus.error("Error reattaching stream to element"); + } + } + }; + // Detect tab close: make sure we don't loose existing onbeforeunload handlers + // (note: for iOS we need to subscribe to a different event, 'pagehide', see + // https://gist.github.com/thehunmonkgroup/6bee8941a49b86be31a787fe8f4b8cfe) + var iOS = ['iPad', 'iPhone', 'iPod'].indexOf(navigator.platform) >= 0; + var eventName = iOS ? 'pagehide' : 'beforeunload'; + var oldOBF = window["on" + eventName]; + window.addEventListener(eventName, function() { + Janus.log("Closing window"); + for(var s in Janus.sessions) { + if(Janus.sessions[s] && Janus.sessions[s].destroyOnUnload) { + Janus.log("Destroying session " + s); + Janus.sessions[s].destroy({unload: true, notifyDestroyed: false}); + } + } + if(oldOBF && typeof oldOBF == "function") { + oldOBF(); + } + }); + // If this is a Safari Technology Preview, check if VP8 is supported + Janus.safariVp8 = false; + if(Janus.webRTCAdapter.browserDetails.browser === 'safari' && + Janus.webRTCAdapter.browserDetails.version >= 605) { + // Let's see if RTCRtpSender.getCapabilities() is there + if(RTCRtpSender && RTCRtpSender.getCapabilities && RTCRtpSender.getCapabilities("video") && + RTCRtpSender.getCapabilities("video").codecs && RTCRtpSender.getCapabilities("video").codecs.length) { + for(var codec of RTCRtpSender.getCapabilities("video").codecs) { + if(codec && codec.mimeType && codec.mimeType.toLowerCase() === "video/vp8") { + Janus.safariVp8 = true; + break; + } + } + if(Janus.safariVp8) { + Janus.log("This version of Safari supports VP8"); + } else { + Janus.warn("This version of Safari does NOT support VP8: if you're using a Technology Preview, " + + "try enabling the 'WebRTC VP8 codec' setting in the 'Experimental Features' Develop menu"); + } + } else { + // We do it in a very ugly way, as there's no alternative... + // We create a PeerConnection to see if VP8 is in an offer + var testpc = new RTCPeerConnection({}); + testpc.createOffer({offerToReceiveVideo: true}).then(function(offer) { + Janus.safariVp8 = offer.sdp.indexOf("VP8") !== -1; + if(Janus.safariVp8) { + Janus.log("This version of Safari supports VP8"); + } else { + Janus.warn("This version of Safari does NOT support VP8: if you're using a Technology Preview, " + + "try enabling the 'WebRTC VP8 codec' setting in the 'Experimental Features' Develop menu"); + } + testpc.close(); + testpc = null; + }); + } + } + // Check if this browser supports Unified Plan and transceivers + // Based on https://codepen.io/anon/pen/ZqLwWV?editors=0010 + Janus.unifiedPlan = false; + if(Janus.webRTCAdapter.browserDetails.browser === 'firefox' && + Janus.webRTCAdapter.browserDetails.version >= 59) { + // Firefox definitely does, starting from version 59 + Janus.unifiedPlan = true; + } else if(Janus.webRTCAdapter.browserDetails.browser === 'chrome' && + Janus.webRTCAdapter.browserDetails.version >= 72) { + // Chrome does, but it's only usable from version 72 on + Janus.unifiedPlan = true; + } else if(!window.RTCRtpTransceiver || !('currentDirection' in RTCRtpTransceiver.prototype)) { + // Safari supports addTransceiver() but not Unified Plan when + // currentDirection is not defined (see codepen above). + Janus.unifiedPlan = false; + } else { + // Check if addTransceiver() throws an exception + var tempPc = new RTCPeerConnection(); + try { + tempPc.addTransceiver('audio'); + Janus.unifiedPlan = true; + } catch (e) {} + tempPc.close(); + } + Janus.initDone = true; + options.callback(); + } +}; + +// Helper method to check whether WebRTC is supported by this browser +Janus.isWebrtcSupported = function() { + return !!window.RTCPeerConnection; +}; +// Helper method to check whether devices can be accessed by this browser (e.g., not possible via plain HTTP) +Janus.isGetUserMediaAvailable = function() { + return navigator.mediaDevices && navigator.mediaDevices.getUserMedia; +}; + +// Helper method to create random identifiers (e.g., transaction) +Janus.randomString = function(len) { + var charSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + var randomString = ''; + for (var i = 0; i < len; i++) { + var randomPoz = Math.floor(Math.random() * charSet.length); + randomString += charSet.substring(randomPoz,randomPoz+1); + } + return randomString; +}; + +function Janus(gatewayCallbacks) { + gatewayCallbacks = gatewayCallbacks || {}; + gatewayCallbacks.success = (typeof gatewayCallbacks.success == "function") ? gatewayCallbacks.success : Janus.noop; + gatewayCallbacks.error = (typeof gatewayCallbacks.error == "function") ? gatewayCallbacks.error : Janus.noop; + gatewayCallbacks.destroyed = (typeof gatewayCallbacks.destroyed == "function") ? gatewayCallbacks.destroyed : Janus.noop; + if(!Janus.initDone) { + gatewayCallbacks.error("Library not initialized"); + return {}; + } + if(!Janus.isWebrtcSupported()) { + gatewayCallbacks.error("WebRTC not supported by this browser"); + return {}; + } + Janus.log("Library initialized: " + Janus.initDone); + if(!gatewayCallbacks.server) { + gatewayCallbacks.error("Invalid server url"); + return {}; + } + var websockets = false; + var ws = null; + var wsHandlers = {}; + var wsKeepaliveTimeoutId = null; + var servers = null; + var serversIndex = 0; + var server = gatewayCallbacks.server; + if(Janus.isArray(server)) { + Janus.log("Multiple servers provided (" + server.length + "), will use the first that works"); + server = null; + servers = gatewayCallbacks.server; + Janus.debug(servers); + } else { + if(server.indexOf("ws") === 0) { + websockets = true; + Janus.log("Using WebSockets to contact Janus: " + server); + } else { + websockets = false; + Janus.log("Using REST API to contact Janus: " + server); + } + } + var iceServers = gatewayCallbacks.iceServers || [{urls: "stun:stun.l.google.com:19302"}]; + var iceTransportPolicy = gatewayCallbacks.iceTransportPolicy; + var bundlePolicy = gatewayCallbacks.bundlePolicy; + // Whether IPv6 candidates should be gathered + var ipv6Support = (gatewayCallbacks.ipv6 === true); + // Whether we should enable the withCredentials flag for XHR requests + var withCredentials = false; + if(gatewayCallbacks.withCredentials !== undefined && gatewayCallbacks.withCredentials !== null) + withCredentials = gatewayCallbacks.withCredentials === true; + // Optional max events + var maxev = 10; + if(gatewayCallbacks.max_poll_events !== undefined && gatewayCallbacks.max_poll_events !== null) + maxev = gatewayCallbacks.max_poll_events; + if(maxev < 1) + maxev = 1; + // Token to use (only if the token based authentication mechanism is enabled) + var token = null; + if(gatewayCallbacks.token !== undefined && gatewayCallbacks.token !== null) + token = gatewayCallbacks.token; + // API secret to use (only if the shared API secret is enabled) + var apisecret = null; + if(gatewayCallbacks.apisecret !== undefined && gatewayCallbacks.apisecret !== null) + apisecret = gatewayCallbacks.apisecret; + // Whether we should destroy this session when onbeforeunload is called + this.destroyOnUnload = true; + if(gatewayCallbacks.destroyOnUnload !== undefined && gatewayCallbacks.destroyOnUnload !== null) + this.destroyOnUnload = (gatewayCallbacks.destroyOnUnload === true); + // Some timeout-related values + var keepAlivePeriod = 25000; + if(gatewayCallbacks.keepAlivePeriod !== undefined && gatewayCallbacks.keepAlivePeriod !== null) + keepAlivePeriod = gatewayCallbacks.keepAlivePeriod; + if(isNaN(keepAlivePeriod)) + keepAlivePeriod = 25000; + var longPollTimeout = 60000; + if(gatewayCallbacks.longPollTimeout !== undefined && gatewayCallbacks.longPollTimeout !== null) + longPollTimeout = gatewayCallbacks.longPollTimeout; + if(isNaN(longPollTimeout)) + longPollTimeout = 60000; + + // overrides for default maxBitrate values for simulcasting + function getMaxBitrates(simulcastMaxBitrates) { + var maxBitrates = { + high: 900000, + medium: 300000, + low: 100000, + }; + + if (simulcastMaxBitrates !== undefined && simulcastMaxBitrates !== null) { + if (simulcastMaxBitrates.high) + maxBitrates.high = simulcastMaxBitrates.high; + if (simulcastMaxBitrates.medium) + maxBitrates.medium = simulcastMaxBitrates.medium; + if (simulcastMaxBitrates.low) + maxBitrates.low = simulcastMaxBitrates.low; + } + + return maxBitrates; + } + + var connected = false; + var sessionId = null; + var pluginHandles = {}; + var that = this; + var retries = 0; + var transactions = {}; + createSession(gatewayCallbacks); + + // Public methods + this.getServer = function() { return server; }; + this.isConnected = function() { return connected; }; + this.reconnect = function(callbacks) { + callbacks = callbacks || {}; + callbacks.success = (typeof callbacks.success == "function") ? callbacks.success : Janus.noop; + callbacks.error = (typeof callbacks.error == "function") ? callbacks.error : Janus.noop; + callbacks["reconnect"] = true; + createSession(callbacks); + }; + this.getSessionId = function() { return sessionId; }; + this.getInfo = function(callbacks) { getInfo(callbacks); }; + this.destroy = function(callbacks) { destroySession(callbacks); }; + this.attach = function(callbacks) { createHandle(callbacks); }; + + function eventHandler() { + if(sessionId == null) + return; + Janus.debug('Long poll...'); + if(!connected) { + Janus.warn("Is the server down? (connected=false)"); + return; + } + var longpoll = server + "/" + sessionId + "?rid=" + new Date().getTime(); + if(maxev) + longpoll = longpoll + "&maxev=" + maxev; + if(token) + longpoll = longpoll + "&token=" + encodeURIComponent(token); + if(apisecret) + longpoll = longpoll + "&apisecret=" + encodeURIComponent(apisecret); + Janus.httpAPICall(longpoll, { + verb: 'GET', + withCredentials: withCredentials, + success: handleEvent, + timeout: longPollTimeout, + error: function(textStatus, errorThrown) { + Janus.error(textStatus + ":", errorThrown); + retries++; + if(retries > 3) { + // Did we just lose the server? :-( + connected = false; + gatewayCallbacks.error("Lost connection to the server (is it down?)"); + return; + } + eventHandler(); + } + }); + } + + // Private event handler: this will trigger plugin callbacks, if set + function handleEvent(json, skipTimeout) { + retries = 0; + if(!websockets && sessionId !== undefined && sessionId !== null && skipTimeout !== true) + eventHandler(); + if(!websockets && Janus.isArray(json)) { + // We got an array: it means we passed a maxev > 1, iterate on all objects + for(var i=0; i data channel: ' + dcState); + if(dcState === 'open') { + // Any pending messages to send? + if(config.dataChannel[label].pending && config.dataChannel[label].pending.length > 0) { + Janus.log("Sending pending messages on <" + label + ">:", config.dataChannel[label].pending.length); + for(var data of config.dataChannel[label].pending) { + Janus.log("Sending data on data channel <" + label + ">"); + Janus.debug(data); + config.dataChannel[label].send(data); + } + config.dataChannel[label].pending = []; + } + // Notify the open data channel + pluginHandle.ondataopen(label, protocol); + } + }; + var onDataChannelError = function(error) { + Janus.error('Got error on data channel:', error); + // TODO + }; + if(!incoming) { + // FIXME Add options (ordered, maxRetransmits, etc.) + var dcoptions = { ordered: true }; + if(dcprotocol) + dcoptions.protocol = dcprotocol; + config.dataChannel[dclabel] = config.pc.createDataChannel(dclabel, dcoptions); + } else { + // The channel was created by Janus + config.dataChannel[dclabel] = incoming; + } + config.dataChannel[dclabel].onmessage = onDataChannelMessage; + config.dataChannel[dclabel].onopen = onDataChannelStateChange; + config.dataChannel[dclabel].onclose = onDataChannelStateChange; + config.dataChannel[dclabel].onerror = onDataChannelError; + config.dataChannel[dclabel].pending = []; + if(pendingData) + config.dataChannel[dclabel].pending.push(pendingData); + } + + // Private method to send a data channel message + function sendData(handleId, callbacks) { + callbacks = callbacks || {}; + callbacks.success = (typeof callbacks.success == "function") ? callbacks.success : Janus.noop; + callbacks.error = (typeof callbacks.error == "function") ? callbacks.error : Janus.noop; + var pluginHandle = pluginHandles[handleId]; + if(!pluginHandle || !pluginHandle.webrtcStuff) { + Janus.warn("Invalid handle"); + callbacks.error("Invalid handle"); + return; + } + var config = pluginHandle.webrtcStuff; + var data = callbacks.text || callbacks.data; + if(!data) { + Janus.warn("Invalid data"); + callbacks.error("Invalid data"); + return; + } + var label = callbacks.label ? callbacks.label : Janus.dataChanDefaultLabel; + if(!config.dataChannel[label]) { + // Create new data channel and wait for it to open + createDataChannel(handleId, label, callbacks.protocol, false, data, callbacks.protocol); + callbacks.success(); + return; + } + if(config.dataChannel[label].readyState !== "open") { + config.dataChannel[label].pending.push(data); + callbacks.success(); + return; + } + Janus.log("Sending data on data channel <" + label + ">"); + Janus.debug(data); + config.dataChannel[label].send(data); + callbacks.success(); + } + + // Private method to send a DTMF tone + function sendDtmf(handleId, callbacks) { + callbacks = callbacks || {}; + callbacks.success = (typeof callbacks.success == "function") ? callbacks.success : Janus.noop; + callbacks.error = (typeof callbacks.error == "function") ? callbacks.error : Janus.noop; + var pluginHandle = pluginHandles[handleId]; + if(!pluginHandle || !pluginHandle.webrtcStuff) { + Janus.warn("Invalid handle"); + callbacks.error("Invalid handle"); + return; + } + var config = pluginHandle.webrtcStuff; + if(!config.dtmfSender) { + // Create the DTMF sender the proper way, if possible + if(config.pc) { + var senders = config.pc.getSenders(); + var audioSender = senders.find(function(sender) { + return sender.track && sender.track.kind === 'audio'; + }); + if(!audioSender) { + Janus.warn("Invalid DTMF configuration (no audio track)"); + callbacks.error("Invalid DTMF configuration (no audio track)"); + return; + } + config.dtmfSender = audioSender.dtmf; + if(config.dtmfSender) { + Janus.log("Created DTMF Sender"); + config.dtmfSender.ontonechange = function(tone) { Janus.debug("Sent DTMF tone: " + tone.tone); }; + } + } + if(!config.dtmfSender) { + Janus.warn("Invalid DTMF configuration"); + callbacks.error("Invalid DTMF configuration"); + return; + } + } + var dtmf = callbacks.dtmf; + if(!dtmf) { + Janus.warn("Invalid DTMF parameters"); + callbacks.error("Invalid DTMF parameters"); + return; + } + var tones = dtmf.tones; + if(!tones) { + Janus.warn("Invalid DTMF string"); + callbacks.error("Invalid DTMF string"); + return; + } + var duration = (typeof dtmf.duration === 'number') ? dtmf.duration : 500; // We choose 500ms as the default duration for a tone + var gap = (typeof dtmf.gap === 'number') ? dtmf.gap : 50; // We choose 50ms as the default gap between tones + Janus.debug("Sending DTMF string " + tones + " (duration " + duration + "ms, gap " + gap + "ms)"); + config.dtmfSender.insertDTMF(tones, duration, gap); + callbacks.success(); + } + + // Private method to destroy a plugin handle + function destroyHandle(handleId, callbacks) { + callbacks = callbacks || {}; + callbacks.success = (typeof callbacks.success == "function") ? callbacks.success : Janus.noop; + callbacks.error = (typeof callbacks.error == "function") ? callbacks.error : Janus.noop; + var noRequest = (callbacks.noRequest === true); + Janus.log("Destroying handle " + handleId + " (only-locally=" + noRequest + ")"); + cleanupWebrtc(handleId); + var pluginHandle = pluginHandles[handleId]; + if(!pluginHandle || pluginHandle.detached) { + // Plugin was already detached by Janus, calling detach again will return a handle not found error, so just exit here + delete pluginHandles[handleId]; + callbacks.success(); + return; + } + pluginHandle.detached = true; + if(noRequest) { + // We're only removing the handle locally + delete pluginHandles[handleId]; + callbacks.success(); + return; + } + if(!connected) { + Janus.warn("Is the server down? (connected=false)"); + callbacks.error("Is the server down? (connected=false)"); + return; + } + var request = { "janus": "detach", "transaction": Janus.randomString(12) }; + if(pluginHandle.token) + request["token"] = pluginHandle.token; + if(apisecret) + request["apisecret"] = apisecret; + if(websockets) { + request["session_id"] = sessionId; + request["handle_id"] = handleId; + ws.send(JSON.stringify(request)); + delete pluginHandles[handleId]; + callbacks.success(); + return; + } + Janus.httpAPICall(server + "/" + sessionId + "/" + handleId, { + verb: 'POST', + withCredentials: withCredentials, + body: request, + success: function(json) { + Janus.log("Destroyed handle:"); + Janus.debug(json); + if(json["janus"] !== "success") { + Janus.error("Ooops: " + json["error"].code + " " + json["error"].reason); // FIXME + } + delete pluginHandles[handleId]; + callbacks.success(); + }, + error: function(textStatus, errorThrown) { + Janus.error(textStatus + ":", errorThrown); // FIXME + // We cleanup anyway + delete pluginHandles[handleId]; + callbacks.success(); + } + }); + } + + // WebRTC stuff + function streamsDone(handleId, jsep, media, callbacks, stream) { + var pluginHandle = pluginHandles[handleId]; + if(!pluginHandle || !pluginHandle.webrtcStuff) { + Janus.warn("Invalid handle"); + // Close all tracks if the given stream has been created internally + if(!callbacks.stream) { + Janus.stopAllTracks(stream); + } + callbacks.error("Invalid handle"); + return; + } + var config = pluginHandle.webrtcStuff; + Janus.debug("streamsDone:", stream); + if(stream) { + Janus.debug(" -- Audio tracks:", stream.getAudioTracks()); + Janus.debug(" -- Video tracks:", stream.getVideoTracks()); + } + // We're now capturing the new stream: check if we're updating or if it's a new thing + var addTracks = false; + if(!config.myStream || !media.update || (config.streamExternal && !media.replaceAudio && !media.replaceVideo)) { + config.myStream = stream; + addTracks = true; + } else { + // We only need to update the existing stream + if(((!media.update && isAudioSendEnabled(media)) || (media.update && (media.addAudio || media.replaceAudio))) && + stream.getAudioTracks() && stream.getAudioTracks().length) { + config.myStream.addTrack(stream.getAudioTracks()[0]); + if(Janus.unifiedPlan) { + // Use Transceivers + Janus.log((media.replaceAudio ? "Replacing" : "Adding") + " audio track:", stream.getAudioTracks()[0]); + var audioTransceiver = null; + const transceivers = config.pc.getTransceivers(); + if(transceivers && transceivers.length > 0) { + for(const t of transceivers) { + if((t.sender && t.sender.track && t.sender.track.kind === "audio") || + (t.receiver && t.receiver.track && t.receiver.track.kind === "audio")) { + audioTransceiver = t; + break; + } + } + } + if(audioTransceiver && audioTransceiver.sender) { + audioTransceiver.sender.replaceTrack(stream.getAudioTracks()[0]); + } else { + config.pc.addTrack(stream.getAudioTracks()[0], stream); + } + } else { + Janus.log((media.replaceAudio ? "Replacing" : "Adding") + " audio track:", stream.getAudioTracks()[0]); + config.pc.addTrack(stream.getAudioTracks()[0], stream); + } + } + if(((!media.update && isVideoSendEnabled(media)) || (media.update && (media.addVideo || media.replaceVideo))) && + stream.getVideoTracks() && stream.getVideoTracks().length) { + config.myStream.addTrack(stream.getVideoTracks()[0]); + if(Janus.unifiedPlan) { + // Use Transceivers + Janus.log((media.replaceVideo ? "Replacing" : "Adding") + " video track:", stream.getVideoTracks()[0]); + var videoTransceiver = null; + const transceivers = config.pc.getTransceivers(); + if(transceivers && transceivers.length > 0) { + for(const t of transceivers) { + if((t.sender && t.sender.track && t.sender.track.kind === "video") || + (t.receiver && t.receiver.track && t.receiver.track.kind === "video")) { + videoTransceiver = t; + break; + } + } + } + if(videoTransceiver && videoTransceiver.sender) { + videoTransceiver.sender.replaceTrack(stream.getVideoTracks()[0]); + } else { + config.pc.addTrack(stream.getVideoTracks()[0], stream); + } + } else { + Janus.log((media.replaceVideo ? "Replacing" : "Adding") + " video track:", stream.getVideoTracks()[0]); + config.pc.addTrack(stream.getVideoTracks()[0], stream); + } + } + } + // If we still need to create a PeerConnection, let's do that + if(!config.pc) { + var pc_config = {"iceServers": iceServers, "iceTransportPolicy": iceTransportPolicy, "bundlePolicy": bundlePolicy}; + if(Janus.webRTCAdapter.browserDetails.browser === "chrome") { + // For Chrome versions before 72, we force a plan-b semantic, and unified-plan otherwise + pc_config["sdpSemantics"] = (Janus.webRTCAdapter.browserDetails.version < 72) ? "plan-b" : "unified-plan"; + } + var pc_constraints = { + "optional": [{"DtlsSrtpKeyAgreement": true}] + }; + if(ipv6Support) { + pc_constraints.optional.push({"googIPv6":true}); + } + // Any custom constraint to add? + if(callbacks.rtcConstraints && typeof callbacks.rtcConstraints === 'object') { + Janus.debug("Adding custom PeerConnection constraints:", callbacks.rtcConstraints); + for(var i in callbacks.rtcConstraints) { + pc_constraints.optional.push(callbacks.rtcConstraints[i]); + } + } + if(Janus.webRTCAdapter.browserDetails.browser === "edge") { + // This is Edge, enable BUNDLE explicitly + pc_config.bundlePolicy = "max-bundle"; + } + // Check if a sender or receiver transform has been provided + if(RTCRtpSender && (RTCRtpSender.prototype.createEncodedStreams || + (RTCRtpSender.prototype.createEncodedAudioStreams && + RTCRtpSender.prototype.createEncodedVideoStreams)) && + (callbacks.senderTransforms || callbacks.receiverTransforms)) { + config.senderTransforms = callbacks.senderTransforms; + config.receiverTransforms = callbacks.receiverTransforms; + pc_config["forceEncodedAudioInsertableStreams"] = true; + pc_config["forceEncodedVideoInsertableStreams"] = true; + pc_config["encodedInsertableStreams"] = true; + } + Janus.log("Creating PeerConnection"); + Janus.debug(pc_constraints); + config.pc = new RTCPeerConnection(pc_config, pc_constraints); + Janus.debug(config.pc); + if(config.pc.getStats) { // FIXME + config.volume = {}; + config.bitrate.value = "0 kbits/sec"; + } + Janus.log("Preparing local SDP and gathering candidates (trickle=" + config.trickle + ")"); + config.pc.oniceconnectionstatechange = function() { + if(config.pc) + pluginHandle.iceState(config.pc.iceConnectionState); + }; + config.pc.onicecandidate = function(event) { + if (!event.candidate || + (Janus.webRTCAdapter.browserDetails.browser === 'edge' && event.candidate.candidate.indexOf('endOfCandidates') > 0)) { + Janus.log("End of candidates."); + config.iceDone = true; + if(config.trickle === true) { + // Notify end of candidates + sendTrickleCandidate(handleId, {"completed": true}); + } else { + // No trickle, time to send the complete SDP (including all candidates) + sendSDP(handleId, callbacks); + } + } else { + // JSON.stringify doesn't work on some WebRTC objects anymore + // See https://code.google.com/p/chromium/issues/detail?id=467366 + var candidate = { + "candidate": event.candidate.candidate, + "sdpMid": event.candidate.sdpMid, + "sdpMLineIndex": event.candidate.sdpMLineIndex + }; + if(config.trickle === true) { + // Send candidate + sendTrickleCandidate(handleId, candidate); + } + } + }; + config.pc.ontrack = function(event) { + Janus.log("Handling Remote Track"); + Janus.debug(event); + if(!event.streams) + return; + config.remoteStream = event.streams[0]; + pluginHandle.onremotestream(config.remoteStream); + if(event.track.onended) + return; + if(config.receiverTransforms) { + var receiverStreams = null; + if(RTCRtpSender.prototype.createEncodedStreams) { + receiverStreams = event.receiver.createEncodedStreams(); + } else if(RTCRtpSender.prototype.createAudioEncodedStreams || RTCRtpSender.prototype.createEncodedVideoStreams) { + if(event.track.kind === "audio" && config.receiverTransforms["audio"]) { + receiverStreams = event.receiver.createEncodedAudioStreams(); + } else if(event.track.kind === "video" && config.receiverTransforms["video"]) { + receiverStreams = event.receiver.createEncodedVideoStreams(); + } + } + if(receiverStreams) { + console.log(receiverStreams); + if(receiverStreams.readableStream && receiverStreams.writableStream) { + receiverStreams.readableStream + .pipeThrough(config.receiverTransforms[event.track.kind]) + .pipeTo(receiverStreams.writableStream); + } else if(receiverStreams.readable && receiverStreams.writable) { + receiverStreams.readable + .pipeThrough(config.receiverTransforms[event.track.kind]) + .pipeTo(receiverStreams.writable); + } + } + } + var trackMutedTimeoutId = null; + Janus.log("Adding onended callback to track:", event.track); + event.track.onended = function(ev) { + Janus.log("Remote track removed:", ev); + if(config.remoteStream) { + clearTimeout(trackMutedTimeoutId); + config.remoteStream.removeTrack(ev.target); + pluginHandle.onremotestream(config.remoteStream); + } + }; + event.track.onmute = function(ev) { + Janus.log("Remote track muted:", ev); + if(config.remoteStream && trackMutedTimeoutId == null) { + trackMutedTimeoutId = setTimeout(function() { + Janus.log("Removing remote track"); + if (config.remoteStream) { + config.remoteStream.removeTrack(ev.target); + pluginHandle.onremotestream(config.remoteStream); + } + trackMutedTimeoutId = null; + // Chrome seems to raise mute events only at multiples of 834ms; + // we set the timeout to three times this value (rounded to 840ms) + }, 3 * 840); + } + }; + event.track.onunmute = function(ev) { + Janus.log("Remote track flowing again:", ev); + if(trackMutedTimeoutId != null) { + clearTimeout(trackMutedTimeoutId); + trackMutedTimeoutId = null; + } else { + try { + config.remoteStream.addTrack(ev.target); + pluginHandle.onremotestream(config.remoteStream); + } catch(e) { + Janus.error(e); + } + } + }; + }; + } + if(addTracks && stream) { + Janus.log('Adding local stream'); + var simulcast2 = (callbacks.simulcast2 === true); + stream.getTracks().forEach(function(track) { + Janus.log('Adding local track:', track); + var sender = null; + if(!simulcast2 || track.kind === 'audio') { + sender = config.pc.addTrack(track, stream); + } else { + Janus.log('Enabling rid-based simulcasting:', track); + var maxBitrates = getMaxBitrates(callbacks.simulcastMaxBitrates); + var tr = config.pc.addTransceiver(track, { + direction: "sendrecv", + streams: [stream], + sendEncodings: callbacks.sendEncodings || [ + { rid: "h", active: true, maxBitrate: maxBitrates.high }, + { rid: "m", active: true, maxBitrate: maxBitrates.medium, scaleResolutionDownBy: 2 }, + { rid: "l", active: true, maxBitrate: maxBitrates.low, scaleResolutionDownBy: 4 } + ] + }); + if(tr) + sender = tr.sender; + } + // Check if insertable streams are involved + if(sender && config.senderTransforms) { + var senderStreams = null; + if(RTCRtpSender.prototype.createEncodedStreams) { + senderStreams = sender.createEncodedStreams(); + } else if(RTCRtpSender.prototype.createAudioEncodedStreams || RTCRtpSender.prototype.createEncodedVideoStreams) { + if(sender.track.kind === "audio" && config.senderTransforms["audio"]) { + senderStreams = sender.createEncodedAudioStreams(); + } else if(sender.track.kind === "video" && config.senderTransforms["video"]) { + senderStreams = sender.createEncodedVideoStreams(); + } + } + if(senderStreams) { + console.log(senderStreams); + if(senderStreams.readableStream && senderStreams.writableStream) { + senderStreams.readableStream + .pipeThrough(config.senderTransforms[sender.track.kind]) + .pipeTo(senderStreams.writableStream); + } else if(senderStreams.readable && senderStreams.writable) { + senderStreams.readable + .pipeThrough(config.senderTransforms[sender.track.kind]) + .pipeTo(senderStreams.writable); + } + } + } + }); + } + // Any data channel to create? + if(isDataEnabled(media) && !config.dataChannel[Janus.dataChanDefaultLabel]) { + Janus.log("Creating default data channel"); + createDataChannel(handleId, Janus.dataChanDefaultLabel, null, false); + config.pc.ondatachannel = function(event) { + Janus.log("Data channel created by Janus:", event); + createDataChannel(handleId, event.channel.label, event.channel.protocol, event.channel); + }; + } + // If there's a new local stream, let's notify the application + if(config.myStream) { + pluginHandle.onlocalstream(config.myStream); + } + // Create offer/answer now + if(!jsep) { + createOffer(handleId, media, callbacks); + } else { + config.pc.setRemoteDescription(jsep) + .then(function() { + Janus.log("Remote description accepted!"); + config.remoteSdp = jsep.sdp; + // Any trickle candidate we cached? + if(config.candidates && config.candidates.length > 0) { + for(var i = 0; i< config.candidates.length; i++) { + var candidate = config.candidates[i]; + Janus.debug("Adding remote candidate:", candidate); + if(!candidate || candidate.completed === true) { + // end-of-candidates + config.pc.addIceCandidate(Janus.endOfCandidates); + } else { + // New candidate + config.pc.addIceCandidate(candidate); + } + } + config.candidates = []; + } + // Create the answer now + createAnswer(handleId, media, callbacks); + }, callbacks.error); + } + } + + function prepareWebrtc(handleId, offer, callbacks) { + callbacks = callbacks || {}; + callbacks.success = (typeof callbacks.success == "function") ? callbacks.success : Janus.noop; + callbacks.error = (typeof callbacks.error == "function") ? callbacks.error : webrtcError; + var jsep = callbacks.jsep; + if(offer && jsep) { + Janus.error("Provided a JSEP to a createOffer"); + callbacks.error("Provided a JSEP to a createOffer"); + return; + } else if(!offer && (!jsep || !jsep.type || !jsep.sdp)) { + Janus.error("A valid JSEP is required for createAnswer"); + callbacks.error("A valid JSEP is required for createAnswer"); + return; + } + /* Check that callbacks.media is a (not null) Object */ + callbacks.media = (typeof callbacks.media === 'object' && callbacks.media) ? callbacks.media : { audio: true, video: true }; + var media = callbacks.media; + var pluginHandle = pluginHandles[handleId]; + if(!pluginHandle || !pluginHandle.webrtcStuff) { + Janus.warn("Invalid handle"); + callbacks.error("Invalid handle"); + return; + } + var config = pluginHandle.webrtcStuff; + config.trickle = isTrickleEnabled(callbacks.trickle); + // Are we updating a session? + if(!config.pc) { + // Nope, new PeerConnection + media.update = false; + media.keepAudio = false; + media.keepVideo = false; + } else { + Janus.log("Updating existing media session"); + media.update = true; + // Check if there's anything to add/remove/replace, or if we + // can go directly to preparing the new SDP offer or answer + if(callbacks.stream) { + // External stream: is this the same as the one we were using before? + if(callbacks.stream !== config.myStream) { + Janus.log("Renegotiation involves a new external stream"); + } + } else { + // Check if there are changes on audio + if(media.addAudio) { + media.keepAudio = false; + media.replaceAudio = false; + media.removeAudio = false; + media.audioSend = true; + if(config.myStream && config.myStream.getAudioTracks() && config.myStream.getAudioTracks().length) { + Janus.error("Can't add audio stream, there already is one"); + callbacks.error("Can't add audio stream, there already is one"); + return; + } + } else if(media.removeAudio) { + media.keepAudio = false; + media.replaceAudio = false; + media.addAudio = false; + media.audioSend = false; + } else if(media.replaceAudio) { + media.keepAudio = false; + media.addAudio = false; + media.removeAudio = false; + media.audioSend = true; + } + if(!config.myStream) { + // No media stream: if we were asked to replace, it's actually an "add" + if(media.replaceAudio) { + media.keepAudio = false; + media.replaceAudio = false; + media.addAudio = true; + media.audioSend = true; + } + if(isAudioSendEnabled(media)) { + media.keepAudio = false; + media.addAudio = true; + } + } else { + if(!config.myStream.getAudioTracks() || config.myStream.getAudioTracks().length === 0) { + // No audio track: if we were asked to replace, it's actually an "add" + if(media.replaceAudio) { + media.keepAudio = false; + media.replaceAudio = false; + media.addAudio = true; + media.audioSend = true; + } + if(isAudioSendEnabled(media)) { + media.keepAudio = false; + media.addAudio = true; + } + } else { + // We have an audio track: should we keep it as it is? + if(isAudioSendEnabled(media) && + !media.removeAudio && !media.replaceAudio) { + media.keepAudio = true; + } + } + } + // Check if there are changes on video + if(media.addVideo) { + media.keepVideo = false; + media.replaceVideo = false; + media.removeVideo = false; + media.videoSend = true; + if(config.myStream && config.myStream.getVideoTracks() && config.myStream.getVideoTracks().length) { + Janus.error("Can't add video stream, there already is one"); + callbacks.error("Can't add video stream, there already is one"); + return; + } + } else if(media.removeVideo) { + media.keepVideo = false; + media.replaceVideo = false; + media.addVideo = false; + media.videoSend = false; + } else if(media.replaceVideo) { + media.keepVideo = false; + media.addVideo = false; + media.removeVideo = false; + media.videoSend = true; + } + if(!config.myStream) { + // No media stream: if we were asked to replace, it's actually an "add" + if(media.replaceVideo) { + media.keepVideo = false; + media.replaceVideo = false; + media.addVideo = true; + media.videoSend = true; + } + if(isVideoSendEnabled(media)) { + media.keepVideo = false; + media.addVideo = true; + } + } else { + if(!config.myStream.getVideoTracks() || config.myStream.getVideoTracks().length === 0) { + // No video track: if we were asked to replace, it's actually an "add" + if(media.replaceVideo) { + media.keepVideo = false; + media.replaceVideo = false; + media.addVideo = true; + media.videoSend = true; + } + if(isVideoSendEnabled(media)) { + media.keepVideo = false; + media.addVideo = true; + } + } else { + // We have a video track: should we keep it as it is? + if(isVideoSendEnabled(media) && !media.removeVideo && !media.replaceVideo) { + media.keepVideo = true; + } + } + } + // Data channels can only be added + if(media.addData) { + media.data = true; + } + } + // If we're updating and keeping all tracks, let's skip the getUserMedia part + if((isAudioSendEnabled(media) && media.keepAudio) && + (isVideoSendEnabled(media) && media.keepVideo)) { + pluginHandle.consentDialog(false); + streamsDone(handleId, jsep, media, callbacks, config.myStream); + return; + } + } + // If we're updating, check if we need to remove/replace one of the tracks + if(media.update && (!config.streamExternal || (config.streamExternal && (media.replaceAudio || media.replaceVideo)))) { + if(media.removeAudio || media.replaceAudio) { + if(config.myStream && config.myStream.getAudioTracks() && config.myStream.getAudioTracks().length) { + var at = config.myStream.getAudioTracks()[0]; + Janus.log("Removing audio track:", at); + config.myStream.removeTrack(at); + try { + at.stop(); + } catch(e) {} + } + if(config.pc.getSenders() && config.pc.getSenders().length) { + var ra = true; + if(media.replaceAudio && Janus.unifiedPlan) { + // We can use replaceTrack + ra = false; + } + if(ra) { + for(var asnd of config.pc.getSenders()) { + if(asnd && asnd.track && asnd.track.kind === "audio") { + Janus.log("Removing audio sender:", asnd); + config.pc.removeTrack(asnd); + } + } + } + } + } + if(media.removeVideo || media.replaceVideo) { + if(config.myStream && config.myStream.getVideoTracks() && config.myStream.getVideoTracks().length) { + var vt = config.myStream.getVideoTracks()[0]; + Janus.log("Removing video track:", vt); + config.myStream.removeTrack(vt); + try { + vt.stop(); + } catch(e) {} + } + if(config.pc.getSenders() && config.pc.getSenders().length) { + var rv = true; + if(media.replaceVideo && Janus.unifiedPlan) { + // We can use replaceTrack + rv = false; + } + if(rv) { + for(var vsnd of config.pc.getSenders()) { + if(vsnd && vsnd.track && vsnd.track.kind === "video") { + Janus.log("Removing video sender:", vsnd); + config.pc.removeTrack(vsnd); + } + } + } + } + } + } + // Was a MediaStream object passed, or do we need to take care of that? + if(callbacks.stream) { + var stream = callbacks.stream; + Janus.log("MediaStream provided by the application"); + Janus.debug(stream); + // If this is an update, let's check if we need to release the previous stream + if(media.update && config.myStream && config.myStream !== callbacks.stream && !config.streamExternal && !media.replaceAudio && !media.replaceVideo) { + // We're replacing a stream we captured ourselves with an external one + Janus.stopAllTracks(config.myStream); + config.myStream = null; + } + // Skip the getUserMedia part + config.streamExternal = true; + pluginHandle.consentDialog(false); + streamsDone(handleId, jsep, media, callbacks, stream); + return; + } + if(isAudioSendEnabled(media) || isVideoSendEnabled(media)) { + if(!Janus.isGetUserMediaAvailable()) { + callbacks.error("getUserMedia not available"); + return; + } + var constraints = { mandatory: {}, optional: []}; + pluginHandle.consentDialog(true); + var audioSupport = isAudioSendEnabled(media); + if(audioSupport && media && typeof media.audio === 'object') + audioSupport = media.audio; + var videoSupport = isVideoSendEnabled(media); + if(videoSupport && media) { + var simulcast = (callbacks.simulcast === true); + var simulcast2 = (callbacks.simulcast2 === true); + if((simulcast || simulcast2) && !jsep && !media.video) + media.video = "hires"; + if(media.video && media.video != 'screen' && media.video != 'window') { + if(typeof media.video === 'object') { + videoSupport = media.video; + } else { + var width = 0; + var height = 0; + if(media.video === 'lowres') { + // Small resolution, 4:3 + height = 240; + width = 320; + } else if(media.video === 'lowres-16:9') { + // Small resolution, 16:9 + height = 180; + width = 320; + } else if(media.video === 'hires' || media.video === 'hires-16:9' || media.video === 'hdres') { + // High(HD) resolution is only 16:9 + height = 720; + width = 1280; + } else if(media.video === 'fhdres') { + // Full HD resolution is only 16:9 + height = 1080; + width = 1920; + } else if(media.video === '4kres') { + // 4K resolution is only 16:9 + height = 2160; + width = 3840; + } else if(media.video === 'stdres') { + // Normal resolution, 4:3 + height = 480; + width = 640; + } else if(media.video === 'stdres-16:9') { + // Normal resolution, 16:9 + height = 360; + width = 640; + } else { + Janus.log("Default video setting is stdres 4:3"); + height = 480; + width = 640; + } + Janus.log("Adding media constraint:", media.video); + videoSupport = { + 'height': {'ideal': height}, + 'width': {'ideal': width} + }; + Janus.log("Adding video constraint:", videoSupport); + } + } else if(media.video === 'screen' || media.video === 'window') { + if(navigator.mediaDevices && navigator.mediaDevices.getDisplayMedia) { + // The new experimental getDisplayMedia API is available, let's use that + // https://groups.google.com/forum/#!topic/discuss-webrtc/Uf0SrR4uxzk + // https://webrtchacks.com/chrome-screensharing-getdisplaymedia/ + constraints.video = {}; + if(media.screenshareFrameRate) { + constraints.video.frameRate = media.screenshareFrameRate; + } + if(media.screenshareHeight) { + constraints.video.height = media.screenshareHeight; + } + if(media.screenshareWidth) { + constraints.video.width = media.screenshareWidth; + } + constraints.audio = media.captureDesktopAudio; + navigator.mediaDevices.getDisplayMedia(constraints) + .then(function(stream) { + pluginHandle.consentDialog(false); + if(isAudioSendEnabled(media) && !media.keepAudio) { + navigator.mediaDevices.getUserMedia({ audio: true, video: false }) + .then(function (audioStream) { + stream.addTrack(audioStream.getAudioTracks()[0]); + streamsDone(handleId, jsep, media, callbacks, stream); + }) + } else { + streamsDone(handleId, jsep, media, callbacks, stream); + } + }, function (error) { + pluginHandle.consentDialog(false); + callbacks.error(error); + }); + return; + } + // We're going to try and use the extension for Chrome 34+, the old approach + // for older versions of Chrome, or the experimental support in Firefox 33+ + const callbackUserMedia = function(error, stream) { + pluginHandle.consentDialog(false); + if(error) { + callbacks.error(error); + } else { + streamsDone(handleId, jsep, media, callbacks, stream); + } + } + const getScreenMedia = function(constraints, gsmCallback, useAudio) { + Janus.log("Adding media constraint (screen capture)"); + Janus.debug(constraints); + navigator.mediaDevices.getUserMedia(constraints) + .then(function(stream) { + if(useAudio) { + navigator.mediaDevices.getUserMedia({ audio: true, video: false }) + .then(function (audioStream) { + stream.addTrack(audioStream.getAudioTracks()[0]); + gsmCallback(null, stream); + }) + } else { + gsmCallback(null, stream); + } + }) + .catch(function(error) { pluginHandle.consentDialog(false); gsmCallback(error); }); + } + if(Janus.webRTCAdapter.browserDetails.browser === 'chrome') { + var chromever = Janus.webRTCAdapter.browserDetails.version; + var maxver = 33; + if(window.navigator.userAgent.match('Linux')) + maxver = 35; // "known" crash in chrome 34 and 35 on linux + if(chromever >= 26 && chromever <= maxver) { + // Chrome 26->33 requires some awkward chrome://flags manipulation + constraints = { + video: { + mandatory: { + googLeakyBucket: true, + maxWidth: window.screen.width, + maxHeight: window.screen.height, + minFrameRate: media.screenshareFrameRate, + maxFrameRate: media.screenshareFrameRate, + chromeMediaSource: 'screen' + } + }, + audio: isAudioSendEnabled(media) && !media.keepAudio + }; + getScreenMedia(constraints, callbackUserMedia); + } else { + // Chrome 34+ requires an extension + Janus.extension.getScreen(function (error, sourceId) { + if (error) { + pluginHandle.consentDialog(false); + return callbacks.error(error); + } + constraints = { + audio: false, + video: { + mandatory: { + chromeMediaSource: 'desktop', + maxWidth: window.screen.width, + maxHeight: window.screen.height, + minFrameRate: media.screenshareFrameRate, + maxFrameRate: media.screenshareFrameRate, + }, + optional: [ + {googLeakyBucket: true}, + {googTemporalLayeredScreencast: true} + ] + } + }; + constraints.video.mandatory.chromeMediaSourceId = sourceId; + getScreenMedia(constraints, callbackUserMedia, + isAudioSendEnabled(media) && !media.keepAudio); + }); + } + } else if(Janus.webRTCAdapter.browserDetails.browser === 'firefox') { + if(Janus.webRTCAdapter.browserDetails.version >= 33) { + // Firefox 33+ has experimental support for screen sharing + constraints = { + video: { + mozMediaSource: media.video, + mediaSource: media.video + }, + audio: isAudioSendEnabled(media) && !media.keepAudio + }; + getScreenMedia(constraints, function (err, stream) { + callbackUserMedia(err, stream); + // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=1045810 + if (!err) { + var lastTime = stream.currentTime; + var polly = window.setInterval(function () { + if(!stream) + window.clearInterval(polly); + if(stream.currentTime == lastTime) { + window.clearInterval(polly); + if(stream.onended) { + stream.onended(); + } + } + lastTime = stream.currentTime; + }, 500); + } + }); + } else { + var error = new Error('NavigatorUserMediaError'); + error.name = 'Your version of Firefox does not support screen sharing, please install Firefox 33 (or more recent versions)'; + pluginHandle.consentDialog(false); + callbacks.error(error); + return; + } + } + return; + } + } + // If we got here, we're not screensharing + if(!media || media.video !== 'screen') { + // Check whether all media sources are actually available or not + navigator.mediaDevices.enumerateDevices().then(function(devices) { + var audioExist = devices.some(function(device) { + return device.kind === 'audioinput'; + }), + videoExist = isScreenSendEnabled(media) || devices.some(function(device) { + return device.kind === 'videoinput'; + }); + + // Check whether a missing device is really a problem + var audioSend = isAudioSendEnabled(media); + var videoSend = isVideoSendEnabled(media); + var needAudioDevice = isAudioSendRequired(media); + var needVideoDevice = isVideoSendRequired(media); + if(audioSend || videoSend || needAudioDevice || needVideoDevice) { + // We need to send either audio or video + var haveAudioDevice = audioSend ? audioExist : false; + var haveVideoDevice = videoSend ? videoExist : false; + if(!haveAudioDevice && !haveVideoDevice) { + // FIXME Should we really give up, or just assume recvonly for both? + pluginHandle.consentDialog(false); + callbacks.error('No capture device found'); + return false; + } else if(!haveAudioDevice && needAudioDevice) { + pluginHandle.consentDialog(false); + callbacks.error('Audio capture is required, but no capture device found'); + return false; + } else if(!haveVideoDevice && needVideoDevice) { + pluginHandle.consentDialog(false); + callbacks.error('Video capture is required, but no capture device found'); + return false; + } + } + + var gumConstraints = { + audio: (audioExist && !media.keepAudio) ? audioSupport : false, + video: (videoExist && !media.keepVideo) ? videoSupport : false + }; + Janus.debug("getUserMedia constraints", gumConstraints); + if (!gumConstraints.audio && !gumConstraints.video) { + pluginHandle.consentDialog(false); + streamsDone(handleId, jsep, media, callbacks, stream); + } else { + navigator.mediaDevices.getUserMedia(gumConstraints) + .then(function(stream) { + pluginHandle.consentDialog(false); + streamsDone(handleId, jsep, media, callbacks, stream); + }).catch(function(error) { + pluginHandle.consentDialog(false); + callbacks.error({code: error.code, name: error.name, message: error.message}); + }); + } + }) + .catch(function(error) { + pluginHandle.consentDialog(false); + callbacks.error(error); + }); + } + } else { + // No need to do a getUserMedia, create offer/answer right away + streamsDone(handleId, jsep, media, callbacks); + } + } + + function prepareWebrtcPeer(handleId, callbacks) { + callbacks = callbacks || {}; + callbacks.success = (typeof callbacks.success == "function") ? callbacks.success : Janus.noop; + callbacks.error = (typeof callbacks.error == "function") ? callbacks.error : webrtcError; + callbacks.customizeSdp = (typeof callbacks.customizeSdp == "function") ? callbacks.customizeSdp : Janus.noop; + var jsep = callbacks.jsep; + var pluginHandle = pluginHandles[handleId]; + if(!pluginHandle || !pluginHandle.webrtcStuff) { + Janus.warn("Invalid handle"); + callbacks.error("Invalid handle"); + return; + } + var config = pluginHandle.webrtcStuff; + if(jsep) { + if(!config.pc) { + Janus.warn("Wait, no PeerConnection?? if this is an answer, use createAnswer and not handleRemoteJsep"); + callbacks.error("No PeerConnection: if this is an answer, use createAnswer and not handleRemoteJsep"); + return; + } + callbacks.customizeSdp(jsep); + config.pc.setRemoteDescription(jsep) + .then(function() { + Janus.log("Remote description accepted!"); + config.remoteSdp = jsep.sdp; + // Any trickle candidate we cached? + if(config.candidates && config.candidates.length > 0) { + for(var i = 0; i< config.candidates.length; i++) { + var candidate = config.candidates[i]; + Janus.debug("Adding remote candidate:", candidate); + if(!candidate || candidate.completed === true) { + // end-of-candidates + config.pc.addIceCandidate(Janus.endOfCandidates); + } else { + // New candidate + config.pc.addIceCandidate(candidate); + } + } + config.candidates = []; + } + // Done + callbacks.success(); + }, callbacks.error); + } else { + callbacks.error("Invalid JSEP"); + } + } + + function createOffer(handleId, media, callbacks) { + callbacks = callbacks || {}; + callbacks.success = (typeof callbacks.success == "function") ? callbacks.success : Janus.noop; + callbacks.error = (typeof callbacks.error == "function") ? callbacks.error : Janus.noop; + callbacks.customizeSdp = (typeof callbacks.customizeSdp == "function") ? callbacks.customizeSdp : Janus.noop; + var pluginHandle = pluginHandles[handleId]; + if(!pluginHandle || !pluginHandle.webrtcStuff) { + Janus.warn("Invalid handle"); + callbacks.error("Invalid handle"); + return; + } + var config = pluginHandle.webrtcStuff; + var simulcast = (callbacks.simulcast === true); + if(!simulcast) { + Janus.log("Creating offer (iceDone=" + config.iceDone + ")"); + } else { + Janus.log("Creating offer (iceDone=" + config.iceDone + ", simulcast=" + simulcast + ")"); + } + // https://code.google.com/p/webrtc/issues/detail?id=3508 + var mediaConstraints = {}; + if(Janus.unifiedPlan) { + // We can use Transceivers + var audioTransceiver = null, videoTransceiver = null; + var transceivers = config.pc.getTransceivers(); + if(transceivers && transceivers.length > 0) { + for(var t of transceivers) { + if((t.sender && t.sender.track && t.sender.track.kind === "audio") || + (t.receiver && t.receiver.track && t.receiver.track.kind === "audio")) { + if(!audioTransceiver) { + audioTransceiver = t; + } + continue; + } + if((t.sender && t.sender.track && t.sender.track.kind === "video") || + (t.receiver && t.receiver.track && t.receiver.track.kind === "video")) { + if(!videoTransceiver) { + videoTransceiver = t; + } + continue; + } + } + } + // Handle audio (and related changes, if any) + var audioSend = isAudioSendEnabled(media); + var audioRecv = isAudioRecvEnabled(media); + if(!audioSend && !audioRecv) { + // Audio disabled: have we removed it? + if(media.removeAudio && audioTransceiver) { + if (audioTransceiver.setDirection) { + audioTransceiver.setDirection("inactive"); + } else { + audioTransceiver.direction = "inactive"; + } + Janus.log("Setting audio transceiver to inactive:", audioTransceiver); + } + } else { + // Take care of audio m-line + if(audioSend && audioRecv) { + if(audioTransceiver) { + if (audioTransceiver.setDirection) { + audioTransceiver.setDirection("sendrecv"); + } else { + audioTransceiver.direction = "sendrecv"; + } + Janus.log("Setting audio transceiver to sendrecv:", audioTransceiver); + } + } else if(audioSend && !audioRecv) { + if(audioTransceiver) { + if (audioTransceiver.setDirection) { + audioTransceiver.setDirection("sendonly"); + } else { + audioTransceiver.direction = "sendonly"; + } + Janus.log("Setting audio transceiver to sendonly:", audioTransceiver); + } + } else if(!audioSend && audioRecv) { + if(audioTransceiver) { + if (audioTransceiver.setDirection) { + audioTransceiver.setDirection("recvonly"); + } else { + audioTransceiver.direction = "recvonly"; + } + Janus.log("Setting audio transceiver to recvonly:", audioTransceiver); + } else { + // In theory, this is the only case where we might not have a transceiver yet + audioTransceiver = config.pc.addTransceiver("audio", { direction: "recvonly" }); + Janus.log("Adding recvonly audio transceiver:", audioTransceiver); + } + } + } + // Handle video (and related changes, if any) + var videoSend = isVideoSendEnabled(media); + var videoRecv = isVideoRecvEnabled(media); + if(!videoSend && !videoRecv) { + // Video disabled: have we removed it? + if(media.removeVideo && videoTransceiver) { + if (videoTransceiver.setDirection) { + videoTransceiver.setDirection("inactive"); + } else { + videoTransceiver.direction = "inactive"; + } + Janus.log("Setting video transceiver to inactive:", videoTransceiver); + } + } else { + // Take care of video m-line + if(videoSend && videoRecv) { + if(videoTransceiver) { + if (videoTransceiver.setDirection) { + videoTransceiver.setDirection("sendrecv"); + } else { + videoTransceiver.direction = "sendrecv"; + } + Janus.log("Setting video transceiver to sendrecv:", videoTransceiver); + } + } else if(videoSend && !videoRecv) { + if(videoTransceiver) { + if (videoTransceiver.setDirection) { + videoTransceiver.setDirection("sendonly"); + } else { + videoTransceiver.direction = "sendonly"; + } + Janus.log("Setting video transceiver to sendonly:", videoTransceiver); + } + } else if(!videoSend && videoRecv) { + if(videoTransceiver) { + if (videoTransceiver.setDirection) { + videoTransceiver.setDirection("recvonly"); + } else { + videoTransceiver.direction = "recvonly"; + } + Janus.log("Setting video transceiver to recvonly:", videoTransceiver); + } else { + // In theory, this is the only case where we might not have a transceiver yet + videoTransceiver = config.pc.addTransceiver("video", { direction: "recvonly" }); + Janus.log("Adding recvonly video transceiver:", videoTransceiver); + } + } + } + } else { + mediaConstraints["offerToReceiveAudio"] = isAudioRecvEnabled(media); + mediaConstraints["offerToReceiveVideo"] = isVideoRecvEnabled(media); + } + var iceRestart = (callbacks.iceRestart === true); + if(iceRestart) { + mediaConstraints["iceRestart"] = true; + } + Janus.debug(mediaConstraints); + // Check if this is Firefox and we've been asked to do simulcasting + var sendVideo = isVideoSendEnabled(media); + if(sendVideo && simulcast && Janus.webRTCAdapter.browserDetails.browser === "firefox") { + // FIXME Based on https://gist.github.com/voluntas/088bc3cc62094730647b + Janus.log("Enabling Simulcasting for Firefox (RID)"); + var sender = config.pc.getSenders().find(function(s) {return s.track && s.track.kind === "video"}); + if(sender) { + var parameters = sender.getParameters(); + if(!parameters) { + parameters = {}; + } + var maxBitrates = getMaxBitrates(callbacks.simulcastMaxBitrates); + parameters.encodings = callbacks.sendEncodings || [ + { rid: "h", active: true, maxBitrate: maxBitrates.high }, + { rid: "m", active: true, maxBitrate: maxBitrates.medium, scaleResolutionDownBy: 2 }, + { rid: "l", active: true, maxBitrate: maxBitrates.low, scaleResolutionDownBy: 4 } + ]; + sender.setParameters(parameters); + } + } + config.pc.createOffer(mediaConstraints) + .then(function(offer) { + Janus.debug(offer); + // JSON.stringify doesn't work on some WebRTC objects anymore + // See https://code.google.com/p/chromium/issues/detail?id=467366 + var jsep = { + "type": offer.type, + "sdp": offer.sdp + }; + callbacks.customizeSdp(jsep); + offer.sdp = jsep.sdp; + Janus.log("Setting local description"); + if(sendVideo && simulcast) { + // This SDP munging only works with Chrome (Safari STP may support it too) + if(Janus.webRTCAdapter.browserDetails.browser === "chrome" || + Janus.webRTCAdapter.browserDetails.browser === "safari") { + Janus.log("Enabling Simulcasting for Chrome (SDP munging)"); + offer.sdp = mungeSdpForSimulcasting(offer.sdp); + } else if(Janus.webRTCAdapter.browserDetails.browser !== "firefox") { + Janus.warn("simulcast=true, but this is not Chrome nor Firefox, ignoring"); + } + } + config.mySdp = { + type: "offer", + sdp: offer.sdp + }; + config.pc.setLocalDescription(offer) + .catch(callbacks.error); + config.mediaConstraints = mediaConstraints; + if(!config.iceDone && !config.trickle) { + // Don't do anything until we have all candidates + Janus.log("Waiting for all candidates..."); + return; + } + // If transforms are present, notify Janus that the media is end-to-end encrypted + if(config.senderTransforms || config.receiverTransforms) { + offer["e2ee"] = true; + } + callbacks.success(offer); + }, callbacks.error); + } + + function createAnswer(handleId, media, callbacks) { + callbacks = callbacks || {}; + callbacks.success = (typeof callbacks.success == "function") ? callbacks.success : Janus.noop; + callbacks.error = (typeof callbacks.error == "function") ? callbacks.error : Janus.noop; + callbacks.customizeSdp = (typeof callbacks.customizeSdp == "function") ? callbacks.customizeSdp : Janus.noop; + var pluginHandle = pluginHandles[handleId]; + if(!pluginHandle || !pluginHandle.webrtcStuff) { + Janus.warn("Invalid handle"); + callbacks.error("Invalid handle"); + return; + } + var config = pluginHandle.webrtcStuff; + var simulcast = (callbacks.simulcast === true); + if(!simulcast) { + Janus.log("Creating answer (iceDone=" + config.iceDone + ")"); + } else { + Janus.log("Creating answer (iceDone=" + config.iceDone + ", simulcast=" + simulcast + ")"); + } + var mediaConstraints = null; + if(Janus.unifiedPlan) { + // We can use Transceivers + mediaConstraints = {}; + var audioTransceiver = null, videoTransceiver = null; + var transceivers = config.pc.getTransceivers(); + if(transceivers && transceivers.length > 0) { + for(var t of transceivers) { + if((t.sender && t.sender.track && t.sender.track.kind === "audio") || + (t.receiver && t.receiver.track && t.receiver.track.kind === "audio")) { + if(!audioTransceiver) + audioTransceiver = t; + continue; + } + if((t.sender && t.sender.track && t.sender.track.kind === "video") || + (t.receiver && t.receiver.track && t.receiver.track.kind === "video")) { + if(!videoTransceiver) + videoTransceiver = t; + continue; + } + } + } + // Handle audio (and related changes, if any) + var audioSend = isAudioSendEnabled(media); + var audioRecv = isAudioRecvEnabled(media); + if(!audioSend && !audioRecv) { + // Audio disabled: have we removed it? + if(media.removeAudio && audioTransceiver) { + try { + if (audioTransceiver.setDirection) { + audioTransceiver.setDirection("inactive"); + } else { + audioTransceiver.direction = "inactive"; + } + Janus.log("Setting audio transceiver to inactive:", audioTransceiver); + } catch(e) { + Janus.error(e); + } + } + } else { + // Take care of audio m-line + if(audioSend && audioRecv) { + if(audioTransceiver) { + try { + if (audioTransceiver.setDirection) { + audioTransceiver.setDirection("sendrecv"); + } else { + audioTransceiver.direction = "sendrecv"; + } + Janus.log("Setting audio transceiver to sendrecv:", audioTransceiver); + } catch(e) { + Janus.error(e); + } + } + } else if(audioSend && !audioRecv) { + try { + if(audioTransceiver) { + if (audioTransceiver.setDirection) { + audioTransceiver.setDirection("sendonly"); + } else { + audioTransceiver.direction = "sendonly"; + } + Janus.log("Setting audio transceiver to sendonly:", audioTransceiver); + } + } catch(e) { + Janus.error(e); + } + } else if(!audioSend && audioRecv) { + if(audioTransceiver) { + try { + if (audioTransceiver.setDirection) { + audioTransceiver.setDirection("recvonly"); + } else { + audioTransceiver.direction = "recvonly"; + } + Janus.log("Setting audio transceiver to recvonly:", audioTransceiver); + } catch(e) { + Janus.error(e); + } + } else { + // In theory, this is the only case where we might not have a transceiver yet + audioTransceiver = config.pc.addTransceiver("audio", { direction: "recvonly" }); + Janus.log("Adding recvonly audio transceiver:", audioTransceiver); + } + } + } + // Handle video (and related changes, if any) + var videoSend = isVideoSendEnabled(media); + var videoRecv = isVideoRecvEnabled(media); + if(!videoSend && !videoRecv) { + // Video disabled: have we removed it? + if(media.removeVideo && videoTransceiver) { + try { + if (videoTransceiver.setDirection) { + videoTransceiver.setDirection("inactive"); + } else { + videoTransceiver.direction = "inactive"; + } + Janus.log("Setting video transceiver to inactive:", videoTransceiver); + } catch(e) { + Janus.error(e); + } + } + } else { + // Take care of video m-line + if(videoSend && videoRecv) { + if(videoTransceiver) { + try { + if (videoTransceiver.setDirection) { + videoTransceiver.setDirection("sendrecv"); + } else { + videoTransceiver.direction = "sendrecv"; + } + Janus.log("Setting video transceiver to sendrecv:", videoTransceiver); + } catch(e) { + Janus.error(e); + } + } + } else if(videoSend && !videoRecv) { + if(videoTransceiver) { + try { + if (videoTransceiver.setDirection) { + videoTransceiver.setDirection("sendonly"); + } else { + videoTransceiver.direction = "sendonly"; + } + Janus.log("Setting video transceiver to sendonly:", videoTransceiver); + } catch(e) { + Janus.error(e); + } + } + } else if(!videoSend && videoRecv) { + if(videoTransceiver) { + try { + if (videoTransceiver.setDirection) { + videoTransceiver.setDirection("recvonly"); + } else { + videoTransceiver.direction = "recvonly"; + } + Janus.log("Setting video transceiver to recvonly:", videoTransceiver); + } catch(e) { + Janus.error(e); + } + } else { + // In theory, this is the only case where we might not have a transceiver yet + videoTransceiver = config.pc.addTransceiver("video", { direction: "recvonly" }); + Janus.log("Adding recvonly video transceiver:", videoTransceiver); + } + } + } + } else { + if(Janus.webRTCAdapter.browserDetails.browser === "firefox" || Janus.webRTCAdapter.browserDetails.browser === "edge") { + mediaConstraints = { + offerToReceiveAudio: isAudioRecvEnabled(media), + offerToReceiveVideo: isVideoRecvEnabled(media) + }; + } else { + mediaConstraints = { + mandatory: { + OfferToReceiveAudio: isAudioRecvEnabled(media), + OfferToReceiveVideo: isVideoRecvEnabled(media) + } + }; + } + } + Janus.debug(mediaConstraints); + // Check if this is Firefox and we've been asked to do simulcasting + var sendVideo = isVideoSendEnabled(media); + if(sendVideo && simulcast && Janus.webRTCAdapter.browserDetails.browser === "firefox") { + // FIXME Based on https://gist.github.com/voluntas/088bc3cc62094730647b + Janus.log("Enabling Simulcasting for Firefox (RID)"); + var sender = config.pc.getSenders()[1]; + Janus.log(sender); + var parameters = sender.getParameters(); + Janus.log(parameters); + + var maxBitrates = getMaxBitrates(callbacks.simulcastMaxBitrates); + sender.setParameters({encodings: callbacks.sendEncodings || [ + { rid: "h", active: true, maxBitrate: maxBitrates.high }, + { rid: "m", active: true, maxBitrate: maxBitrates.medium, scaleResolutionDownBy: 2}, + { rid: "l", active: true, maxBitrate: maxBitrates.low, scaleResolutionDownBy: 4} + ]}); + } + config.pc.createAnswer(mediaConstraints) + .then(function(answer) { + Janus.debug(answer); + // JSON.stringify doesn't work on some WebRTC objects anymore + // See https://code.google.com/p/chromium/issues/detail?id=467366 + var jsep = { + "type": answer.type, + "sdp": answer.sdp + }; + callbacks.customizeSdp(jsep); + answer.sdp = jsep.sdp; + Janus.log("Setting local description"); + if(sendVideo && simulcast) { + // This SDP munging only works with Chrome + if(Janus.webRTCAdapter.browserDetails.browser === "chrome") { + // FIXME Apparently trying to simulcast when answering breaks video in Chrome... + //~ Janus.log("Enabling Simulcasting for Chrome (SDP munging)"); + //~ answer.sdp = mungeSdpForSimulcasting(answer.sdp); + Janus.warn("simulcast=true, but this is an answer, and video breaks in Chrome if we enable it"); + } else if(Janus.webRTCAdapter.browserDetails.browser !== "firefox") { + Janus.warn("simulcast=true, but this is not Chrome nor Firefox, ignoring"); + } + } + config.mySdp = { + type: "answer", + sdp: answer.sdp + }; + config.pc.setLocalDescription(answer) + .catch(callbacks.error); + config.mediaConstraints = mediaConstraints; + if(!config.iceDone && !config.trickle) { + // Don't do anything until we have all candidates + Janus.log("Waiting for all candidates..."); + return; + } + // If transforms are present, notify Janus that the media is end-to-end encrypted + if(config.senderTransforms || config.receiverTransforms) { + answer["e2ee"] = true; + } + callbacks.success(answer); + }, callbacks.error); + } + + function sendSDP(handleId, callbacks) { + callbacks = callbacks || {}; + callbacks.success = (typeof callbacks.success == "function") ? callbacks.success : Janus.noop; + callbacks.error = (typeof callbacks.error == "function") ? callbacks.error : Janus.noop; + var pluginHandle = pluginHandles[handleId]; + if(!pluginHandle || !pluginHandle.webrtcStuff) { + Janus.warn("Invalid handle, not sending anything"); + return; + } + var config = pluginHandle.webrtcStuff; + Janus.log("Sending offer/answer SDP..."); + if(!config.mySdp) { + Janus.warn("Local SDP instance is invalid, not sending anything..."); + return; + } + config.mySdp = { + "type": config.pc.localDescription.type, + "sdp": config.pc.localDescription.sdp + }; + if(config.trickle === false) + config.mySdp["trickle"] = false; + Janus.debug(callbacks); + config.sdpSent = true; + callbacks.success(config.mySdp); + } + + function getVolume(handleId, remote) { + var pluginHandle = pluginHandles[handleId]; + if(!pluginHandle || !pluginHandle.webrtcStuff) { + Janus.warn("Invalid handle"); + return 0; + } + var stream = remote ? "remote" : "local"; + var config = pluginHandle.webrtcStuff; + if(!config.volume[stream]) + config.volume[stream] = { value: 0 }; + // Start getting the volume, if audioLevel in getStats is supported (apparently + // they're only available in Chrome/Safari right now: https://webrtc-stats.callstats.io/) + if(config.pc.getStats && (Janus.webRTCAdapter.browserDetails.browser === "chrome" || + Janus.webRTCAdapter.browserDetails.browser === "safari")) { + if(remote && !config.remoteStream) { + Janus.warn("Remote stream unavailable"); + return 0; + } else if(!remote && !config.myStream) { + Janus.warn("Local stream unavailable"); + return 0; + } + if(!config.volume[stream].timer) { + Janus.log("Starting " + stream + " volume monitor"); + config.volume[stream].timer = setInterval(function() { + config.pc.getStats() + .then(function(stats) { + stats.forEach(function (res) { + if(!res || res.kind !== "audio") + return; + if((remote && !res.remoteSource) || (!remote && res.type !== "media-source")) + return; + config.volume[stream].value = (res.audioLevel ? res.audioLevel : 0); + }); + }); + }, 200); + return 0; // We don't have a volume to return yet + } + return config.volume[stream].value; + } else { + // audioInputLevel and audioOutputLevel seem only available in Chrome? audioLevel + // seems to be available on Chrome and Firefox, but they don't seem to work + Janus.warn("Getting the " + stream + " volume unsupported by browser"); + return 0; + } + } + + function isMuted(handleId, video) { + var pluginHandle = pluginHandles[handleId]; + if(!pluginHandle || !pluginHandle.webrtcStuff) { + Janus.warn("Invalid handle"); + return true; + } + var config = pluginHandle.webrtcStuff; + if(!config.pc) { + Janus.warn("Invalid PeerConnection"); + return true; + } + if(!config.myStream) { + Janus.warn("Invalid local MediaStream"); + return true; + } + if(video) { + // Check video track + if(!config.myStream.getVideoTracks() || config.myStream.getVideoTracks().length === 0) { + Janus.warn("No video track"); + return true; + } + return !config.myStream.getVideoTracks()[0].enabled; + } else { + // Check audio track + if(!config.myStream.getAudioTracks() || config.myStream.getAudioTracks().length === 0) { + Janus.warn("No audio track"); + return true; + } + return !config.myStream.getAudioTracks()[0].enabled; + } + } + + function mute(handleId, video, mute) { + var pluginHandle = pluginHandles[handleId]; + if(!pluginHandle || !pluginHandle.webrtcStuff) { + Janus.warn("Invalid handle"); + return false; + } + var config = pluginHandle.webrtcStuff; + if(!config.pc) { + Janus.warn("Invalid PeerConnection"); + return false; + } + if(!config.myStream) { + Janus.warn("Invalid local MediaStream"); + return false; + } + if(video) { + // Mute/unmute video track + if(!config.myStream.getVideoTracks() || config.myStream.getVideoTracks().length === 0) { + Janus.warn("No video track"); + return false; + } + config.myStream.getVideoTracks()[0].enabled = !mute; + return true; + } else { + // Mute/unmute audio track + if(!config.myStream.getAudioTracks() || config.myStream.getAudioTracks().length === 0) { + Janus.warn("No audio track"); + return false; + } + config.myStream.getAudioTracks()[0].enabled = !mute; + return true; + } + } + + function getBitrate(handleId) { + var pluginHandle = pluginHandles[handleId]; + if(!pluginHandle || !pluginHandle.webrtcStuff) { + Janus.warn("Invalid handle"); + return "Invalid handle"; + } + var config = pluginHandle.webrtcStuff; + if(!config.pc) + return "Invalid PeerConnection"; + // Start getting the bitrate, if getStats is supported + if(config.pc.getStats) { + if(!config.bitrate.timer) { + Janus.log("Starting bitrate timer (via getStats)"); + config.bitrate.timer = setInterval(function() { + config.pc.getStats() + .then(function(stats) { + stats.forEach(function (res) { + if(!res) + return; + var inStats = false; + // Check if these are statistics on incoming media + if((res.mediaType === "video" || res.id.toLowerCase().indexOf("video") > -1) && + res.type === "inbound-rtp" && res.id.indexOf("rtcp") < 0) { + // New stats + inStats = true; + } else if(res.type == 'ssrc' && res.bytesReceived && + (res.googCodecName === "VP8" || res.googCodecName === "")) { + // Older Chromer versions + inStats = true; + } + // Parse stats now + if(inStats) { + config.bitrate.bsnow = res.bytesReceived; + config.bitrate.tsnow = res.timestamp; + if(config.bitrate.bsbefore === null || config.bitrate.tsbefore === null) { + // Skip this round + config.bitrate.bsbefore = config.bitrate.bsnow; + config.bitrate.tsbefore = config.bitrate.tsnow; + } else { + // Calculate bitrate + var timePassed = config.bitrate.tsnow - config.bitrate.tsbefore; + if(Janus.webRTCAdapter.browserDetails.browser === "safari") + timePassed = timePassed/1000; // Apparently the timestamp is in microseconds, in Safari + var bitRate = Math.round((config.bitrate.bsnow - config.bitrate.bsbefore) * 8 / timePassed); + if(Janus.webRTCAdapter.browserDetails.browser === "safari") + bitRate = parseInt(bitRate/1000); + config.bitrate.value = bitRate + ' kbits/sec'; + //~ Janus.log("Estimated bitrate is " + config.bitrate.value); + config.bitrate.bsbefore = config.bitrate.bsnow; + config.bitrate.tsbefore = config.bitrate.tsnow; + } + } + }); + }); + }, 1000); + return "0 kbits/sec"; // We don't have a bitrate value yet + } + return config.bitrate.value; + } else { + Janus.warn("Getting the video bitrate unsupported by browser"); + return "Feature unsupported by browser"; + } + } + + function webrtcError(error) { + Janus.error("WebRTC error:", error); + } + + function cleanupWebrtc(handleId, hangupRequest) { + Janus.log("Cleaning WebRTC stuff"); + var pluginHandle = pluginHandles[handleId]; + if(!pluginHandle) { + // Nothing to clean + return; + } + var config = pluginHandle.webrtcStuff; + if(config) { + if(hangupRequest === true) { + // Send a hangup request (we don't really care about the response) + var request = { "janus": "hangup", "transaction": Janus.randomString(12) }; + if(pluginHandle.token) + request["token"] = pluginHandle.token; + if(apisecret) + request["apisecret"] = apisecret; + Janus.debug("Sending hangup request (handle=" + handleId + "):"); + Janus.debug(request); + if(websockets) { + request["session_id"] = sessionId; + request["handle_id"] = handleId; + ws.send(JSON.stringify(request)); + } else { + Janus.httpAPICall(server + "/" + sessionId + "/" + handleId, { + verb: 'POST', + withCredentials: withCredentials, + body: request + }); + } + } + // Cleanup stack + config.remoteStream = null; + if(config.volume) { + if(config.volume["local"] && config.volume["local"].timer) + clearInterval(config.volume["local"].timer); + if(config.volume["remote"] && config.volume["remote"].timer) + clearInterval(config.volume["remote"].timer); + } + config.volume = {}; + if(config.bitrate.timer) + clearInterval(config.bitrate.timer); + config.bitrate.timer = null; + config.bitrate.bsnow = null; + config.bitrate.bsbefore = null; + config.bitrate.tsnow = null; + config.bitrate.tsbefore = null; + config.bitrate.value = null; + if(!config.streamExternal && config.myStream) { + Janus.log("Stopping local stream tracks"); + Janus.stopAllTracks(config.myStream); + } + config.streamExternal = false; + config.myStream = null; + // Close PeerConnection + try { + config.pc.close(); + } catch(e) { + // Do nothing + } + config.pc = null; + config.candidates = null; + config.mySdp = null; + config.remoteSdp = null; + config.iceDone = false; + config.dataChannel = {}; + config.dtmfSender = null; + config.senderTransforms = null; + config.receiverTransforms = null; + } + pluginHandle.oncleanup(); + } + + // Helper method to munge an SDP to enable simulcasting (Chrome only) + function mungeSdpForSimulcasting(sdp) { + // Let's munge the SDP to add the attributes for enabling simulcasting + // (based on https://gist.github.com/ggarber/a19b4c33510028b9c657) + var lines = sdp.split("\r\n"); + var video = false; + var ssrc = [ -1 ], ssrc_fid = [ -1 ]; + var cname = null, msid = null, mslabel = null, label = null; + var insertAt = -1; + for(let i=0; i -1) { + // We're done, let's add the new attributes here + insertAt = i; + break; + } + } + continue; + } + if(!video) + continue; + var sim = lines[i].match(/a=ssrc-group:SIM (\d+) (\d+) (\d+)/); + if(sim) { + Janus.warn("The SDP already contains a SIM attribute, munging will be skipped"); + return sdp; + } + var fid = lines[i].match(/a=ssrc-group:FID (\d+) (\d+)/); + if(fid) { + ssrc[0] = fid[1]; + ssrc_fid[0] = fid[2]; + lines.splice(i, 1); i--; + continue; + } + if(ssrc[0]) { + var match = lines[i].match('a=ssrc:' + ssrc[0] + ' cname:(.+)') + if(match) { + cname = match[1]; + } + match = lines[i].match('a=ssrc:' + ssrc[0] + ' msid:(.+)') + if(match) { + msid = match[1]; + } + match = lines[i].match('a=ssrc:' + ssrc[0] + ' mslabel:(.+)') + if(match) { + mslabel = match[1]; + } + match = lines[i].match('a=ssrc:' + ssrc[0] + ' label:(.+)') + if(match) { + label = match[1]; + } + if(lines[i].indexOf('a=ssrc:' + ssrc_fid[0]) === 0) { + lines.splice(i, 1); i--; + continue; + } + if(lines[i].indexOf('a=ssrc:' + ssrc[0]) === 0) { + lines.splice(i, 1); i--; + continue; + } + } + if(lines[i].length == 0) { + lines.splice(i, 1); i--; + continue; + } + } + if(ssrc[0] < 0) { + // Couldn't find a FID attribute, let's just take the first video SSRC we find + insertAt = -1; + video = false; + for(let i=0; i -1) { + // We're done, let's add the new attributes here + insertAt = i; + break; + } + } + continue; + } + if(!video) + continue; + if(ssrc[0] < 0) { + var value = lines[i].match(/a=ssrc:(\d+)/); + if(value) { + ssrc[0] = value[1]; + lines.splice(i, 1); i--; + continue; + } + } else { + let match = lines[i].match('a=ssrc:' + ssrc[0] + ' cname:(.+)') + if(match) { + cname = match[1]; + } + match = lines[i].match('a=ssrc:' + ssrc[0] + ' msid:(.+)') + if(match) { + msid = match[1]; + } + match = lines[i].match('a=ssrc:' + ssrc[0] + ' mslabel:(.+)') + if(match) { + mslabel = match[1]; + } + match = lines[i].match('a=ssrc:' + ssrc[0] + ' label:(.+)') + if(match) { + label = match[1]; + } + if(lines[i].indexOf('a=ssrc:' + ssrc_fid[0]) === 0) { + lines.splice(i, 1); i--; + continue; + } + if(lines[i].indexOf('a=ssrc:' + ssrc[0]) === 0) { + lines.splice(i, 1); i--; + continue; + } + } + if(lines[i].length === 0) { + lines.splice(i, 1); i--; + continue; + } + } + } + if(ssrc[0] < 0) { + // Still nothing, let's just return the SDP we were asked to munge + Janus.warn("Couldn't find the video SSRC, simulcasting NOT enabled"); + return sdp; + } + if(insertAt < 0) { + // Append at the end + insertAt = lines.length; + } + // Generate a couple of SSRCs (for retransmissions too) + // Note: should we check if there are conflicts, here? + ssrc[1] = Math.floor(Math.random()*0xFFFFFFFF); + ssrc[2] = Math.floor(Math.random()*0xFFFFFFFF); + ssrc_fid[1] = Math.floor(Math.random()*0xFFFFFFFF); + ssrc_fid[2] = Math.floor(Math.random()*0xFFFFFFFF); + // Add attributes to the SDP + for(var i=0; i { + app.isActive = true; + app.ui.markUnread(app.conversation, false); + }); + + $(document).on("mouseenter", e => { + app.isActive = true; + app.ui.markUnread(app.conversation, false); + }); + + $(window).on("blur", e => { + app.isActive = false; + }); + + $(document).on("mouseleave", e => { + app.isActive = false; + }); + + $(document).on("keydown", e => { + if (app.isKey(e, 27)) { + e.preventDefault(); + + if (app.ui.undoProfileIfNeeded()) { + return; + } + + if (app.ui.removeReplyingIfNeeded()) { + return; + } + + if (app.ui.removePopoverIfNeeded()) { + return; + } + } + + app.ui.preventTabIfNeeded(e); + app.ui.focusInputIfNeeded(e); + }); + + $("html").on("click", "#blackout", (e) => { + if (!this.longPress) { + app.ui.close(); + } + }); + + $("html").on("click", "#closeMenu", () => { + app.ui.closeMenusIfNeeded(); + }); + + $("html").on("click", "#conversations .tabs .tab", e => { + app.tab = $(e.target).data("tab"); + app.ui.setConversationTab(); + }); + + $("html").on("change", ".header .domains select", e => { + app.typing = false; + + let domain = $(e.target).val(); + + if (domain == "manageDomains") { + app.ui.openURL("/id"); + } + else { + app.changeDomain(domain); + } + }); + + $("html").on("click", "#conversations tr", e => { + app.typing = false; + + let row = e.target.closest("tr"); + let conversation = $(row).data("id"); + + if (conversation == app.conversation || app.loadingMessages) { + app.ui.closeMenusIfNeeded(); + return; + } + + app.changeConversation(conversation); + localStorage.setItem("conversation", conversation); + }); + + $("#messageHolder").on("scroll", e => { + let messageHolder = $(e.target); + if (app.loadingMessages) { + return; + } + + let height = messageHolder.outerHeight(); + let scrollTop = messageHolder[0].scrollTop; + let scrollHeight = messageHolder[0].scrollHeight - messageHolder.height(); + + if ((scrollHeight - height) == 0) { + return; + } + + let calc = Math.floor(scrollHeight + scrollTop); + if (calc <= 1) { + let firstMessage = $("#messages > .messageRow[data-id]").first(); + let firstMessageID = firstMessage.data("id"); + if (firstMessageID) { + let options = { + before: firstMessageID + } + app.getMessages(options); + } + } + else if (calc == scrollHeight) { + app.ui.fetchNewMessages(); + } + }); + + $("html").on("keydown", "textarea#message", e => { + let target = $(e.target); + + let key = app.key(e); + + if ($("#completions.shown").length) { + switch (key) { + case 38: + case 40: + e.preventDefault(); + break; + + case 9: + case 13: + e.preventDefault(); + $("#completions tr.active").click(); + return; + } + } + + switch (key) { + case 9: + app.ui.tabComplete(); + break; + + case 38: + case 40: + case 27: + return; + } + + if (target.val() && target.val()[0] !== "/" && e.key.length == 1) { + app.lastTyped = app.time(); + } + + if (app.isKey(e, 13) && !e.shiftKey) { + e.preventDefault(); + + let data; + let attachments = $("#attachments .attachment"); + if (attachments.find(".uploading").length) { + return; + } + + $.each(attachments, (k, attachment) => { + let id = $(attachment).data("id"); + data = { + hnschat: 1, + attachment: id + }; + app.sendMessage(app.conversation, JSON.stringify(data)); + }); + + let value = target.val().trim(); + app.ui.clear("input"); + $("#attachments").empty(); + app.ui.showOrHideAttachments(); + + let replaced = app.replaceCompletions(value); + if (replaced.length) { + if (replaced[0] == "/") { + replaced = replaced.substring(1); + let split = replaced.split(" "); + let command = split.shift(); + let rest = split.join(" "); + + switch (command) { + case "me": + data = { + hnschat: 1, + action: rest + }; + app.sendMessage(app.conversation, JSON.stringify(data)); + break; + + case "shrug": + data = { + hnschat: 1, + message: "ยฏ\\_(ใƒ„)_/ยฏ" + }; + app.sendMessage(app.conversation, JSON.stringify(data)); + break; + + case "fancy": + data = { + hnschat: 1, + message: rest, + style: command + }; + app.sendMessage(app.conversation, JSON.stringify(data)); + break; + + case "confetti": + data = { + hnschat: 1, + message: rest, + effect: command + }; + app.sendMessage(app.conversation, JSON.stringify(data)); + break; + + case "slap": + data = { + hnschat: 1, + action: `slaps ${rest} around a bit with a large trout` + }; + app.sendMessage(app.conversation, JSON.stringify(data)); + break; + + default: + break; + } + } + else { + data = { + hnschat: 1, + message: replaced + }; + app.sendMessage(app.conversation, JSON.stringify(data)); + } + } + } + + app.ui.sizeInput(); + }); + + $("html").on("input paste keyup focus click", "textarea#message", e => { + let key = app.key(e); + + switch (key) { + case 13: + return; + + case 27: + app.ui.close(); + return; + + case 38: + case 40: + e.preventDefault(); + app.ui.updateSelectedCompletion(key); + return; + } + + switch (key) { + case 16: + case 17: + case 18: + case 20: + case 91: + case 93: + break; + + default: + app.ui.updateCompletions(); + break; + } + + app.ui.sizeInput(); + }); + + $("html").on("click", "#completions tr", e => { + let target = $(e.target).closest("tr"); + + $("#completions tr").removeClass("active"); + target.addClass("active"); + + let completion = target.find(".title").html(); + if (target.hasClass("user")) { + completion = `@${completion}/`; + } + else { + completion = `#${completion}`; + } + + let input = $("textarea#message"); + let text = input.val(); + let words = text.split(" "); + let position = input[0].selectionStart; + let word = app.ui.wordForPosition(text, position); + let before = words[word]; + words[word] = `${completion} `; + + let newPosition = 0; + for (let i = 0; i < words.length; i++) { + newPosition += words[i].length; + + if (i == word) { + newPosition += i; + break; + } + } + + let replaced = words.join(" "); + input.val(replaced); + app.ui.setCaretPosition(input[0], newPosition); + app.ui.close(); + }); + + $("html").on("click", ".action, .button, .link", e => { + let target = $(e.target); + + if ($("body").hasClass("touching")) { + return; + } + + target.parent().find(".response").html(''); + target.parent().parent().find(".response").html(''); + + if (target.hasClass("disabled")) { + return; + } + target.addClass("disabled"); + + let action = target.data("action"); + + var sender,context; + var data; + var id,domain,sld,tld,message,name; + + switch (action) { + case "scanQR": + app.ui.scanQR(); + app.ui.popover("qr"); + app.ui.enableTarget(target); + break; + + case "reply": + context = target.closest(".contextMenu"); + if (context.length) { + app.replying = { + message: context.data("id"), + sender: context.data("sender"), + } + } + else { + app.replying = { + message: target.closest(".messageRow").data("id"), + sender: target.closest(".messageRow").data("sender"), + } + } + + app.ui.close(); + app.ui.updateReplying(); + $(".input #message").focus(); + app.ui.enableTarget(target); + break; + + case "removeReply": + app.replying = null; + app.ui.updateReplying(); + app.ui.enableTarget(target); + break; + + case "donate": + case "syncSession": + app.ui.popover(action); + app.ui.enableTarget(target); + break; + + case "replayEffect": + app.ui.handleEffect(target.data("effect")).then(() => { + app.ui.enableTarget(target); + }); + break; + + case "settings": + $(".popover[data-name=settings] input[name=bubbleBackground]").val(app.ui.css.getPropertyValue("--bubbleBackground").trim()); + $(".popover[data-name=settings] input[name=bubbleSelfBackground]").val(app.ui.css.getPropertyValue("--bubbleSelfBackground").trim()); + $(".popover[data-name=settings] input[name=bubbleMentionBackground]").val(app.ui.css.getPropertyValue("--bubbleMentionBackground").trim()); + if (app.settings.chatDisplayMode) { + $(".popover[data-name=settings] select[name=chatDisplayMode]").val(app.settings.chatDisplayMode); + } + app.ui.popover(action); + app.ui.enableTarget(target); + break; + + case "docs": + app.ui.openURL("https://docs.hns.chat", { newTab: true }); + app.ui.enableTarget(target); + break; + + case "pay": + let conversation = app.pmForID(app.conversation); + app.ws.send(`GETADDRESS ${app.otherUser(conversation.users)}`); + app.ui.popover(action); + app.ui.enableTarget(target); + break; + + case "sendPayment": + let address = target.parent().find("input[name=address]").val(); + let amount = target.parent().find("input[name=hns]").val().replace(/[^0-9.]/g, ''); + app.sendPayment(address, amount).then(r => { + if (r.message) { + let data = { + type: action, + message: `Error: ${r.message}` + } + app.ui.errorResponse(data); + } + else if (r.hash) { + let data = { + hnschat: 1, + payment: r.hash, + amount: amount + } + app.sendMessage(app.conversation, JSON.stringify(data)); + app.ui.close(); + } + app.ui.enableTarget(target); + }); + break; + + case "newConversation": + if (!app.userForID(app.domain).locked) { + app.ui.popover(action); + } + app.ui.enableTarget(target); + break; + + case "newConversationWith": + id = target.closest(".contextMenu").data("id"); + name = app.userForID(id).domain; + let puny = `${app.ui.toUnicode(name)}/`; + $(`.popover[data-name=newConversation] input[name=domain]`).val(puny); + app.ui.popover("newConversation"); + app.ui.enableTarget(target); + break; + + case "mentionUser": + id = target.closest(".contextMenu").data("id"); + name = `@${app.userForID(id).domain}/`; + let text = $("#message").val(); + text = `${text}${name} `; + $("#message").val(text); + app.ui.close(); + app.ui.closeMenusIfNeeded(); + app.ui.enableTarget(target); + $("#message").focus(); + break; + + case "slapUser": + id = target.closest(".contextMenu").data("id"); + name = `@${app.userForID(id).domain}/`; + message = app.replaceCompletions(`slaps ${name} around a bit with a large trout`); + data = { + hnschat: 1, + action: message + }; + app.sendMessage(app.conversation, JSON.stringify(data)); + app.ui.close(); + app.ui.closeMenusIfNeeded(); + app.ui.enableTarget(target); + $("#message").focus(); + break; + + case "switchConversation": + id = target.closest(".contextMenu").data("id"); + $(`#conversations tr[data-id=${id}]`).click(); + app.ui.close(); + app.ui.enableTarget(target); + break; + + case "startConversation": + domain = target.parent().find("input[name=domain]").val().trim(); + domain = app.rtrim(domain, "/").trim(); + domain = app.userForName(domain).domain; + message = target.parent().find("input[name=message]").val(); + + if (message.length) { + app.queued.push({ + domain: domain, + message: message + }); + + data = { + domain: domain + } + app.ws.send(`PM ${JSON.stringify(data)}`); + } + else { + data = { + type: action, + message: "Please enter a message.", + } + app.ui.errorResponse(data); + } + app.ui.enableTarget(target); + break; + + case "clipboard": + app.ui.copyToClipboard(target); + app.ui.enableTarget(target); + break; + + case "gifs": + case "emojis": + context = target.closest(".contextMenu"); + if (context.length) { + sender = context.data("id"); + } + else { + sender = target.closest(".messageRow").data("id"); + } + + app.ui.setupReactView(e, sender); + app.ui.popover("react"); + app.ui.enableTarget(target); + break; + + case "createSLD": + e.newTab = true; + app.ui.openURL("/id"); + app.ui.enableTarget(target); + break; + + case "purchaseSLD": + e.newTab = true; + app.ui.openURL(target.data("link"), e); + app.ui.enableTarget(target); + break; + + case "switchName": + domain = target.data("id"); + app.changeDomain(domain); + break; + + case "newDomain": + app.ui.showSection("addDomain"); + app.ui.enableTarget(target); + break; + + case "addDomain": + app.varo.auth().then(auth => { + if (auth.success) { + let data = { + request: auth.data.request + }; + app.ws.send(`ADDDOMAIN ${JSON.stringify(data)}`); + } + app.ui.enableTarget(target); + }); + break; + + case "verifyDomain": + app.varo.auth().then(auth => { + if (auth.success) { + let data = { + id: target.closest(".domain").data("id"), + request: auth.data.request + }; + app.ws.send(`VERIFYDOMAIN ${JSON.stringify(data)}`); + } + app.ui.enableTarget(target); + }); + break; + + case "addSLD": + sld = target.parent().find("input[name=sld]").val(); + tld = target.parent().find("select[name=tld]").val(); + data = { + sld: sld, + tld: tld + } + app.ws.send(`ADDSLD ${JSON.stringify(data)}`); + break; + + case "deleteDomain": + domain = target.closest(".domain").data("id"); + data = { + id: domain + }; + app.ws.send(`DELETEDOMAIN ${JSON.stringify(data)}`); + break; + + case "manageDomains": + app.ui.showSection("manageDomains"); + app.ui.enableTarget(target); + break; + + case "deleteMessage": + message = target.closest(".contextMenu").data("id"); + data = { + id: message + } + app.ws.send(`DELETEMESSAGE ${JSON.stringify(data)}`); + app.ui.close(); + app.ui.enableTarget(target); + break; + + case "pinMessage": + message = target.closest(".contextMenu").data("id"); + data = { + conversation: app.conversation, + id: message + } + app.ws.send(`PINMESSAGE ${JSON.stringify(data)}`); + app.ui.close(); + app.ui.enableTarget(target); + break; + + case "searchUsers": + if (target.hasClass("close")) { + app.ui.searchUsers(false); + } + else { + app.ui.searchUsers(true); + } + app.ui.enableTarget(target); + break; + + case "saveSettings": + let fields = $(".popover[data-name=settings] .local"); + $.each(fields, (k, field) => { + let name = $(field).attr("name"); + let val = $(field).val(); + app.settings[name] = val; + }); + localStorage.setItem("settings", JSON.stringify(app.settings)); + app.loadSettings(); + + data = { + action: "saveSettings", + domain: app.domain, + settings: {} + } + + fields = $(".popover[data-name=settings] input.remote"); + $.each(fields, (k, field) => { + let name = $(field).attr("name"); + let val = $(field).val(); + data.settings[name] = val; + }); + + data.settings = JSON.stringify(data.settings); + + app.api(data).then(r => { + if (r.success) { + if (r.avatar) { + delete app.avatars[app.domain]; + app.userForID(app.domain).avatar = r.avatar; + $(`.favicon.loaded[data-id=${app.domain}]`).removeClass("loaded"); + app.ui.updateAvatars(); + app.ws.send(`SAVEDSETTINGS`); + } + app.ui.close(); + } + else { + data = { + type: action, + message: r.message, + } + app.ui.errorResponse(data); + } + + app.ui.enableTarget(target); + }); + break; + + case "file": + $("#file")[0].click(); + app.ui.enableTarget(target); + break; + + case "removeAttachment": + let attachment = target.parent().parent(); + attachment.remove(); + app.ui.showOrHideAttachments(); + data = { + id: attachment.data("id") + } + app.ws.send(`DELETEATTACHMENT ${JSON.stringify(data)}`); + break; + + case "editProfile": + app.ui.editProfile(); + app.ui.enableTarget(target); + break; + + case "saveProfile": + app.ui.saveProfile(); + app.ui.enableTarget(target); + break; + + case "undoProfile": + app.ui.undoProfile(); + app.ui.enableTarget(target); + break; + + case "close": + app.ui.close(); + app.ui.enableTarget(target); + break; + + case "reload": + window.location.reload(); + break; + + case "startVideo": + case "joinVideo": + app.channelForID(app.conversation).watching = true; + data = { + conversation: app.conversation + } + if (app.channelForID(app.conversation).video) { + app.ws.send(`JOINVIDEO ${JSON.stringify(data)}`); + } + else { + app.ws.send(`STARTVIDEO ${JSON.stringify(data)}`); + } + app.ui.enableTarget(target); + break; + + case "inviteVideo": + id = target.closest(".contextMenu").data("id"); + + data = { + conversation: app.conversation, + user: id + } + app.ws.send(`INVITEVIDEO ${JSON.stringify(data)}`); + app.ui.close(); + app.ui.closeMenusIfNeeded(); + app.ui.enableTarget(target); + break; + + case "leaveVideo": + if (Object.keys(app.channelForID(app.conversation).videoUsers).includes(app.domain)) { + app.stream.unpublish(); + } + else { + app.channelForID(app.conversation).watching = false; + app.stream.close(); + app.ui.showVideoIfNeeded(); + } + data = { + conversation: app.conversation + } + app.ws.send(`LEAVEVIDEO ${JSON.stringify(data)}`); + app.ui.enableTarget(target); + break; + + case "endVideo": + if (Object.keys(app.channelForID(app.conversation).videoUsers).includes(app.domain)) { + app.stream.unpublish(); + } + data = { + conversation: app.conversation + } + app.ws.send(`ENDVIDEO ${JSON.stringify(data)}`); + app.ui.enableTarget(target); + break; + + case "toggleVideo": + app.stream.mute("video", !$(".controls .button[data-action=toggleVideo]").hasClass("muted")); + data = { + conversation: app.conversation + } + app.ws.send(`MUTEVIDEO ${JSON.stringify(data)}`); + app.ui.enableTarget(target); + break; + + case "toggleAudio": + app.stream.mute("audio", !$(".controls .button[data-action=toggleAudio]").hasClass("muted")); + data = { + conversation: app.conversation + } + app.ws.send(`MUTEAUDIO ${JSON.stringify(data)}`); + app.ui.enableTarget(target); + break; + + case "toggleScreen": + app.stream.toggleScreen(); + app.ui.enableTarget(target); + break; + + case "viewVideo": + data = { + conversation: app.conversation + } + app.ws.send(`VIEWVIDEO ${JSON.stringify(data)}`); + app.ui.enableTarget(target); + break; + + default: + app.ui.enableTarget(target); + break; + } + }); + + $("html").on("keyup", ".popover[data-name=react] input", e => { + if (app.isKey(e, 27)) { + e.preventDefault(); + return; + } + + let query = $(e.currentTarget).val().replace(/[^a-zA-Z0-9]/gi, '').toLowerCase(); + if (query) { + let emo = $(".popover[data-name=react] .section:not([data-name=Search]) .emoji"); + let matches = emo.filter((k, em) => { + let aliases = $(em).data("aliases"); + + $.each(aliases, (k, alias) => { + aliases[k] = alias.replace(/[^a-zA-Z0-9]/gi, '').toLowerCase(); + }); + + return aliases.join("|").includes(query); + }); + + $(".popover[data-name=react] .grid .section[data-name=Search] .emojis").empty(); + $.each(matches, (k, match) => { + let clone = match.cloneNode(true); + $(".popover[data-name=react] .grid .section[data-name=Search] .emojis").append(clone); + }); + + $(".popover[data-name=react] .grid .section").addClass("hidden"); + $(".popover[data-name=react] .grid .section[data-name=Search]").removeClass("hidden"); + } + else { + $(".popover[data-name=react] .grid .section").removeClass("hidden"); + $(".popover[data-name=react] .grid .section[data-name=Search]").addClass("hidden"); + } + }); + + $("html").on("click", ".popover[data-name=react] .emoji", e => { + let sender = $(".popover[data-name=react]").data("sender"); + let emoji = $(e.currentTarget); + let em = emoji.html(); + + if (sender.length) { + let reacting = $(".messageRow .hover.visible").closest(".messageRow").data("id"); + app.ui.close(); + let data = { + conversation: app.conversation, + message: reacting, + reaction: em + }; + app.ws.send(`REACT ${JSON.stringify(data)}`); + } + else { + let field = $(".input #message"); + let current = field.val(); + let split = Array.from(current); + let position = field[0].selectionStart; + let added = app.replaceRange(current, position, position, em); + field.val(added); + app.ui.close(); + $(".input #message").focus(); + app.ui.setCaretPosition(field[0], position + em.length); + } + }); + + $("html").on("click", ".reaction", e => { + let target = $(e.currentTarget); + let reacting = target.closest(".messageRow").data("id"); + let em = target.data("reaction"); + + let data = { + conversation: app.conversation, + message: reacting, + reaction: em + }; + app.ws.send(`REACT ${JSON.stringify(data)}`); + }); + + $("html").on("click", "#react .tab", e => { + let target = $(e.target); + let name = target.data("name"); + app.ui.switchReactTab(name); + }); + + $("html").on("click", "#react .category", e => { + let target = $(e.target); + let term = target.data("term"); + $("#react input[name=searchGifs]").val(term); + app.ui.searchGifs(term); + }); + + $("html").on("input", "#react input[name=searchGifs]", e => { + let target = $(e.target); + let value = target.val().trim(); + + clearInterval(this.gifTimer); + this.lastGifSearch = app.time(); + this.gifTimer = setInterval(() => { + let timeSince = app.time() - this.lastGifSearch; + if (timeSince >= 1) { + app.ui.searchGifs(value); + clearInterval(this.gifTimer); + } + }, 100); + }); + + $("html").on("click", "#react .gif", e => { + let target = $(e.target); + let gif = target.data("full"); + + let data = { + hnschat: 1, + attachment: gif + }; + app.sendMessage(app.conversation, JSON.stringify(data)); + app.ui.close(); + }); + + $("html").on("click", e => { + let target = $(e.currentTarget); + }); + + $("html").on("click", "#users .user, .messageRow .user, .messageRow .favicon, .inline.nick, .header .favicon, .inline.channel, .cam table .user, .screen table .user, #videoInfo .avatar > div", e => { + let target = $(e.currentTarget); + + if (!app.userForID(app.domain).locked) { + app.ui.handleRightClick(e, target); + } + }); + + $("html").on("input paste keydown focus click", ".contextMenu[data-name=userContext] .bioHolder .bio", e => { + app.ui.updateBioLimit(e); + }); + + $(window).on("contextmenu", e => { + let target = $(e.target); + + if (["INPUT", "TEXTAREA", "A"].includes(target.prop("tagName")) || target.hasClass("body") || (target.hasClass("inline") && !(target.hasClass("nick") || target.hasClass("channel")))) { + return; + } + else { + e.preventDefault(); + + app.ui.handleRightClick(e, target); + } + }); + + $("html").on("touchstart", ".messageRow", e => { + let target = $(e.target); + if (!(target.hasClass("messageRow") || target.hasClass("message") || target.hasClass("body") || target.hasClass("main") || target.hasClass("msg") || target.hasClass("hover"))) { + return; + } + + $("body").addClass("touching"); + this.longPress = e.timeStamp; + this.longPressTimer = setTimeout(() => { + app.ui.handleRightClick(e, target); + }, 500); + }); + + $("html").on("touchcancel", ".messageRow", e => { + $("body").removeClass("touching"); + this.longPress = 0; + clearTimeout(this.longPressTimer); + }); + + $("html").on("touchend", ".messageRow", e => { + if ($("#blackout").hasClass("shown")) { + setTimeout(() => { + this.longPress = 0; + clearTimeout(this.longPressTimer); + $("body").removeClass("touching"); + }, 500); + } + + let duration = e.timeStamp - this.longPress; + if (duration < 500) { + this.longPress = 0; + clearTimeout(this.longPressTimer); + $("body").removeClass("touching"); + } + }); + + $("html").on("click", ".header .icon.menu", e => { + if ($("#conversations").hasClass("showing")) { + $("body").removeClass("menu"); + $("#conversations").removeClass("showing"); + } + else { + if ($("#users").hasClass("showing")) { + $("body").removeClass("menu"); + $("#users").removeClass("showing") + } + $("body").addClass("menu"); + $("#conversations").addClass("showing"); + } + }); + + $("html").on("click", ".header .icon.users", e => { + if ($("#holder[data-type=pms]").length) { + return; + } + + if ($("#users").hasClass("showing")) { + $("body").removeClass("menu"); + $("#users").removeClass("showing"); + } + else { + if ($("#conversations").hasClass("showing")) { + $("body").removeClass("menu"); + $("#conversations").removeClass("showing") + } + $("body").addClass("menu"); + $("#users").addClass("showing"); + } + }); + + $("html").on("keyup", "input", e => { + if (app.isKey(e, 13)) { + let target = $(e.target); + let submit = target.parent().find(".button").last(); + if (!submit.length) { + submit = target.closest(".section").find(".button").last(); + } + submit.click(); + } + }); + + $("html").on("keydown", "input[name=hns]", e => { + let key = e.key; + let keyCode = app.key(e); + let match = key.match(/[a-z ]/g); + if (match && !(e.shiftKey || e.metaKey || e.ctrlKey) && !(keyCode >= 37 && keyCode <= 40)) { + e.preventDefault(); + } + }); + + $("html").on("keyup", "#users input[name=search]", e => { + if (app.isKey(e, 27)) { + app.ui.searchUsers(false); + } + else { + let target = $(e.target); + let value = target.val().trim(); + app.ui.queryUsers(value); + } + }); + + $("html").on("change", "#file", e => { + let file = $(e.currentTarget)[0].files[0]; + + if (file) { + let url = URL.createObjectURL(file); + let attachment = $(` +
+
+
+
+
+
+ `); + $("#attachments").append(attachment); + app.ui.showOrHideAttachments(); + + let data = new FormData; + data.append("file", file); + data.append("key", app.session); + app.upload(data, attachment).then(r => { + attachment.find(".uploading").remove(); + + if (r.success) { + attachment.attr("data-id", r.id); + } + else { + alert(r.message); + attachment.remove(); + } + + app.ui.showOrHideAttachments(); + $("#message").focus(); + }); + } + }); + + $("html").on("input paste keydown focus click", ".popover[data-name=settings] input.color", e => { + let target = $(e.currentTarget); + let name = `--${target.attr("name")}`; + let value = target.val(); + app.ui.root.style.setProperty(name, value); + }); + + $("html").on("change", ".popover[data-name=settings] select[name=chatDisplayMode]", e => { + let target = $(e.target); + let value = target.val(); + app.ui.chatDisplayMode(value); + }); + + $("html").on("click", ".messageRow .reply .body", e => { + let target = $(e.target); + let message = target.closest(".reply").data("id"); + app.ui.gotoMessage(message); + }); + + $("html").on("click", ".pinnedMessage", e => { + let target = $(e.target); + if (target.hasClass("delete")) { + return; + } + let message = app.channelForID(app.conversation).pinned; + app.ui.gotoMessage(message); + }); + + $("html").on("click", "#jumpToPresent", e => { + app.ui.setInThePast(false); + app.ui.clear("messages"); + app.ui.messagesLoading(true); + app.getMessages(); + }); + + $(window).on("message", e => { + if (e.originalEvent.data) { + switch (e.originalEvent.data) { + case "handlePush": + app.handlePush(); + break; + + case "mobileApp": + localStorage.setItem("mobile", true); + break; + } + } + }); + } +} \ No newline at end of file diff --git a/assets/js/mask.js b/assets/js/mask.js new file mode 100755 index 0000000..24f600d --- /dev/null +++ b/assets/js/mask.js @@ -0,0 +1,8 @@ +/*! + * dist/jquery.inputmask.min + * https://github.com/RobinHerbots/Inputmask + * Copyright (c) 2010 - 2023 Robin Herbots + * Licensed under the MIT license + * Version: 5.0.8-beta.73 + */ +!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t(require("jquery"));else if("function"==typeof define&&define.amd)define(["jquery"],t);else{var i="object"==typeof exports?t(require("jquery")):t(e.jQuery);for(var a in i)("object"==typeof exports?exports:e)[a]=i[a]}}("undefined"!=typeof self?self:this,(function(e){return function(){"use strict";var t={3046:function(e,t,i){var a;Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0,i(7149),i(3194),i(9302),i(4013),i(3851),i(219),i(207),i(5296);var n=((a=i(2394))&&a.__esModule?a:{default:a}).default;t.default=n},8741:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var i=!("undefined"==typeof window||!window.document||!window.document.createElement);t.default=i},3976:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var a=i(2839),n={_maxTestPos:500,placeholder:"_",optionalmarker:["[","]"],quantifiermarker:["{","}"],groupmarker:["(",")"],alternatormarker:"|",escapeChar:"\\",mask:null,regex:null,oncomplete:function(){},onincomplete:function(){},oncleared:function(){},repeat:0,greedy:!1,autoUnmask:!1,removeMaskOnSubmit:!1,clearMaskOnLostFocus:!0,insertMode:!0,insertModeVisual:!0,clearIncomplete:!1,alias:null,onKeyDown:function(){},onBeforeMask:null,onBeforePaste:function(e,t){return"function"==typeof t.onBeforeMask?t.onBeforeMask.call(this,e,t):e},onBeforeWrite:null,onUnMask:null,showMaskOnFocus:!0,showMaskOnHover:!0,onKeyValidation:function(){},skipOptionalPartCharacter:" ",numericInput:!1,rightAlign:!1,undoOnEscape:!0,radixPoint:"",_radixDance:!1,groupSeparator:"",keepStatic:null,positionCaretOnTab:!0,tabThrough:!1,supportsInputType:["text","tel","url","password","search"],ignorables:[a.keys.Backspace,a.keys.Tab,a.keys.Pause,a.keys.Escape,a.keys.PageUp,a.keys.PageDown,a.keys.End,a.keys.Home,a.keys.ArrowLeft,a.keys.ArrowUp,a.keys.ArrowRight,a.keys.ArrowDown,a.keys.Insert,a.keys.Delete,a.keys.ContextMenu,a.keys.F1,a.keys.F2,a.keys.F3,a.keys.F4,a.keys.F5,a.keys.F6,a.keys.F7,a.keys.F8,a.keys.F9,a.keys.F10,a.keys.F11,a.keys.F12,a.keys.Process,a.keys.Unidentified,a.keys.Shift,a.keys.Control,a.keys.Alt,a.keys.Tab,a.keys.AltGraph,a.keys.CapsLock],isComplete:null,preValidation:null,postValidation:null,staticDefinitionSymbol:void 0,jitMasking:!1,nullable:!0,inputEventOnly:!1,noValuePatching:!1,positionCaretOnClick:"lvp",casing:null,inputmode:"text",importDataAttributes:!0,shiftPositions:!0,usePrototypeDefinitions:!0,validationEventTimeOut:3e3,substitutes:{}};t.default=n},7392:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;t.default={9:{validator:"[0-9\uff10-\uff19]",definitionSymbol:"*"},a:{validator:"[A-Za-z\u0410-\u044f\u0401\u0451\xc0-\xff\xb5]",definitionSymbol:"*"},"*":{validator:"[0-9\uff10-\uff19A-Za-z\u0410-\u044f\u0401\u0451\xc0-\xff\xb5]"}}},3287:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var a,n=(a=i(7957))&&a.__esModule?a:{default:a};if(void 0===n.default)throw"jQuery not loaded!";var r=n.default;t.default=r},9845:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.mobile=t.iphone=t.ie=void 0;var a,n=(a=i(9380))&&a.__esModule?a:{default:a};var r=n.default.navigator&&n.default.navigator.userAgent||"",o=r.indexOf("MSIE ")>0||r.indexOf("Trident/")>0,s=navigator.userAgentData&&navigator.userAgentData.mobile||n.default.navigator&&n.default.navigator.maxTouchPoints||"ontouchstart"in n.default,l=/iphone/i.test(r);t.iphone=l,t.mobile=s,t.ie=o},7184:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){return e.replace(i,"\\$1")};var i=new RegExp("(\\"+["/",".","*","+","?","|","(",")","[","]","{","}","\\","$","^"].join("|\\")+")","gim")},6030:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.EventHandlers=void 0;var a=i(8711),n=i(2839),r=i(9845),o=i(7215),s=i(7760),l=i(4713);function c(e,t){var i="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!i){if(Array.isArray(e)||(i=function(e,t){if(!e)return;if("string"==typeof e)return u(e,t);var i=Object.prototype.toString.call(e).slice(8,-1);"Object"===i&&e.constructor&&(i=e.constructor.name);if("Map"===i||"Set"===i)return Array.from(e);if("Arguments"===i||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(i))return u(e,t)}(e))||t&&e&&"number"==typeof e.length){i&&(e=i);var a=0,n=function(){};return{s:n,n:function(){return a>=e.length?{done:!0}:{done:!1,value:e[a++]}},e:function(e){throw e},f:n}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var r,o=!0,s=!1;return{s:function(){i=i.call(e)},n:function(){var e=i.next();return o=e.done,e},e:function(e){s=!0,r=e},f:function(){try{o||null==i.return||i.return()}finally{if(s)throw r}}}}function u(e,t){(null==t||t>e.length)&&(t=e.length);for(var i=0,a=new Array(t);i=0&&y.end>0&&(e.preventDefault(),a.caret.call(p,v,y.begin,y.end))):(y.begin=a.seekNext.call(p,y.begin,!0),y.end=a.seekNext.call(p,y.begin,!0),y.end=p.length?u.length:p.length,m=f.length>=d.length?f.length:d.length,v="",g=[],k="~";u.length0;){var o=r.pop();["submit","reset"].includes(n)?null!==e.form&&i(e.form).off(n,o):i(e).off(n,o)}delete e.inputmask.events[n]}}}};t.EventRuler=l},219:function(e,t,i){var a=p(i(2394)),n=i(2839),r=p(i(7184)),o=i(8711),s=i(4713);function l(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var i=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=i){var a,n,r,o,s=[],l=!0,c=!1;try{if(r=(i=i.call(e)).next,0===t){if(Object(i)!==i)return;l=!1}else for(;!(l=(a=r.call(i)).done)&&(s.push(a.value),s.length!==t);l=!0);}catch(e){c=!0,n=e}finally{try{if(!l&&null!=i.return&&(o=i.return(),Object(o)!==o))return}finally{if(c)throw n}}return s}}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return c(e,t);var i=Object.prototype.toString.call(e).slice(8,-1);"Object"===i&&e.constructor&&(i=e.constructor.name);if("Map"===i||"Set"===i)return Array.from(e);if("Arguments"===i||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(i))return c(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function c(e,t){(null==t||t>e.length)&&(t=e.length);for(var i=0,a=new Array(t);i0&&t--,Date.prototype.setMonth.call(this,t)},"month",function(){return Date.prototype.getMonth.call(this)+1}],mm:["0[1-9]|1[012]",function(e){var t=e?parseInt(e):0;return t>0&&t--,Date.prototype.setMonth.call(this,t)},"month",function(){return M(Date.prototype.getMonth.call(this)+1,2)}],mmm:[""],mmmm:[""],yy:["[0-9]{2}",Date.prototype.setFullYear,"year",function(){return M(Date.prototype.getFullYear.call(this),2)}],yyyy:["[0-9]{4}",Date.prototype.setFullYear,"year",function(){return M(Date.prototype.getFullYear.call(this),4)}],h:["[1-9]|1[0-2]",Date.prototype.setHours,"hours",Date.prototype.getHours],hh:["0[1-9]|1[0-2]",Date.prototype.setHours,"hours",function(){return M(Date.prototype.getHours.call(this),2)}],hx:[function(e){return"[0-9]{".concat(e,"}")},Date.prototype.setHours,"hours",function(e){return Date.prototype.getHours}],H:["1?[0-9]|2[0-3]",Date.prototype.setHours,"hours",Date.prototype.getHours],HH:["0[0-9]|1[0-9]|2[0-3]",Date.prototype.setHours,"hours",function(){return M(Date.prototype.getHours.call(this),2)}],Hx:[function(e){return"[0-9]{".concat(e,"}")},Date.prototype.setHours,"hours",function(e){return function(){return M(Date.prototype.getHours.call(this),e)}}],M:["[1-5]?[0-9]",Date.prototype.setMinutes,"minutes",Date.prototype.getMinutes],MM:["0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]",Date.prototype.setMinutes,"minutes",function(){return M(Date.prototype.getMinutes.call(this),2)}],s:["[1-5]?[0-9]",Date.prototype.setSeconds,"seconds",Date.prototype.getSeconds],ss:["0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]",Date.prototype.setSeconds,"seconds",function(){return M(Date.prototype.getSeconds.call(this),2)}],l:["[0-9]{3}",Date.prototype.setMilliseconds,"milliseconds",function(){return M(Date.prototype.getMilliseconds.call(this),3)},3],L:["[0-9]{2}",Date.prototype.setMilliseconds,"milliseconds",function(){return M(Date.prototype.getMilliseconds.call(this),2)},2],t:["[ap]",y,"ampm",b,1],tt:["[ap]m",y,"ampm",b,2],T:["[AP]",y,"ampm",b,1],TT:["[AP]M",y,"ampm",b,2],Z:[".*",void 0,"Z",function(){var e=this.toString().match(/\((.+)\)/)[1];e.includes(" ")&&(e=(e=e.replace("-"," ").toUpperCase()).split(" ").map((function(e){return l(e,1)[0]})).join(""));return e}],o:[""],S:[""]},k={isoDate:"yyyy-mm-dd",isoTime:"HH:MM:ss",isoDateTime:"yyyy-mm-dd'T'HH:MM:ss",isoUtcDateTime:"UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"};function y(e){var t=this.getHours();e.toLowerCase().includes("p")?this.setHours(t+12):e.toLowerCase().includes("a")&&t>=12&&this.setHours(t-12)}function b(){var e=this.getHours();return(e=e||12)>=12?"PM":"AM"}function x(e){var t=new RegExp("\\d+$").exec(e[0]);if(t&&void 0!==t[0]){var i=g[e[0][0]+"x"].slice("");return i[0]=i[0](t[0]),i[3]=i[3](t[0]),i}if(g[e[0]])return g[e[0]]}function P(e){if(!e.tokenizer){var t=[],i=[];for(var a in g)if(/\.*x$/.test(a)){var n=a[0]+"\\d+";-1===i.indexOf(n)&&i.push(n)}else-1===t.indexOf(a[0])&&t.push(a[0]);e.tokenizer="("+(i.length>0?i.join("|")+"|":"")+t.join("+|")+")+?|.",e.tokenizer=new RegExp(e.tokenizer,"g")}return e.tokenizer}function w(e,t,i){if(!v)return!0;if(void 0===e.rawday||!isFinite(e.rawday)&&new Date(e.date.getFullYear(),isFinite(e.rawmonth)?e.month:e.date.getMonth()+1,0).getDate()>=e.day||"29"==e.day&&(!isFinite(e.rawyear)||void 0===e.rawyear||""===e.rawyear)||new Date(e.date.getFullYear(),isFinite(e.rawmonth)?e.month:e.date.getMonth()+1,0).getDate()>=e.day)return t;if("29"==e.day){var a=T(t.pos,i);if("yyyy"===a.targetMatch[0]&&t.pos-a.targetMatchIndex==2)return t.remove=t.pos+1,t}else if("02"==e.month&&"30"==e.day&&void 0!==t.c)return e.day="03",e.date.setDate(3),e.date.setMonth(1),t.insert=[{pos:t.pos,c:"0"},{pos:t.pos+1,c:t.c}],t.caret=o.seekNext.call(this,t.pos+1),t;return!1}function S(e,t,i,a){var n,o,s="";for(P(i).lastIndex=0;n=P(i).exec(e);){if(void 0===t)if(o=x(n))s+="("+o[0]+")";else switch(n[0]){case"[":s+="(";break;case"]":s+=")?";break;default:s+=(0,r.default)(n[0])}else if(o=x(n))if(!0!==a&&o[3])s+=o[3].call(t.date);else o[2]?s+=t["raw"+o[2]]:s+=n[0];else s+=n[0]}return s}function M(e,t,i){for(e=String(e),t=t||2;e.length=e+1){i=a,a=P(t).exec(t.inputFormat);break}}return{targetMatchIndex:n-r,nextMatch:a,targetMatch:i}}a.default.extendAliases({datetime:{mask:function(e){return e.numericInput=!1,g.S=e.i18n.ordinalSuffix.join("|"),e.inputFormat=k[e.inputFormat]||e.inputFormat,e.displayFormat=k[e.displayFormat]||e.displayFormat||e.inputFormat,e.outputFormat=k[e.outputFormat]||e.outputFormat||e.inputFormat,e.placeholder=""!==e.placeholder?e.placeholder:e.inputFormat.replace(/[[\]]/,""),e.regex=S(e.inputFormat,void 0,e),e.min=_(e.min,e.inputFormat,e),e.max=_(e.max,e.inputFormat,e),null},placeholder:"",inputFormat:"isoDateTime",displayFormat:null,outputFormat:null,min:null,max:null,skipOptionalPartCharacter:"",i18n:{dayNames:["Mon","Tue","Wed","Thu","Fri","Sat","Sun","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],monthNames:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec","January","February","March","April","May","June","July","August","September","October","November","December"],ordinalSuffix:["st","nd","rd","th"]},preValidation:function(e,t,i,a,n,r,o,s){if(s)return!0;if(isNaN(i)&&e[t]!==i){var l=T(t,n);if(l.nextMatch&&l.nextMatch[0]===i&&l.targetMatch[0].length>1){var c=g[l.targetMatch[0]][0];if(new RegExp(c).test("0"+e[t-1]))return e[t]=e[t-1],e[t-1]="0",{fuzzy:!0,buffer:e,refreshFromBuffer:{start:t-1,end:t+1},pos:t+1}}}return!0},postValidation:function(e,t,i,a,n,r,o,l){var c,u;if(o)return!0;if(!1===a&&(((c=T(t+1,n)).targetMatch&&c.targetMatchIndex===t&&c.targetMatch[0].length>1&&void 0!==g[c.targetMatch[0]]||(c=T(t+2,n)).targetMatch&&c.targetMatchIndex===t+1&&c.targetMatch[0].length>1&&void 0!==g[c.targetMatch[0]])&&(u=g[c.targetMatch[0]][0]),void 0!==u&&(void 0!==r.validPositions[t+1]&&new RegExp(u).test(i+"0")?(e[t]=i,e[t+1]="0",a={pos:t+2,caret:t}):new RegExp(u).test("0"+i)&&(e[t]="0",e[t+1]=i,a={pos:t+2})),!1===a))return a;if(a.fuzzy&&(e=a.buffer,t=a.pos),(c=T(t,n)).targetMatch&&c.targetMatch[0]&&void 0!==g[c.targetMatch[0]]){var f=g[c.targetMatch[0]];u=f[0];var p=e.slice(c.targetMatchIndex,c.targetMatchIndex+c.targetMatch[0].length);if(!1===new RegExp(u).test(p.join(""))&&2===c.targetMatch[0].length&&r.validPositions[c.targetMatchIndex]&&r.validPositions[c.targetMatchIndex+1]&&(r.validPositions[c.targetMatchIndex+1].input="0"),"year"==f[2])for(var d=s.getMaskTemplate.call(this,!1,1,void 0,!0),h=t+1;h=s.getTime())&&(e.date.setFullYear(m),e.year=a,t.insert=[{pos:t.pos+1,c:o[0]},{pos:t.pos+2,c:o[1]}])}}return t}(k,v,n)),v=function(e,t,i,a,n){if(!t)return t;if(t&&i.min&&!isNaN(i.min.date.getTime())){var r;for(e.reset(),P(i).lastIndex=0;r=P(i).exec(i.inputFormat);){var o;if((o=x(r))&&o[3]){for(var s=o[1],l=e[o[2]],c=i.min[o[2]],u=i.max?i.max[o[2]]:c,f=[],p=!1,d=0;dc[d]):(f[d]=c[d],"year"===o[2]&&l.length-1==d&&c!=u&&(f=(parseInt(f.join(""))+1).toString().split("")),"ampm"===o[2]&&c!=u&&i.min.date.getTime()>e.date.getTime()&&(f[d]=u[d]));s.call(e._date,f.join(""))}}t=i.min.date.getTime()<=e.date.getTime(),e.reInit()}return t&&i.max&&(isNaN(i.max.date.getTime())||(t=i.max.date.getTime()>=e.date.getTime())),t}(k,v=w.call(this,k,v,n),n,r)),void 0!==t&&v&&a.pos!==t?{buffer:S(n.inputFormat,k,n).split(""),refreshFromBuffer:{start:t,end:a.pos},pos:a.caret||a.pos}:v},onKeyDown:function(e,t,i,a){e.ctrlKey&&e.key===n.keys.ArrowRight&&(this.inputmask._valueSet(O(new Date,a)),d(this).trigger("setvalue"))},onUnMask:function(e,t,i){return t?S(i.outputFormat,_(e,i.inputFormat,i),i,!0):t},casing:function(e,t,i,a){return 0==t.nativeDef.indexOf("[ap]")?e.toLowerCase():0==t.nativeDef.indexOf("[AP]")?e.toUpperCase():e},onBeforeMask:function(e,t){return"[object Date]"===Object.prototype.toString.call(e)&&(e=O(e,t)),e},insertMode:!1,insertModeVisual:!1,shiftPositions:!1,keepStatic:!1,inputmode:"numeric",prefillYear:!0}})},3851:function(e,t,i){var a,n=(a=i(2394))&&a.__esModule?a:{default:a},r=i(8711),o=i(4713);n.default.extendDefinitions({A:{validator:"[A-Za-z\u0410-\u044f\u0401\u0451\xc0-\xff\xb5]",casing:"upper"},"&":{validator:"[0-9A-Za-z\u0410-\u044f\u0401\u0451\xc0-\xff\xb5]",casing:"upper"},"#":{validator:"[0-9A-Fa-f]",casing:"upper"}});var s=new RegExp("25[0-5]|2[0-4][0-9]|[01][0-9][0-9]");function l(e,t,i,a,n){return i-1>-1&&"."!==t.buffer[i-1]?(e=t.buffer[i-1]+e,e=i-2>-1&&"."!==t.buffer[i-2]?t.buffer[i-2]+e:"0"+e):e="00"+e,s.test(e)}n.default.extendAliases({cssunit:{regex:"[+-]?[0-9]+\\.?([0-9]+)?(px|em|rem|ex|%|in|cm|mm|pt|pc)"},url:{regex:"(https?|ftp)://.*",autoUnmask:!1,keepStatic:!1,tabThrough:!0},ip:{mask:"i{1,3}.j{1,3}.k{1,3}.l{1,3}",definitions:{i:{validator:l},j:{validator:l},k:{validator:l},l:{validator:l}},onUnMask:function(e,t,i){return e},inputmode:"decimal",substitutes:{",":"."}},email:{mask:function(e){var t=e.separator,i=e.quantifier,a="*{1,64}[.*{1,64}][.*{1,64}][.*{1,63}]@-{1,63}.-{1,63}[.-{1,63}][.-{1,63}]",n=a;if(t)for(var r=0;r0&&t>0&&(!i.digitsOptional||a)){var n=e.indexOf(i.radixPoint),r=!1;i.negationSymbol.back===e[e.length-1]&&(r=!0,e.length--),-1===n&&(e.push(i.radixPoint),n=e.length-1);for(var o=1;o<=t;o++)isFinite(e[n+o])||(e[n+o]="0")}return r&&e.push(i.negationSymbol.back),e}function f(e,t){var i=0;for(var a in"+"===e&&(i=r.seekNext.call(this,t.validPositions.length-1)),t.tests)if((a=parseInt(a))>=i)for(var n=0,o=t.tests[a].length;n1&&(e.placeholder=e.placeholder.charAt(0)),"radixFocus"===e.positionCaretOnClick&&""===e.placeholder&&(e.positionCaretOnClick="lvp");var t="0",i=e.radixPoint;!0===e.numericInput&&void 0===e.__financeInput?(t="1",e.positionCaretOnClick="radixFocus"===e.positionCaretOnClick?"lvp":e.positionCaretOnClick,e.digitsOptional=!1,isNaN(e.digits)&&(e.digits=2),e._radixDance=!1,i=","===e.radixPoint?"?":"!",""!==e.radixPoint&&void 0===e.definitions[i]&&(e.definitions[i]={},e.definitions[i].validator="["+e.radixPoint+"]",e.definitions[i].placeholder=e.radixPoint,e.definitions[i].static=!0,e.definitions[i].generated=!0)):(e.__financeInput=!1,e.numericInput=!0);var a,r="[+]";if(r+=c(e.prefix,e),""!==e.groupSeparator?(void 0===e.definitions[e.groupSeparator]&&(e.definitions[e.groupSeparator]={},e.definitions[e.groupSeparator].validator="["+e.groupSeparator+"]",e.definitions[e.groupSeparator].placeholder=e.groupSeparator,e.definitions[e.groupSeparator].static=!0,e.definitions[e.groupSeparator].generated=!0),r+=e._mask(e)):r+="9{+}",void 0!==e.digits&&0!==e.digits){var o=e.digits.toString().split(",");isFinite(o[0])&&o[1]&&isFinite(o[1])?r+=i+t+"{"+e.digits+"}":(isNaN(e.digits)||parseInt(e.digits)>0)&&(e.digitsOptional||e.jitMasking?(a=r+i+t+"{0,"+e.digits+"}",e.keepStatic=!0):r+=i+t+"{"+e.digits+"}")}else e.inputmode="numeric";return r+=c(e.suffix,e),r+="[-]",a&&(r=[a+c(e.suffix,e)+"[-]",r]),e.greedy=!1,function(e){void 0===e.parseMinMaxOptions&&(null!==e.min&&(e.min=e.min.toString().replace(new RegExp((0,n.default)(e.groupSeparator),"g"),""),","===e.radixPoint&&(e.min=e.min.replace(e.radixPoint,".")),e.min=isFinite(e.min)?parseFloat(e.min):NaN,isNaN(e.min)&&(e.min=Number.MIN_VALUE)),null!==e.max&&(e.max=e.max.toString().replace(new RegExp((0,n.default)(e.groupSeparator),"g"),""),","===e.radixPoint&&(e.max=e.max.replace(e.radixPoint,".")),e.max=isFinite(e.max)?parseFloat(e.max):NaN,isNaN(e.max)&&(e.max=Number.MAX_VALUE)),e.parseMinMaxOptions="done")}(e),""!==e.radixPoint&&e.substituteRadixPoint&&(e.substitutes["."==e.radixPoint?",":"."]=e.radixPoint),r},_mask:function(e){return"("+e.groupSeparator+"999){+|1}"},digits:"*",digitsOptional:!0,enforceDigitsOnBlur:!1,radixPoint:".",positionCaretOnClick:"radixFocus",_radixDance:!0,groupSeparator:"",allowMinus:!0,negationSymbol:{front:"-",back:""},prefix:"",suffix:"",min:null,max:null,SetMaxOnOverflow:!1,step:1,inputType:"text",unmaskAsNumber:!1,roundingFN:Math.round,inputmode:"decimal",shortcuts:{k:"1000",m:"1000000"},placeholder:"0",greedy:!1,rightAlign:!0,insertMode:!0,autoUnmask:!1,skipOptionalPartCharacter:"",usePrototypeDefinitions:!1,stripLeadingZeroes:!0,substituteRadixPoint:!0,definitions:{0:{validator:d},1:{validator:d,definitionSymbol:"9"},9:{validator:"[0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9]",definitionSymbol:"*"},"+":{validator:function(e,t,i,a,n){return n.allowMinus&&("-"===e||e===n.negationSymbol.front)}},"-":{validator:function(e,t,i,a,n){return n.allowMinus&&e===n.negationSymbol.back}}},preValidation:function(e,t,i,a,n,r,o,s){if(!1!==n.__financeInput&&i===n.radixPoint)return!1;var l=e.indexOf(n.radixPoint),c=t;if(t=function(e,t,i,a,n){return n._radixDance&&n.numericInput&&t!==n.negationSymbol.back&&e<=i&&(i>0||t==n.radixPoint)&&(void 0===a.validPositions[e-1]||a.validPositions[e-1].input!==n.negationSymbol.back)&&(e-=1),e}(t,i,l,r,n),"-"===i||i===n.negationSymbol.front){if(!0!==n.allowMinus)return!1;var u=!1,d=p("+",r),h=p("-",r);return-1!==d&&(u=[d,h]),!1!==u?{remove:u,caret:c-n.negationSymbol.back.length}:{insert:[{pos:f.call(this,"+",r),c:n.negationSymbol.front,fromIsValid:!0},{pos:f.call(this,"-",r),c:n.negationSymbol.back,fromIsValid:void 0}],caret:c+n.negationSymbol.back.length}}if(i===n.groupSeparator)return{caret:c};if(s)return!0;if(-1!==l&&!0===n._radixDance&&!1===a&&i===n.radixPoint&&void 0!==n.digits&&(isNaN(n.digits)||parseInt(n.digits)>0)&&l!==t)return{caret:n._radixDance&&t===l-1?l+1:l};if(!1===n.__financeInput)if(a){if(n.digitsOptional)return{rewritePosition:o.end};if(!n.digitsOptional){if(o.begin>l&&o.end<=l)return i===n.radixPoint?{insert:{pos:l+1,c:"0",fromIsValid:!0},rewritePosition:l}:{rewritePosition:l+1};if(o.begin0&&""===this.__valueGet.call(this.el))return{rewritePosition:l};return{rewritePosition:t}},postValidation:function(e,t,i,a,n,r,o){if(!1===a)return a;if(o)return!0;if(null!==n.min||null!==n.max){var s=n.onUnMask(e.slice().reverse().join(""),void 0,l.extend({},n,{unmaskAsNumber:!0}));if(null!==n.min&&sn.min.toString().length||s<0))return!1;if(null!==n.max&&s>n.max)return!!n.SetMaxOnOverflow&&{refreshFromBuffer:!0,buffer:u(n.max.toString().replace(".",n.radixPoint).split(""),n.digits,n).reverse()}}return a},onUnMask:function(e,t,i){if(""===t&&!0===i.nullable)return t;var a=e.replace(i.prefix,"");return a=(a=a.replace(i.suffix,"")).replace(new RegExp((0,n.default)(i.groupSeparator),"g"),""),""!==i.placeholder.charAt(0)&&(a=a.replace(new RegExp(i.placeholder.charAt(0),"g"),"0")),i.unmaskAsNumber?(""!==i.radixPoint&&-1!==a.indexOf(i.radixPoint)&&(a=a.replace(n.default.call(this,i.radixPoint),".")),a=(a=a.replace(new RegExp("^"+(0,n.default)(i.negationSymbol.front)),"-")).replace(new RegExp((0,n.default)(i.negationSymbol.back)+"$"),""),Number(a)):a},isComplete:function(e,t){var i=(t.numericInput?e.slice().reverse():e).join("");return i=(i=(i=(i=(i=i.replace(new RegExp("^"+(0,n.default)(t.negationSymbol.front)),"-")).replace(new RegExp((0,n.default)(t.negationSymbol.back)+"$"),"")).replace(t.prefix,"")).replace(t.suffix,"")).replace(new RegExp((0,n.default)(t.groupSeparator)+"([0-9]{3})","g"),"$1"),","===t.radixPoint&&(i=i.replace((0,n.default)(t.radixPoint),".")),isFinite(i)},onBeforeMask:function(e,t){var i=t.radixPoint||",";isFinite(t.digits)&&(t.digits=parseInt(t.digits)),"number"!=typeof e&&"number"!==t.inputType||""===i||(e=e.toString().replace(".",i));var a="-"===e.charAt(0)||e.charAt(0)===t.negationSymbol.front,r=e.split(i),o=r[0].replace(/[^\-0-9]/g,""),s=r.length>1?r[1].replace(/[^0-9]/g,""):"",l=r.length>1;e=o+(""!==s?i+s:s);var c=0;if(""!==i&&(c=t.digitsOptional?t.digitst.max&&(e=t.max.toString().replace(".",i))}return a&&"-"!==e.charAt(0)&&(e="-"+e),u(e.toString().split(""),c,t,l).join("")},onBeforeWrite:function(e,t,i,a){function r(e,t){if(!1!==a.__financeInput||t){var i=e.indexOf(a.radixPoint);-1!==i&&e.splice(i,1)}if(""!==a.groupSeparator)for(;-1!==(i=e.indexOf(a.groupSeparator));)e.splice(i,1);return e}var o,s;if(a.stripLeadingZeroes&&(s=function(e,t){var i=new RegExp("(^"+(""!==t.negationSymbol.front?(0,n.default)(t.negationSymbol.front)+"?":"")+(0,n.default)(t.prefix)+")(.*)("+(0,n.default)(t.suffix)+(""!=t.negationSymbol.back?(0,n.default)(t.negationSymbol.back)+"?":"")+"$)").exec(e.slice().reverse().join("")),a=i?i[2]:"",r=!1;return a&&(a=a.split(t.radixPoint.charAt(0))[0],r=new RegExp("^[0"+t.groupSeparator+"]*").exec(a)),!(!r||!(r[0].length>1||r[0].length>0&&r[0].length0;p--)delete this.maskset.validPositions[c+p],delete t[c+p];if(e)switch(e.type){case"blur":case"checkval":if(null!==a.min){var d=a.onUnMask(t.slice().reverse().join(""),void 0,l.extend({},a,{unmaskAsNumber:!0}));if(null!==a.min&&d1)return this.inputmask.__valueSet.call(this,parseFloat(this.inputmask.unmaskedvalue())*parseInt(s)),r.trigger("setvalue"),!1}if(e.ctrlKey)switch(e.key){case o.keys.ArrowUp:return this.inputmask.__valueSet.call(this,parseFloat(this.inputmask.unmaskedvalue())+parseInt(a.step)),r.trigger("setvalue"),!1;case o.keys.ArrowDown:return this.inputmask.__valueSet.call(this,parseFloat(this.inputmask.unmaskedvalue())-parseInt(a.step)),r.trigger("setvalue"),!1}if(!e.shiftKey&&(e.key===o.keys.Delete||e.key===o.keys.Backspace||e.key===o.keys.BACKSPACE_SAFARI)&&i.begin!==t.length){if(t[e.key===o.keys.Delete?i.begin-1:i.end]===a.negationSymbol.front)return n=t.slice().reverse(),""!==a.negationSymbol.front&&n.shift(),""!==a.negationSymbol.back&&n.pop(),r.trigger("setvalue",[n.join(""),i.begin]),!1;if(!0===a._radixDance){var f=t.indexOf(a.radixPoint);if(a.digitsOptional){if(0===f)return(n=t.slice().reverse()).pop(),r.trigger("setvalue",[n.join(""),i.begin>=n.length?n.length:i.begin]),!1}else if(-1!==f&&(i.begin=n.length?f+1:i.begin]),!1}}}}},currency:{prefix:"",groupSeparator:",",alias:"numeric",digits:2,digitsOptional:!1},decimal:{alias:"numeric"},integer:{alias:"numeric",inputmode:"numeric",digits:0},percentage:{alias:"numeric",min:0,max:100,suffix:" %",digits:0,allowMinus:!1},indianns:{alias:"numeric",_mask:function(e){return"("+e.groupSeparator+"99){*|1}("+e.groupSeparator+"999){1|1}"},groupSeparator:",",radixPoint:".",placeholder:"0",digits:2,digitsOptional:!1}})},9380:function(e,t,i){var a;Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=((a=i(8741))&&a.__esModule?a:{default:a}).default?window:{};t.default=n},7760:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.HandleNativePlaceholder=function(e,t){var i=e?e.inputmask:this;if(s.ie){if(e.inputmask._valueGet()!==t&&(e.placeholder!==t||""===e.placeholder)){var a=r.getBuffer.call(i).slice(),n=e.inputmask._valueGet();if(n!==t){var o=r.getLastValidPosition.call(i);-1===o&&n===r.getBufferTemplate.call(i).join("")?a=[]:-1!==o&&u.call(i,a),p(e,a)}}}else e.placeholder!==t&&(e.placeholder=t,""===e.placeholder&&e.removeAttribute("placeholder"))},t.applyInputValue=c,t.checkVal=f,t.clearOptionalTail=u,t.unmaskedvalue=function(e){var t=e?e.inputmask:this,i=t.opts,a=t.maskset;if(e){if(void 0===e.inputmask)return e.value;e.inputmask&&e.inputmask.refreshValue&&c(e,e.inputmask._valueGet(!0))}for(var n=[],o=a.validPositions,s=0,l=o.length;s0&&" "===i[a-1];)a--;var o=0===a&&!r.isMask.call(c,e)&&(n.getTest.call(c,e).match.nativeDef===t.charAt(0)||!0===n.getTest.call(c,e).match.static&&n.getTest.call(c,e).match.nativeDef==="'"+t.charAt(0)||" "===n.getTest.call(c,e).match.nativeDef&&(n.getTest.call(c,e+1).match.nativeDef===t.charAt(0)||!0===n.getTest.call(c,e+1).match.static&&n.getTest.call(c,e+1).match.nativeDef==="'"+t.charAt(0)));if(!o&&a>0&&!r.isMask.call(c,e,!1,!0)){var s=r.seekNext.call(c,e);c.caretPos.begin0){var x,P,w=r.seekNext.call(c,-1,void 0,!1);if(!o.isComplete.call(c,r.getBuffer.call(c))&&y.length<=w||o.isComplete.call(c,r.getBuffer.call(c))&&y.length>0&&y.length!==w&&0===y[0])for(var S=w;void 0!==(x=y.shift());){var M=new d.Event("_checkval");if((P=u.validPositions[x]).generatedInput=!0,M.key=P.input,(g=l.EventHandlers.keypressEvent.call(c,M,!0,!1,i,S))&&void 0!==g.pos&&g.pos!==x&&u.validPositions[g.pos]&&!0===u.validPositions[g.pos].match.static)y.push(g.pos);else if(!g)break;S++}}t&&p.call(c,e,r.getBuffer.call(c),g?g.forwardPosition:c.caretPos.begin,s||new d.Event("checkval"),s&&("input"===s.type&&c.undoValue!==r.getBuffer.call(c).join("")||"paste"===s.type)),f.skipOptionalPartCharacter=k}function p(e,t,i,n,s){var l=e?e.inputmask:this,c=l.opts,u=l.dependencyLib;if(n&&"function"==typeof c.onBeforeWrite){var f=c.onBeforeWrite.call(l,n,t,i,c);if(f){if(f.refreshFromBuffer){var p=f.refreshFromBuffer;o.refreshFromBuffer.call(l,!0===p?p:p.start,p.end,f.buffer||t),t=r.getBuffer.call(l,!0)}void 0!==i&&(i=void 0!==f.caret?f.caret:i)}}if(void 0!==e&&(e.inputmask._valueSet(t.join("")),void 0===i||void 0!==n&&"blur"===n.type||r.caret.call(l,e,i,void 0,void 0,void 0!==n&&"keydown"===n.type&&(n.key===a.keys.Delete||n.key===a.keys.Backspace)),!0===s)){var d=u(e),h=e.inputmask._valueGet();e.inputmask.skipInputEvent=!0,d.trigger("input"),setTimeout((function(){h===r.getBufferTemplate.call(l).join("")?d.trigger("cleared"):!0===o.isComplete.call(l,t)&&d.trigger("complete")}),0)}}},2394:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var a=i(157),n=v(i(3287)),r=v(i(9380)),o=i(2391),s=i(4713),l=i(8711),c=i(7215),u=i(7760),f=i(9716),p=v(i(7392)),d=v(i(3976)),h=v(i(8741));function m(e){return m="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},m(e)}function v(e){return e&&e.__esModule?e:{default:e}}var g=r.default.document,k="_inputmask_opts";function y(e,t,i){if(h.default){if(!(this instanceof y))return new y(e,t,i);this.dependencyLib=n.default,this.el=void 0,this.events={},this.maskset=void 0,!0!==i&&("[object Object]"===Object.prototype.toString.call(e)?t=e:(t=t||{},e&&(t.alias=e)),this.opts=n.default.extend(!0,{},this.defaults,t),this.noMasksCache=t&&void 0!==t.definitions,this.userOptions=t||{},b(this.opts.alias,t,this.opts)),this.refreshValue=!1,this.undoValue=void 0,this.$el=void 0,this.skipInputEvent=!1,this.validationEvent=!1,this.ignorable=!1,this.maxLength,this.mouseEnter=!1,this.clicked=0,this.originalPlaceholder=void 0,this.isComposing=!1,this.hasAlternator=!1}}function b(e,t,i){var a=y.prototype.aliases[e];return a?(a.alias&&b(a.alias,void 0,i),n.default.extend(!0,i,a),n.default.extend(!0,i,t),!0):(null===i.mask&&(i.mask=e),!1)}y.prototype={dataAttribute:"data-inputmask",defaults:d.default,definitions:p.default,aliases:{},masksCache:{},get isRTL(){return this.opts.isRTL||this.opts.numericInput},mask:function(e){var t=this;return"string"==typeof e&&(e=g.getElementById(e)||g.querySelectorAll(e)),(e=e.nodeName?[e]:Array.isArray(e)?e:[].slice.call(e)).forEach((function(e,i){var s=n.default.extend(!0,{},t.opts);if(function(e,t,i,a){function o(t,n){var o=""===a?t:a+"-"+t;null!==(n=void 0!==n?n:e.getAttribute(o))&&("string"==typeof n&&(0===t.indexOf("on")?n=r.default[n]:"false"===n?n=!1:"true"===n&&(n=!0)),i[t]=n)}if(!0===t.importDataAttributes){var s,l,c,u,f=e.getAttribute(a);if(f&&""!==f&&(f=f.replace(/'/g,'"'),l=JSON.parse("{"+f+"}")),l)for(u in c=void 0,l)if("alias"===u.toLowerCase()){c=l[u];break}for(s in o("alias",c),i.alias&&b(i.alias,i,t),t){if(l)for(u in c=void 0,l)if(u.toLowerCase()===s.toLowerCase()){c=l[u];break}o(s,c)}}n.default.extend(!0,t,i),("rtl"===e.dir||t.rightAlign)&&(e.style.textAlign="right");("rtl"===e.dir||t.numericInput)&&(e.dir="ltr",e.removeAttribute("dir"),t.isRTL=!0);return Object.keys(i).length}(e,s,n.default.extend(!0,{},t.userOptions),t.dataAttribute)){var l=(0,o.generateMaskSet)(s,t.noMasksCache);void 0!==l&&(void 0!==e.inputmask&&(e.inputmask.opts.autoUnmask=!0,e.inputmask.remove()),e.inputmask=new y(void 0,void 0,!0),e.inputmask.opts=s,e.inputmask.noMasksCache=t.noMasksCache,e.inputmask.userOptions=n.default.extend(!0,{},t.userOptions),e.inputmask.el=e,e.inputmask.$el=(0,n.default)(e),e.inputmask.maskset=l,n.default.data(e,k,t.userOptions),a.mask.call(e.inputmask))}})),e&&e[0]&&e[0].inputmask||this},option:function(e,t){return"string"==typeof e?this.opts[e]:"object"===m(e)?(n.default.extend(this.userOptions,e),this.el&&!0!==t&&this.mask(this.el),this):void 0},unmaskedvalue:function(e){if(this.maskset=this.maskset||(0,o.generateMaskSet)(this.opts,this.noMasksCache),void 0===this.el||void 0!==e){var t=("function"==typeof this.opts.onBeforeMask&&this.opts.onBeforeMask.call(this,e,this.opts)||e).split("");u.checkVal.call(this,void 0,!1,!1,t),"function"==typeof this.opts.onBeforeWrite&&this.opts.onBeforeWrite.call(this,void 0,l.getBuffer.call(this),0,this.opts)}return u.unmaskedvalue.call(this,this.el)},remove:function(){if(this.el){n.default.data(this.el,k,null);var e=this.opts.autoUnmask?(0,u.unmaskedvalue)(this.el):this._valueGet(this.opts.autoUnmask);e!==l.getBufferTemplate.call(this).join("")?this._valueSet(e,this.opts.autoUnmask):this._valueSet(""),f.EventRuler.off(this.el),Object.getOwnPropertyDescriptor&&Object.getPrototypeOf?Object.getOwnPropertyDescriptor(Object.getPrototypeOf(this.el),"value")&&this.__valueGet&&Object.defineProperty(this.el,"value",{get:this.__valueGet,set:this.__valueSet,configurable:!0}):g.__lookupGetter__&&this.el.__lookupGetter__("value")&&this.__valueGet&&(this.el.__defineGetter__("value",this.__valueGet),this.el.__defineSetter__("value",this.__valueSet)),this.el.inputmask=void 0}return this.el},getemptymask:function(){return this.maskset=this.maskset||(0,o.generateMaskSet)(this.opts,this.noMasksCache),(this.isRTL?l.getBufferTemplate.call(this).reverse():l.getBufferTemplate.call(this)).join("")},hasMaskedValue:function(){return!this.opts.autoUnmask},isComplete:function(){return this.maskset=this.maskset||(0,o.generateMaskSet)(this.opts,this.noMasksCache),c.isComplete.call(this,l.getBuffer.call(this))},getmetadata:function(){if(this.maskset=this.maskset||(0,o.generateMaskSet)(this.opts,this.noMasksCache),Array.isArray(this.maskset.metadata)){var e=s.getMaskTemplate.call(this,!0,0,!1).join("");return this.maskset.metadata.forEach((function(t){return t.mask!==e||(e=t,!1)})),e}return this.maskset.metadata},isValid:function(e){if(this.maskset=this.maskset||(0,o.generateMaskSet)(this.opts,this.noMasksCache),e){var t=("function"==typeof this.opts.onBeforeMask&&this.opts.onBeforeMask.call(this,e,this.opts)||e).split("");u.checkVal.call(this,void 0,!0,!1,t)}else e=this.isRTL?l.getBuffer.call(this).slice().reverse().join(""):l.getBuffer.call(this).join("");for(var i=l.getBuffer.call(this),a=l.determineLastRequiredPosition.call(this),n=i.length-1;n>a&&!l.isMask.call(this,n);n--);return i.splice(a,n+1-a),c.isComplete.call(this,i)&&e===(this.isRTL?l.getBuffer.call(this).slice().reverse().join(""):l.getBuffer.call(this).join(""))},format:function(e,t){this.maskset=this.maskset||(0,o.generateMaskSet)(this.opts,this.noMasksCache);var i=("function"==typeof this.opts.onBeforeMask&&this.opts.onBeforeMask.call(this,e,this.opts)||e).split("");u.checkVal.call(this,void 0,!0,!1,i);var a=this.isRTL?l.getBuffer.call(this).slice().reverse().join(""):l.getBuffer.call(this).join("");return t?{value:a,metadata:this.getmetadata()}:a},setValue:function(e){this.el&&(0,n.default)(this.el).trigger("setvalue",[e])},analyseMask:o.analyseMask},y.extendDefaults=function(e){n.default.extend(!0,y.prototype.defaults,e)},y.extendDefinitions=function(e){n.default.extend(!0,y.prototype.definitions,e)},y.extendAliases=function(e){n.default.extend(!0,y.prototype.aliases,e)},y.format=function(e,t,i){return y(t).format(e,i)},y.unmask=function(e,t){return y(t).unmaskedvalue(e)},y.isValid=function(e,t){return y(t).isValid(e)},y.remove=function(e){"string"==typeof e&&(e=g.getElementById(e)||g.querySelectorAll(e)),(e=e.nodeName?[e]:e).forEach((function(e){e.inputmask&&e.inputmask.remove()}))},y.setValue=function(e,t){"string"==typeof e&&(e=g.getElementById(e)||g.querySelectorAll(e)),(e=e.nodeName?[e]:e).forEach((function(e){e.inputmask?e.inputmask.setValue(t):(0,n.default)(e).trigger("setvalue",[t])}))},y.dependencyLib=n.default,r.default.Inputmask=y;var x=y;t.default=x},5296:function(e,t,i){function a(e){return a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},a(e)}var n=h(i(9380)),r=h(i(2394)),o=h(i(8741));function s(e,t){for(var i=0;ie.length)&&(t=e.length);for(var i=0,a=new Array(t);i0){if(k(l=m[m.length-1],o),l.isAlternator){c=m.pop();for(var e=0;e0?(l=m[m.length-1]).matches.push(c):h.matches.push(c)}}else k(h,o)}function b(e){var t=new n.default(!0);return t.openGroup=!1,t.matches=e,t}function x(){if((s=m.pop()).openGroup=!1,void 0!==s)if(m.length>0){if((l=m[m.length-1]).matches.push(s),l.isAlternator){for(var e=(c=m.pop()).matches[0].matches?c.matches[0].matches.length:1,t=0;t0?(l=m[m.length-1]).matches.push(c):h.matches.push(c)}}else h.matches.push(s);else y()}function P(e){var t=e.pop();return t.isQuantifier&&(t=b([e.pop(),t])),t}t&&(i.optionalmarker[0]=void 0,i.optionalmarker[1]=void 0);for(;a=t?p.exec(e):f.exec(e);){if(o=a[0],t){switch(o.charAt(0)){case"?":o="{0,1}";break;case"+":case"*":o="{"+o+"}";break;case"|":if(0===m.length){var w=b(h.matches);w.openGroup=!0,m.push(w),h.matches=[],g=!0}}switch(o){case"\\d":o="[0-9]";break;case"\\p":o+=p.exec(e)[0],o+=p.exec(e)[0]}}if(d)y();else switch(o.charAt(0)){case"$":case"^":t||y();break;case i.escapeChar:d=!0,t&&y();break;case i.optionalmarker[1]:case i.groupmarker[1]:x();break;case i.optionalmarker[0]:m.push(new n.default(!1,!0));break;case i.groupmarker[0]:m.push(new n.default(!0));break;case i.quantifiermarker[0]:var S=new n.default(!1,!1,!0),M=(o=o.replace(/[{}?]/g,"")).split("|"),_=M[0].split(","),O=isNaN(_[0])?_[0]:parseInt(_[0]),T=1===_.length?O:isNaN(_[1])?_[1]:parseInt(_[1]),E=isNaN(M[1])?M[1]:parseInt(M[1]);"*"!==O&&"+"!==O||(O="*"===T?0:1),S.quantifier={min:O,max:T,jit:E};var j=m.length>0?m[m.length-1].matches:h.matches;(a=j.pop()).isGroup||(a=b([a])),j.push(a),j.push(S);break;case i.alternatormarker:if(m.length>0){var A=(l=m[m.length-1]).matches[l.matches.length-1];u=l.openGroup&&(void 0===A.matches||!1===A.isGroup&&!1===A.isAlternator)?m.pop():P(l.matches)}else u=P(h.matches);if(u.isAlternator)m.push(u);else if(u.alternatorGroup?(c=m.pop(),u.alternatorGroup=!1):c=new n.default(!1,!1,!1,!0),c.matches.push(u),m.push(c),u.openGroup){u.openGroup=!1;var D=new n.default(!0);D.alternatorGroup=!0,m.push(D)}break;default:y()}}g&&x();for(;m.length>0;)s=m.pop(),h.matches.push(s);h.matches.length>0&&(!function e(a){a&&a.matches&&a.matches.forEach((function(n,r){var o=a.matches[r+1];(void 0===o||void 0===o.matches||!1===o.isQuantifier)&&n&&n.isGroup&&(n.isGroup=!1,t||(k(n,i.groupmarker[0],0),!0!==n.openGroup&&k(n,i.groupmarker[1]))),e(n)}))}(h),v.push(h));(i.numericInput||i.isRTL)&&function e(t){for(var a in t.matches=t.matches.reverse(),t.matches)if(Object.prototype.hasOwnProperty.call(t.matches,a)){var n=parseInt(a);if(t.matches[a].isQuantifier&&t.matches[n+1]&&t.matches[n+1].isGroup){var r=t.matches[a];t.matches.splice(a,1),t.matches.splice(n+1,0,r)}void 0!==t.matches[a].matches?t.matches[a]=e(t.matches[a]):t.matches[a]=((o=t.matches[a])===i.optionalmarker[0]?o=i.optionalmarker[1]:o===i.optionalmarker[1]?o=i.optionalmarker[0]:o===i.groupmarker[0]?o=i.groupmarker[1]:o===i.groupmarker[1]&&(o=i.groupmarker[0]),o)}var o;return t}(v[0]);return v},t.generateMaskSet=function(e,t){var i;function n(e,t){var i=t.repeat,a=t.groupmarker,n=t.quantifiermarker,r=t.keepStatic;if(i>0||"*"===i||"+"===i){var l="*"===i?0:"+"===i?1:i;e=a[0]+e+a[1]+n[0]+l+","+i+n[1]}if(!0===r){var c=e.match(new RegExp("(.)\\[([^\\]]*)\\]","g"));c&&c.forEach((function(t,i){var a=function(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var i=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=i){var a,n,r,o,s=[],l=!0,c=!1;try{if(r=(i=i.call(e)).next,0===t){if(Object(i)!==i)return;l=!1}else for(;!(l=(a=r.call(i)).done)&&(s.push(a.value),s.length!==t);l=!0);}catch(e){c=!0,n=e}finally{try{if(!l&&null!=i.return&&(o=i.return(),Object(o)!==o))return}finally{if(c)throw n}}return s}}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return s(e,t);var i=Object.prototype.toString.call(e).slice(8,-1);"Object"===i&&e.constructor&&(i=e.constructor.name);if("Map"===i||"Set"===i)return Array.from(e);if("Arguments"===i||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(i))return s(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}(t.split("["),2),n=a[0],r=a[1];r=r.replace("]",""),e=e.replace(new RegExp("".concat((0,o.default)(n),"\\[").concat((0,o.default)(r),"\\]")),n.charAt(0)===r.charAt(0)?"(".concat(n,"|").concat(n).concat(r,")"):"".concat(n,"[").concat(r,"]"))}))}return e}function l(e,i,o){var s,l,c=!1;return null!==e&&""!==e||((c=null!==o.regex)?e=(e=o.regex).replace(/^(\^)(.*)(\$)$/,"$2"):(c=!0,e=".*")),1===e.length&&!1===o.greedy&&0!==o.repeat&&(o.placeholder=""),e=n(e,o),l=c?"regex_"+o.regex:o.numericInput?e.split("").reverse().join(""):e,null!==o.keepStatic&&(l="ks_"+o.keepStatic+l),void 0===r.default.prototype.masksCache[l]||!0===t?(s={mask:e,maskToken:r.default.prototype.analyseMask(e,c,o),validPositions:[],_buffer:void 0,buffer:void 0,tests:{},excludes:{},metadata:i,maskLength:void 0,jitOffset:{}},!0!==t&&(r.default.prototype.masksCache[l]=s,s=a.default.extend(!0,{},r.default.prototype.masksCache[l]))):s=a.default.extend(!0,{},r.default.prototype.masksCache[l]),s}"function"==typeof e.mask&&(e.mask=e.mask(e));if(Array.isArray(e.mask)){if(e.mask.length>1){null===e.keepStatic&&(e.keepStatic=!0);var c=e.groupmarker[0];return(e.isRTL?e.mask.reverse():e.mask).forEach((function(t){c.length>1&&(c+=e.alternatormarker),void 0!==t.mask&&"function"!=typeof t.mask?c+=t.mask:c+=t})),l(c+=e.groupmarker[1],e.mask,e)}e.mask=e.mask.pop()}i=e.mask&&void 0!==e.mask.mask&&"function"!=typeof e.mask.mask?l(e.mask.mask,e.mask,e):l(e.mask,e.mask,e);null===e.keepStatic&&(e.keepStatic=!1);return i};var a=l(i(3287)),n=l(i(9695)),r=l(i(2394)),o=l(i(7184));function s(e,t){(null==t||t>e.length)&&(t=e.length);for(var i=0,a=new Array(t);i>>0;if(0===a)return!1;for(var n=0|t,r=Math.max(n>=0?n:a-Math.abs(n),0);rthis.length)&&-1!==this.indexOf(e,t)})},8711:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.caret=function(e,t,i,a,n){var r,o=this,s=this.opts;if(void 0===t)return"selectionStart"in e&&"selectionEnd"in e?(t=e.selectionStart,i=e.selectionEnd):window.getSelection?(r=window.getSelection().getRangeAt(0)).commonAncestorContainer.parentNode!==e&&r.commonAncestorContainer!==e||(t=r.startOffset,i=r.endOffset):document.selection&&document.selection.createRange&&(i=(t=0-(r=document.selection.createRange()).duplicate().moveStart("character",-e.inputmask._valueGet().length))+r.text.length),{begin:a?t:c.call(o,t),end:a?i:c.call(o,i)};if(Array.isArray(t)&&(i=o.isRTL?t[0]:t[1],t=o.isRTL?t[1]:t[0]),void 0!==t.begin&&(i=o.isRTL?t.begin:t.end,t=o.isRTL?t.end:t.begin),"number"==typeof t){t=a?t:c.call(o,t),i="number"==typeof(i=a?i:c.call(o,i))?i:t;var l=parseInt(((e.ownerDocument.defaultView||window).getComputedStyle?(e.ownerDocument.defaultView||window).getComputedStyle(e,null):e.currentStyle).fontSize)*i;if(e.scrollLeft=l>e.scrollWidth?l:0,e.inputmask.caretPos={begin:t,end:i},s.insertModeVisual&&!1===s.insertMode&&t===i&&(n||i++),e===(e.inputmask.shadowRoot||e.ownerDocument).activeElement)if("setSelectionRange"in e)e.setSelectionRange(t,i);else if(window.getSelection){if(r=document.createRange(),void 0===e.firstChild||null===e.firstChild){var u=document.createTextNode("");e.appendChild(u)}r.setStart(e.firstChild,tf&&(((i=p[t]).match.optionality||i.match.optionalQuantifier&&i.match.newBlockMarker||m&&(m!==p[t].locator[d.alternation]&&1!=i.match.static||!0===i.match.static&&i.locator[d.alternation]&&n.checkAlternationMatch.call(r,i.locator[d.alternation].toString().split(","),m.toString().split(","))&&""!==a.getTests.call(r,t)[0].def))&&c[t]===a.getPlaceholder.call(r,t,i.match));t--)u--;return e?{l:u,def:p[u]?p[u].match:void 0}:u},t.determineNewCaretPosition=function(e,t,i){var n=this,c=n.maskset,u=n.opts;t&&(n.isRTL?e.end=e.begin:e.begin=e.end);if(e.begin===e.end){switch(i=i||u.positionCaretOnClick){case"none":break;case"select":e={begin:0,end:r.call(n).length};break;case"ignore":e.end=e.begin=l.call(n,o.call(n));break;case"radixFocus":if(n.clicked>1&&0==c.validPositions.length)break;if(function(e){if(""!==u.radixPoint&&0!==u.digits){var t=c.validPositions;if(void 0===t[e]||t[e].input===a.getPlaceholder.call(n,e)){if(e=k||p===h)&&(h=k)}e.end=e.begin=h}}return e}},t.getBuffer=r,t.getBufferTemplate=function(){var e=this.maskset;void 0===e._buffer&&(e._buffer=a.getMaskTemplate.call(this,!1,1),void 0===e.buffer&&(e.buffer=e._buffer.slice()));return e._buffer},t.getLastValidPosition=o,t.isMask=s,t.resetMaskSet=function(e){var t=this.maskset;t.buffer=void 0,!0!==e&&(t.validPositions=[],t.p=0)},t.seekNext=l,t.seekPrevious=function(e,t){var i=this,n=e-1;if(e<=0)return 0;for(;n>0&&(!0===t&&(!0!==a.getTest.call(i,n).match.newBlockMarker||!s.call(i,n,void 0,!0))||!0!==t&&!s.call(i,n,void 0,!0));)n--;return n},t.translatePosition=c;var a=i(4713),n=i(7215);function r(e){var t=this,i=t.maskset;return void 0!==i.buffer&&!0!==e||(i.buffer=a.getMaskTemplate.call(t,!0,o.call(t),!0),void 0===i._buffer&&(i._buffer=i.buffer.slice())),i.buffer}function o(e,t,i){var a=this.maskset,n=-1,r=-1,o=i||a.validPositions;void 0===e&&(e=-1);for(var s=0,l=o.length;s=e&&(r=s));return-1===n||n==e?r:-1==r||e-n-1){if(i){var s=a.getTests.call(n,e);return s.length>1+(""===s[s.length-1].match.def?1:0)}var l=a.determineTestTemplate.call(n,e,a.getTests.call(n,e)),c=a.getPlaceholder.call(n,e,l.match);return l.match.def!==c}return!1}function l(e,t,i){var n=this;void 0===i&&(i=!0);for(var r=e+1;""!==a.getTest.call(n,r).match.def&&(!0===t&&(!0!==a.getTest.call(n,r).match.newBlockMarker||!s.call(n,r,void 0,!0))||!0!==t&&!s.call(n,r,void 0,i));)r++;return r}function c(e){var t=this.opts,i=this.el;return!this.isRTL||"number"!=typeof e||t.greedy&&""===t.placeholder||!i||(e=this._valueGet().length-e)<0&&(e=0),e}},4713:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.determineTestTemplate=c,t.getDecisionTaker=o,t.getMaskTemplate=function(e,t,i,a,n){var r=this,o=this.opts,u=this.maskset,f=o.greedy;n&&o.greedy&&(o.greedy=!1,r.maskset.tests={});t=t||0;var d,h,m,v,g=[],k=0;do{if(!0===e&&u.validPositions[k])h=(m=n&&u.validPositions[k].match.optionality&&void 0===u.validPositions[k+1]&&(!0===u.validPositions[k].generatedInput||u.validPositions[k].input==o.skipOptionalPartCharacter&&k>0)?c.call(r,k,p.call(r,k,d,k-1)):u.validPositions[k]).match,d=m.locator.slice(),g.push(!0===i?m.input:!1===i?h.nativeDef:s.call(r,k,h));else{h=(m=l.call(r,k,d,k-1)).match,d=m.locator.slice();var y=!0!==a&&(!1!==o.jitMasking?o.jitMasking:h.jit);(v=(v&&h.static&&h.def!==o.groupSeparator&&null===h.fn||u.validPositions[k-1]&&h.static&&h.def!==o.groupSeparator&&null===h.fn)&&u.tests[k]&&1===u.tests[k].length)||!1===y||void 0===y||"number"==typeof y&&isFinite(y)&&y>k?g.push(!1===i?h.nativeDef:s.call(r,g.length,h)):v=!1}k++}while(!0!==h.static||""!==h.def||t>k);""===g[g.length-1]&&g.pop();!1===i&&void 0!==u.maskLength||(u.maskLength=k-1);return o.greedy=f,g},t.getPlaceholder=s,t.getTest=u,t.getTestTemplate=l,t.getTests=p,t.isSubsetOf=f;var a,n=(a=i(2394))&&a.__esModule?a:{default:a};function r(e,t){var i=(null!=e.alternation?e.mloc[o(e)]:e.locator).join("");if(""!==i)for(;i.length0&&(t=t.split(",")[0]),void 0!==t?t.toString():""}function s(e,t,i){var a=this.opts,n=this.maskset;if(void 0!==(t=t||u.call(this,e).match).placeholder||!0===i)return"function"==typeof t.placeholder?t.placeholder(a):t.placeholder;if(!0===t.static){if(e>-1&&void 0===n.validPositions[e]){var r,o=p.call(this,e),s=[];if(o.length>1+(""===o[o.length-1].match.def?1:0))for(var l=0;l1&&/[0-9a-bA-Z]/.test(s[0].match.def)))return a.placeholder.charAt(e%a.placeholder.length)}return t.def}return a.placeholder.charAt(e%a.placeholder.length)}function l(e,t,i){return this.maskset.validPositions[e]||c.call(this,e,p.call(this,e,t?t.slice():t,i))}function c(e,t){var i=this.opts,a=0,n=function(e,t){var i=0,a=!1;t.forEach((function(e){e.match.optionality&&(0!==i&&i!==e.match.optionality&&(a=!0),(0===i||i>e.match.optionality)&&(i=e.match.optionality))})),i&&(0==e||1==t.length?i=0:a||(i=0));return i}(e,t);e=e>0?e-1:0;var o,s,l,c=r(u.call(this,e));i.greedy&&t.length>1&&""===t[t.length-1].match.def&&(a=1);for(var f=0;f0&&"master"===l.match.newBlockMarker&&(!p.match.optionality||p.match.optionality-n<1||!p.match.newBlockMarker)||l&&!i.greedy&&l.match.optionalQuantifier&&!p.match.optionalQuantifier)&&(s=d,l=p)}return l}function u(e,t){var i=this.maskset;return i.validPositions[e]?i.validPositions[e]:(t||p.call(this,e))[0]}function f(e,t,i){function a(e){for(var t,i=[],a=-1,n=0,r=e.length;nt.alternation)for(var n=t.alternation;ne+u._maxTestPos)throw"Inputmask: There is probably an error in your mask definition or in the code. Create an issue on github with an example of the mask you are using. "+l.mask;if(h===e&&void 0===r.matches){if(v.push({match:r,locator:s.reverse(),cd:k,mloc:{}}),!r.optionality||void 0!==d||!(u.definitions&&u.definitions[r.nativeDef]&&u.definitions[r.nativeDef].optional||n.default.prototype.definitions[r.nativeDef]&&n.default.prototype.definitions[r.nativeDef].optional))return!0;g=!0,h=e}else if(void 0!==r.matches){if(r.isGroup&&d!==r)return function(){if(r=c(t.matches[t.matches.indexOf(r)+1],s,d))return!0}();if(r.isOptional)return function(){var t=r,n=v.length;if(r=y(r,i,s,d),v.length>0){if(v.forEach((function(e,t){t>=n&&(e.match.optionality=e.match.optionality?e.match.optionality+1:1)})),a=v[v.length-1].match,void 0!==d||!m(a,t))return r;g=!0,h=e}}();if(r.isAlternator)return function(){o.hasAlternator=!0;var a,n,m,k=r,y=[],b=v.slice(),S=s.length,M=!1,_=i.length>0?i.shift():-1;if(-1===_||"string"==typeof _){var O,T=h,E=i.slice(),j=[];if("string"==typeof _)j=_.split(",");else for(O=0;O=u.keepStatic)&&(j=j.slice(0,1));for(var R=0;Rk.matches[0].matches.length)break;a=v.slice(),h=T,v=[];for(var L=0;L0,r=y.length>0,i=E.slice()}else r=c(k.matches[_]||t.matches[_],[_].concat(s),d);if(r)return!0}();if(r.isQuantifier&&d!==t.matches[t.matches.indexOf(r)-1])return function(){for(var n=r,o=!1,f=i.length>0?i.shift():0;f<(isNaN(n.quantifier.max)?f+1:n.quantifier.max)&&h<=e;f++){var p=t.matches[t.matches.indexOf(n)-1];if(r=c(p,[f].concat(s),p)){if(v.forEach((function(t,i){(a=b(p,t.match)?t.match:v[v.length-1].match).optionalQuantifier=f>=n.quantifier.min,a.jit=(f+1)*(p.matches.indexOf(a)+1)>n.quantifier.jit,a.optionalQuantifier&&m(a,p)&&(g=!0,h=e,u.greedy&&null==l.validPositions[e-1]&&f>n.quantifier.min&&-1!=["*","+"].indexOf(n.quantifier.max)&&(v.pop(),k=void 0),o=!0,r=!1),!o&&a.jit&&(l.jitOffset[e]=p.matches.length-p.matches.indexOf(a))})),o)break;return!0}}}();if(r=y(r,i,s,d))return!0}else h++}for(var d=i.length>0?i.shift():0;de)break}}function b(e,t){var i=-1!=e.matches.indexOf(t);return i||e.matches.forEach((function(e,a){void 0===e.matches||i||(i=b(e,t))})),i}if(e>-1){if(void 0===t){for(var x,P=e-1;void 0===(x=l.validPositions[P]||l.tests[P])&&P>-1;)P--;void 0!==x&&P>-1&&(m=function(e,t){var i,a=[];return Array.isArray(t)||(t=[t]),t.length>0&&(void 0===t[0].alternation||!0===u.keepStatic?0===(a=c.call(o,e,t.slice()).locator.slice()).length&&(a=t[0].locator.slice()):t.forEach((function(e){""!==e.def&&(0===a.length?(i=e.alternation,a=e.locator.slice()):e.locator[i]&&-1===a[i].toString().indexOf(e.locator[i])&&(a[i]+=","+e.locator[i]))}))),a}(P,x),k=m.join(""),h=P)}if(l.tests[e]&&l.tests[e][0].cd===k)return l.tests[e];for(var w=m.shift();we)break}}return(0===v.length||g)&&v.push({match:{fn:null,static:!0,optionality:!1,casing:null,def:"",placeholder:""},locator:[],mloc:{},cd:k}),void 0!==t&&l.tests[e]?r=s.extend(!0,[],v):(l.tests[e]=s.extend(!0,[],v),r=l.tests[e]),v.forEach((function(e){e.match.optionality=e.match.defOptionality||!1})),r}},7215:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.alternate=s,t.checkAlternationMatch=function(e,t,i){for(var a,n=this.opts.greedy?t:t.slice(0,1),r=!1,o=void 0!==i?i.split(","):[],s=0;s=r.getBuffer.call(c).length&&h>=i.end&&(i.end=h+1);t===n.keys.Backspace?i.end-i.begin<1&&(i.begin=r.seekPrevious.call(c,i.begin)):t===n.keys.Delete&&i.begin===i.end&&(i.end=r.isMask.call(c,i.end,!0,!0)?i.end+1:r.seekNext.call(c,i.end)+1);if(!1!==(d=m.call(c,i))){if(!0!==o&&!1!==f.keepStatic||null!==f.regex&&-1!==a.getTest.call(c,i.begin).match.def.indexOf("|")){var v=s.call(c,!0);if(v){var g=void 0!==v.caret?v.caret:v.pos?r.seekNext.call(c,v.pos.begin?v.pos.begin:v.pos):r.getLastValidPosition.call(c,-1,!0);(t!==n.keys.Delete||i.begin>g)&&i.begin}}!0!==o&&(u.p=t===n.keys.Delete?i.begin+d:i.begin,u.p=r.determineNewCaretPosition.call(c,{begin:u.p,end:u.p},!1,!1===f.insertMode&&t===n.keys.Backspace?"none":void 0).begin)}},t.isComplete=c,t.isSelection=u,t.isValid=f,t.refreshFromBuffer=d,t.revalidateMask=m;var a=i(4713),n=i(2839),r=i(8711),o=i(6030);function s(e,t,i,n,o,l){var c,u,p,d,h,m,v,g,k,y,b,x=this,P=this.dependencyLib,w=this.opts,S=x.maskset,M=P.extend(!0,[],S.validPositions),_=P.extend(!0,{},S.tests),O=!1,T=!1,E=void 0!==o?o:r.getLastValidPosition.call(x);if(l&&(y=l.begin,b=l.end,l.begin>l.end&&(y=l.end,b=l.begin)),-1===E&&void 0===o)c=0,u=(d=a.getTest.call(x,c)).alternation;else for(;E>=0;E--)if((p=S.validPositions[E])&&void 0!==p.alternation){if(E<=(e||0)&&d&&d.locator[p.alternation]!==p.locator[p.alternation])break;c=E,u=S.validPositions[c].alternation,d=p}if(void 0!==u){v=parseInt(c),S.excludes[v]=S.excludes[v]||[],!0!==e&&S.excludes[v].push((0,a.getDecisionTaker)(d)+":"+d.alternation);var j=[],A=-1;for(h=v;h=b)&&j.push(m.input),delete S.validPositions[h];for(-1===A&&void 0!==t&&(j.push(t),A=j.length-1);void 0!==S.excludes[v]&&S.excludes[v].length<10;){for(S.tests={},r.resetMaskSet.call(x,!0),O=!0,h=0;ht:e.end-e.begin>t}function f(e,t,i,n,o,p,v){var g=this,k=this.dependencyLib,y=this.opts,b=g.maskset;i=!0===i;var x=e;function P(e){if(void 0!==e){if(void 0!==e.remove&&(Array.isArray(e.remove)||(e.remove=[e.remove]),e.remove.sort((function(e,t){return g.isRTL?e.pos-t.pos:t.pos-e.pos})).forEach((function(e){m.call(g,{begin:e,end:e+1})})),e.remove=void 0),void 0!==e.insert&&(Array.isArray(e.insert)||(e.insert=[e.insert]),e.insert.sort((function(e,t){return g.isRTL?t.pos-e.pos:e.pos-t.pos})).forEach((function(e){""!==e.c&&f.call(g,e.pos,e.c,void 0===e.strict||e.strict,void 0!==e.fromIsValid?e.fromIsValid:n)})),e.insert=void 0),e.refreshFromBuffer&&e.buffer){var t=e.refreshFromBuffer;d.call(g,!0===t?t:t.start,t.end,e.buffer),e.refreshFromBuffer=void 0}void 0!==e.rewritePosition&&(x=e.rewritePosition,e=!0)}return e}function w(t,i,o){var s=!1;return a.getTests.call(g,t).every((function(c,f){var p=c.match;if(r.getBuffer.call(g,!0),!1!==(s=(!p.jit||void 0!==b.validPositions[r.seekPrevious.call(g,t)])&&(null!=p.fn?p.fn.test(i,b,t,o,y,u.call(g,e)):(i===p.def||i===y.skipOptionalPartCharacter)&&""!==p.def&&{c:a.getPlaceholder.call(g,t,p,!0)||p.def,pos:t}))){var d=void 0!==s.c?s.c:i,h=t;return d=d===y.skipOptionalPartCharacter&&!0===p.static?a.getPlaceholder.call(g,t,p,!0)||p.def:d,!0!==(s=P(s))&&void 0!==s.pos&&s.pos!==t&&(h=s.pos),!0!==s&&void 0===s.pos&&void 0===s.c?!1:(!1===m.call(g,e,k.extend({},c,{input:l.call(g,d,p,h)}),n,h)&&(s=!1),!1)}return!0})),s}void 0!==e.begin&&(x=g.isRTL?e.end:e.begin);var S=!0,M=k.extend(!0,{},b.validPositions);if(!1===y.keepStatic&&void 0!==b.excludes[x]&&!0!==o&&!0!==n)for(var _=x;_<(g.isRTL?e.begin:e.end);_++)void 0!==b.excludes[_]&&(b.excludes[_]=void 0,delete b.tests[_]);if("function"==typeof y.preValidation&&!0!==n&&!0!==p&&(S=P(S=y.preValidation.call(g,r.getBuffer.call(g),x,t,u.call(g,e),y,b,e,i||o))),!0===S){if(S=w(x,t,i),(!i||!0===n)&&!1===S&&!0!==p){var O=b.validPositions[x];if(!O||!0!==O.match.static||O.match.def!==t&&t!==y.skipOptionalPartCharacter){if(y.insertMode||void 0===b.validPositions[r.seekNext.call(g,x)]||e.end>x){var T=!1;if(b.jitOffset[x]&&void 0===b.validPositions[r.seekNext.call(g,x)]&&!1!==(S=f.call(g,x+b.jitOffset[x],t,!0,!0))&&(!0!==o&&(S.caret=x),T=!0),e.end>x&&(b.validPositions[x]=void 0),!T&&!r.isMask.call(g,x,y.keepStatic&&0===x))for(var E=x+1,j=r.seekNext.call(g,x,!1,0!==x);E<=j;E++)if(!1!==(S=w(E,t,i))){S=h.call(g,x,void 0!==S.pos?S.pos:E)||S,x=E;break}}}else S={caret:r.seekNext.call(g,x)}}g.hasAlternator&&!0!==o&&!i&&(!1===S&&y.keepStatic&&(c.call(g,r.getBuffer.call(g))||0===x)?S=s.call(g,x,t,i,n,void 0,e):(u.call(g,e)&&b.tests[x]&&b.tests[x].length>1&&y.keepStatic||1==S&&!0!==y.numericInput&&b.tests[x]&&b.tests[x].length>1&&r.getLastValidPosition.call(g,void 0,!0)>x)&&(S=s.call(g,!0))),!0===S&&(S={pos:x})}if("function"==typeof y.postValidation&&!0!==n&&!0!==p){var A=y.postValidation.call(g,r.getBuffer.call(g,!0),void 0!==e.begin?g.isRTL?e.end:e.begin:e,t,S,y,b,i,v);void 0!==A&&(S=!0===A?S:A)}S&&void 0===S.pos&&(S.pos=x),!1===S||!0===p?(r.resetMaskSet.call(g,!0),b.validPositions=k.extend(!0,[],M)):h.call(g,void 0,x,!0);var D=P(S);void 0!==g.maxLength&&(r.getBuffer.call(g).length>g.maxLength&&!n&&(r.resetMaskSet.call(g,!0),b.validPositions=k.extend(!0,[],M),D=!1));return D}function p(e,t,i){for(var n=this.maskset,r=!1,o=a.getTests.call(this,e),s=0;s0&&!o.validPositions[e];e--);for(var l=e;le+1?t[e+1]&&!0===t[e+1].match.static&&t[e+1]:t[e+1];return n&&r}return!1}var d=0,h=void 0!==e.begin?e.begin:e,m=void 0!==e.end?e.end:e,v=!0;if(e.begin>e.end&&(h=e.end,m=e.begin),n=void 0!==n?n:h,void 0===i&&(h!==m||l.insertMode&&void 0!==s.validPositions[n]||void 0===t||t.match.optionalQuantifier||t.match.optionality)){var g,k=c.extend(!0,{},s.validPositions),y=r.getLastValidPosition.call(o,void 0,!0);for(s.p=h,g=y;g>=h;g--)delete s.validPositions[g],void 0===t&&delete s.tests[g+1];var b,x,P=n,w=P;for(t&&(s.validPositions[n]=c.extend(!0,{},t),w++,P++),g=t?m:m-1;g<=y;g++){if(void 0!==(b=k[g])&&!0!==b.generatedInput&&(g>=m||g>=h&&u(g,k,{begin:h,end:m}))){for(;""!==a.getTest.call(o,w).match.def;){if(!1!==(x=p.call(o,w,b,l))||"+"===b.match.def){"+"===b.match.def&&r.getBuffer.call(o,!0);var S=f.call(o,w,b.input,"+"!==b.match.def,!0);if(v=!1!==S,P=(S.pos||w)+1,!v&&x)break}else v=!1;if(v){void 0===t&&b.match.static&&g===e.begin&&d++;break}if(!v&&r.getBuffer.call(o),w>s.maskLength)break;w++}""==a.getTest.call(o,w).match.def&&(v=!1),w=P}if(!v)break}if(!v)return s.validPositions=c.extend(!0,[],k),r.resetMaskSet.call(o,!0),!1}else t&&a.getTest.call(o,n).match.cd===t.match.cd&&(s.validPositions[n]=c.extend(!0,{},t));return r.resetMaskSet.call(o,!0),d}},7957:function(t){t.exports=e}},i={};function a(e){var n=i[e];if(void 0!==n)return n.exports;var r=i[e]={exports:{}};return t[e](r,r.exports,a),r.exports}var n={};return function(){var e=n;Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var t,i=(t=a(3046))&&t.__esModule?t:{default:t};a(443);var r=i.default;e.default=r}(),n}()})); \ No newline at end of file diff --git a/assets/js/punycode.js b/assets/js/punycode.js new file mode 100755 index 0000000..b96b32e --- /dev/null +++ b/assets/js/punycode.js @@ -0,0 +1,320 @@ +var punycode = new function Punycode() { + // This object converts to and from puny-code used in IDN + // + // punycode.ToASCII ( domain ) + // + // Returns a puny coded representation of "domain". + // It only converts the part of the domain name that + // has non ASCII characters. I.e. it dosent matter if + // you call it with a domain that already is in ASCII. + // + // punycode.ToUnicode (domain) + // + // Converts a puny-coded domain name to unicode. + // It only converts the puny-coded parts of the domain name. + // I.e. it dosent matter if you call it on a string + // that already has been converted to unicode. + // + // + this.utf16 = { + // The utf16-class is necessary to convert from javascripts internal character representation to unicode and back. + decode:function(input){ + var output = [], i=0, len=input.length,value,extra; + while (i < len) { + value = input.charCodeAt(i++); + if ((value & 0xF800) === 0xD800) { + extra = input.charCodeAt(i++); + if ( ((value & 0xFC00) !== 0xD800) || ((extra & 0xFC00) !== 0xDC00) ) { + throw new RangeError("UTF-16(decode): Illegal UTF-16 sequence"); + } + value = ((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000; + } + output.push(value); + } + return output; + }, + encode:function(input){ + var output = [], i=0, len=input.length,value; + while (i < len) { + value = input[i++]; + if ( (value & 0xF800) === 0xD800 ) { + throw new RangeError("UTF-16(encode): Illegal UTF-16 value"); + } + if (value > 0xFFFF) { + value -= 0x10000; + output.push(String.fromCharCode(((value >>>10) & 0x3FF) | 0xD800)); + value = 0xDC00 | (value & 0x3FF); + } + output.push(String.fromCharCode(value)); + } + return output.join(""); + } + } + + //Default parameters + var initial_n = 0x80; + var initial_bias = 72; + var delimiter = "\x2D"; + var base = 36; + var damp = 700; + var tmin=1; + var tmax=26; + var skew=38; + var maxint = 0x7FFFFFFF; + + // decode_digit(cp) returns the numeric value of a basic code + // point (for use in representing integers) in the range 0 to + // base-1, or base if cp is does not represent a value. + + function decode_digit(cp) { + return cp - 48 < 10 ? cp - 22 : cp - 65 < 26 ? cp - 65 : cp - 97 < 26 ? cp - 97 : base; + } + + // encode_digit(d,flag) returns the basic code point whose value + // (when used for representing integers) is d, which needs to be in + // the range 0 to base-1. The lowercase form is used unless flag is + // nonzero, in which case the uppercase form is used. The behavior + // is undefined if flag is nonzero and digit d has no uppercase form. + + function encode_digit(d, flag) { + return d + 22 + 75 * (d < 26) - ((flag != 0) << 5); + // 0..25 map to ASCII a..z or A..Z + // 26..35 map to ASCII 0..9 + } + //** Bias adaptation function ** + function adapt(delta, numpoints, firsttime ) { + var k; + delta = firsttime ? Math.floor(delta / damp) : (delta >> 1); + delta += Math.floor(delta / numpoints); + + for (k = 0; delta > (((base - tmin) * tmax) >> 1); k += base) { + delta = Math.floor(delta / ( base - tmin )); + } + return Math.floor(k + (base - tmin + 1) * delta / (delta + skew)); + } + + // encode_basic(bcp,flag) forces a basic code point to lowercase if flag is zero, + // uppercase if flag is nonzero, and returns the resulting code point. + // The code point is unchanged if it is caseless. + // The behavior is undefined if bcp is not a basic code point. + + function encode_basic(bcp, flag) { + bcp -= (bcp - 97 < 26) << 5; + return bcp + ((!flag && (bcp - 65 < 26)) << 5); + } + + // Main decode + this.decode=function(input,preserveCase) { + // Dont use utf16 + var output=[]; + var case_flags=[]; + var input_length = input.length; + + var n, out, i, bias, basic, j, ic, oldi, w, k, digit, t, len; + + // Initialize the state: + + n = initial_n; + i = 0; + bias = initial_bias; + + // Handle the basic code points: Let basic be the number of input code + // points before the last delimiter, or 0 if there is none, then + // copy the first basic code points to the output. + + basic = input.lastIndexOf(delimiter); + if (basic < 0) basic = 0; + + for (j = 0; j < basic; ++j) { + if(preserveCase) case_flags[output.length] = ( input.charCodeAt(j) -65 < 26); + if ( input.charCodeAt(j) >= 0x80) { + throw new RangeError("Illegal input >= 0x80"); + } + output.push( input.charCodeAt(j) ); + } + + // Main decoding loop: Start just after the last delimiter if any + // basic code points were copied; start at the beginning otherwise. + + for (ic = basic > 0 ? basic + 1 : 0; ic < input_length; ) { + + // ic is the index of the next character to be consumed, + + // Decode a generalized variable-length integer into delta, + // which gets added to i. The overflow checking is easier + // if we increase i as we go, then subtract off its starting + // value at the end to obtain delta. + for (oldi = i, w = 1, k = base; ; k += base) { + if (ic >= input_length) { + throw RangeError ("punycode_bad_input(1)"); + } + digit = decode_digit(input.charCodeAt(ic++)); + + if (digit >= base) { + throw RangeError("punycode_bad_input(2)"); + } + if (digit > Math.floor((maxint - i) / w)) { + throw RangeError ("punycode_overflow(1)"); + } + i += digit * w; + t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias; + if (digit < t) { break; } + if (w > Math.floor(maxint / (base - t))) { + throw RangeError("punycode_overflow(2)"); + } + w *= (base - t); + } + + out = output.length + 1; + bias = adapt(i - oldi, out, oldi === 0); + + // i was supposed to wrap around from out to 0, + // incrementing n each time, so we'll fix that now: + if ( Math.floor(i / out) > maxint - n) { + throw RangeError("punycode_overflow(3)"); + } + n += Math.floor( i / out ) ; + i %= out; + + // Insert n at position i of the output: + // Case of last character determines uppercase flag: + if (preserveCase) { case_flags.splice(i, 0, input.charCodeAt(ic -1) -65 < 26);} + + output.splice(i, 0, n); + i++; + } + if (preserveCase) { + for (i = 0, len = output.length; i < len; i++) { + if (case_flags[i]) { + output[i] = (String.fromCharCode(output[i]).toUpperCase()).charCodeAt(0); + } + } + } + return this.utf16.encode(output); + }; + + //** Main encode function ** + + this.encode = function (input,preserveCase) { + //** Bias adaptation function ** + + var n, delta, h, b, bias, j, m, q, k, t, ijv, case_flags; + + if (preserveCase) { + // Preserve case, step1 of 2: Get a list of the unaltered string + case_flags = this.utf16.decode(input); + } + // Converts the input in UTF-16 to Unicode + input = this.utf16.decode(input.toLowerCase()); + + var input_length = input.length; // Cache the length + + if (preserveCase) { + // Preserve case, step2 of 2: Modify the list to true/false + for (j=0; j < input_length; j++) { + case_flags[j] = input[j] != case_flags[j]; + } + } + + var output=[]; + + + // Initialize the state: + n = initial_n; + delta = 0; + bias = initial_bias; + + // Handle the basic code points: + for (j = 0; j < input_length; ++j) { + if ( input[j] < 0x80) { + output.push( + String.fromCharCode( + case_flags ? encode_basic(input[j], case_flags[j]) : input[j] + ) + ); + } + } + + h = b = output.length; + + // h is the number of code points that have been handled, b is the + // number of basic code points + + if (b > 0) output.push(delimiter); + + // Main encoding loop: + // + while (h < input_length) { + // All non-basic code points < n have been + // handled already. Find the next larger one: + + for (m = maxint, j = 0; j < input_length; ++j) { + ijv = input[j]; + if (ijv >= n && ijv < m) m = ijv; + } + + // Increase delta enough to advance the decoder's + // state to , but guard against overflow: + + if (m - n > Math.floor((maxint - delta) / (h + 1))) { + throw RangeError("punycode_overflow (1)"); + } + delta += (m - n) * (h + 1); + n = m; + + for (j = 0; j < input_length; ++j) { + ijv = input[j]; + + if (ijv < n ) { + if (++delta > maxint) return Error("punycode_overflow(2)"); + } + + if (ijv == n) { + // Represent delta as a generalized variable-length integer: + for (q = delta, k = base; ; k += base) { + t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias; + if (q < t) break; + output.push( String.fromCharCode(encode_digit(t + (q - t) % (base - t), 0)) ); + q = Math.floor( (q - t) / (base - t) ); + } + output.push( String.fromCharCode(encode_digit(q, preserveCase && case_flags[j] ? 1:0 ))); + bias = adapt(delta, h + 1, h == b); + delta = 0; + ++h; + } + } + + ++delta, ++n; + } + return output.join(""); + } + + this.ToASCII = function ( domain ) { + var domain_array = domain.split("."); + var out = []; + for (var i=0; i < domain_array.length; ++i) { + var s = domain_array[i]; + out.push( + s.match(/[^A-Za-z0-9-]/) ? + "xn--" + punycode.encode(s) : + s + ); + } + return out.join("."); + } + this.ToUnicode = function ( domain ) { + var domain_array = domain.split("."); + var out = []; + for (var i=0; i < domain_array.length; ++i) { + var s = domain_array[i]; + out.push( + s.match(/^xn--/) ? + punycode.decode(s.slice(4)) : + s + ); + } + return out.join("."); + } +}(); + +export { punycode }; \ No newline at end of file diff --git a/assets/js/qr.js b/assets/js/qr.js new file mode 100755 index 0000000..993e88f --- /dev/null +++ b/assets/js/qr.js @@ -0,0 +1 @@ +var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this.parsedData=[];for(var b=[],d=0,e=this.data.length;e>d;d++){var f=this.data.charCodeAt(d);f>65536?(b[0]=240|(1835008&f)>>>18,b[1]=128|(258048&f)>>>12,b[2]=128|(4032&f)>>>6,b[3]=128|63&f):f>2048?(b[0]=224|(61440&f)>>>12,b[1]=128|(4032&f)>>>6,b[2]=128|63&f):f>128?(b[0]=192|(1984&f)>>>6,b[1]=128|63&f):b[0]=f,this.parsedData=this.parsedData.concat(b)}this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function b(a,b){this.typeNumber=a,this.errorCorrectLevel=b,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}function i(a,b){if(void 0==a.length)throw new Error(a.length+"/"+b);for(var c=0;c=f;f++){var h=0;switch(b){case d.L:h=l[f][0];break;case d.M:h=l[f][1];break;case d.Q:h=l[f][2];break;case d.H:h=l[f][3]}if(h>=e)break;c++}if(c>l.length)throw new Error("Too long data");return c}function s(a){var b=encodeURI(a).toString().replace(/\%[0-9a-fA-F]{2}/g,"a");return b.length+(b.length!=a?3:0)}a.prototype={getLength:function(){return this.parsedData.length},write:function(a){for(var b=0,c=this.parsedData.length;c>b;b++)a.put(this.parsedData[b],8)}},b.prototype={addData:function(b){var c=new a(b);this.dataList.push(c),this.dataCache=null},isDark:function(a,b){if(0>a||this.moduleCount<=a||0>b||this.moduleCount<=b)throw new Error(a+","+b);return this.modules[a][b]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var d=0;d=7&&this.setupTypeNumber(a),null==this.dataCache&&(this.dataCache=b.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,b){for(var c=-1;7>=c;c++)if(!(-1>=a+c||this.moduleCount<=a+c))for(var d=-1;7>=d;d++)-1>=b+d||this.moduleCount<=b+d||(this.modules[a+c][b+d]=c>=0&&6>=c&&(0==d||6==d)||d>=0&&6>=d&&(0==c||6==c)||c>=2&&4>=c&&d>=2&&4>=d?!0:!1)},getBestMaskPattern:function(){for(var a=0,b=0,c=0;8>c;c++){this.makeImpl(!0,c);var d=f.getLostPoint(this);(0==c||a>d)&&(a=d,b=c)}return b},createMovieClip:function(a,b,c){var d=a.createEmptyMovieClip(b,c),e=1;this.make();for(var f=0;f=g;g++)for(var h=-2;2>=h;h++)this.modules[d+g][e+h]=-2==g||2==g||-2==h||2==h||0==g&&0==h?!0:!1}},setupTypeNumber:function(a){for(var b=f.getBCHTypeNumber(this.typeNumber),c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[Math.floor(c/3)][c%3+this.moduleCount-8-3]=d}for(var c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[c%3+this.moduleCount-8-3][Math.floor(c/3)]=d}},setupTypeInfo:function(a,b){for(var c=this.errorCorrectLevel<<3|b,d=f.getBCHTypeInfo(c),e=0;15>e;e++){var g=!a&&1==(1&d>>e);6>e?this.modules[e][8]=g:8>e?this.modules[e+1][8]=g:this.modules[this.moduleCount-15+e][8]=g}for(var e=0;15>e;e++){var g=!a&&1==(1&d>>e);8>e?this.modules[8][this.moduleCount-e-1]=g:9>e?this.modules[8][15-e-1+1]=g:this.modules[8][15-e-1]=g}this.modules[this.moduleCount-8][8]=!a},mapData:function(a,b){for(var c=-1,d=this.moduleCount-1,e=7,g=0,h=this.moduleCount-1;h>0;h-=2)for(6==h&&h--;;){for(var i=0;2>i;i++)if(null==this.modules[d][h-i]){var j=!1;g>>e));var k=f.getMask(b,d,h-i);k&&(j=!j),this.modules[d][h-i]=j,e--,-1==e&&(g++,e=7)}if(d+=c,0>d||this.moduleCount<=d){d-=c,c=-c;break}}}},b.PAD0=236,b.PAD1=17,b.createData=function(a,c,d){for(var e=j.getRSBlocks(a,c),g=new k,h=0;h8*l)throw new Error("code length overflow. ("+g.getLengthInBits()+">"+8*l+")");for(g.getLengthInBits()+4<=8*l&&g.put(0,4);0!=g.getLengthInBits()%8;)g.putBit(!1);for(;;){if(g.getLengthInBits()>=8*l)break;if(g.put(b.PAD0,8),g.getLengthInBits()>=8*l)break;g.put(b.PAD1,8)}return b.createBytes(g,e)},b.createBytes=function(a,b){for(var c=0,d=0,e=0,g=new Array(b.length),h=new Array(b.length),j=0;j=0?p.get(q):0}}for(var r=0,m=0;mm;m++)for(var j=0;jm;m++)for(var j=0;j=0;)b^=f.G15<=0;)b^=f.G18<>>=1;return b},getPatternPosition:function(a){return f.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,b,c){switch(a){case e.PATTERN000:return 0==(b+c)%2;case e.PATTERN001:return 0==b%2;case e.PATTERN010:return 0==c%3;case e.PATTERN011:return 0==(b+c)%3;case e.PATTERN100:return 0==(Math.floor(b/2)+Math.floor(c/3))%2;case e.PATTERN101:return 0==b*c%2+b*c%3;case e.PATTERN110:return 0==(b*c%2+b*c%3)%2;case e.PATTERN111:return 0==(b*c%3+(b+c)%2)%2;default:throw new Error("bad maskPattern:"+a)}},getErrorCorrectPolynomial:function(a){for(var b=new i([1],0),c=0;a>c;c++)b=b.multiply(new i([1,g.gexp(c)],0));return b},getLengthInBits:function(a,b){if(b>=1&&10>b)switch(a){case c.MODE_NUMBER:return 10;case c.MODE_ALPHA_NUM:return 9;case c.MODE_8BIT_BYTE:return 8;case c.MODE_KANJI:return 8;default:throw new Error("mode:"+a)}else if(27>b)switch(a){case c.MODE_NUMBER:return 12;case c.MODE_ALPHA_NUM:return 11;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 10;default:throw new Error("mode:"+a)}else{if(!(41>b))throw new Error("type:"+b);switch(a){case c.MODE_NUMBER:return 14;case c.MODE_ALPHA_NUM:return 13;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 12;default:throw new Error("mode:"+a)}}},getLostPoint:function(a){for(var b=a.getModuleCount(),c=0,d=0;b>d;d++)for(var e=0;b>e;e++){for(var f=0,g=a.isDark(d,e),h=-1;1>=h;h++)if(!(0>d+h||d+h>=b))for(var i=-1;1>=i;i++)0>e+i||e+i>=b||(0!=h||0!=i)&&g==a.isDark(d+h,e+i)&&f++;f>5&&(c+=3+f-5)}for(var d=0;b-1>d;d++)for(var e=0;b-1>e;e++){var j=0;a.isDark(d,e)&&j++,a.isDark(d+1,e)&&j++,a.isDark(d,e+1)&&j++,a.isDark(d+1,e+1)&&j++,(0==j||4==j)&&(c+=3)}for(var d=0;b>d;d++)for(var e=0;b-6>e;e++)a.isDark(d,e)&&!a.isDark(d,e+1)&&a.isDark(d,e+2)&&a.isDark(d,e+3)&&a.isDark(d,e+4)&&!a.isDark(d,e+5)&&a.isDark(d,e+6)&&(c+=40);for(var e=0;b>e;e++)for(var d=0;b-6>d;d++)a.isDark(d,e)&&!a.isDark(d+1,e)&&a.isDark(d+2,e)&&a.isDark(d+3,e)&&a.isDark(d+4,e)&&!a.isDark(d+5,e)&&a.isDark(d+6,e)&&(c+=40);for(var k=0,e=0;b>e;e++)for(var d=0;b>d;d++)a.isDark(d,e)&&k++;var l=Math.abs(100*k/b/b-50)/5;return c+=10*l}},g={glog:function(a){if(1>a)throw new Error("glog("+a+")");return g.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;a>=256;)a-=255;return g.EXP_TABLE[a]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},h=0;8>h;h++)g.EXP_TABLE[h]=1<h;h++)g.EXP_TABLE[h]=g.EXP_TABLE[h-4]^g.EXP_TABLE[h-5]^g.EXP_TABLE[h-6]^g.EXP_TABLE[h-8];for(var h=0;255>h;h++)g.LOG_TABLE[g.EXP_TABLE[h]]=h;i.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var b=new Array(this.getLength()+a.getLength()-1),c=0;cf;f++)for(var g=c[3*f+0],h=c[3*f+1],i=c[3*f+2],k=0;g>k;k++)e.push(new j(h,i));return e},j.getRsBlockTable=function(a,b){switch(b){case d.L:return j.RS_BLOCK_TABLE[4*(a-1)+0];case d.M:return j.RS_BLOCK_TABLE[4*(a-1)+1];case d.Q:return j.RS_BLOCK_TABLE[4*(a-1)+2];case d.H:return j.RS_BLOCK_TABLE[4*(a-1)+3];default:return void 0}},k.prototype={get:function(a){var b=Math.floor(a/8);return 1==(1&this.buffer[b]>>>7-a%8)},put:function(a,b){for(var c=0;b>c;c++)this.putBit(1==(1&a>>>b-c-1))},getLengthInBits:function(){return this.length},putBit:function(a){var b=Math.floor(this.length/8);this.buffer.length<=b&&this.buffer.push(0),a&&(this.buffer[b]|=128>>>this.length%8),this.length++}};var l=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],o=function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){function g(a,b){var c=document.createElementNS("http://www.w3.org/2000/svg",a);for(var d in b)b.hasOwnProperty(d)&&c.setAttribute(d,b[d]);return c}var b=this._htOption,c=this._el,d=a.getModuleCount();Math.floor(b.width/d),Math.floor(b.height/d),this.clear();var h=g("svg",{viewBox:"0 0 "+String(d)+" "+String(d),width:"100%",height:"100%",fill:b.colorLight});h.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),c.appendChild(h),h.appendChild(g("rect",{fill:b.colorDark,width:"1",height:"1",id:"template"}));for(var i=0;d>i;i++)for(var j=0;d>j;j++)if(a.isDark(i,j)){var k=g("use",{x:String(i),y:String(j)});k.setAttributeNS("http://www.w3.org/1999/xlink","href","#template"),h.appendChild(k)}},a.prototype.clear=function(){for(;this._el.hasChildNodes();)this._el.removeChild(this._el.lastChild)},a}(),p="svg"===document.documentElement.tagName.toLowerCase(),q=p?o:m()?function(){function a(){this._elImage.src=this._elCanvas.toDataURL("image/png"),this._elImage.style.display="block",this._elCanvas.style.display="none"}function d(a,b){var c=this;if(c._fFail=b,c._fSuccess=a,null===c._bSupportDataURI){var d=document.createElement("img"),e=function(){c._bSupportDataURI=!1,c._fFail&&_fFail.call(c)},f=function(){c._bSupportDataURI=!0,c._fSuccess&&c._fSuccess.call(c)};return d.onabort=e,d.onerror=e,d.onload=f,d.src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",void 0}c._bSupportDataURI===!0&&c._fSuccess?c._fSuccess.call(c):c._bSupportDataURI===!1&&c._fFail&&c._fFail.call(c)}if(this._android&&this._android<=2.1){var b=1/window.devicePixelRatio,c=CanvasRenderingContext2D.prototype.drawImage;CanvasRenderingContext2D.prototype.drawImage=function(a,d,e,f,g,h,i,j){if("nodeName"in a&&/img/i.test(a.nodeName))for(var l=arguments.length-1;l>=1;l--)arguments[l]=arguments[l]*b;else"undefined"==typeof j&&(arguments[1]*=b,arguments[2]*=b,arguments[3]*=b,arguments[4]*=b);c.apply(this,arguments)}}var e=function(a,b){this._bIsPainted=!1,this._android=n(),this._htOption=b,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=b.width,this._elCanvas.height=b.height,a.appendChild(this._elCanvas),this._el=a,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._elImage=document.createElement("img"),this._elImage.style.display="none",this._el.appendChild(this._elImage),this._bSupportDataURI=null};return e.prototype.draw=function(a){var b=this._elImage,c=this._oContext,d=this._htOption,e=a.getModuleCount(),f=d.width/e,g=d.height/e,h=Math.round(f),i=Math.round(g);b.style.display="none",this.clear();for(var j=0;e>j;j++)for(var k=0;e>k;k++){var l=a.isDark(j,k),m=k*f,n=j*g;c.strokeStyle=l?d.colorDark:d.colorLight,c.lineWidth=1,c.fillStyle=l?d.colorDark:d.colorLight,c.fillRect(m,n,f,g),c.strokeRect(Math.floor(m)+.5,Math.floor(n)+.5,h,i),c.strokeRect(Math.ceil(m)-.5,Math.ceil(n)-.5,h,i)}this._bIsPainted=!0},e.prototype.makeImage=function(){this._bIsPainted&&d.call(this,a)},e.prototype.isPainted=function(){return this._bIsPainted},e.prototype.clear=function(){this._oContext.clearRect(0,0,this._elCanvas.width,this._elCanvas.height),this._bIsPainted=!1},e.prototype.round=function(a){return a?Math.floor(1e3*a)/1e3:a},e}():function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){for(var b=this._htOption,c=this._el,d=a.getModuleCount(),e=Math.floor(b.width/d),f=Math.floor(b.height/d),g=[''],h=0;d>h;h++){g.push("");for(var i=0;d>i;i++)g.push('');g.push("")}g.push("
"),c.innerHTML=g.join("");var j=c.childNodes[0],k=(b.width-j.offsetWidth)/2,l=(b.height-j.offsetHeight)/2;k>0&&l>0&&(j.style.margin=l+"px "+k+"px")},a.prototype.clear=function(){this._el.innerHTML=""},a}();QRCode=function(a,b){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:d.H},"string"==typeof b&&(b={text:b}),b)for(var c in b)this._htOption[c]=b[c];"string"==typeof a&&(a=document.getElementById(a)),this._android=n(),this._el=a,this._oQRCode=null,this._oDrawing=new q(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)},QRCode.prototype.makeCode=function(a){this._oQRCode=new b(r(a,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(a),this._oQRCode.make(),this._el.title=a,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=d}(); \ No newline at end of file diff --git a/assets/js/qr2.js b/assets/js/qr2.js new file mode 100755 index 0000000..99ea9df --- /dev/null +++ b/assets/js/qr2.js @@ -0,0 +1,10100 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define([], factory); + else if(typeof exports === 'object') + exports["jsQR"] = factory(); + else + root["jsQR"] = factory(); +})(typeof self !== 'undefined' ? self : this, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 3); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +var BitMatrix = /** @class */ (function () { + function BitMatrix(data, width) { + this.width = width; + this.height = data.length / width; + this.data = data; + } + BitMatrix.createEmpty = function (width, height) { + return new BitMatrix(new Uint8ClampedArray(width * height), width); + }; + BitMatrix.prototype.get = function (x, y) { + if (x < 0 || x >= this.width || y < 0 || y >= this.height) { + return false; + } + return !!this.data[y * this.width + x]; + }; + BitMatrix.prototype.set = function (x, y, v) { + this.data[y * this.width + x] = v ? 1 : 0; + }; + BitMatrix.prototype.setRegion = function (left, top, width, height, v) { + for (var y = top; y < top + height; y++) { + for (var x = left; x < left + width; x++) { + this.set(x, y, !!v); + } + } + }; + return BitMatrix; +}()); +exports.BitMatrix = BitMatrix; + + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +var GenericGFPoly_1 = __webpack_require__(2); +function addOrSubtractGF(a, b) { + return a ^ b; // tslint:disable-line:no-bitwise +} +exports.addOrSubtractGF = addOrSubtractGF; +var GenericGF = /** @class */ (function () { + function GenericGF(primitive, size, genBase) { + this.primitive = primitive; + this.size = size; + this.generatorBase = genBase; + this.expTable = new Array(this.size); + this.logTable = new Array(this.size); + var x = 1; + for (var i = 0; i < this.size; i++) { + this.expTable[i] = x; + x = x * 2; + if (x >= this.size) { + x = (x ^ this.primitive) & (this.size - 1); // tslint:disable-line:no-bitwise + } + } + for (var i = 0; i < this.size - 1; i++) { + this.logTable[this.expTable[i]] = i; + } + this.zero = new GenericGFPoly_1.default(this, Uint8ClampedArray.from([0])); + this.one = new GenericGFPoly_1.default(this, Uint8ClampedArray.from([1])); + } + GenericGF.prototype.multiply = function (a, b) { + if (a === 0 || b === 0) { + return 0; + } + return this.expTable[(this.logTable[a] + this.logTable[b]) % (this.size - 1)]; + }; + GenericGF.prototype.inverse = function (a) { + if (a === 0) { + throw new Error("Can't invert 0"); + } + return this.expTable[this.size - this.logTable[a] - 1]; + }; + GenericGF.prototype.buildMonomial = function (degree, coefficient) { + if (degree < 0) { + throw new Error("Invalid monomial degree less than 0"); + } + if (coefficient === 0) { + return this.zero; + } + var coefficients = new Uint8ClampedArray(degree + 1); + coefficients[0] = coefficient; + return new GenericGFPoly_1.default(this, coefficients); + }; + GenericGF.prototype.log = function (a) { + if (a === 0) { + throw new Error("Can't take log(0)"); + } + return this.logTable[a]; + }; + GenericGF.prototype.exp = function (a) { + return this.expTable[a]; + }; + return GenericGF; +}()); +exports.default = GenericGF; + + +/***/ }), +/* 2 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +var GenericGF_1 = __webpack_require__(1); +var GenericGFPoly = /** @class */ (function () { + function GenericGFPoly(field, coefficients) { + if (coefficients.length === 0) { + throw new Error("No coefficients."); + } + this.field = field; + var coefficientsLength = coefficients.length; + if (coefficientsLength > 1 && coefficients[0] === 0) { + // Leading term must be non-zero for anything except the constant polynomial "0" + var firstNonZero = 1; + while (firstNonZero < coefficientsLength && coefficients[firstNonZero] === 0) { + firstNonZero++; + } + if (firstNonZero === coefficientsLength) { + this.coefficients = field.zero.coefficients; + } + else { + this.coefficients = new Uint8ClampedArray(coefficientsLength - firstNonZero); + for (var i = 0; i < this.coefficients.length; i++) { + this.coefficients[i] = coefficients[firstNonZero + i]; + } + } + } + else { + this.coefficients = coefficients; + } + } + GenericGFPoly.prototype.degree = function () { + return this.coefficients.length - 1; + }; + GenericGFPoly.prototype.isZero = function () { + return this.coefficients[0] === 0; + }; + GenericGFPoly.prototype.getCoefficient = function (degree) { + return this.coefficients[this.coefficients.length - 1 - degree]; + }; + GenericGFPoly.prototype.addOrSubtract = function (other) { + var _a; + if (this.isZero()) { + return other; + } + if (other.isZero()) { + return this; + } + var smallerCoefficients = this.coefficients; + var largerCoefficients = other.coefficients; + if (smallerCoefficients.length > largerCoefficients.length) { + _a = [largerCoefficients, smallerCoefficients], smallerCoefficients = _a[0], largerCoefficients = _a[1]; + } + var sumDiff = new Uint8ClampedArray(largerCoefficients.length); + var lengthDiff = largerCoefficients.length - smallerCoefficients.length; + for (var i = 0; i < lengthDiff; i++) { + sumDiff[i] = largerCoefficients[i]; + } + for (var i = lengthDiff; i < largerCoefficients.length; i++) { + sumDiff[i] = GenericGF_1.addOrSubtractGF(smallerCoefficients[i - lengthDiff], largerCoefficients[i]); + } + return new GenericGFPoly(this.field, sumDiff); + }; + GenericGFPoly.prototype.multiply = function (scalar) { + if (scalar === 0) { + return this.field.zero; + } + if (scalar === 1) { + return this; + } + var size = this.coefficients.length; + var product = new Uint8ClampedArray(size); + for (var i = 0; i < size; i++) { + product[i] = this.field.multiply(this.coefficients[i], scalar); + } + return new GenericGFPoly(this.field, product); + }; + GenericGFPoly.prototype.multiplyPoly = function (other) { + if (this.isZero() || other.isZero()) { + return this.field.zero; + } + var aCoefficients = this.coefficients; + var aLength = aCoefficients.length; + var bCoefficients = other.coefficients; + var bLength = bCoefficients.length; + var product = new Uint8ClampedArray(aLength + bLength - 1); + for (var i = 0; i < aLength; i++) { + var aCoeff = aCoefficients[i]; + for (var j = 0; j < bLength; j++) { + product[i + j] = GenericGF_1.addOrSubtractGF(product[i + j], this.field.multiply(aCoeff, bCoefficients[j])); + } + } + return new GenericGFPoly(this.field, product); + }; + GenericGFPoly.prototype.multiplyByMonomial = function (degree, coefficient) { + if (degree < 0) { + throw new Error("Invalid degree less than 0"); + } + if (coefficient === 0) { + return this.field.zero; + } + var size = this.coefficients.length; + var product = new Uint8ClampedArray(size + degree); + for (var i = 0; i < size; i++) { + product[i] = this.field.multiply(this.coefficients[i], coefficient); + } + return new GenericGFPoly(this.field, product); + }; + GenericGFPoly.prototype.evaluateAt = function (a) { + var result = 0; + if (a === 0) { + // Just return the x^0 coefficient + return this.getCoefficient(0); + } + var size = this.coefficients.length; + if (a === 1) { + // Just the sum of the coefficients + this.coefficients.forEach(function (coefficient) { + result = GenericGF_1.addOrSubtractGF(result, coefficient); + }); + return result; + } + result = this.coefficients[0]; + for (var i = 1; i < size; i++) { + result = GenericGF_1.addOrSubtractGF(this.field.multiply(a, result), this.coefficients[i]); + } + return result; + }; + return GenericGFPoly; +}()); +exports.default = GenericGFPoly; + + +/***/ }), +/* 3 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +var binarizer_1 = __webpack_require__(4); +var decoder_1 = __webpack_require__(5); +var extractor_1 = __webpack_require__(11); +var locator_1 = __webpack_require__(12); +function scan(matrix) { + var locations = locator_1.locate(matrix); + if (!locations) { + return null; + } + for (var _i = 0, locations_1 = locations; _i < locations_1.length; _i++) { + var location_1 = locations_1[_i]; + var extracted = extractor_1.extract(matrix, location_1); + var decoded = decoder_1.decode(extracted.matrix); + if (decoded) { + return { + binaryData: decoded.bytes, + data: decoded.text, + chunks: decoded.chunks, + version: decoded.version, + location: { + topRightCorner: extracted.mappingFunction(location_1.dimension, 0), + topLeftCorner: extracted.mappingFunction(0, 0), + bottomRightCorner: extracted.mappingFunction(location_1.dimension, location_1.dimension), + bottomLeftCorner: extracted.mappingFunction(0, location_1.dimension), + topRightFinderPattern: location_1.topRight, + topLeftFinderPattern: location_1.topLeft, + bottomLeftFinderPattern: location_1.bottomLeft, + bottomRightAlignmentPattern: location_1.alignmentPattern, + }, + }; + } + } + return null; +} +var defaultOptions = { + inversionAttempts: "attemptBoth", +}; +function jsQR(data, width, height, providedOptions) { + if (providedOptions === void 0) { providedOptions = {}; } + var options = defaultOptions; + Object.keys(options || {}).forEach(function (opt) { + options[opt] = providedOptions[opt] || options[opt]; + }); + var shouldInvert = options.inversionAttempts === "attemptBoth" || options.inversionAttempts === "invertFirst"; + var tryInvertedFirst = options.inversionAttempts === "onlyInvert" || options.inversionAttempts === "invertFirst"; + var _a = binarizer_1.binarize(data, width, height, shouldInvert), binarized = _a.binarized, inverted = _a.inverted; + var result = scan(tryInvertedFirst ? inverted : binarized); + if (!result && (options.inversionAttempts === "attemptBoth" || options.inversionAttempts === "invertFirst")) { + result = scan(tryInvertedFirst ? binarized : inverted); + } + return result; +} +jsQR.default = jsQR; +exports.default = jsQR; + + +/***/ }), +/* 4 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +var BitMatrix_1 = __webpack_require__(0); +var REGION_SIZE = 8; +var MIN_DYNAMIC_RANGE = 24; +function numBetween(value, min, max) { + return value < min ? min : value > max ? max : value; +} +// Like BitMatrix but accepts arbitry Uint8 values +var Matrix = /** @class */ (function () { + function Matrix(width, height) { + this.width = width; + this.data = new Uint8ClampedArray(width * height); + } + Matrix.prototype.get = function (x, y) { + return this.data[y * this.width + x]; + }; + Matrix.prototype.set = function (x, y, value) { + this.data[y * this.width + x] = value; + }; + return Matrix; +}()); +function binarize(data, width, height, returnInverted) { + if (data.length !== width * height * 4) { + throw new Error("Malformed data passed to binarizer."); + } + // Convert image to greyscale + var greyscalePixels = new Matrix(width, height); + for (var x = 0; x < width; x++) { + for (var y = 0; y < height; y++) { + var r = data[((y * width + x) * 4) + 0]; + var g = data[((y * width + x) * 4) + 1]; + var b = data[((y * width + x) * 4) + 2]; + greyscalePixels.set(x, y, 0.2126 * r + 0.7152 * g + 0.0722 * b); + } + } + var horizontalRegionCount = Math.ceil(width / REGION_SIZE); + var verticalRegionCount = Math.ceil(height / REGION_SIZE); + var blackPoints = new Matrix(horizontalRegionCount, verticalRegionCount); + for (var verticalRegion = 0; verticalRegion < verticalRegionCount; verticalRegion++) { + for (var hortizontalRegion = 0; hortizontalRegion < horizontalRegionCount; hortizontalRegion++) { + var sum = 0; + var min = Infinity; + var max = 0; + for (var y = 0; y < REGION_SIZE; y++) { + for (var x = 0; x < REGION_SIZE; x++) { + var pixelLumosity = greyscalePixels.get(hortizontalRegion * REGION_SIZE + x, verticalRegion * REGION_SIZE + y); + sum += pixelLumosity; + min = Math.min(min, pixelLumosity); + max = Math.max(max, pixelLumosity); + } + } + var average = sum / (Math.pow(REGION_SIZE, 2)); + if (max - min <= MIN_DYNAMIC_RANGE) { + // If variation within the block is low, assume this is a block with only light or only + // dark pixels. In that case we do not want to use the average, as it would divide this + // low contrast area into black and white pixels, essentially creating data out of noise. + // + // Default the blackpoint for these blocks to be half the min - effectively white them out + average = min / 2; + if (verticalRegion > 0 && hortizontalRegion > 0) { + // Correct the "white background" assumption for blocks that have neighbors by comparing + // the pixels in this block to the previously calculated black points. This is based on + // the fact that dark barcode symbology is always surrounded by some amount of light + // background for which reasonable black point estimates were made. The bp estimated at + // the boundaries is used for the interior. + // The (min < bp) is arbitrary but works better than other heuristics that were tried. + var averageNeighborBlackPoint = (blackPoints.get(hortizontalRegion, verticalRegion - 1) + + (2 * blackPoints.get(hortizontalRegion - 1, verticalRegion)) + + blackPoints.get(hortizontalRegion - 1, verticalRegion - 1)) / 4; + if (min < averageNeighborBlackPoint) { + average = averageNeighborBlackPoint; + } + } + } + blackPoints.set(hortizontalRegion, verticalRegion, average); + } + } + var binarized = BitMatrix_1.BitMatrix.createEmpty(width, height); + var inverted = null; + if (returnInverted) { + inverted = BitMatrix_1.BitMatrix.createEmpty(width, height); + } + for (var verticalRegion = 0; verticalRegion < verticalRegionCount; verticalRegion++) { + for (var hortizontalRegion = 0; hortizontalRegion < horizontalRegionCount; hortizontalRegion++) { + var left = numBetween(hortizontalRegion, 2, horizontalRegionCount - 3); + var top_1 = numBetween(verticalRegion, 2, verticalRegionCount - 3); + var sum = 0; + for (var xRegion = -2; xRegion <= 2; xRegion++) { + for (var yRegion = -2; yRegion <= 2; yRegion++) { + sum += blackPoints.get(left + xRegion, top_1 + yRegion); + } + } + var threshold = sum / 25; + for (var xRegion = 0; xRegion < REGION_SIZE; xRegion++) { + for (var yRegion = 0; yRegion < REGION_SIZE; yRegion++) { + var x = hortizontalRegion * REGION_SIZE + xRegion; + var y = verticalRegion * REGION_SIZE + yRegion; + var lum = greyscalePixels.get(x, y); + binarized.set(x, y, lum <= threshold); + if (returnInverted) { + inverted.set(x, y, !(lum <= threshold)); + } + } + } + } + } + if (returnInverted) { + return { binarized: binarized, inverted: inverted }; + } + return { binarized: binarized }; +} +exports.binarize = binarize; + + +/***/ }), +/* 5 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +var BitMatrix_1 = __webpack_require__(0); +var decodeData_1 = __webpack_require__(6); +var reedsolomon_1 = __webpack_require__(9); +var version_1 = __webpack_require__(10); +// tslint:disable:no-bitwise +function numBitsDiffering(x, y) { + var z = x ^ y; + var bitCount = 0; + while (z) { + bitCount++; + z &= z - 1; + } + return bitCount; +} +function pushBit(bit, byte) { + return (byte << 1) | bit; +} +// tslint:enable:no-bitwise +var FORMAT_INFO_TABLE = [ + { bits: 0x5412, formatInfo: { errorCorrectionLevel: 1, dataMask: 0 } }, + { bits: 0x5125, formatInfo: { errorCorrectionLevel: 1, dataMask: 1 } }, + { bits: 0x5E7C, formatInfo: { errorCorrectionLevel: 1, dataMask: 2 } }, + { bits: 0x5B4B, formatInfo: { errorCorrectionLevel: 1, dataMask: 3 } }, + { bits: 0x45F9, formatInfo: { errorCorrectionLevel: 1, dataMask: 4 } }, + { bits: 0x40CE, formatInfo: { errorCorrectionLevel: 1, dataMask: 5 } }, + { bits: 0x4F97, formatInfo: { errorCorrectionLevel: 1, dataMask: 6 } }, + { bits: 0x4AA0, formatInfo: { errorCorrectionLevel: 1, dataMask: 7 } }, + { bits: 0x77C4, formatInfo: { errorCorrectionLevel: 0, dataMask: 0 } }, + { bits: 0x72F3, formatInfo: { errorCorrectionLevel: 0, dataMask: 1 } }, + { bits: 0x7DAA, formatInfo: { errorCorrectionLevel: 0, dataMask: 2 } }, + { bits: 0x789D, formatInfo: { errorCorrectionLevel: 0, dataMask: 3 } }, + { bits: 0x662F, formatInfo: { errorCorrectionLevel: 0, dataMask: 4 } }, + { bits: 0x6318, formatInfo: { errorCorrectionLevel: 0, dataMask: 5 } }, + { bits: 0x6C41, formatInfo: { errorCorrectionLevel: 0, dataMask: 6 } }, + { bits: 0x6976, formatInfo: { errorCorrectionLevel: 0, dataMask: 7 } }, + { bits: 0x1689, formatInfo: { errorCorrectionLevel: 3, dataMask: 0 } }, + { bits: 0x13BE, formatInfo: { errorCorrectionLevel: 3, dataMask: 1 } }, + { bits: 0x1CE7, formatInfo: { errorCorrectionLevel: 3, dataMask: 2 } }, + { bits: 0x19D0, formatInfo: { errorCorrectionLevel: 3, dataMask: 3 } }, + { bits: 0x0762, formatInfo: { errorCorrectionLevel: 3, dataMask: 4 } }, + { bits: 0x0255, formatInfo: { errorCorrectionLevel: 3, dataMask: 5 } }, + { bits: 0x0D0C, formatInfo: { errorCorrectionLevel: 3, dataMask: 6 } }, + { bits: 0x083B, formatInfo: { errorCorrectionLevel: 3, dataMask: 7 } }, + { bits: 0x355F, formatInfo: { errorCorrectionLevel: 2, dataMask: 0 } }, + { bits: 0x3068, formatInfo: { errorCorrectionLevel: 2, dataMask: 1 } }, + { bits: 0x3F31, formatInfo: { errorCorrectionLevel: 2, dataMask: 2 } }, + { bits: 0x3A06, formatInfo: { errorCorrectionLevel: 2, dataMask: 3 } }, + { bits: 0x24B4, formatInfo: { errorCorrectionLevel: 2, dataMask: 4 } }, + { bits: 0x2183, formatInfo: { errorCorrectionLevel: 2, dataMask: 5 } }, + { bits: 0x2EDA, formatInfo: { errorCorrectionLevel: 2, dataMask: 6 } }, + { bits: 0x2BED, formatInfo: { errorCorrectionLevel: 2, dataMask: 7 } }, +]; +var DATA_MASKS = [ + function (p) { return ((p.y + p.x) % 2) === 0; }, + function (p) { return (p.y % 2) === 0; }, + function (p) { return p.x % 3 === 0; }, + function (p) { return (p.y + p.x) % 3 === 0; }, + function (p) { return (Math.floor(p.y / 2) + Math.floor(p.x / 3)) % 2 === 0; }, + function (p) { return ((p.x * p.y) % 2) + ((p.x * p.y) % 3) === 0; }, + function (p) { return ((((p.y * p.x) % 2) + (p.y * p.x) % 3) % 2) === 0; }, + function (p) { return ((((p.y + p.x) % 2) + (p.y * p.x) % 3) % 2) === 0; }, +]; +function buildFunctionPatternMask(version) { + var dimension = 17 + 4 * version.versionNumber; + var matrix = BitMatrix_1.BitMatrix.createEmpty(dimension, dimension); + matrix.setRegion(0, 0, 9, 9, true); // Top left finder pattern + separator + format + matrix.setRegion(dimension - 8, 0, 8, 9, true); // Top right finder pattern + separator + format + matrix.setRegion(0, dimension - 8, 9, 8, true); // Bottom left finder pattern + separator + format + // Alignment patterns + for (var _i = 0, _a = version.alignmentPatternCenters; _i < _a.length; _i++) { + var x = _a[_i]; + for (var _b = 0, _c = version.alignmentPatternCenters; _b < _c.length; _b++) { + var y = _c[_b]; + if (!(x === 6 && y === 6 || x === 6 && y === dimension - 7 || x === dimension - 7 && y === 6)) { + matrix.setRegion(x - 2, y - 2, 5, 5, true); + } + } + } + matrix.setRegion(6, 9, 1, dimension - 17, true); // Vertical timing pattern + matrix.setRegion(9, 6, dimension - 17, 1, true); // Horizontal timing pattern + if (version.versionNumber > 6) { + matrix.setRegion(dimension - 11, 0, 3, 6, true); // Version info, top right + matrix.setRegion(0, dimension - 11, 6, 3, true); // Version info, bottom left + } + return matrix; +} +function readCodewords(matrix, version, formatInfo) { + var dataMask = DATA_MASKS[formatInfo.dataMask]; + var dimension = matrix.height; + var functionPatternMask = buildFunctionPatternMask(version); + var codewords = []; + var currentByte = 0; + var bitsRead = 0; + // Read columns in pairs, from right to left + var readingUp = true; + for (var columnIndex = dimension - 1; columnIndex > 0; columnIndex -= 2) { + if (columnIndex === 6) { // Skip whole column with vertical alignment pattern; + columnIndex--; + } + for (var i = 0; i < dimension; i++) { + var y = readingUp ? dimension - 1 - i : i; + for (var columnOffset = 0; columnOffset < 2; columnOffset++) { + var x = columnIndex - columnOffset; + if (!functionPatternMask.get(x, y)) { + bitsRead++; + var bit = matrix.get(x, y); + if (dataMask({ y: y, x: x })) { + bit = !bit; + } + currentByte = pushBit(bit, currentByte); + if (bitsRead === 8) { // Whole bytes + codewords.push(currentByte); + bitsRead = 0; + currentByte = 0; + } + } + } + } + readingUp = !readingUp; + } + return codewords; +} +function readVersion(matrix) { + var dimension = matrix.height; + var provisionalVersion = Math.floor((dimension - 17) / 4); + if (provisionalVersion <= 6) { // 6 and under dont have version info in the QR code + return version_1.VERSIONS[provisionalVersion - 1]; + } + var topRightVersionBits = 0; + for (var y = 5; y >= 0; y--) { + for (var x = dimension - 9; x >= dimension - 11; x--) { + topRightVersionBits = pushBit(matrix.get(x, y), topRightVersionBits); + } + } + var bottomLeftVersionBits = 0; + for (var x = 5; x >= 0; x--) { + for (var y = dimension - 9; y >= dimension - 11; y--) { + bottomLeftVersionBits = pushBit(matrix.get(x, y), bottomLeftVersionBits); + } + } + var bestDifference = Infinity; + var bestVersion; + for (var _i = 0, VERSIONS_1 = version_1.VERSIONS; _i < VERSIONS_1.length; _i++) { + var version = VERSIONS_1[_i]; + if (version.infoBits === topRightVersionBits || version.infoBits === bottomLeftVersionBits) { + return version; + } + var difference = numBitsDiffering(topRightVersionBits, version.infoBits); + if (difference < bestDifference) { + bestVersion = version; + bestDifference = difference; + } + difference = numBitsDiffering(bottomLeftVersionBits, version.infoBits); + if (difference < bestDifference) { + bestVersion = version; + bestDifference = difference; + } + } + // We can tolerate up to 3 bits of error since no two version info codewords will + // differ in less than 8 bits. + if (bestDifference <= 3) { + return bestVersion; + } +} +function readFormatInformation(matrix) { + var topLeftFormatInfoBits = 0; + for (var x = 0; x <= 8; x++) { + if (x !== 6) { // Skip timing pattern bit + topLeftFormatInfoBits = pushBit(matrix.get(x, 8), topLeftFormatInfoBits); + } + } + for (var y = 7; y >= 0; y--) { + if (y !== 6) { // Skip timing pattern bit + topLeftFormatInfoBits = pushBit(matrix.get(8, y), topLeftFormatInfoBits); + } + } + var dimension = matrix.height; + var topRightBottomRightFormatInfoBits = 0; + for (var y = dimension - 1; y >= dimension - 7; y--) { // bottom left + topRightBottomRightFormatInfoBits = pushBit(matrix.get(8, y), topRightBottomRightFormatInfoBits); + } + for (var x = dimension - 8; x < dimension; x++) { // top right + topRightBottomRightFormatInfoBits = pushBit(matrix.get(x, 8), topRightBottomRightFormatInfoBits); + } + var bestDifference = Infinity; + var bestFormatInfo = null; + for (var _i = 0, FORMAT_INFO_TABLE_1 = FORMAT_INFO_TABLE; _i < FORMAT_INFO_TABLE_1.length; _i++) { + var _a = FORMAT_INFO_TABLE_1[_i], bits = _a.bits, formatInfo = _a.formatInfo; + if (bits === topLeftFormatInfoBits || bits === topRightBottomRightFormatInfoBits) { + return formatInfo; + } + var difference = numBitsDiffering(topLeftFormatInfoBits, bits); + if (difference < bestDifference) { + bestFormatInfo = formatInfo; + bestDifference = difference; + } + if (topLeftFormatInfoBits !== topRightBottomRightFormatInfoBits) { // also try the other option + difference = numBitsDiffering(topRightBottomRightFormatInfoBits, bits); + if (difference < bestDifference) { + bestFormatInfo = formatInfo; + bestDifference = difference; + } + } + } + // Hamming distance of the 32 masked codes is 7, by construction, so <= 3 bits differing means we found a match + if (bestDifference <= 3) { + return bestFormatInfo; + } + return null; +} +function getDataBlocks(codewords, version, ecLevel) { + var ecInfo = version.errorCorrectionLevels[ecLevel]; + var dataBlocks = []; + var totalCodewords = 0; + ecInfo.ecBlocks.forEach(function (block) { + for (var i = 0; i < block.numBlocks; i++) { + dataBlocks.push({ numDataCodewords: block.dataCodewordsPerBlock, codewords: [] }); + totalCodewords += block.dataCodewordsPerBlock + ecInfo.ecCodewordsPerBlock; + } + }); + // In some cases the QR code will be malformed enough that we pull off more or less than we should. + // If we pull off less there's nothing we can do. + // If we pull off more we can safely truncate + if (codewords.length < totalCodewords) { + return null; + } + codewords = codewords.slice(0, totalCodewords); + var shortBlockSize = ecInfo.ecBlocks[0].dataCodewordsPerBlock; + // Pull codewords to fill the blocks up to the minimum size + for (var i = 0; i < shortBlockSize; i++) { + for (var _i = 0, dataBlocks_1 = dataBlocks; _i < dataBlocks_1.length; _i++) { + var dataBlock = dataBlocks_1[_i]; + dataBlock.codewords.push(codewords.shift()); + } + } + // If there are any large blocks, pull codewords to fill the last element of those + if (ecInfo.ecBlocks.length > 1) { + var smallBlockCount = ecInfo.ecBlocks[0].numBlocks; + var largeBlockCount = ecInfo.ecBlocks[1].numBlocks; + for (var i = 0; i < largeBlockCount; i++) { + dataBlocks[smallBlockCount + i].codewords.push(codewords.shift()); + } + } + // Add the rest of the codewords to the blocks. These are the error correction codewords. + while (codewords.length > 0) { + for (var _a = 0, dataBlocks_2 = dataBlocks; _a < dataBlocks_2.length; _a++) { + var dataBlock = dataBlocks_2[_a]; + dataBlock.codewords.push(codewords.shift()); + } + } + return dataBlocks; +} +function decodeMatrix(matrix) { + var version = readVersion(matrix); + if (!version) { + return null; + } + var formatInfo = readFormatInformation(matrix); + if (!formatInfo) { + return null; + } + var codewords = readCodewords(matrix, version, formatInfo); + var dataBlocks = getDataBlocks(codewords, version, formatInfo.errorCorrectionLevel); + if (!dataBlocks) { + return null; + } + // Count total number of data bytes + var totalBytes = dataBlocks.reduce(function (a, b) { return a + b.numDataCodewords; }, 0); + var resultBytes = new Uint8ClampedArray(totalBytes); + var resultIndex = 0; + for (var _i = 0, dataBlocks_3 = dataBlocks; _i < dataBlocks_3.length; _i++) { + var dataBlock = dataBlocks_3[_i]; + var correctedBytes = reedsolomon_1.decode(dataBlock.codewords, dataBlock.codewords.length - dataBlock.numDataCodewords); + if (!correctedBytes) { + return null; + } + for (var i = 0; i < dataBlock.numDataCodewords; i++) { + resultBytes[resultIndex++] = correctedBytes[i]; + } + } + try { + return decodeData_1.decode(resultBytes, version.versionNumber); + } + catch (_a) { + return null; + } +} +function decode(matrix) { + if (matrix == null) { + return null; + } + var result = decodeMatrix(matrix); + if (result) { + return result; + } + // Decoding didn't work, try mirroring the QR across the topLeft -> bottomRight line. + for (var x = 0; x < matrix.width; x++) { + for (var y = x + 1; y < matrix.height; y++) { + if (matrix.get(x, y) !== matrix.get(y, x)) { + matrix.set(x, y, !matrix.get(x, y)); + matrix.set(y, x, !matrix.get(y, x)); + } + } + } + return decodeMatrix(matrix); +} +exports.decode = decode; + + +/***/ }), +/* 6 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +// tslint:disable:no-bitwise +var BitStream_1 = __webpack_require__(7); +var shiftJISTable_1 = __webpack_require__(8); +var Mode; +(function (Mode) { + Mode["Numeric"] = "numeric"; + Mode["Alphanumeric"] = "alphanumeric"; + Mode["Byte"] = "byte"; + Mode["Kanji"] = "kanji"; + Mode["ECI"] = "eci"; +})(Mode = exports.Mode || (exports.Mode = {})); +var ModeByte; +(function (ModeByte) { + ModeByte[ModeByte["Terminator"] = 0] = "Terminator"; + ModeByte[ModeByte["Numeric"] = 1] = "Numeric"; + ModeByte[ModeByte["Alphanumeric"] = 2] = "Alphanumeric"; + ModeByte[ModeByte["Byte"] = 4] = "Byte"; + ModeByte[ModeByte["Kanji"] = 8] = "Kanji"; + ModeByte[ModeByte["ECI"] = 7] = "ECI"; + // StructuredAppend = 0x3, + // FNC1FirstPosition = 0x5, + // FNC1SecondPosition = 0x9, +})(ModeByte || (ModeByte = {})); +function decodeNumeric(stream, size) { + var bytes = []; + var text = ""; + var characterCountSize = [10, 12, 14][size]; + var length = stream.readBits(characterCountSize); + // Read digits in groups of 3 + while (length >= 3) { + var num = stream.readBits(10); + if (num >= 1000) { + throw new Error("Invalid numeric value above 999"); + } + var a = Math.floor(num / 100); + var b = Math.floor(num / 10) % 10; + var c = num % 10; + bytes.push(48 + a, 48 + b, 48 + c); + text += a.toString() + b.toString() + c.toString(); + length -= 3; + } + // If the number of digits aren't a multiple of 3, the remaining digits are special cased. + if (length === 2) { + var num = stream.readBits(7); + if (num >= 100) { + throw new Error("Invalid numeric value above 99"); + } + var a = Math.floor(num / 10); + var b = num % 10; + bytes.push(48 + a, 48 + b); + text += a.toString() + b.toString(); + } + else if (length === 1) { + var num = stream.readBits(4); + if (num >= 10) { + throw new Error("Invalid numeric value above 9"); + } + bytes.push(48 + num); + text += num.toString(); + } + return { bytes: bytes, text: text }; +} +var AlphanumericCharacterCodes = [ + "0", "1", "2", "3", "4", "5", "6", "7", "8", + "9", "A", "B", "C", "D", "E", "F", "G", "H", + "I", "J", "K", "L", "M", "N", "O", "P", "Q", + "R", "S", "T", "U", "V", "W", "X", "Y", "Z", + " ", "$", "%", "*", "+", "-", ".", "/", ":", +]; +function decodeAlphanumeric(stream, size) { + var bytes = []; + var text = ""; + var characterCountSize = [9, 11, 13][size]; + var length = stream.readBits(characterCountSize); + while (length >= 2) { + var v = stream.readBits(11); + var a = Math.floor(v / 45); + var b = v % 45; + bytes.push(AlphanumericCharacterCodes[a].charCodeAt(0), AlphanumericCharacterCodes[b].charCodeAt(0)); + text += AlphanumericCharacterCodes[a] + AlphanumericCharacterCodes[b]; + length -= 2; + } + if (length === 1) { + var a = stream.readBits(6); + bytes.push(AlphanumericCharacterCodes[a].charCodeAt(0)); + text += AlphanumericCharacterCodes[a]; + } + return { bytes: bytes, text: text }; +} +function decodeByte(stream, size) { + var bytes = []; + var text = ""; + var characterCountSize = [8, 16, 16][size]; + var length = stream.readBits(characterCountSize); + for (var i = 0; i < length; i++) { + var b = stream.readBits(8); + bytes.push(b); + } + try { + text += decodeURIComponent(bytes.map(function (b) { return "%" + ("0" + b.toString(16)).substr(-2); }).join("")); + } + catch (_a) { + // failed to decode + } + return { bytes: bytes, text: text }; +} +function decodeKanji(stream, size) { + var bytes = []; + var text = ""; + var characterCountSize = [8, 10, 12][size]; + var length = stream.readBits(characterCountSize); + for (var i = 0; i < length; i++) { + var k = stream.readBits(13); + var c = (Math.floor(k / 0xC0) << 8) | (k % 0xC0); + if (c < 0x1F00) { + c += 0x8140; + } + else { + c += 0xC140; + } + bytes.push(c >> 8, c & 0xFF); + text += String.fromCharCode(shiftJISTable_1.shiftJISTable[c]); + } + return { bytes: bytes, text: text }; +} +function decode(data, version) { + var _a, _b, _c, _d; + var stream = new BitStream_1.BitStream(data); + // There are 3 'sizes' based on the version. 1-9 is small (0), 10-26 is medium (1) and 27-40 is large (2). + var size = version <= 9 ? 0 : version <= 26 ? 1 : 2; + var result = { + text: "", + bytes: [], + chunks: [], + version: version, + }; + while (stream.available() >= 4) { + var mode = stream.readBits(4); + if (mode === ModeByte.Terminator) { + return result; + } + else if (mode === ModeByte.ECI) { + if (stream.readBits(1) === 0) { + result.chunks.push({ + type: Mode.ECI, + assignmentNumber: stream.readBits(7), + }); + } + else if (stream.readBits(1) === 0) { + result.chunks.push({ + type: Mode.ECI, + assignmentNumber: stream.readBits(14), + }); + } + else if (stream.readBits(1) === 0) { + result.chunks.push({ + type: Mode.ECI, + assignmentNumber: stream.readBits(21), + }); + } + else { + // ECI data seems corrupted + result.chunks.push({ + type: Mode.ECI, + assignmentNumber: -1, + }); + } + } + else if (mode === ModeByte.Numeric) { + var numericResult = decodeNumeric(stream, size); + result.text += numericResult.text; + (_a = result.bytes).push.apply(_a, numericResult.bytes); + result.chunks.push({ + type: Mode.Numeric, + text: numericResult.text, + }); + } + else if (mode === ModeByte.Alphanumeric) { + var alphanumericResult = decodeAlphanumeric(stream, size); + result.text += alphanumericResult.text; + (_b = result.bytes).push.apply(_b, alphanumericResult.bytes); + result.chunks.push({ + type: Mode.Alphanumeric, + text: alphanumericResult.text, + }); + } + else if (mode === ModeByte.Byte) { + var byteResult = decodeByte(stream, size); + result.text += byteResult.text; + (_c = result.bytes).push.apply(_c, byteResult.bytes); + result.chunks.push({ + type: Mode.Byte, + bytes: byteResult.bytes, + text: byteResult.text, + }); + } + else if (mode === ModeByte.Kanji) { + var kanjiResult = decodeKanji(stream, size); + result.text += kanjiResult.text; + (_d = result.bytes).push.apply(_d, kanjiResult.bytes); + result.chunks.push({ + type: Mode.Kanji, + bytes: kanjiResult.bytes, + text: kanjiResult.text, + }); + } + } + // If there is no data left, or the remaining bits are all 0, then that counts as a termination marker + if (stream.available() === 0 || stream.readBits(stream.available()) === 0) { + return result; + } +} +exports.decode = decode; + + +/***/ }), +/* 7 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// tslint:disable:no-bitwise +Object.defineProperty(exports, "__esModule", { value: true }); +var BitStream = /** @class */ (function () { + function BitStream(bytes) { + this.byteOffset = 0; + this.bitOffset = 0; + this.bytes = bytes; + } + BitStream.prototype.readBits = function (numBits) { + if (numBits < 1 || numBits > 32 || numBits > this.available()) { + throw new Error("Cannot read " + numBits.toString() + " bits"); + } + var result = 0; + // First, read remainder from current byte + if (this.bitOffset > 0) { + var bitsLeft = 8 - this.bitOffset; + var toRead = numBits < bitsLeft ? numBits : bitsLeft; + var bitsToNotRead = bitsLeft - toRead; + var mask = (0xFF >> (8 - toRead)) << bitsToNotRead; + result = (this.bytes[this.byteOffset] & mask) >> bitsToNotRead; + numBits -= toRead; + this.bitOffset += toRead; + if (this.bitOffset === 8) { + this.bitOffset = 0; + this.byteOffset++; + } + } + // Next read whole bytes + if (numBits > 0) { + while (numBits >= 8) { + result = (result << 8) | (this.bytes[this.byteOffset] & 0xFF); + this.byteOffset++; + numBits -= 8; + } + // Finally read a partial byte + if (numBits > 0) { + var bitsToNotRead = 8 - numBits; + var mask = (0xFF >> bitsToNotRead) << bitsToNotRead; + result = (result << numBits) | ((this.bytes[this.byteOffset] & mask) >> bitsToNotRead); + this.bitOffset += numBits; + } + } + return result; + }; + BitStream.prototype.available = function () { + return 8 * (this.bytes.length - this.byteOffset) - this.bitOffset; + }; + return BitStream; +}()); +exports.BitStream = BitStream; + + +/***/ }), +/* 8 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +exports.shiftJISTable = { + 0x20: 0x0020, + 0x21: 0x0021, + 0x22: 0x0022, + 0x23: 0x0023, + 0x24: 0x0024, + 0x25: 0x0025, + 0x26: 0x0026, + 0x27: 0x0027, + 0x28: 0x0028, + 0x29: 0x0029, + 0x2A: 0x002A, + 0x2B: 0x002B, + 0x2C: 0x002C, + 0x2D: 0x002D, + 0x2E: 0x002E, + 0x2F: 0x002F, + 0x30: 0x0030, + 0x31: 0x0031, + 0x32: 0x0032, + 0x33: 0x0033, + 0x34: 0x0034, + 0x35: 0x0035, + 0x36: 0x0036, + 0x37: 0x0037, + 0x38: 0x0038, + 0x39: 0x0039, + 0x3A: 0x003A, + 0x3B: 0x003B, + 0x3C: 0x003C, + 0x3D: 0x003D, + 0x3E: 0x003E, + 0x3F: 0x003F, + 0x40: 0x0040, + 0x41: 0x0041, + 0x42: 0x0042, + 0x43: 0x0043, + 0x44: 0x0044, + 0x45: 0x0045, + 0x46: 0x0046, + 0x47: 0x0047, + 0x48: 0x0048, + 0x49: 0x0049, + 0x4A: 0x004A, + 0x4B: 0x004B, + 0x4C: 0x004C, + 0x4D: 0x004D, + 0x4E: 0x004E, + 0x4F: 0x004F, + 0x50: 0x0050, + 0x51: 0x0051, + 0x52: 0x0052, + 0x53: 0x0053, + 0x54: 0x0054, + 0x55: 0x0055, + 0x56: 0x0056, + 0x57: 0x0057, + 0x58: 0x0058, + 0x59: 0x0059, + 0x5A: 0x005A, + 0x5B: 0x005B, + 0x5C: 0x00A5, + 0x5D: 0x005D, + 0x5E: 0x005E, + 0x5F: 0x005F, + 0x60: 0x0060, + 0x61: 0x0061, + 0x62: 0x0062, + 0x63: 0x0063, + 0x64: 0x0064, + 0x65: 0x0065, + 0x66: 0x0066, + 0x67: 0x0067, + 0x68: 0x0068, + 0x69: 0x0069, + 0x6A: 0x006A, + 0x6B: 0x006B, + 0x6C: 0x006C, + 0x6D: 0x006D, + 0x6E: 0x006E, + 0x6F: 0x006F, + 0x70: 0x0070, + 0x71: 0x0071, + 0x72: 0x0072, + 0x73: 0x0073, + 0x74: 0x0074, + 0x75: 0x0075, + 0x76: 0x0076, + 0x77: 0x0077, + 0x78: 0x0078, + 0x79: 0x0079, + 0x7A: 0x007A, + 0x7B: 0x007B, + 0x7C: 0x007C, + 0x7D: 0x007D, + 0x7E: 0x203E, + 0x8140: 0x3000, + 0x8141: 0x3001, + 0x8142: 0x3002, + 0x8143: 0xFF0C, + 0x8144: 0xFF0E, + 0x8145: 0x30FB, + 0x8146: 0xFF1A, + 0x8147: 0xFF1B, + 0x8148: 0xFF1F, + 0x8149: 0xFF01, + 0x814A: 0x309B, + 0x814B: 0x309C, + 0x814C: 0x00B4, + 0x814D: 0xFF40, + 0x814E: 0x00A8, + 0x814F: 0xFF3E, + 0x8150: 0xFFE3, + 0x8151: 0xFF3F, + 0x8152: 0x30FD, + 0x8153: 0x30FE, + 0x8154: 0x309D, + 0x8155: 0x309E, + 0x8156: 0x3003, + 0x8157: 0x4EDD, + 0x8158: 0x3005, + 0x8159: 0x3006, + 0x815A: 0x3007, + 0x815B: 0x30FC, + 0x815C: 0x2015, + 0x815D: 0x2010, + 0x815E: 0xFF0F, + 0x815F: 0x005C, + 0x8160: 0x301C, + 0x8161: 0x2016, + 0x8162: 0xFF5C, + 0x8163: 0x2026, + 0x8164: 0x2025, + 0x8165: 0x2018, + 0x8166: 0x2019, + 0x8167: 0x201C, + 0x8168: 0x201D, + 0x8169: 0xFF08, + 0x816A: 0xFF09, + 0x816B: 0x3014, + 0x816C: 0x3015, + 0x816D: 0xFF3B, + 0x816E: 0xFF3D, + 0x816F: 0xFF5B, + 0x8170: 0xFF5D, + 0x8171: 0x3008, + 0x8172: 0x3009, + 0x8173: 0x300A, + 0x8174: 0x300B, + 0x8175: 0x300C, + 0x8176: 0x300D, + 0x8177: 0x300E, + 0x8178: 0x300F, + 0x8179: 0x3010, + 0x817A: 0x3011, + 0x817B: 0xFF0B, + 0x817C: 0x2212, + 0x817D: 0x00B1, + 0x817E: 0x00D7, + 0x8180: 0x00F7, + 0x8181: 0xFF1D, + 0x8182: 0x2260, + 0x8183: 0xFF1C, + 0x8184: 0xFF1E, + 0x8185: 0x2266, + 0x8186: 0x2267, + 0x8187: 0x221E, + 0x8188: 0x2234, + 0x8189: 0x2642, + 0x818A: 0x2640, + 0x818B: 0x00B0, + 0x818C: 0x2032, + 0x818D: 0x2033, + 0x818E: 0x2103, + 0x818F: 0xFFE5, + 0x8190: 0xFF04, + 0x8191: 0x00A2, + 0x8192: 0x00A3, + 0x8193: 0xFF05, + 0x8194: 0xFF03, + 0x8195: 0xFF06, + 0x8196: 0xFF0A, + 0x8197: 0xFF20, + 0x8198: 0x00A7, + 0x8199: 0x2606, + 0x819A: 0x2605, + 0x819B: 0x25CB, + 0x819C: 0x25CF, + 0x819D: 0x25CE, + 0x819E: 0x25C7, + 0x819F: 0x25C6, + 0x81A0: 0x25A1, + 0x81A1: 0x25A0, + 0x81A2: 0x25B3, + 0x81A3: 0x25B2, + 0x81A4: 0x25BD, + 0x81A5: 0x25BC, + 0x81A6: 0x203B, + 0x81A7: 0x3012, + 0x81A8: 0x2192, + 0x81A9: 0x2190, + 0x81AA: 0x2191, + 0x81AB: 0x2193, + 0x81AC: 0x3013, + 0x81B8: 0x2208, + 0x81B9: 0x220B, + 0x81BA: 0x2286, + 0x81BB: 0x2287, + 0x81BC: 0x2282, + 0x81BD: 0x2283, + 0x81BE: 0x222A, + 0x81BF: 0x2229, + 0x81C8: 0x2227, + 0x81C9: 0x2228, + 0x81CA: 0x00AC, + 0x81CB: 0x21D2, + 0x81CC: 0x21D4, + 0x81CD: 0x2200, + 0x81CE: 0x2203, + 0x81DA: 0x2220, + 0x81DB: 0x22A5, + 0x81DC: 0x2312, + 0x81DD: 0x2202, + 0x81DE: 0x2207, + 0x81DF: 0x2261, + 0x81E0: 0x2252, + 0x81E1: 0x226A, + 0x81E2: 0x226B, + 0x81E3: 0x221A, + 0x81E4: 0x223D, + 0x81E5: 0x221D, + 0x81E6: 0x2235, + 0x81E7: 0x222B, + 0x81E8: 0x222C, + 0x81F0: 0x212B, + 0x81F1: 0x2030, + 0x81F2: 0x266F, + 0x81F3: 0x266D, + 0x81F4: 0x266A, + 0x81F5: 0x2020, + 0x81F6: 0x2021, + 0x81F7: 0x00B6, + 0x81FC: 0x25EF, + 0x824F: 0xFF10, + 0x8250: 0xFF11, + 0x8251: 0xFF12, + 0x8252: 0xFF13, + 0x8253: 0xFF14, + 0x8254: 0xFF15, + 0x8255: 0xFF16, + 0x8256: 0xFF17, + 0x8257: 0xFF18, + 0x8258: 0xFF19, + 0x8260: 0xFF21, + 0x8261: 0xFF22, + 0x8262: 0xFF23, + 0x8263: 0xFF24, + 0x8264: 0xFF25, + 0x8265: 0xFF26, + 0x8266: 0xFF27, + 0x8267: 0xFF28, + 0x8268: 0xFF29, + 0x8269: 0xFF2A, + 0x826A: 0xFF2B, + 0x826B: 0xFF2C, + 0x826C: 0xFF2D, + 0x826D: 0xFF2E, + 0x826E: 0xFF2F, + 0x826F: 0xFF30, + 0x8270: 0xFF31, + 0x8271: 0xFF32, + 0x8272: 0xFF33, + 0x8273: 0xFF34, + 0x8274: 0xFF35, + 0x8275: 0xFF36, + 0x8276: 0xFF37, + 0x8277: 0xFF38, + 0x8278: 0xFF39, + 0x8279: 0xFF3A, + 0x8281: 0xFF41, + 0x8282: 0xFF42, + 0x8283: 0xFF43, + 0x8284: 0xFF44, + 0x8285: 0xFF45, + 0x8286: 0xFF46, + 0x8287: 0xFF47, + 0x8288: 0xFF48, + 0x8289: 0xFF49, + 0x828A: 0xFF4A, + 0x828B: 0xFF4B, + 0x828C: 0xFF4C, + 0x828D: 0xFF4D, + 0x828E: 0xFF4E, + 0x828F: 0xFF4F, + 0x8290: 0xFF50, + 0x8291: 0xFF51, + 0x8292: 0xFF52, + 0x8293: 0xFF53, + 0x8294: 0xFF54, + 0x8295: 0xFF55, + 0x8296: 0xFF56, + 0x8297: 0xFF57, + 0x8298: 0xFF58, + 0x8299: 0xFF59, + 0x829A: 0xFF5A, + 0x829F: 0x3041, + 0x82A0: 0x3042, + 0x82A1: 0x3043, + 0x82A2: 0x3044, + 0x82A3: 0x3045, + 0x82A4: 0x3046, + 0x82A5: 0x3047, + 0x82A6: 0x3048, + 0x82A7: 0x3049, + 0x82A8: 0x304A, + 0x82A9: 0x304B, + 0x82AA: 0x304C, + 0x82AB: 0x304D, + 0x82AC: 0x304E, + 0x82AD: 0x304F, + 0x82AE: 0x3050, + 0x82AF: 0x3051, + 0x82B0: 0x3052, + 0x82B1: 0x3053, + 0x82B2: 0x3054, + 0x82B3: 0x3055, + 0x82B4: 0x3056, + 0x82B5: 0x3057, + 0x82B6: 0x3058, + 0x82B7: 0x3059, + 0x82B8: 0x305A, + 0x82B9: 0x305B, + 0x82BA: 0x305C, + 0x82BB: 0x305D, + 0x82BC: 0x305E, + 0x82BD: 0x305F, + 0x82BE: 0x3060, + 0x82BF: 0x3061, + 0x82C0: 0x3062, + 0x82C1: 0x3063, + 0x82C2: 0x3064, + 0x82C3: 0x3065, + 0x82C4: 0x3066, + 0x82C5: 0x3067, + 0x82C6: 0x3068, + 0x82C7: 0x3069, + 0x82C8: 0x306A, + 0x82C9: 0x306B, + 0x82CA: 0x306C, + 0x82CB: 0x306D, + 0x82CC: 0x306E, + 0x82CD: 0x306F, + 0x82CE: 0x3070, + 0x82CF: 0x3071, + 0x82D0: 0x3072, + 0x82D1: 0x3073, + 0x82D2: 0x3074, + 0x82D3: 0x3075, + 0x82D4: 0x3076, + 0x82D5: 0x3077, + 0x82D6: 0x3078, + 0x82D7: 0x3079, + 0x82D8: 0x307A, + 0x82D9: 0x307B, + 0x82DA: 0x307C, + 0x82DB: 0x307D, + 0x82DC: 0x307E, + 0x82DD: 0x307F, + 0x82DE: 0x3080, + 0x82DF: 0x3081, + 0x82E0: 0x3082, + 0x82E1: 0x3083, + 0x82E2: 0x3084, + 0x82E3: 0x3085, + 0x82E4: 0x3086, + 0x82E5: 0x3087, + 0x82E6: 0x3088, + 0x82E7: 0x3089, + 0x82E8: 0x308A, + 0x82E9: 0x308B, + 0x82EA: 0x308C, + 0x82EB: 0x308D, + 0x82EC: 0x308E, + 0x82ED: 0x308F, + 0x82EE: 0x3090, + 0x82EF: 0x3091, + 0x82F0: 0x3092, + 0x82F1: 0x3093, + 0x8340: 0x30A1, + 0x8341: 0x30A2, + 0x8342: 0x30A3, + 0x8343: 0x30A4, + 0x8344: 0x30A5, + 0x8345: 0x30A6, + 0x8346: 0x30A7, + 0x8347: 0x30A8, + 0x8348: 0x30A9, + 0x8349: 0x30AA, + 0x834A: 0x30AB, + 0x834B: 0x30AC, + 0x834C: 0x30AD, + 0x834D: 0x30AE, + 0x834E: 0x30AF, + 0x834F: 0x30B0, + 0x8350: 0x30B1, + 0x8351: 0x30B2, + 0x8352: 0x30B3, + 0x8353: 0x30B4, + 0x8354: 0x30B5, + 0x8355: 0x30B6, + 0x8356: 0x30B7, + 0x8357: 0x30B8, + 0x8358: 0x30B9, + 0x8359: 0x30BA, + 0x835A: 0x30BB, + 0x835B: 0x30BC, + 0x835C: 0x30BD, + 0x835D: 0x30BE, + 0x835E: 0x30BF, + 0x835F: 0x30C0, + 0x8360: 0x30C1, + 0x8361: 0x30C2, + 0x8362: 0x30C3, + 0x8363: 0x30C4, + 0x8364: 0x30C5, + 0x8365: 0x30C6, + 0x8366: 0x30C7, + 0x8367: 0x30C8, + 0x8368: 0x30C9, + 0x8369: 0x30CA, + 0x836A: 0x30CB, + 0x836B: 0x30CC, + 0x836C: 0x30CD, + 0x836D: 0x30CE, + 0x836E: 0x30CF, + 0x836F: 0x30D0, + 0x8370: 0x30D1, + 0x8371: 0x30D2, + 0x8372: 0x30D3, + 0x8373: 0x30D4, + 0x8374: 0x30D5, + 0x8375: 0x30D6, + 0x8376: 0x30D7, + 0x8377: 0x30D8, + 0x8378: 0x30D9, + 0x8379: 0x30DA, + 0x837A: 0x30DB, + 0x837B: 0x30DC, + 0x837C: 0x30DD, + 0x837D: 0x30DE, + 0x837E: 0x30DF, + 0x8380: 0x30E0, + 0x8381: 0x30E1, + 0x8382: 0x30E2, + 0x8383: 0x30E3, + 0x8384: 0x30E4, + 0x8385: 0x30E5, + 0x8386: 0x30E6, + 0x8387: 0x30E7, + 0x8388: 0x30E8, + 0x8389: 0x30E9, + 0x838A: 0x30EA, + 0x838B: 0x30EB, + 0x838C: 0x30EC, + 0x838D: 0x30ED, + 0x838E: 0x30EE, + 0x838F: 0x30EF, + 0x8390: 0x30F0, + 0x8391: 0x30F1, + 0x8392: 0x30F2, + 0x8393: 0x30F3, + 0x8394: 0x30F4, + 0x8395: 0x30F5, + 0x8396: 0x30F6, + 0x839F: 0x0391, + 0x83A0: 0x0392, + 0x83A1: 0x0393, + 0x83A2: 0x0394, + 0x83A3: 0x0395, + 0x83A4: 0x0396, + 0x83A5: 0x0397, + 0x83A6: 0x0398, + 0x83A7: 0x0399, + 0x83A8: 0x039A, + 0x83A9: 0x039B, + 0x83AA: 0x039C, + 0x83AB: 0x039D, + 0x83AC: 0x039E, + 0x83AD: 0x039F, + 0x83AE: 0x03A0, + 0x83AF: 0x03A1, + 0x83B0: 0x03A3, + 0x83B1: 0x03A4, + 0x83B2: 0x03A5, + 0x83B3: 0x03A6, + 0x83B4: 0x03A7, + 0x83B5: 0x03A8, + 0x83B6: 0x03A9, + 0x83BF: 0x03B1, + 0x83C0: 0x03B2, + 0x83C1: 0x03B3, + 0x83C2: 0x03B4, + 0x83C3: 0x03B5, + 0x83C4: 0x03B6, + 0x83C5: 0x03B7, + 0x83C6: 0x03B8, + 0x83C7: 0x03B9, + 0x83C8: 0x03BA, + 0x83C9: 0x03BB, + 0x83CA: 0x03BC, + 0x83CB: 0x03BD, + 0x83CC: 0x03BE, + 0x83CD: 0x03BF, + 0x83CE: 0x03C0, + 0x83CF: 0x03C1, + 0x83D0: 0x03C3, + 0x83D1: 0x03C4, + 0x83D2: 0x03C5, + 0x83D3: 0x03C6, + 0x83D4: 0x03C7, + 0x83D5: 0x03C8, + 0x83D6: 0x03C9, + 0x8440: 0x0410, + 0x8441: 0x0411, + 0x8442: 0x0412, + 0x8443: 0x0413, + 0x8444: 0x0414, + 0x8445: 0x0415, + 0x8446: 0x0401, + 0x8447: 0x0416, + 0x8448: 0x0417, + 0x8449: 0x0418, + 0x844A: 0x0419, + 0x844B: 0x041A, + 0x844C: 0x041B, + 0x844D: 0x041C, + 0x844E: 0x041D, + 0x844F: 0x041E, + 0x8450: 0x041F, + 0x8451: 0x0420, + 0x8452: 0x0421, + 0x8453: 0x0422, + 0x8454: 0x0423, + 0x8455: 0x0424, + 0x8456: 0x0425, + 0x8457: 0x0426, + 0x8458: 0x0427, + 0x8459: 0x0428, + 0x845A: 0x0429, + 0x845B: 0x042A, + 0x845C: 0x042B, + 0x845D: 0x042C, + 0x845E: 0x042D, + 0x845F: 0x042E, + 0x8460: 0x042F, + 0x8470: 0x0430, + 0x8471: 0x0431, + 0x8472: 0x0432, + 0x8473: 0x0433, + 0x8474: 0x0434, + 0x8475: 0x0435, + 0x8476: 0x0451, + 0x8477: 0x0436, + 0x8478: 0x0437, + 0x8479: 0x0438, + 0x847A: 0x0439, + 0x847B: 0x043A, + 0x847C: 0x043B, + 0x847D: 0x043C, + 0x847E: 0x043D, + 0x8480: 0x043E, + 0x8481: 0x043F, + 0x8482: 0x0440, + 0x8483: 0x0441, + 0x8484: 0x0442, + 0x8485: 0x0443, + 0x8486: 0x0444, + 0x8487: 0x0445, + 0x8488: 0x0446, + 0x8489: 0x0447, + 0x848A: 0x0448, + 0x848B: 0x0449, + 0x848C: 0x044A, + 0x848D: 0x044B, + 0x848E: 0x044C, + 0x848F: 0x044D, + 0x8490: 0x044E, + 0x8491: 0x044F, + 0x849F: 0x2500, + 0x84A0: 0x2502, + 0x84A1: 0x250C, + 0x84A2: 0x2510, + 0x84A3: 0x2518, + 0x84A4: 0x2514, + 0x84A5: 0x251C, + 0x84A6: 0x252C, + 0x84A7: 0x2524, + 0x84A8: 0x2534, + 0x84A9: 0x253C, + 0x84AA: 0x2501, + 0x84AB: 0x2503, + 0x84AC: 0x250F, + 0x84AD: 0x2513, + 0x84AE: 0x251B, + 0x84AF: 0x2517, + 0x84B0: 0x2523, + 0x84B1: 0x2533, + 0x84B2: 0x252B, + 0x84B3: 0x253B, + 0x84B4: 0x254B, + 0x84B5: 0x2520, + 0x84B6: 0x252F, + 0x84B7: 0x2528, + 0x84B8: 0x2537, + 0x84B9: 0x253F, + 0x84BA: 0x251D, + 0x84BB: 0x2530, + 0x84BC: 0x2525, + 0x84BD: 0x2538, + 0x84BE: 0x2542, + 0x889F: 0x4E9C, + 0x88A0: 0x5516, + 0x88A1: 0x5A03, + 0x88A2: 0x963F, + 0x88A3: 0x54C0, + 0x88A4: 0x611B, + 0x88A5: 0x6328, + 0x88A6: 0x59F6, + 0x88A7: 0x9022, + 0x88A8: 0x8475, + 0x88A9: 0x831C, + 0x88AA: 0x7A50, + 0x88AB: 0x60AA, + 0x88AC: 0x63E1, + 0x88AD: 0x6E25, + 0x88AE: 0x65ED, + 0x88AF: 0x8466, + 0x88B0: 0x82A6, + 0x88B1: 0x9BF5, + 0x88B2: 0x6893, + 0x88B3: 0x5727, + 0x88B4: 0x65A1, + 0x88B5: 0x6271, + 0x88B6: 0x5B9B, + 0x88B7: 0x59D0, + 0x88B8: 0x867B, + 0x88B9: 0x98F4, + 0x88BA: 0x7D62, + 0x88BB: 0x7DBE, + 0x88BC: 0x9B8E, + 0x88BD: 0x6216, + 0x88BE: 0x7C9F, + 0x88BF: 0x88B7, + 0x88C0: 0x5B89, + 0x88C1: 0x5EB5, + 0x88C2: 0x6309, + 0x88C3: 0x6697, + 0x88C4: 0x6848, + 0x88C5: 0x95C7, + 0x88C6: 0x978D, + 0x88C7: 0x674F, + 0x88C8: 0x4EE5, + 0x88C9: 0x4F0A, + 0x88CA: 0x4F4D, + 0x88CB: 0x4F9D, + 0x88CC: 0x5049, + 0x88CD: 0x56F2, + 0x88CE: 0x5937, + 0x88CF: 0x59D4, + 0x88D0: 0x5A01, + 0x88D1: 0x5C09, + 0x88D2: 0x60DF, + 0x88D3: 0x610F, + 0x88D4: 0x6170, + 0x88D5: 0x6613, + 0x88D6: 0x6905, + 0x88D7: 0x70BA, + 0x88D8: 0x754F, + 0x88D9: 0x7570, + 0x88DA: 0x79FB, + 0x88DB: 0x7DAD, + 0x88DC: 0x7DEF, + 0x88DD: 0x80C3, + 0x88DE: 0x840E, + 0x88DF: 0x8863, + 0x88E0: 0x8B02, + 0x88E1: 0x9055, + 0x88E2: 0x907A, + 0x88E3: 0x533B, + 0x88E4: 0x4E95, + 0x88E5: 0x4EA5, + 0x88E6: 0x57DF, + 0x88E7: 0x80B2, + 0x88E8: 0x90C1, + 0x88E9: 0x78EF, + 0x88EA: 0x4E00, + 0x88EB: 0x58F1, + 0x88EC: 0x6EA2, + 0x88ED: 0x9038, + 0x88EE: 0x7A32, + 0x88EF: 0x8328, + 0x88F0: 0x828B, + 0x88F1: 0x9C2F, + 0x88F2: 0x5141, + 0x88F3: 0x5370, + 0x88F4: 0x54BD, + 0x88F5: 0x54E1, + 0x88F6: 0x56E0, + 0x88F7: 0x59FB, + 0x88F8: 0x5F15, + 0x88F9: 0x98F2, + 0x88FA: 0x6DEB, + 0x88FB: 0x80E4, + 0x88FC: 0x852D, + 0x8940: 0x9662, + 0x8941: 0x9670, + 0x8942: 0x96A0, + 0x8943: 0x97FB, + 0x8944: 0x540B, + 0x8945: 0x53F3, + 0x8946: 0x5B87, + 0x8947: 0x70CF, + 0x8948: 0x7FBD, + 0x8949: 0x8FC2, + 0x894A: 0x96E8, + 0x894B: 0x536F, + 0x894C: 0x9D5C, + 0x894D: 0x7ABA, + 0x894E: 0x4E11, + 0x894F: 0x7893, + 0x8950: 0x81FC, + 0x8951: 0x6E26, + 0x8952: 0x5618, + 0x8953: 0x5504, + 0x8954: 0x6B1D, + 0x8955: 0x851A, + 0x8956: 0x9C3B, + 0x8957: 0x59E5, + 0x8958: 0x53A9, + 0x8959: 0x6D66, + 0x895A: 0x74DC, + 0x895B: 0x958F, + 0x895C: 0x5642, + 0x895D: 0x4E91, + 0x895E: 0x904B, + 0x895F: 0x96F2, + 0x8960: 0x834F, + 0x8961: 0x990C, + 0x8962: 0x53E1, + 0x8963: 0x55B6, + 0x8964: 0x5B30, + 0x8965: 0x5F71, + 0x8966: 0x6620, + 0x8967: 0x66F3, + 0x8968: 0x6804, + 0x8969: 0x6C38, + 0x896A: 0x6CF3, + 0x896B: 0x6D29, + 0x896C: 0x745B, + 0x896D: 0x76C8, + 0x896E: 0x7A4E, + 0x896F: 0x9834, + 0x8970: 0x82F1, + 0x8971: 0x885B, + 0x8972: 0x8A60, + 0x8973: 0x92ED, + 0x8974: 0x6DB2, + 0x8975: 0x75AB, + 0x8976: 0x76CA, + 0x8977: 0x99C5, + 0x8978: 0x60A6, + 0x8979: 0x8B01, + 0x897A: 0x8D8A, + 0x897B: 0x95B2, + 0x897C: 0x698E, + 0x897D: 0x53AD, + 0x897E: 0x5186, + 0x8980: 0x5712, + 0x8981: 0x5830, + 0x8982: 0x5944, + 0x8983: 0x5BB4, + 0x8984: 0x5EF6, + 0x8985: 0x6028, + 0x8986: 0x63A9, + 0x8987: 0x63F4, + 0x8988: 0x6CBF, + 0x8989: 0x6F14, + 0x898A: 0x708E, + 0x898B: 0x7114, + 0x898C: 0x7159, + 0x898D: 0x71D5, + 0x898E: 0x733F, + 0x898F: 0x7E01, + 0x8990: 0x8276, + 0x8991: 0x82D1, + 0x8992: 0x8597, + 0x8993: 0x9060, + 0x8994: 0x925B, + 0x8995: 0x9D1B, + 0x8996: 0x5869, + 0x8997: 0x65BC, + 0x8998: 0x6C5A, + 0x8999: 0x7525, + 0x899A: 0x51F9, + 0x899B: 0x592E, + 0x899C: 0x5965, + 0x899D: 0x5F80, + 0x899E: 0x5FDC, + 0x899F: 0x62BC, + 0x89A0: 0x65FA, + 0x89A1: 0x6A2A, + 0x89A2: 0x6B27, + 0x89A3: 0x6BB4, + 0x89A4: 0x738B, + 0x89A5: 0x7FC1, + 0x89A6: 0x8956, + 0x89A7: 0x9D2C, + 0x89A8: 0x9D0E, + 0x89A9: 0x9EC4, + 0x89AA: 0x5CA1, + 0x89AB: 0x6C96, + 0x89AC: 0x837B, + 0x89AD: 0x5104, + 0x89AE: 0x5C4B, + 0x89AF: 0x61B6, + 0x89B0: 0x81C6, + 0x89B1: 0x6876, + 0x89B2: 0x7261, + 0x89B3: 0x4E59, + 0x89B4: 0x4FFA, + 0x89B5: 0x5378, + 0x89B6: 0x6069, + 0x89B7: 0x6E29, + 0x89B8: 0x7A4F, + 0x89B9: 0x97F3, + 0x89BA: 0x4E0B, + 0x89BB: 0x5316, + 0x89BC: 0x4EEE, + 0x89BD: 0x4F55, + 0x89BE: 0x4F3D, + 0x89BF: 0x4FA1, + 0x89C0: 0x4F73, + 0x89C1: 0x52A0, + 0x89C2: 0x53EF, + 0x89C3: 0x5609, + 0x89C4: 0x590F, + 0x89C5: 0x5AC1, + 0x89C6: 0x5BB6, + 0x89C7: 0x5BE1, + 0x89C8: 0x79D1, + 0x89C9: 0x6687, + 0x89CA: 0x679C, + 0x89CB: 0x67B6, + 0x89CC: 0x6B4C, + 0x89CD: 0x6CB3, + 0x89CE: 0x706B, + 0x89CF: 0x73C2, + 0x89D0: 0x798D, + 0x89D1: 0x79BE, + 0x89D2: 0x7A3C, + 0x89D3: 0x7B87, + 0x89D4: 0x82B1, + 0x89D5: 0x82DB, + 0x89D6: 0x8304, + 0x89D7: 0x8377, + 0x89D8: 0x83EF, + 0x89D9: 0x83D3, + 0x89DA: 0x8766, + 0x89DB: 0x8AB2, + 0x89DC: 0x5629, + 0x89DD: 0x8CA8, + 0x89DE: 0x8FE6, + 0x89DF: 0x904E, + 0x89E0: 0x971E, + 0x89E1: 0x868A, + 0x89E2: 0x4FC4, + 0x89E3: 0x5CE8, + 0x89E4: 0x6211, + 0x89E5: 0x7259, + 0x89E6: 0x753B, + 0x89E7: 0x81E5, + 0x89E8: 0x82BD, + 0x89E9: 0x86FE, + 0x89EA: 0x8CC0, + 0x89EB: 0x96C5, + 0x89EC: 0x9913, + 0x89ED: 0x99D5, + 0x89EE: 0x4ECB, + 0x89EF: 0x4F1A, + 0x89F0: 0x89E3, + 0x89F1: 0x56DE, + 0x89F2: 0x584A, + 0x89F3: 0x58CA, + 0x89F4: 0x5EFB, + 0x89F5: 0x5FEB, + 0x89F6: 0x602A, + 0x89F7: 0x6094, + 0x89F8: 0x6062, + 0x89F9: 0x61D0, + 0x89FA: 0x6212, + 0x89FB: 0x62D0, + 0x89FC: 0x6539, + 0x8A40: 0x9B41, + 0x8A41: 0x6666, + 0x8A42: 0x68B0, + 0x8A43: 0x6D77, + 0x8A44: 0x7070, + 0x8A45: 0x754C, + 0x8A46: 0x7686, + 0x8A47: 0x7D75, + 0x8A48: 0x82A5, + 0x8A49: 0x87F9, + 0x8A4A: 0x958B, + 0x8A4B: 0x968E, + 0x8A4C: 0x8C9D, + 0x8A4D: 0x51F1, + 0x8A4E: 0x52BE, + 0x8A4F: 0x5916, + 0x8A50: 0x54B3, + 0x8A51: 0x5BB3, + 0x8A52: 0x5D16, + 0x8A53: 0x6168, + 0x8A54: 0x6982, + 0x8A55: 0x6DAF, + 0x8A56: 0x788D, + 0x8A57: 0x84CB, + 0x8A58: 0x8857, + 0x8A59: 0x8A72, + 0x8A5A: 0x93A7, + 0x8A5B: 0x9AB8, + 0x8A5C: 0x6D6C, + 0x8A5D: 0x99A8, + 0x8A5E: 0x86D9, + 0x8A5F: 0x57A3, + 0x8A60: 0x67FF, + 0x8A61: 0x86CE, + 0x8A62: 0x920E, + 0x8A63: 0x5283, + 0x8A64: 0x5687, + 0x8A65: 0x5404, + 0x8A66: 0x5ED3, + 0x8A67: 0x62E1, + 0x8A68: 0x64B9, + 0x8A69: 0x683C, + 0x8A6A: 0x6838, + 0x8A6B: 0x6BBB, + 0x8A6C: 0x7372, + 0x8A6D: 0x78BA, + 0x8A6E: 0x7A6B, + 0x8A6F: 0x899A, + 0x8A70: 0x89D2, + 0x8A71: 0x8D6B, + 0x8A72: 0x8F03, + 0x8A73: 0x90ED, + 0x8A74: 0x95A3, + 0x8A75: 0x9694, + 0x8A76: 0x9769, + 0x8A77: 0x5B66, + 0x8A78: 0x5CB3, + 0x8A79: 0x697D, + 0x8A7A: 0x984D, + 0x8A7B: 0x984E, + 0x8A7C: 0x639B, + 0x8A7D: 0x7B20, + 0x8A7E: 0x6A2B, + 0x8A80: 0x6A7F, + 0x8A81: 0x68B6, + 0x8A82: 0x9C0D, + 0x8A83: 0x6F5F, + 0x8A84: 0x5272, + 0x8A85: 0x559D, + 0x8A86: 0x6070, + 0x8A87: 0x62EC, + 0x8A88: 0x6D3B, + 0x8A89: 0x6E07, + 0x8A8A: 0x6ED1, + 0x8A8B: 0x845B, + 0x8A8C: 0x8910, + 0x8A8D: 0x8F44, + 0x8A8E: 0x4E14, + 0x8A8F: 0x9C39, + 0x8A90: 0x53F6, + 0x8A91: 0x691B, + 0x8A92: 0x6A3A, + 0x8A93: 0x9784, + 0x8A94: 0x682A, + 0x8A95: 0x515C, + 0x8A96: 0x7AC3, + 0x8A97: 0x84B2, + 0x8A98: 0x91DC, + 0x8A99: 0x938C, + 0x8A9A: 0x565B, + 0x8A9B: 0x9D28, + 0x8A9C: 0x6822, + 0x8A9D: 0x8305, + 0x8A9E: 0x8431, + 0x8A9F: 0x7CA5, + 0x8AA0: 0x5208, + 0x8AA1: 0x82C5, + 0x8AA2: 0x74E6, + 0x8AA3: 0x4E7E, + 0x8AA4: 0x4F83, + 0x8AA5: 0x51A0, + 0x8AA6: 0x5BD2, + 0x8AA7: 0x520A, + 0x8AA8: 0x52D8, + 0x8AA9: 0x52E7, + 0x8AAA: 0x5DFB, + 0x8AAB: 0x559A, + 0x8AAC: 0x582A, + 0x8AAD: 0x59E6, + 0x8AAE: 0x5B8C, + 0x8AAF: 0x5B98, + 0x8AB0: 0x5BDB, + 0x8AB1: 0x5E72, + 0x8AB2: 0x5E79, + 0x8AB3: 0x60A3, + 0x8AB4: 0x611F, + 0x8AB5: 0x6163, + 0x8AB6: 0x61BE, + 0x8AB7: 0x63DB, + 0x8AB8: 0x6562, + 0x8AB9: 0x67D1, + 0x8ABA: 0x6853, + 0x8ABB: 0x68FA, + 0x8ABC: 0x6B3E, + 0x8ABD: 0x6B53, + 0x8ABE: 0x6C57, + 0x8ABF: 0x6F22, + 0x8AC0: 0x6F97, + 0x8AC1: 0x6F45, + 0x8AC2: 0x74B0, + 0x8AC3: 0x7518, + 0x8AC4: 0x76E3, + 0x8AC5: 0x770B, + 0x8AC6: 0x7AFF, + 0x8AC7: 0x7BA1, + 0x8AC8: 0x7C21, + 0x8AC9: 0x7DE9, + 0x8ACA: 0x7F36, + 0x8ACB: 0x7FF0, + 0x8ACC: 0x809D, + 0x8ACD: 0x8266, + 0x8ACE: 0x839E, + 0x8ACF: 0x89B3, + 0x8AD0: 0x8ACC, + 0x8AD1: 0x8CAB, + 0x8AD2: 0x9084, + 0x8AD3: 0x9451, + 0x8AD4: 0x9593, + 0x8AD5: 0x9591, + 0x8AD6: 0x95A2, + 0x8AD7: 0x9665, + 0x8AD8: 0x97D3, + 0x8AD9: 0x9928, + 0x8ADA: 0x8218, + 0x8ADB: 0x4E38, + 0x8ADC: 0x542B, + 0x8ADD: 0x5CB8, + 0x8ADE: 0x5DCC, + 0x8ADF: 0x73A9, + 0x8AE0: 0x764C, + 0x8AE1: 0x773C, + 0x8AE2: 0x5CA9, + 0x8AE3: 0x7FEB, + 0x8AE4: 0x8D0B, + 0x8AE5: 0x96C1, + 0x8AE6: 0x9811, + 0x8AE7: 0x9854, + 0x8AE8: 0x9858, + 0x8AE9: 0x4F01, + 0x8AEA: 0x4F0E, + 0x8AEB: 0x5371, + 0x8AEC: 0x559C, + 0x8AED: 0x5668, + 0x8AEE: 0x57FA, + 0x8AEF: 0x5947, + 0x8AF0: 0x5B09, + 0x8AF1: 0x5BC4, + 0x8AF2: 0x5C90, + 0x8AF3: 0x5E0C, + 0x8AF4: 0x5E7E, + 0x8AF5: 0x5FCC, + 0x8AF6: 0x63EE, + 0x8AF7: 0x673A, + 0x8AF8: 0x65D7, + 0x8AF9: 0x65E2, + 0x8AFA: 0x671F, + 0x8AFB: 0x68CB, + 0x8AFC: 0x68C4, + 0x8B40: 0x6A5F, + 0x8B41: 0x5E30, + 0x8B42: 0x6BC5, + 0x8B43: 0x6C17, + 0x8B44: 0x6C7D, + 0x8B45: 0x757F, + 0x8B46: 0x7948, + 0x8B47: 0x5B63, + 0x8B48: 0x7A00, + 0x8B49: 0x7D00, + 0x8B4A: 0x5FBD, + 0x8B4B: 0x898F, + 0x8B4C: 0x8A18, + 0x8B4D: 0x8CB4, + 0x8B4E: 0x8D77, + 0x8B4F: 0x8ECC, + 0x8B50: 0x8F1D, + 0x8B51: 0x98E2, + 0x8B52: 0x9A0E, + 0x8B53: 0x9B3C, + 0x8B54: 0x4E80, + 0x8B55: 0x507D, + 0x8B56: 0x5100, + 0x8B57: 0x5993, + 0x8B58: 0x5B9C, + 0x8B59: 0x622F, + 0x8B5A: 0x6280, + 0x8B5B: 0x64EC, + 0x8B5C: 0x6B3A, + 0x8B5D: 0x72A0, + 0x8B5E: 0x7591, + 0x8B5F: 0x7947, + 0x8B60: 0x7FA9, + 0x8B61: 0x87FB, + 0x8B62: 0x8ABC, + 0x8B63: 0x8B70, + 0x8B64: 0x63AC, + 0x8B65: 0x83CA, + 0x8B66: 0x97A0, + 0x8B67: 0x5409, + 0x8B68: 0x5403, + 0x8B69: 0x55AB, + 0x8B6A: 0x6854, + 0x8B6B: 0x6A58, + 0x8B6C: 0x8A70, + 0x8B6D: 0x7827, + 0x8B6E: 0x6775, + 0x8B6F: 0x9ECD, + 0x8B70: 0x5374, + 0x8B71: 0x5BA2, + 0x8B72: 0x811A, + 0x8B73: 0x8650, + 0x8B74: 0x9006, + 0x8B75: 0x4E18, + 0x8B76: 0x4E45, + 0x8B77: 0x4EC7, + 0x8B78: 0x4F11, + 0x8B79: 0x53CA, + 0x8B7A: 0x5438, + 0x8B7B: 0x5BAE, + 0x8B7C: 0x5F13, + 0x8B7D: 0x6025, + 0x8B7E: 0x6551, + 0x8B80: 0x673D, + 0x8B81: 0x6C42, + 0x8B82: 0x6C72, + 0x8B83: 0x6CE3, + 0x8B84: 0x7078, + 0x8B85: 0x7403, + 0x8B86: 0x7A76, + 0x8B87: 0x7AAE, + 0x8B88: 0x7B08, + 0x8B89: 0x7D1A, + 0x8B8A: 0x7CFE, + 0x8B8B: 0x7D66, + 0x8B8C: 0x65E7, + 0x8B8D: 0x725B, + 0x8B8E: 0x53BB, + 0x8B8F: 0x5C45, + 0x8B90: 0x5DE8, + 0x8B91: 0x62D2, + 0x8B92: 0x62E0, + 0x8B93: 0x6319, + 0x8B94: 0x6E20, + 0x8B95: 0x865A, + 0x8B96: 0x8A31, + 0x8B97: 0x8DDD, + 0x8B98: 0x92F8, + 0x8B99: 0x6F01, + 0x8B9A: 0x79A6, + 0x8B9B: 0x9B5A, + 0x8B9C: 0x4EA8, + 0x8B9D: 0x4EAB, + 0x8B9E: 0x4EAC, + 0x8B9F: 0x4F9B, + 0x8BA0: 0x4FA0, + 0x8BA1: 0x50D1, + 0x8BA2: 0x5147, + 0x8BA3: 0x7AF6, + 0x8BA4: 0x5171, + 0x8BA5: 0x51F6, + 0x8BA6: 0x5354, + 0x8BA7: 0x5321, + 0x8BA8: 0x537F, + 0x8BA9: 0x53EB, + 0x8BAA: 0x55AC, + 0x8BAB: 0x5883, + 0x8BAC: 0x5CE1, + 0x8BAD: 0x5F37, + 0x8BAE: 0x5F4A, + 0x8BAF: 0x602F, + 0x8BB0: 0x6050, + 0x8BB1: 0x606D, + 0x8BB2: 0x631F, + 0x8BB3: 0x6559, + 0x8BB4: 0x6A4B, + 0x8BB5: 0x6CC1, + 0x8BB6: 0x72C2, + 0x8BB7: 0x72ED, + 0x8BB8: 0x77EF, + 0x8BB9: 0x80F8, + 0x8BBA: 0x8105, + 0x8BBB: 0x8208, + 0x8BBC: 0x854E, + 0x8BBD: 0x90F7, + 0x8BBE: 0x93E1, + 0x8BBF: 0x97FF, + 0x8BC0: 0x9957, + 0x8BC1: 0x9A5A, + 0x8BC2: 0x4EF0, + 0x8BC3: 0x51DD, + 0x8BC4: 0x5C2D, + 0x8BC5: 0x6681, + 0x8BC6: 0x696D, + 0x8BC7: 0x5C40, + 0x8BC8: 0x66F2, + 0x8BC9: 0x6975, + 0x8BCA: 0x7389, + 0x8BCB: 0x6850, + 0x8BCC: 0x7C81, + 0x8BCD: 0x50C5, + 0x8BCE: 0x52E4, + 0x8BCF: 0x5747, + 0x8BD0: 0x5DFE, + 0x8BD1: 0x9326, + 0x8BD2: 0x65A4, + 0x8BD3: 0x6B23, + 0x8BD4: 0x6B3D, + 0x8BD5: 0x7434, + 0x8BD6: 0x7981, + 0x8BD7: 0x79BD, + 0x8BD8: 0x7B4B, + 0x8BD9: 0x7DCA, + 0x8BDA: 0x82B9, + 0x8BDB: 0x83CC, + 0x8BDC: 0x887F, + 0x8BDD: 0x895F, + 0x8BDE: 0x8B39, + 0x8BDF: 0x8FD1, + 0x8BE0: 0x91D1, + 0x8BE1: 0x541F, + 0x8BE2: 0x9280, + 0x8BE3: 0x4E5D, + 0x8BE4: 0x5036, + 0x8BE5: 0x53E5, + 0x8BE6: 0x533A, + 0x8BE7: 0x72D7, + 0x8BE8: 0x7396, + 0x8BE9: 0x77E9, + 0x8BEA: 0x82E6, + 0x8BEB: 0x8EAF, + 0x8BEC: 0x99C6, + 0x8BED: 0x99C8, + 0x8BEE: 0x99D2, + 0x8BEF: 0x5177, + 0x8BF0: 0x611A, + 0x8BF1: 0x865E, + 0x8BF2: 0x55B0, + 0x8BF3: 0x7A7A, + 0x8BF4: 0x5076, + 0x8BF5: 0x5BD3, + 0x8BF6: 0x9047, + 0x8BF7: 0x9685, + 0x8BF8: 0x4E32, + 0x8BF9: 0x6ADB, + 0x8BFA: 0x91E7, + 0x8BFB: 0x5C51, + 0x8BFC: 0x5C48, + 0x8C40: 0x6398, + 0x8C41: 0x7A9F, + 0x8C42: 0x6C93, + 0x8C43: 0x9774, + 0x8C44: 0x8F61, + 0x8C45: 0x7AAA, + 0x8C46: 0x718A, + 0x8C47: 0x9688, + 0x8C48: 0x7C82, + 0x8C49: 0x6817, + 0x8C4A: 0x7E70, + 0x8C4B: 0x6851, + 0x8C4C: 0x936C, + 0x8C4D: 0x52F2, + 0x8C4E: 0x541B, + 0x8C4F: 0x85AB, + 0x8C50: 0x8A13, + 0x8C51: 0x7FA4, + 0x8C52: 0x8ECD, + 0x8C53: 0x90E1, + 0x8C54: 0x5366, + 0x8C55: 0x8888, + 0x8C56: 0x7941, + 0x8C57: 0x4FC2, + 0x8C58: 0x50BE, + 0x8C59: 0x5211, + 0x8C5A: 0x5144, + 0x8C5B: 0x5553, + 0x8C5C: 0x572D, + 0x8C5D: 0x73EA, + 0x8C5E: 0x578B, + 0x8C5F: 0x5951, + 0x8C60: 0x5F62, + 0x8C61: 0x5F84, + 0x8C62: 0x6075, + 0x8C63: 0x6176, + 0x8C64: 0x6167, + 0x8C65: 0x61A9, + 0x8C66: 0x63B2, + 0x8C67: 0x643A, + 0x8C68: 0x656C, + 0x8C69: 0x666F, + 0x8C6A: 0x6842, + 0x8C6B: 0x6E13, + 0x8C6C: 0x7566, + 0x8C6D: 0x7A3D, + 0x8C6E: 0x7CFB, + 0x8C6F: 0x7D4C, + 0x8C70: 0x7D99, + 0x8C71: 0x7E4B, + 0x8C72: 0x7F6B, + 0x8C73: 0x830E, + 0x8C74: 0x834A, + 0x8C75: 0x86CD, + 0x8C76: 0x8A08, + 0x8C77: 0x8A63, + 0x8C78: 0x8B66, + 0x8C79: 0x8EFD, + 0x8C7A: 0x981A, + 0x8C7B: 0x9D8F, + 0x8C7C: 0x82B8, + 0x8C7D: 0x8FCE, + 0x8C7E: 0x9BE8, + 0x8C80: 0x5287, + 0x8C81: 0x621F, + 0x8C82: 0x6483, + 0x8C83: 0x6FC0, + 0x8C84: 0x9699, + 0x8C85: 0x6841, + 0x8C86: 0x5091, + 0x8C87: 0x6B20, + 0x8C88: 0x6C7A, + 0x8C89: 0x6F54, + 0x8C8A: 0x7A74, + 0x8C8B: 0x7D50, + 0x8C8C: 0x8840, + 0x8C8D: 0x8A23, + 0x8C8E: 0x6708, + 0x8C8F: 0x4EF6, + 0x8C90: 0x5039, + 0x8C91: 0x5026, + 0x8C92: 0x5065, + 0x8C93: 0x517C, + 0x8C94: 0x5238, + 0x8C95: 0x5263, + 0x8C96: 0x55A7, + 0x8C97: 0x570F, + 0x8C98: 0x5805, + 0x8C99: 0x5ACC, + 0x8C9A: 0x5EFA, + 0x8C9B: 0x61B2, + 0x8C9C: 0x61F8, + 0x8C9D: 0x62F3, + 0x8C9E: 0x6372, + 0x8C9F: 0x691C, + 0x8CA0: 0x6A29, + 0x8CA1: 0x727D, + 0x8CA2: 0x72AC, + 0x8CA3: 0x732E, + 0x8CA4: 0x7814, + 0x8CA5: 0x786F, + 0x8CA6: 0x7D79, + 0x8CA7: 0x770C, + 0x8CA8: 0x80A9, + 0x8CA9: 0x898B, + 0x8CAA: 0x8B19, + 0x8CAB: 0x8CE2, + 0x8CAC: 0x8ED2, + 0x8CAD: 0x9063, + 0x8CAE: 0x9375, + 0x8CAF: 0x967A, + 0x8CB0: 0x9855, + 0x8CB1: 0x9A13, + 0x8CB2: 0x9E78, + 0x8CB3: 0x5143, + 0x8CB4: 0x539F, + 0x8CB5: 0x53B3, + 0x8CB6: 0x5E7B, + 0x8CB7: 0x5F26, + 0x8CB8: 0x6E1B, + 0x8CB9: 0x6E90, + 0x8CBA: 0x7384, + 0x8CBB: 0x73FE, + 0x8CBC: 0x7D43, + 0x8CBD: 0x8237, + 0x8CBE: 0x8A00, + 0x8CBF: 0x8AFA, + 0x8CC0: 0x9650, + 0x8CC1: 0x4E4E, + 0x8CC2: 0x500B, + 0x8CC3: 0x53E4, + 0x8CC4: 0x547C, + 0x8CC5: 0x56FA, + 0x8CC6: 0x59D1, + 0x8CC7: 0x5B64, + 0x8CC8: 0x5DF1, + 0x8CC9: 0x5EAB, + 0x8CCA: 0x5F27, + 0x8CCB: 0x6238, + 0x8CCC: 0x6545, + 0x8CCD: 0x67AF, + 0x8CCE: 0x6E56, + 0x8CCF: 0x72D0, + 0x8CD0: 0x7CCA, + 0x8CD1: 0x88B4, + 0x8CD2: 0x80A1, + 0x8CD3: 0x80E1, + 0x8CD4: 0x83F0, + 0x8CD5: 0x864E, + 0x8CD6: 0x8A87, + 0x8CD7: 0x8DE8, + 0x8CD8: 0x9237, + 0x8CD9: 0x96C7, + 0x8CDA: 0x9867, + 0x8CDB: 0x9F13, + 0x8CDC: 0x4E94, + 0x8CDD: 0x4E92, + 0x8CDE: 0x4F0D, + 0x8CDF: 0x5348, + 0x8CE0: 0x5449, + 0x8CE1: 0x543E, + 0x8CE2: 0x5A2F, + 0x8CE3: 0x5F8C, + 0x8CE4: 0x5FA1, + 0x8CE5: 0x609F, + 0x8CE6: 0x68A7, + 0x8CE7: 0x6A8E, + 0x8CE8: 0x745A, + 0x8CE9: 0x7881, + 0x8CEA: 0x8A9E, + 0x8CEB: 0x8AA4, + 0x8CEC: 0x8B77, + 0x8CED: 0x9190, + 0x8CEE: 0x4E5E, + 0x8CEF: 0x9BC9, + 0x8CF0: 0x4EA4, + 0x8CF1: 0x4F7C, + 0x8CF2: 0x4FAF, + 0x8CF3: 0x5019, + 0x8CF4: 0x5016, + 0x8CF5: 0x5149, + 0x8CF6: 0x516C, + 0x8CF7: 0x529F, + 0x8CF8: 0x52B9, + 0x8CF9: 0x52FE, + 0x8CFA: 0x539A, + 0x8CFB: 0x53E3, + 0x8CFC: 0x5411, + 0x8D40: 0x540E, + 0x8D41: 0x5589, + 0x8D42: 0x5751, + 0x8D43: 0x57A2, + 0x8D44: 0x597D, + 0x8D45: 0x5B54, + 0x8D46: 0x5B5D, + 0x8D47: 0x5B8F, + 0x8D48: 0x5DE5, + 0x8D49: 0x5DE7, + 0x8D4A: 0x5DF7, + 0x8D4B: 0x5E78, + 0x8D4C: 0x5E83, + 0x8D4D: 0x5E9A, + 0x8D4E: 0x5EB7, + 0x8D4F: 0x5F18, + 0x8D50: 0x6052, + 0x8D51: 0x614C, + 0x8D52: 0x6297, + 0x8D53: 0x62D8, + 0x8D54: 0x63A7, + 0x8D55: 0x653B, + 0x8D56: 0x6602, + 0x8D57: 0x6643, + 0x8D58: 0x66F4, + 0x8D59: 0x676D, + 0x8D5A: 0x6821, + 0x8D5B: 0x6897, + 0x8D5C: 0x69CB, + 0x8D5D: 0x6C5F, + 0x8D5E: 0x6D2A, + 0x8D5F: 0x6D69, + 0x8D60: 0x6E2F, + 0x8D61: 0x6E9D, + 0x8D62: 0x7532, + 0x8D63: 0x7687, + 0x8D64: 0x786C, + 0x8D65: 0x7A3F, + 0x8D66: 0x7CE0, + 0x8D67: 0x7D05, + 0x8D68: 0x7D18, + 0x8D69: 0x7D5E, + 0x8D6A: 0x7DB1, + 0x8D6B: 0x8015, + 0x8D6C: 0x8003, + 0x8D6D: 0x80AF, + 0x8D6E: 0x80B1, + 0x8D6F: 0x8154, + 0x8D70: 0x818F, + 0x8D71: 0x822A, + 0x8D72: 0x8352, + 0x8D73: 0x884C, + 0x8D74: 0x8861, + 0x8D75: 0x8B1B, + 0x8D76: 0x8CA2, + 0x8D77: 0x8CFC, + 0x8D78: 0x90CA, + 0x8D79: 0x9175, + 0x8D7A: 0x9271, + 0x8D7B: 0x783F, + 0x8D7C: 0x92FC, + 0x8D7D: 0x95A4, + 0x8D7E: 0x964D, + 0x8D80: 0x9805, + 0x8D81: 0x9999, + 0x8D82: 0x9AD8, + 0x8D83: 0x9D3B, + 0x8D84: 0x525B, + 0x8D85: 0x52AB, + 0x8D86: 0x53F7, + 0x8D87: 0x5408, + 0x8D88: 0x58D5, + 0x8D89: 0x62F7, + 0x8D8A: 0x6FE0, + 0x8D8B: 0x8C6A, + 0x8D8C: 0x8F5F, + 0x8D8D: 0x9EB9, + 0x8D8E: 0x514B, + 0x8D8F: 0x523B, + 0x8D90: 0x544A, + 0x8D91: 0x56FD, + 0x8D92: 0x7A40, + 0x8D93: 0x9177, + 0x8D94: 0x9D60, + 0x8D95: 0x9ED2, + 0x8D96: 0x7344, + 0x8D97: 0x6F09, + 0x8D98: 0x8170, + 0x8D99: 0x7511, + 0x8D9A: 0x5FFD, + 0x8D9B: 0x60DA, + 0x8D9C: 0x9AA8, + 0x8D9D: 0x72DB, + 0x8D9E: 0x8FBC, + 0x8D9F: 0x6B64, + 0x8DA0: 0x9803, + 0x8DA1: 0x4ECA, + 0x8DA2: 0x56F0, + 0x8DA3: 0x5764, + 0x8DA4: 0x58BE, + 0x8DA5: 0x5A5A, + 0x8DA6: 0x6068, + 0x8DA7: 0x61C7, + 0x8DA8: 0x660F, + 0x8DA9: 0x6606, + 0x8DAA: 0x6839, + 0x8DAB: 0x68B1, + 0x8DAC: 0x6DF7, + 0x8DAD: 0x75D5, + 0x8DAE: 0x7D3A, + 0x8DAF: 0x826E, + 0x8DB0: 0x9B42, + 0x8DB1: 0x4E9B, + 0x8DB2: 0x4F50, + 0x8DB3: 0x53C9, + 0x8DB4: 0x5506, + 0x8DB5: 0x5D6F, + 0x8DB6: 0x5DE6, + 0x8DB7: 0x5DEE, + 0x8DB8: 0x67FB, + 0x8DB9: 0x6C99, + 0x8DBA: 0x7473, + 0x8DBB: 0x7802, + 0x8DBC: 0x8A50, + 0x8DBD: 0x9396, + 0x8DBE: 0x88DF, + 0x8DBF: 0x5750, + 0x8DC0: 0x5EA7, + 0x8DC1: 0x632B, + 0x8DC2: 0x50B5, + 0x8DC3: 0x50AC, + 0x8DC4: 0x518D, + 0x8DC5: 0x6700, + 0x8DC6: 0x54C9, + 0x8DC7: 0x585E, + 0x8DC8: 0x59BB, + 0x8DC9: 0x5BB0, + 0x8DCA: 0x5F69, + 0x8DCB: 0x624D, + 0x8DCC: 0x63A1, + 0x8DCD: 0x683D, + 0x8DCE: 0x6B73, + 0x8DCF: 0x6E08, + 0x8DD0: 0x707D, + 0x8DD1: 0x91C7, + 0x8DD2: 0x7280, + 0x8DD3: 0x7815, + 0x8DD4: 0x7826, + 0x8DD5: 0x796D, + 0x8DD6: 0x658E, + 0x8DD7: 0x7D30, + 0x8DD8: 0x83DC, + 0x8DD9: 0x88C1, + 0x8DDA: 0x8F09, + 0x8DDB: 0x969B, + 0x8DDC: 0x5264, + 0x8DDD: 0x5728, + 0x8DDE: 0x6750, + 0x8DDF: 0x7F6A, + 0x8DE0: 0x8CA1, + 0x8DE1: 0x51B4, + 0x8DE2: 0x5742, + 0x8DE3: 0x962A, + 0x8DE4: 0x583A, + 0x8DE5: 0x698A, + 0x8DE6: 0x80B4, + 0x8DE7: 0x54B2, + 0x8DE8: 0x5D0E, + 0x8DE9: 0x57FC, + 0x8DEA: 0x7895, + 0x8DEB: 0x9DFA, + 0x8DEC: 0x4F5C, + 0x8DED: 0x524A, + 0x8DEE: 0x548B, + 0x8DEF: 0x643E, + 0x8DF0: 0x6628, + 0x8DF1: 0x6714, + 0x8DF2: 0x67F5, + 0x8DF3: 0x7A84, + 0x8DF4: 0x7B56, + 0x8DF5: 0x7D22, + 0x8DF6: 0x932F, + 0x8DF7: 0x685C, + 0x8DF8: 0x9BAD, + 0x8DF9: 0x7B39, + 0x8DFA: 0x5319, + 0x8DFB: 0x518A, + 0x8DFC: 0x5237, + 0x8E40: 0x5BDF, + 0x8E41: 0x62F6, + 0x8E42: 0x64AE, + 0x8E43: 0x64E6, + 0x8E44: 0x672D, + 0x8E45: 0x6BBA, + 0x8E46: 0x85A9, + 0x8E47: 0x96D1, + 0x8E48: 0x7690, + 0x8E49: 0x9BD6, + 0x8E4A: 0x634C, + 0x8E4B: 0x9306, + 0x8E4C: 0x9BAB, + 0x8E4D: 0x76BF, + 0x8E4E: 0x6652, + 0x8E4F: 0x4E09, + 0x8E50: 0x5098, + 0x8E51: 0x53C2, + 0x8E52: 0x5C71, + 0x8E53: 0x60E8, + 0x8E54: 0x6492, + 0x8E55: 0x6563, + 0x8E56: 0x685F, + 0x8E57: 0x71E6, + 0x8E58: 0x73CA, + 0x8E59: 0x7523, + 0x8E5A: 0x7B97, + 0x8E5B: 0x7E82, + 0x8E5C: 0x8695, + 0x8E5D: 0x8B83, + 0x8E5E: 0x8CDB, + 0x8E5F: 0x9178, + 0x8E60: 0x9910, + 0x8E61: 0x65AC, + 0x8E62: 0x66AB, + 0x8E63: 0x6B8B, + 0x8E64: 0x4ED5, + 0x8E65: 0x4ED4, + 0x8E66: 0x4F3A, + 0x8E67: 0x4F7F, + 0x8E68: 0x523A, + 0x8E69: 0x53F8, + 0x8E6A: 0x53F2, + 0x8E6B: 0x55E3, + 0x8E6C: 0x56DB, + 0x8E6D: 0x58EB, + 0x8E6E: 0x59CB, + 0x8E6F: 0x59C9, + 0x8E70: 0x59FF, + 0x8E71: 0x5B50, + 0x8E72: 0x5C4D, + 0x8E73: 0x5E02, + 0x8E74: 0x5E2B, + 0x8E75: 0x5FD7, + 0x8E76: 0x601D, + 0x8E77: 0x6307, + 0x8E78: 0x652F, + 0x8E79: 0x5B5C, + 0x8E7A: 0x65AF, + 0x8E7B: 0x65BD, + 0x8E7C: 0x65E8, + 0x8E7D: 0x679D, + 0x8E7E: 0x6B62, + 0x8E80: 0x6B7B, + 0x8E81: 0x6C0F, + 0x8E82: 0x7345, + 0x8E83: 0x7949, + 0x8E84: 0x79C1, + 0x8E85: 0x7CF8, + 0x8E86: 0x7D19, + 0x8E87: 0x7D2B, + 0x8E88: 0x80A2, + 0x8E89: 0x8102, + 0x8E8A: 0x81F3, + 0x8E8B: 0x8996, + 0x8E8C: 0x8A5E, + 0x8E8D: 0x8A69, + 0x8E8E: 0x8A66, + 0x8E8F: 0x8A8C, + 0x8E90: 0x8AEE, + 0x8E91: 0x8CC7, + 0x8E92: 0x8CDC, + 0x8E93: 0x96CC, + 0x8E94: 0x98FC, + 0x8E95: 0x6B6F, + 0x8E96: 0x4E8B, + 0x8E97: 0x4F3C, + 0x8E98: 0x4F8D, + 0x8E99: 0x5150, + 0x8E9A: 0x5B57, + 0x8E9B: 0x5BFA, + 0x8E9C: 0x6148, + 0x8E9D: 0x6301, + 0x8E9E: 0x6642, + 0x8E9F: 0x6B21, + 0x8EA0: 0x6ECB, + 0x8EA1: 0x6CBB, + 0x8EA2: 0x723E, + 0x8EA3: 0x74BD, + 0x8EA4: 0x75D4, + 0x8EA5: 0x78C1, + 0x8EA6: 0x793A, + 0x8EA7: 0x800C, + 0x8EA8: 0x8033, + 0x8EA9: 0x81EA, + 0x8EAA: 0x8494, + 0x8EAB: 0x8F9E, + 0x8EAC: 0x6C50, + 0x8EAD: 0x9E7F, + 0x8EAE: 0x5F0F, + 0x8EAF: 0x8B58, + 0x8EB0: 0x9D2B, + 0x8EB1: 0x7AFA, + 0x8EB2: 0x8EF8, + 0x8EB3: 0x5B8D, + 0x8EB4: 0x96EB, + 0x8EB5: 0x4E03, + 0x8EB6: 0x53F1, + 0x8EB7: 0x57F7, + 0x8EB8: 0x5931, + 0x8EB9: 0x5AC9, + 0x8EBA: 0x5BA4, + 0x8EBB: 0x6089, + 0x8EBC: 0x6E7F, + 0x8EBD: 0x6F06, + 0x8EBE: 0x75BE, + 0x8EBF: 0x8CEA, + 0x8EC0: 0x5B9F, + 0x8EC1: 0x8500, + 0x8EC2: 0x7BE0, + 0x8EC3: 0x5072, + 0x8EC4: 0x67F4, + 0x8EC5: 0x829D, + 0x8EC6: 0x5C61, + 0x8EC7: 0x854A, + 0x8EC8: 0x7E1E, + 0x8EC9: 0x820E, + 0x8ECA: 0x5199, + 0x8ECB: 0x5C04, + 0x8ECC: 0x6368, + 0x8ECD: 0x8D66, + 0x8ECE: 0x659C, + 0x8ECF: 0x716E, + 0x8ED0: 0x793E, + 0x8ED1: 0x7D17, + 0x8ED2: 0x8005, + 0x8ED3: 0x8B1D, + 0x8ED4: 0x8ECA, + 0x8ED5: 0x906E, + 0x8ED6: 0x86C7, + 0x8ED7: 0x90AA, + 0x8ED8: 0x501F, + 0x8ED9: 0x52FA, + 0x8EDA: 0x5C3A, + 0x8EDB: 0x6753, + 0x8EDC: 0x707C, + 0x8EDD: 0x7235, + 0x8EDE: 0x914C, + 0x8EDF: 0x91C8, + 0x8EE0: 0x932B, + 0x8EE1: 0x82E5, + 0x8EE2: 0x5BC2, + 0x8EE3: 0x5F31, + 0x8EE4: 0x60F9, + 0x8EE5: 0x4E3B, + 0x8EE6: 0x53D6, + 0x8EE7: 0x5B88, + 0x8EE8: 0x624B, + 0x8EE9: 0x6731, + 0x8EEA: 0x6B8A, + 0x8EEB: 0x72E9, + 0x8EEC: 0x73E0, + 0x8EED: 0x7A2E, + 0x8EEE: 0x816B, + 0x8EEF: 0x8DA3, + 0x8EF0: 0x9152, + 0x8EF1: 0x9996, + 0x8EF2: 0x5112, + 0x8EF3: 0x53D7, + 0x8EF4: 0x546A, + 0x8EF5: 0x5BFF, + 0x8EF6: 0x6388, + 0x8EF7: 0x6A39, + 0x8EF8: 0x7DAC, + 0x8EF9: 0x9700, + 0x8EFA: 0x56DA, + 0x8EFB: 0x53CE, + 0x8EFC: 0x5468, + 0x8F40: 0x5B97, + 0x8F41: 0x5C31, + 0x8F42: 0x5DDE, + 0x8F43: 0x4FEE, + 0x8F44: 0x6101, + 0x8F45: 0x62FE, + 0x8F46: 0x6D32, + 0x8F47: 0x79C0, + 0x8F48: 0x79CB, + 0x8F49: 0x7D42, + 0x8F4A: 0x7E4D, + 0x8F4B: 0x7FD2, + 0x8F4C: 0x81ED, + 0x8F4D: 0x821F, + 0x8F4E: 0x8490, + 0x8F4F: 0x8846, + 0x8F50: 0x8972, + 0x8F51: 0x8B90, + 0x8F52: 0x8E74, + 0x8F53: 0x8F2F, + 0x8F54: 0x9031, + 0x8F55: 0x914B, + 0x8F56: 0x916C, + 0x8F57: 0x96C6, + 0x8F58: 0x919C, + 0x8F59: 0x4EC0, + 0x8F5A: 0x4F4F, + 0x8F5B: 0x5145, + 0x8F5C: 0x5341, + 0x8F5D: 0x5F93, + 0x8F5E: 0x620E, + 0x8F5F: 0x67D4, + 0x8F60: 0x6C41, + 0x8F61: 0x6E0B, + 0x8F62: 0x7363, + 0x8F63: 0x7E26, + 0x8F64: 0x91CD, + 0x8F65: 0x9283, + 0x8F66: 0x53D4, + 0x8F67: 0x5919, + 0x8F68: 0x5BBF, + 0x8F69: 0x6DD1, + 0x8F6A: 0x795D, + 0x8F6B: 0x7E2E, + 0x8F6C: 0x7C9B, + 0x8F6D: 0x587E, + 0x8F6E: 0x719F, + 0x8F6F: 0x51FA, + 0x8F70: 0x8853, + 0x8F71: 0x8FF0, + 0x8F72: 0x4FCA, + 0x8F73: 0x5CFB, + 0x8F74: 0x6625, + 0x8F75: 0x77AC, + 0x8F76: 0x7AE3, + 0x8F77: 0x821C, + 0x8F78: 0x99FF, + 0x8F79: 0x51C6, + 0x8F7A: 0x5FAA, + 0x8F7B: 0x65EC, + 0x8F7C: 0x696F, + 0x8F7D: 0x6B89, + 0x8F7E: 0x6DF3, + 0x8F80: 0x6E96, + 0x8F81: 0x6F64, + 0x8F82: 0x76FE, + 0x8F83: 0x7D14, + 0x8F84: 0x5DE1, + 0x8F85: 0x9075, + 0x8F86: 0x9187, + 0x8F87: 0x9806, + 0x8F88: 0x51E6, + 0x8F89: 0x521D, + 0x8F8A: 0x6240, + 0x8F8B: 0x6691, + 0x8F8C: 0x66D9, + 0x8F8D: 0x6E1A, + 0x8F8E: 0x5EB6, + 0x8F8F: 0x7DD2, + 0x8F90: 0x7F72, + 0x8F91: 0x66F8, + 0x8F92: 0x85AF, + 0x8F93: 0x85F7, + 0x8F94: 0x8AF8, + 0x8F95: 0x52A9, + 0x8F96: 0x53D9, + 0x8F97: 0x5973, + 0x8F98: 0x5E8F, + 0x8F99: 0x5F90, + 0x8F9A: 0x6055, + 0x8F9B: 0x92E4, + 0x8F9C: 0x9664, + 0x8F9D: 0x50B7, + 0x8F9E: 0x511F, + 0x8F9F: 0x52DD, + 0x8FA0: 0x5320, + 0x8FA1: 0x5347, + 0x8FA2: 0x53EC, + 0x8FA3: 0x54E8, + 0x8FA4: 0x5546, + 0x8FA5: 0x5531, + 0x8FA6: 0x5617, + 0x8FA7: 0x5968, + 0x8FA8: 0x59BE, + 0x8FA9: 0x5A3C, + 0x8FAA: 0x5BB5, + 0x8FAB: 0x5C06, + 0x8FAC: 0x5C0F, + 0x8FAD: 0x5C11, + 0x8FAE: 0x5C1A, + 0x8FAF: 0x5E84, + 0x8FB0: 0x5E8A, + 0x8FB1: 0x5EE0, + 0x8FB2: 0x5F70, + 0x8FB3: 0x627F, + 0x8FB4: 0x6284, + 0x8FB5: 0x62DB, + 0x8FB6: 0x638C, + 0x8FB7: 0x6377, + 0x8FB8: 0x6607, + 0x8FB9: 0x660C, + 0x8FBA: 0x662D, + 0x8FBB: 0x6676, + 0x8FBC: 0x677E, + 0x8FBD: 0x68A2, + 0x8FBE: 0x6A1F, + 0x8FBF: 0x6A35, + 0x8FC0: 0x6CBC, + 0x8FC1: 0x6D88, + 0x8FC2: 0x6E09, + 0x8FC3: 0x6E58, + 0x8FC4: 0x713C, + 0x8FC5: 0x7126, + 0x8FC6: 0x7167, + 0x8FC7: 0x75C7, + 0x8FC8: 0x7701, + 0x8FC9: 0x785D, + 0x8FCA: 0x7901, + 0x8FCB: 0x7965, + 0x8FCC: 0x79F0, + 0x8FCD: 0x7AE0, + 0x8FCE: 0x7B11, + 0x8FCF: 0x7CA7, + 0x8FD0: 0x7D39, + 0x8FD1: 0x8096, + 0x8FD2: 0x83D6, + 0x8FD3: 0x848B, + 0x8FD4: 0x8549, + 0x8FD5: 0x885D, + 0x8FD6: 0x88F3, + 0x8FD7: 0x8A1F, + 0x8FD8: 0x8A3C, + 0x8FD9: 0x8A54, + 0x8FDA: 0x8A73, + 0x8FDB: 0x8C61, + 0x8FDC: 0x8CDE, + 0x8FDD: 0x91A4, + 0x8FDE: 0x9266, + 0x8FDF: 0x937E, + 0x8FE0: 0x9418, + 0x8FE1: 0x969C, + 0x8FE2: 0x9798, + 0x8FE3: 0x4E0A, + 0x8FE4: 0x4E08, + 0x8FE5: 0x4E1E, + 0x8FE6: 0x4E57, + 0x8FE7: 0x5197, + 0x8FE8: 0x5270, + 0x8FE9: 0x57CE, + 0x8FEA: 0x5834, + 0x8FEB: 0x58CC, + 0x8FEC: 0x5B22, + 0x8FED: 0x5E38, + 0x8FEE: 0x60C5, + 0x8FEF: 0x64FE, + 0x8FF0: 0x6761, + 0x8FF1: 0x6756, + 0x8FF2: 0x6D44, + 0x8FF3: 0x72B6, + 0x8FF4: 0x7573, + 0x8FF5: 0x7A63, + 0x8FF6: 0x84B8, + 0x8FF7: 0x8B72, + 0x8FF8: 0x91B8, + 0x8FF9: 0x9320, + 0x8FFA: 0x5631, + 0x8FFB: 0x57F4, + 0x8FFC: 0x98FE, + 0x9040: 0x62ED, + 0x9041: 0x690D, + 0x9042: 0x6B96, + 0x9043: 0x71ED, + 0x9044: 0x7E54, + 0x9045: 0x8077, + 0x9046: 0x8272, + 0x9047: 0x89E6, + 0x9048: 0x98DF, + 0x9049: 0x8755, + 0x904A: 0x8FB1, + 0x904B: 0x5C3B, + 0x904C: 0x4F38, + 0x904D: 0x4FE1, + 0x904E: 0x4FB5, + 0x904F: 0x5507, + 0x9050: 0x5A20, + 0x9051: 0x5BDD, + 0x9052: 0x5BE9, + 0x9053: 0x5FC3, + 0x9054: 0x614E, + 0x9055: 0x632F, + 0x9056: 0x65B0, + 0x9057: 0x664B, + 0x9058: 0x68EE, + 0x9059: 0x699B, + 0x905A: 0x6D78, + 0x905B: 0x6DF1, + 0x905C: 0x7533, + 0x905D: 0x75B9, + 0x905E: 0x771F, + 0x905F: 0x795E, + 0x9060: 0x79E6, + 0x9061: 0x7D33, + 0x9062: 0x81E3, + 0x9063: 0x82AF, + 0x9064: 0x85AA, + 0x9065: 0x89AA, + 0x9066: 0x8A3A, + 0x9067: 0x8EAB, + 0x9068: 0x8F9B, + 0x9069: 0x9032, + 0x906A: 0x91DD, + 0x906B: 0x9707, + 0x906C: 0x4EBA, + 0x906D: 0x4EC1, + 0x906E: 0x5203, + 0x906F: 0x5875, + 0x9070: 0x58EC, + 0x9071: 0x5C0B, + 0x9072: 0x751A, + 0x9073: 0x5C3D, + 0x9074: 0x814E, + 0x9075: 0x8A0A, + 0x9076: 0x8FC5, + 0x9077: 0x9663, + 0x9078: 0x976D, + 0x9079: 0x7B25, + 0x907A: 0x8ACF, + 0x907B: 0x9808, + 0x907C: 0x9162, + 0x907D: 0x56F3, + 0x907E: 0x53A8, + 0x9080: 0x9017, + 0x9081: 0x5439, + 0x9082: 0x5782, + 0x9083: 0x5E25, + 0x9084: 0x63A8, + 0x9085: 0x6C34, + 0x9086: 0x708A, + 0x9087: 0x7761, + 0x9088: 0x7C8B, + 0x9089: 0x7FE0, + 0x908A: 0x8870, + 0x908B: 0x9042, + 0x908C: 0x9154, + 0x908D: 0x9310, + 0x908E: 0x9318, + 0x908F: 0x968F, + 0x9090: 0x745E, + 0x9091: 0x9AC4, + 0x9092: 0x5D07, + 0x9093: 0x5D69, + 0x9094: 0x6570, + 0x9095: 0x67A2, + 0x9096: 0x8DA8, + 0x9097: 0x96DB, + 0x9098: 0x636E, + 0x9099: 0x6749, + 0x909A: 0x6919, + 0x909B: 0x83C5, + 0x909C: 0x9817, + 0x909D: 0x96C0, + 0x909E: 0x88FE, + 0x909F: 0x6F84, + 0x90A0: 0x647A, + 0x90A1: 0x5BF8, + 0x90A2: 0x4E16, + 0x90A3: 0x702C, + 0x90A4: 0x755D, + 0x90A5: 0x662F, + 0x90A6: 0x51C4, + 0x90A7: 0x5236, + 0x90A8: 0x52E2, + 0x90A9: 0x59D3, + 0x90AA: 0x5F81, + 0x90AB: 0x6027, + 0x90AC: 0x6210, + 0x90AD: 0x653F, + 0x90AE: 0x6574, + 0x90AF: 0x661F, + 0x90B0: 0x6674, + 0x90B1: 0x68F2, + 0x90B2: 0x6816, + 0x90B3: 0x6B63, + 0x90B4: 0x6E05, + 0x90B5: 0x7272, + 0x90B6: 0x751F, + 0x90B7: 0x76DB, + 0x90B8: 0x7CBE, + 0x90B9: 0x8056, + 0x90BA: 0x58F0, + 0x90BB: 0x88FD, + 0x90BC: 0x897F, + 0x90BD: 0x8AA0, + 0x90BE: 0x8A93, + 0x90BF: 0x8ACB, + 0x90C0: 0x901D, + 0x90C1: 0x9192, + 0x90C2: 0x9752, + 0x90C3: 0x9759, + 0x90C4: 0x6589, + 0x90C5: 0x7A0E, + 0x90C6: 0x8106, + 0x90C7: 0x96BB, + 0x90C8: 0x5E2D, + 0x90C9: 0x60DC, + 0x90CA: 0x621A, + 0x90CB: 0x65A5, + 0x90CC: 0x6614, + 0x90CD: 0x6790, + 0x90CE: 0x77F3, + 0x90CF: 0x7A4D, + 0x90D0: 0x7C4D, + 0x90D1: 0x7E3E, + 0x90D2: 0x810A, + 0x90D3: 0x8CAC, + 0x90D4: 0x8D64, + 0x90D5: 0x8DE1, + 0x90D6: 0x8E5F, + 0x90D7: 0x78A9, + 0x90D8: 0x5207, + 0x90D9: 0x62D9, + 0x90DA: 0x63A5, + 0x90DB: 0x6442, + 0x90DC: 0x6298, + 0x90DD: 0x8A2D, + 0x90DE: 0x7A83, + 0x90DF: 0x7BC0, + 0x90E0: 0x8AAC, + 0x90E1: 0x96EA, + 0x90E2: 0x7D76, + 0x90E3: 0x820C, + 0x90E4: 0x8749, + 0x90E5: 0x4ED9, + 0x90E6: 0x5148, + 0x90E7: 0x5343, + 0x90E8: 0x5360, + 0x90E9: 0x5BA3, + 0x90EA: 0x5C02, + 0x90EB: 0x5C16, + 0x90EC: 0x5DDD, + 0x90ED: 0x6226, + 0x90EE: 0x6247, + 0x90EF: 0x64B0, + 0x90F0: 0x6813, + 0x90F1: 0x6834, + 0x90F2: 0x6CC9, + 0x90F3: 0x6D45, + 0x90F4: 0x6D17, + 0x90F5: 0x67D3, + 0x90F6: 0x6F5C, + 0x90F7: 0x714E, + 0x90F8: 0x717D, + 0x90F9: 0x65CB, + 0x90FA: 0x7A7F, + 0x90FB: 0x7BAD, + 0x90FC: 0x7DDA, + 0x9140: 0x7E4A, + 0x9141: 0x7FA8, + 0x9142: 0x817A, + 0x9143: 0x821B, + 0x9144: 0x8239, + 0x9145: 0x85A6, + 0x9146: 0x8A6E, + 0x9147: 0x8CCE, + 0x9148: 0x8DF5, + 0x9149: 0x9078, + 0x914A: 0x9077, + 0x914B: 0x92AD, + 0x914C: 0x9291, + 0x914D: 0x9583, + 0x914E: 0x9BAE, + 0x914F: 0x524D, + 0x9150: 0x5584, + 0x9151: 0x6F38, + 0x9152: 0x7136, + 0x9153: 0x5168, + 0x9154: 0x7985, + 0x9155: 0x7E55, + 0x9156: 0x81B3, + 0x9157: 0x7CCE, + 0x9158: 0x564C, + 0x9159: 0x5851, + 0x915A: 0x5CA8, + 0x915B: 0x63AA, + 0x915C: 0x66FE, + 0x915D: 0x66FD, + 0x915E: 0x695A, + 0x915F: 0x72D9, + 0x9160: 0x758F, + 0x9161: 0x758E, + 0x9162: 0x790E, + 0x9163: 0x7956, + 0x9164: 0x79DF, + 0x9165: 0x7C97, + 0x9166: 0x7D20, + 0x9167: 0x7D44, + 0x9168: 0x8607, + 0x9169: 0x8A34, + 0x916A: 0x963B, + 0x916B: 0x9061, + 0x916C: 0x9F20, + 0x916D: 0x50E7, + 0x916E: 0x5275, + 0x916F: 0x53CC, + 0x9170: 0x53E2, + 0x9171: 0x5009, + 0x9172: 0x55AA, + 0x9173: 0x58EE, + 0x9174: 0x594F, + 0x9175: 0x723D, + 0x9176: 0x5B8B, + 0x9177: 0x5C64, + 0x9178: 0x531D, + 0x9179: 0x60E3, + 0x917A: 0x60F3, + 0x917B: 0x635C, + 0x917C: 0x6383, + 0x917D: 0x633F, + 0x917E: 0x63BB, + 0x9180: 0x64CD, + 0x9181: 0x65E9, + 0x9182: 0x66F9, + 0x9183: 0x5DE3, + 0x9184: 0x69CD, + 0x9185: 0x69FD, + 0x9186: 0x6F15, + 0x9187: 0x71E5, + 0x9188: 0x4E89, + 0x9189: 0x75E9, + 0x918A: 0x76F8, + 0x918B: 0x7A93, + 0x918C: 0x7CDF, + 0x918D: 0x7DCF, + 0x918E: 0x7D9C, + 0x918F: 0x8061, + 0x9190: 0x8349, + 0x9191: 0x8358, + 0x9192: 0x846C, + 0x9193: 0x84BC, + 0x9194: 0x85FB, + 0x9195: 0x88C5, + 0x9196: 0x8D70, + 0x9197: 0x9001, + 0x9198: 0x906D, + 0x9199: 0x9397, + 0x919A: 0x971C, + 0x919B: 0x9A12, + 0x919C: 0x50CF, + 0x919D: 0x5897, + 0x919E: 0x618E, + 0x919F: 0x81D3, + 0x91A0: 0x8535, + 0x91A1: 0x8D08, + 0x91A2: 0x9020, + 0x91A3: 0x4FC3, + 0x91A4: 0x5074, + 0x91A5: 0x5247, + 0x91A6: 0x5373, + 0x91A7: 0x606F, + 0x91A8: 0x6349, + 0x91A9: 0x675F, + 0x91AA: 0x6E2C, + 0x91AB: 0x8DB3, + 0x91AC: 0x901F, + 0x91AD: 0x4FD7, + 0x91AE: 0x5C5E, + 0x91AF: 0x8CCA, + 0x91B0: 0x65CF, + 0x91B1: 0x7D9A, + 0x91B2: 0x5352, + 0x91B3: 0x8896, + 0x91B4: 0x5176, + 0x91B5: 0x63C3, + 0x91B6: 0x5B58, + 0x91B7: 0x5B6B, + 0x91B8: 0x5C0A, + 0x91B9: 0x640D, + 0x91BA: 0x6751, + 0x91BB: 0x905C, + 0x91BC: 0x4ED6, + 0x91BD: 0x591A, + 0x91BE: 0x592A, + 0x91BF: 0x6C70, + 0x91C0: 0x8A51, + 0x91C1: 0x553E, + 0x91C2: 0x5815, + 0x91C3: 0x59A5, + 0x91C4: 0x60F0, + 0x91C5: 0x6253, + 0x91C6: 0x67C1, + 0x91C7: 0x8235, + 0x91C8: 0x6955, + 0x91C9: 0x9640, + 0x91CA: 0x99C4, + 0x91CB: 0x9A28, + 0x91CC: 0x4F53, + 0x91CD: 0x5806, + 0x91CE: 0x5BFE, + 0x91CF: 0x8010, + 0x91D0: 0x5CB1, + 0x91D1: 0x5E2F, + 0x91D2: 0x5F85, + 0x91D3: 0x6020, + 0x91D4: 0x614B, + 0x91D5: 0x6234, + 0x91D6: 0x66FF, + 0x91D7: 0x6CF0, + 0x91D8: 0x6EDE, + 0x91D9: 0x80CE, + 0x91DA: 0x817F, + 0x91DB: 0x82D4, + 0x91DC: 0x888B, + 0x91DD: 0x8CB8, + 0x91DE: 0x9000, + 0x91DF: 0x902E, + 0x91E0: 0x968A, + 0x91E1: 0x9EDB, + 0x91E2: 0x9BDB, + 0x91E3: 0x4EE3, + 0x91E4: 0x53F0, + 0x91E5: 0x5927, + 0x91E6: 0x7B2C, + 0x91E7: 0x918D, + 0x91E8: 0x984C, + 0x91E9: 0x9DF9, + 0x91EA: 0x6EDD, + 0x91EB: 0x7027, + 0x91EC: 0x5353, + 0x91ED: 0x5544, + 0x91EE: 0x5B85, + 0x91EF: 0x6258, + 0x91F0: 0x629E, + 0x91F1: 0x62D3, + 0x91F2: 0x6CA2, + 0x91F3: 0x6FEF, + 0x91F4: 0x7422, + 0x91F5: 0x8A17, + 0x91F6: 0x9438, + 0x91F7: 0x6FC1, + 0x91F8: 0x8AFE, + 0x91F9: 0x8338, + 0x91FA: 0x51E7, + 0x91FB: 0x86F8, + 0x91FC: 0x53EA, + 0x9240: 0x53E9, + 0x9241: 0x4F46, + 0x9242: 0x9054, + 0x9243: 0x8FB0, + 0x9244: 0x596A, + 0x9245: 0x8131, + 0x9246: 0x5DFD, + 0x9247: 0x7AEA, + 0x9248: 0x8FBF, + 0x9249: 0x68DA, + 0x924A: 0x8C37, + 0x924B: 0x72F8, + 0x924C: 0x9C48, + 0x924D: 0x6A3D, + 0x924E: 0x8AB0, + 0x924F: 0x4E39, + 0x9250: 0x5358, + 0x9251: 0x5606, + 0x9252: 0x5766, + 0x9253: 0x62C5, + 0x9254: 0x63A2, + 0x9255: 0x65E6, + 0x9256: 0x6B4E, + 0x9257: 0x6DE1, + 0x9258: 0x6E5B, + 0x9259: 0x70AD, + 0x925A: 0x77ED, + 0x925B: 0x7AEF, + 0x925C: 0x7BAA, + 0x925D: 0x7DBB, + 0x925E: 0x803D, + 0x925F: 0x80C6, + 0x9260: 0x86CB, + 0x9261: 0x8A95, + 0x9262: 0x935B, + 0x9263: 0x56E3, + 0x9264: 0x58C7, + 0x9265: 0x5F3E, + 0x9266: 0x65AD, + 0x9267: 0x6696, + 0x9268: 0x6A80, + 0x9269: 0x6BB5, + 0x926A: 0x7537, + 0x926B: 0x8AC7, + 0x926C: 0x5024, + 0x926D: 0x77E5, + 0x926E: 0x5730, + 0x926F: 0x5F1B, + 0x9270: 0x6065, + 0x9271: 0x667A, + 0x9272: 0x6C60, + 0x9273: 0x75F4, + 0x9274: 0x7A1A, + 0x9275: 0x7F6E, + 0x9276: 0x81F4, + 0x9277: 0x8718, + 0x9278: 0x9045, + 0x9279: 0x99B3, + 0x927A: 0x7BC9, + 0x927B: 0x755C, + 0x927C: 0x7AF9, + 0x927D: 0x7B51, + 0x927E: 0x84C4, + 0x9280: 0x9010, + 0x9281: 0x79E9, + 0x9282: 0x7A92, + 0x9283: 0x8336, + 0x9284: 0x5AE1, + 0x9285: 0x7740, + 0x9286: 0x4E2D, + 0x9287: 0x4EF2, + 0x9288: 0x5B99, + 0x9289: 0x5FE0, + 0x928A: 0x62BD, + 0x928B: 0x663C, + 0x928C: 0x67F1, + 0x928D: 0x6CE8, + 0x928E: 0x866B, + 0x928F: 0x8877, + 0x9290: 0x8A3B, + 0x9291: 0x914E, + 0x9292: 0x92F3, + 0x9293: 0x99D0, + 0x9294: 0x6A17, + 0x9295: 0x7026, + 0x9296: 0x732A, + 0x9297: 0x82E7, + 0x9298: 0x8457, + 0x9299: 0x8CAF, + 0x929A: 0x4E01, + 0x929B: 0x5146, + 0x929C: 0x51CB, + 0x929D: 0x558B, + 0x929E: 0x5BF5, + 0x929F: 0x5E16, + 0x92A0: 0x5E33, + 0x92A1: 0x5E81, + 0x92A2: 0x5F14, + 0x92A3: 0x5F35, + 0x92A4: 0x5F6B, + 0x92A5: 0x5FB4, + 0x92A6: 0x61F2, + 0x92A7: 0x6311, + 0x92A8: 0x66A2, + 0x92A9: 0x671D, + 0x92AA: 0x6F6E, + 0x92AB: 0x7252, + 0x92AC: 0x753A, + 0x92AD: 0x773A, + 0x92AE: 0x8074, + 0x92AF: 0x8139, + 0x92B0: 0x8178, + 0x92B1: 0x8776, + 0x92B2: 0x8ABF, + 0x92B3: 0x8ADC, + 0x92B4: 0x8D85, + 0x92B5: 0x8DF3, + 0x92B6: 0x929A, + 0x92B7: 0x9577, + 0x92B8: 0x9802, + 0x92B9: 0x9CE5, + 0x92BA: 0x52C5, + 0x92BB: 0x6357, + 0x92BC: 0x76F4, + 0x92BD: 0x6715, + 0x92BE: 0x6C88, + 0x92BF: 0x73CD, + 0x92C0: 0x8CC3, + 0x92C1: 0x93AE, + 0x92C2: 0x9673, + 0x92C3: 0x6D25, + 0x92C4: 0x589C, + 0x92C5: 0x690E, + 0x92C6: 0x69CC, + 0x92C7: 0x8FFD, + 0x92C8: 0x939A, + 0x92C9: 0x75DB, + 0x92CA: 0x901A, + 0x92CB: 0x585A, + 0x92CC: 0x6802, + 0x92CD: 0x63B4, + 0x92CE: 0x69FB, + 0x92CF: 0x4F43, + 0x92D0: 0x6F2C, + 0x92D1: 0x67D8, + 0x92D2: 0x8FBB, + 0x92D3: 0x8526, + 0x92D4: 0x7DB4, + 0x92D5: 0x9354, + 0x92D6: 0x693F, + 0x92D7: 0x6F70, + 0x92D8: 0x576A, + 0x92D9: 0x58F7, + 0x92DA: 0x5B2C, + 0x92DB: 0x7D2C, + 0x92DC: 0x722A, + 0x92DD: 0x540A, + 0x92DE: 0x91E3, + 0x92DF: 0x9DB4, + 0x92E0: 0x4EAD, + 0x92E1: 0x4F4E, + 0x92E2: 0x505C, + 0x92E3: 0x5075, + 0x92E4: 0x5243, + 0x92E5: 0x8C9E, + 0x92E6: 0x5448, + 0x92E7: 0x5824, + 0x92E8: 0x5B9A, + 0x92E9: 0x5E1D, + 0x92EA: 0x5E95, + 0x92EB: 0x5EAD, + 0x92EC: 0x5EF7, + 0x92ED: 0x5F1F, + 0x92EE: 0x608C, + 0x92EF: 0x62B5, + 0x92F0: 0x633A, + 0x92F1: 0x63D0, + 0x92F2: 0x68AF, + 0x92F3: 0x6C40, + 0x92F4: 0x7887, + 0x92F5: 0x798E, + 0x92F6: 0x7A0B, + 0x92F7: 0x7DE0, + 0x92F8: 0x8247, + 0x92F9: 0x8A02, + 0x92FA: 0x8AE6, + 0x92FB: 0x8E44, + 0x92FC: 0x9013, + 0x9340: 0x90B8, + 0x9341: 0x912D, + 0x9342: 0x91D8, + 0x9343: 0x9F0E, + 0x9344: 0x6CE5, + 0x9345: 0x6458, + 0x9346: 0x64E2, + 0x9347: 0x6575, + 0x9348: 0x6EF4, + 0x9349: 0x7684, + 0x934A: 0x7B1B, + 0x934B: 0x9069, + 0x934C: 0x93D1, + 0x934D: 0x6EBA, + 0x934E: 0x54F2, + 0x934F: 0x5FB9, + 0x9350: 0x64A4, + 0x9351: 0x8F4D, + 0x9352: 0x8FED, + 0x9353: 0x9244, + 0x9354: 0x5178, + 0x9355: 0x586B, + 0x9356: 0x5929, + 0x9357: 0x5C55, + 0x9358: 0x5E97, + 0x9359: 0x6DFB, + 0x935A: 0x7E8F, + 0x935B: 0x751C, + 0x935C: 0x8CBC, + 0x935D: 0x8EE2, + 0x935E: 0x985B, + 0x935F: 0x70B9, + 0x9360: 0x4F1D, + 0x9361: 0x6BBF, + 0x9362: 0x6FB1, + 0x9363: 0x7530, + 0x9364: 0x96FB, + 0x9365: 0x514E, + 0x9366: 0x5410, + 0x9367: 0x5835, + 0x9368: 0x5857, + 0x9369: 0x59AC, + 0x936A: 0x5C60, + 0x936B: 0x5F92, + 0x936C: 0x6597, + 0x936D: 0x675C, + 0x936E: 0x6E21, + 0x936F: 0x767B, + 0x9370: 0x83DF, + 0x9371: 0x8CED, + 0x9372: 0x9014, + 0x9373: 0x90FD, + 0x9374: 0x934D, + 0x9375: 0x7825, + 0x9376: 0x783A, + 0x9377: 0x52AA, + 0x9378: 0x5EA6, + 0x9379: 0x571F, + 0x937A: 0x5974, + 0x937B: 0x6012, + 0x937C: 0x5012, + 0x937D: 0x515A, + 0x937E: 0x51AC, + 0x9380: 0x51CD, + 0x9381: 0x5200, + 0x9382: 0x5510, + 0x9383: 0x5854, + 0x9384: 0x5858, + 0x9385: 0x5957, + 0x9386: 0x5B95, + 0x9387: 0x5CF6, + 0x9388: 0x5D8B, + 0x9389: 0x60BC, + 0x938A: 0x6295, + 0x938B: 0x642D, + 0x938C: 0x6771, + 0x938D: 0x6843, + 0x938E: 0x68BC, + 0x938F: 0x68DF, + 0x9390: 0x76D7, + 0x9391: 0x6DD8, + 0x9392: 0x6E6F, + 0x9393: 0x6D9B, + 0x9394: 0x706F, + 0x9395: 0x71C8, + 0x9396: 0x5F53, + 0x9397: 0x75D8, + 0x9398: 0x7977, + 0x9399: 0x7B49, + 0x939A: 0x7B54, + 0x939B: 0x7B52, + 0x939C: 0x7CD6, + 0x939D: 0x7D71, + 0x939E: 0x5230, + 0x939F: 0x8463, + 0x93A0: 0x8569, + 0x93A1: 0x85E4, + 0x93A2: 0x8A0E, + 0x93A3: 0x8B04, + 0x93A4: 0x8C46, + 0x93A5: 0x8E0F, + 0x93A6: 0x9003, + 0x93A7: 0x900F, + 0x93A8: 0x9419, + 0x93A9: 0x9676, + 0x93AA: 0x982D, + 0x93AB: 0x9A30, + 0x93AC: 0x95D8, + 0x93AD: 0x50CD, + 0x93AE: 0x52D5, + 0x93AF: 0x540C, + 0x93B0: 0x5802, + 0x93B1: 0x5C0E, + 0x93B2: 0x61A7, + 0x93B3: 0x649E, + 0x93B4: 0x6D1E, + 0x93B5: 0x77B3, + 0x93B6: 0x7AE5, + 0x93B7: 0x80F4, + 0x93B8: 0x8404, + 0x93B9: 0x9053, + 0x93BA: 0x9285, + 0x93BB: 0x5CE0, + 0x93BC: 0x9D07, + 0x93BD: 0x533F, + 0x93BE: 0x5F97, + 0x93BF: 0x5FB3, + 0x93C0: 0x6D9C, + 0x93C1: 0x7279, + 0x93C2: 0x7763, + 0x93C3: 0x79BF, + 0x93C4: 0x7BE4, + 0x93C5: 0x6BD2, + 0x93C6: 0x72EC, + 0x93C7: 0x8AAD, + 0x93C8: 0x6803, + 0x93C9: 0x6A61, + 0x93CA: 0x51F8, + 0x93CB: 0x7A81, + 0x93CC: 0x6934, + 0x93CD: 0x5C4A, + 0x93CE: 0x9CF6, + 0x93CF: 0x82EB, + 0x93D0: 0x5BC5, + 0x93D1: 0x9149, + 0x93D2: 0x701E, + 0x93D3: 0x5678, + 0x93D4: 0x5C6F, + 0x93D5: 0x60C7, + 0x93D6: 0x6566, + 0x93D7: 0x6C8C, + 0x93D8: 0x8C5A, + 0x93D9: 0x9041, + 0x93DA: 0x9813, + 0x93DB: 0x5451, + 0x93DC: 0x66C7, + 0x93DD: 0x920D, + 0x93DE: 0x5948, + 0x93DF: 0x90A3, + 0x93E0: 0x5185, + 0x93E1: 0x4E4D, + 0x93E2: 0x51EA, + 0x93E3: 0x8599, + 0x93E4: 0x8B0E, + 0x93E5: 0x7058, + 0x93E6: 0x637A, + 0x93E7: 0x934B, + 0x93E8: 0x6962, + 0x93E9: 0x99B4, + 0x93EA: 0x7E04, + 0x93EB: 0x7577, + 0x93EC: 0x5357, + 0x93ED: 0x6960, + 0x93EE: 0x8EDF, + 0x93EF: 0x96E3, + 0x93F0: 0x6C5D, + 0x93F1: 0x4E8C, + 0x93F2: 0x5C3C, + 0x93F3: 0x5F10, + 0x93F4: 0x8FE9, + 0x93F5: 0x5302, + 0x93F6: 0x8CD1, + 0x93F7: 0x8089, + 0x93F8: 0x8679, + 0x93F9: 0x5EFF, + 0x93FA: 0x65E5, + 0x93FB: 0x4E73, + 0x93FC: 0x5165, + 0x9440: 0x5982, + 0x9441: 0x5C3F, + 0x9442: 0x97EE, + 0x9443: 0x4EFB, + 0x9444: 0x598A, + 0x9445: 0x5FCD, + 0x9446: 0x8A8D, + 0x9447: 0x6FE1, + 0x9448: 0x79B0, + 0x9449: 0x7962, + 0x944A: 0x5BE7, + 0x944B: 0x8471, + 0x944C: 0x732B, + 0x944D: 0x71B1, + 0x944E: 0x5E74, + 0x944F: 0x5FF5, + 0x9450: 0x637B, + 0x9451: 0x649A, + 0x9452: 0x71C3, + 0x9453: 0x7C98, + 0x9454: 0x4E43, + 0x9455: 0x5EFC, + 0x9456: 0x4E4B, + 0x9457: 0x57DC, + 0x9458: 0x56A2, + 0x9459: 0x60A9, + 0x945A: 0x6FC3, + 0x945B: 0x7D0D, + 0x945C: 0x80FD, + 0x945D: 0x8133, + 0x945E: 0x81BF, + 0x945F: 0x8FB2, + 0x9460: 0x8997, + 0x9461: 0x86A4, + 0x9462: 0x5DF4, + 0x9463: 0x628A, + 0x9464: 0x64AD, + 0x9465: 0x8987, + 0x9466: 0x6777, + 0x9467: 0x6CE2, + 0x9468: 0x6D3E, + 0x9469: 0x7436, + 0x946A: 0x7834, + 0x946B: 0x5A46, + 0x946C: 0x7F75, + 0x946D: 0x82AD, + 0x946E: 0x99AC, + 0x946F: 0x4FF3, + 0x9470: 0x5EC3, + 0x9471: 0x62DD, + 0x9472: 0x6392, + 0x9473: 0x6557, + 0x9474: 0x676F, + 0x9475: 0x76C3, + 0x9476: 0x724C, + 0x9477: 0x80CC, + 0x9478: 0x80BA, + 0x9479: 0x8F29, + 0x947A: 0x914D, + 0x947B: 0x500D, + 0x947C: 0x57F9, + 0x947D: 0x5A92, + 0x947E: 0x6885, + 0x9480: 0x6973, + 0x9481: 0x7164, + 0x9482: 0x72FD, + 0x9483: 0x8CB7, + 0x9484: 0x58F2, + 0x9485: 0x8CE0, + 0x9486: 0x966A, + 0x9487: 0x9019, + 0x9488: 0x877F, + 0x9489: 0x79E4, + 0x948A: 0x77E7, + 0x948B: 0x8429, + 0x948C: 0x4F2F, + 0x948D: 0x5265, + 0x948E: 0x535A, + 0x948F: 0x62CD, + 0x9490: 0x67CF, + 0x9491: 0x6CCA, + 0x9492: 0x767D, + 0x9493: 0x7B94, + 0x9494: 0x7C95, + 0x9495: 0x8236, + 0x9496: 0x8584, + 0x9497: 0x8FEB, + 0x9498: 0x66DD, + 0x9499: 0x6F20, + 0x949A: 0x7206, + 0x949B: 0x7E1B, + 0x949C: 0x83AB, + 0x949D: 0x99C1, + 0x949E: 0x9EA6, + 0x949F: 0x51FD, + 0x94A0: 0x7BB1, + 0x94A1: 0x7872, + 0x94A2: 0x7BB8, + 0x94A3: 0x8087, + 0x94A4: 0x7B48, + 0x94A5: 0x6AE8, + 0x94A6: 0x5E61, + 0x94A7: 0x808C, + 0x94A8: 0x7551, + 0x94A9: 0x7560, + 0x94AA: 0x516B, + 0x94AB: 0x9262, + 0x94AC: 0x6E8C, + 0x94AD: 0x767A, + 0x94AE: 0x9197, + 0x94AF: 0x9AEA, + 0x94B0: 0x4F10, + 0x94B1: 0x7F70, + 0x94B2: 0x629C, + 0x94B3: 0x7B4F, + 0x94B4: 0x95A5, + 0x94B5: 0x9CE9, + 0x94B6: 0x567A, + 0x94B7: 0x5859, + 0x94B8: 0x86E4, + 0x94B9: 0x96BC, + 0x94BA: 0x4F34, + 0x94BB: 0x5224, + 0x94BC: 0x534A, + 0x94BD: 0x53CD, + 0x94BE: 0x53DB, + 0x94BF: 0x5E06, + 0x94C0: 0x642C, + 0x94C1: 0x6591, + 0x94C2: 0x677F, + 0x94C3: 0x6C3E, + 0x94C4: 0x6C4E, + 0x94C5: 0x7248, + 0x94C6: 0x72AF, + 0x94C7: 0x73ED, + 0x94C8: 0x7554, + 0x94C9: 0x7E41, + 0x94CA: 0x822C, + 0x94CB: 0x85E9, + 0x94CC: 0x8CA9, + 0x94CD: 0x7BC4, + 0x94CE: 0x91C6, + 0x94CF: 0x7169, + 0x94D0: 0x9812, + 0x94D1: 0x98EF, + 0x94D2: 0x633D, + 0x94D3: 0x6669, + 0x94D4: 0x756A, + 0x94D5: 0x76E4, + 0x94D6: 0x78D0, + 0x94D7: 0x8543, + 0x94D8: 0x86EE, + 0x94D9: 0x532A, + 0x94DA: 0x5351, + 0x94DB: 0x5426, + 0x94DC: 0x5983, + 0x94DD: 0x5E87, + 0x94DE: 0x5F7C, + 0x94DF: 0x60B2, + 0x94E0: 0x6249, + 0x94E1: 0x6279, + 0x94E2: 0x62AB, + 0x94E3: 0x6590, + 0x94E4: 0x6BD4, + 0x94E5: 0x6CCC, + 0x94E6: 0x75B2, + 0x94E7: 0x76AE, + 0x94E8: 0x7891, + 0x94E9: 0x79D8, + 0x94EA: 0x7DCB, + 0x94EB: 0x7F77, + 0x94EC: 0x80A5, + 0x94ED: 0x88AB, + 0x94EE: 0x8AB9, + 0x94EF: 0x8CBB, + 0x94F0: 0x907F, + 0x94F1: 0x975E, + 0x94F2: 0x98DB, + 0x94F3: 0x6A0B, + 0x94F4: 0x7C38, + 0x94F5: 0x5099, + 0x94F6: 0x5C3E, + 0x94F7: 0x5FAE, + 0x94F8: 0x6787, + 0x94F9: 0x6BD8, + 0x94FA: 0x7435, + 0x94FB: 0x7709, + 0x94FC: 0x7F8E, + 0x9540: 0x9F3B, + 0x9541: 0x67CA, + 0x9542: 0x7A17, + 0x9543: 0x5339, + 0x9544: 0x758B, + 0x9545: 0x9AED, + 0x9546: 0x5F66, + 0x9547: 0x819D, + 0x9548: 0x83F1, + 0x9549: 0x8098, + 0x954A: 0x5F3C, + 0x954B: 0x5FC5, + 0x954C: 0x7562, + 0x954D: 0x7B46, + 0x954E: 0x903C, + 0x954F: 0x6867, + 0x9550: 0x59EB, + 0x9551: 0x5A9B, + 0x9552: 0x7D10, + 0x9553: 0x767E, + 0x9554: 0x8B2C, + 0x9555: 0x4FF5, + 0x9556: 0x5F6A, + 0x9557: 0x6A19, + 0x9558: 0x6C37, + 0x9559: 0x6F02, + 0x955A: 0x74E2, + 0x955B: 0x7968, + 0x955C: 0x8868, + 0x955D: 0x8A55, + 0x955E: 0x8C79, + 0x955F: 0x5EDF, + 0x9560: 0x63CF, + 0x9561: 0x75C5, + 0x9562: 0x79D2, + 0x9563: 0x82D7, + 0x9564: 0x9328, + 0x9565: 0x92F2, + 0x9566: 0x849C, + 0x9567: 0x86ED, + 0x9568: 0x9C2D, + 0x9569: 0x54C1, + 0x956A: 0x5F6C, + 0x956B: 0x658C, + 0x956C: 0x6D5C, + 0x956D: 0x7015, + 0x956E: 0x8CA7, + 0x956F: 0x8CD3, + 0x9570: 0x983B, + 0x9571: 0x654F, + 0x9572: 0x74F6, + 0x9573: 0x4E0D, + 0x9574: 0x4ED8, + 0x9575: 0x57E0, + 0x9576: 0x592B, + 0x9577: 0x5A66, + 0x9578: 0x5BCC, + 0x9579: 0x51A8, + 0x957A: 0x5E03, + 0x957B: 0x5E9C, + 0x957C: 0x6016, + 0x957D: 0x6276, + 0x957E: 0x6577, + 0x9580: 0x65A7, + 0x9581: 0x666E, + 0x9582: 0x6D6E, + 0x9583: 0x7236, + 0x9584: 0x7B26, + 0x9585: 0x8150, + 0x9586: 0x819A, + 0x9587: 0x8299, + 0x9588: 0x8B5C, + 0x9589: 0x8CA0, + 0x958A: 0x8CE6, + 0x958B: 0x8D74, + 0x958C: 0x961C, + 0x958D: 0x9644, + 0x958E: 0x4FAE, + 0x958F: 0x64AB, + 0x9590: 0x6B66, + 0x9591: 0x821E, + 0x9592: 0x8461, + 0x9593: 0x856A, + 0x9594: 0x90E8, + 0x9595: 0x5C01, + 0x9596: 0x6953, + 0x9597: 0x98A8, + 0x9598: 0x847A, + 0x9599: 0x8557, + 0x959A: 0x4F0F, + 0x959B: 0x526F, + 0x959C: 0x5FA9, + 0x959D: 0x5E45, + 0x959E: 0x670D, + 0x959F: 0x798F, + 0x95A0: 0x8179, + 0x95A1: 0x8907, + 0x95A2: 0x8986, + 0x95A3: 0x6DF5, + 0x95A4: 0x5F17, + 0x95A5: 0x6255, + 0x95A6: 0x6CB8, + 0x95A7: 0x4ECF, + 0x95A8: 0x7269, + 0x95A9: 0x9B92, + 0x95AA: 0x5206, + 0x95AB: 0x543B, + 0x95AC: 0x5674, + 0x95AD: 0x58B3, + 0x95AE: 0x61A4, + 0x95AF: 0x626E, + 0x95B0: 0x711A, + 0x95B1: 0x596E, + 0x95B2: 0x7C89, + 0x95B3: 0x7CDE, + 0x95B4: 0x7D1B, + 0x95B5: 0x96F0, + 0x95B6: 0x6587, + 0x95B7: 0x805E, + 0x95B8: 0x4E19, + 0x95B9: 0x4F75, + 0x95BA: 0x5175, + 0x95BB: 0x5840, + 0x95BC: 0x5E63, + 0x95BD: 0x5E73, + 0x95BE: 0x5F0A, + 0x95BF: 0x67C4, + 0x95C0: 0x4E26, + 0x95C1: 0x853D, + 0x95C2: 0x9589, + 0x95C3: 0x965B, + 0x95C4: 0x7C73, + 0x95C5: 0x9801, + 0x95C6: 0x50FB, + 0x95C7: 0x58C1, + 0x95C8: 0x7656, + 0x95C9: 0x78A7, + 0x95CA: 0x5225, + 0x95CB: 0x77A5, + 0x95CC: 0x8511, + 0x95CD: 0x7B86, + 0x95CE: 0x504F, + 0x95CF: 0x5909, + 0x95D0: 0x7247, + 0x95D1: 0x7BC7, + 0x95D2: 0x7DE8, + 0x95D3: 0x8FBA, + 0x95D4: 0x8FD4, + 0x95D5: 0x904D, + 0x95D6: 0x4FBF, + 0x95D7: 0x52C9, + 0x95D8: 0x5A29, + 0x95D9: 0x5F01, + 0x95DA: 0x97AD, + 0x95DB: 0x4FDD, + 0x95DC: 0x8217, + 0x95DD: 0x92EA, + 0x95DE: 0x5703, + 0x95DF: 0x6355, + 0x95E0: 0x6B69, + 0x95E1: 0x752B, + 0x95E2: 0x88DC, + 0x95E3: 0x8F14, + 0x95E4: 0x7A42, + 0x95E5: 0x52DF, + 0x95E6: 0x5893, + 0x95E7: 0x6155, + 0x95E8: 0x620A, + 0x95E9: 0x66AE, + 0x95EA: 0x6BCD, + 0x95EB: 0x7C3F, + 0x95EC: 0x83E9, + 0x95ED: 0x5023, + 0x95EE: 0x4FF8, + 0x95EF: 0x5305, + 0x95F0: 0x5446, + 0x95F1: 0x5831, + 0x95F2: 0x5949, + 0x95F3: 0x5B9D, + 0x95F4: 0x5CF0, + 0x95F5: 0x5CEF, + 0x95F6: 0x5D29, + 0x95F7: 0x5E96, + 0x95F8: 0x62B1, + 0x95F9: 0x6367, + 0x95FA: 0x653E, + 0x95FB: 0x65B9, + 0x95FC: 0x670B, + 0x9640: 0x6CD5, + 0x9641: 0x6CE1, + 0x9642: 0x70F9, + 0x9643: 0x7832, + 0x9644: 0x7E2B, + 0x9645: 0x80DE, + 0x9646: 0x82B3, + 0x9647: 0x840C, + 0x9648: 0x84EC, + 0x9649: 0x8702, + 0x964A: 0x8912, + 0x964B: 0x8A2A, + 0x964C: 0x8C4A, + 0x964D: 0x90A6, + 0x964E: 0x92D2, + 0x964F: 0x98FD, + 0x9650: 0x9CF3, + 0x9651: 0x9D6C, + 0x9652: 0x4E4F, + 0x9653: 0x4EA1, + 0x9654: 0x508D, + 0x9655: 0x5256, + 0x9656: 0x574A, + 0x9657: 0x59A8, + 0x9658: 0x5E3D, + 0x9659: 0x5FD8, + 0x965A: 0x5FD9, + 0x965B: 0x623F, + 0x965C: 0x66B4, + 0x965D: 0x671B, + 0x965E: 0x67D0, + 0x965F: 0x68D2, + 0x9660: 0x5192, + 0x9661: 0x7D21, + 0x9662: 0x80AA, + 0x9663: 0x81A8, + 0x9664: 0x8B00, + 0x9665: 0x8C8C, + 0x9666: 0x8CBF, + 0x9667: 0x927E, + 0x9668: 0x9632, + 0x9669: 0x5420, + 0x966A: 0x982C, + 0x966B: 0x5317, + 0x966C: 0x50D5, + 0x966D: 0x535C, + 0x966E: 0x58A8, + 0x966F: 0x64B2, + 0x9670: 0x6734, + 0x9671: 0x7267, + 0x9672: 0x7766, + 0x9673: 0x7A46, + 0x9674: 0x91E6, + 0x9675: 0x52C3, + 0x9676: 0x6CA1, + 0x9677: 0x6B86, + 0x9678: 0x5800, + 0x9679: 0x5E4C, + 0x967A: 0x5954, + 0x967B: 0x672C, + 0x967C: 0x7FFB, + 0x967D: 0x51E1, + 0x967E: 0x76C6, + 0x9680: 0x6469, + 0x9681: 0x78E8, + 0x9682: 0x9B54, + 0x9683: 0x9EBB, + 0x9684: 0x57CB, + 0x9685: 0x59B9, + 0x9686: 0x6627, + 0x9687: 0x679A, + 0x9688: 0x6BCE, + 0x9689: 0x54E9, + 0x968A: 0x69D9, + 0x968B: 0x5E55, + 0x968C: 0x819C, + 0x968D: 0x6795, + 0x968E: 0x9BAA, + 0x968F: 0x67FE, + 0x9690: 0x9C52, + 0x9691: 0x685D, + 0x9692: 0x4EA6, + 0x9693: 0x4FE3, + 0x9694: 0x53C8, + 0x9695: 0x62B9, + 0x9696: 0x672B, + 0x9697: 0x6CAB, + 0x9698: 0x8FC4, + 0x9699: 0x4FAD, + 0x969A: 0x7E6D, + 0x969B: 0x9EBF, + 0x969C: 0x4E07, + 0x969D: 0x6162, + 0x969E: 0x6E80, + 0x969F: 0x6F2B, + 0x96A0: 0x8513, + 0x96A1: 0x5473, + 0x96A2: 0x672A, + 0x96A3: 0x9B45, + 0x96A4: 0x5DF3, + 0x96A5: 0x7B95, + 0x96A6: 0x5CAC, + 0x96A7: 0x5BC6, + 0x96A8: 0x871C, + 0x96A9: 0x6E4A, + 0x96AA: 0x84D1, + 0x96AB: 0x7A14, + 0x96AC: 0x8108, + 0x96AD: 0x5999, + 0x96AE: 0x7C8D, + 0x96AF: 0x6C11, + 0x96B0: 0x7720, + 0x96B1: 0x52D9, + 0x96B2: 0x5922, + 0x96B3: 0x7121, + 0x96B4: 0x725F, + 0x96B5: 0x77DB, + 0x96B6: 0x9727, + 0x96B7: 0x9D61, + 0x96B8: 0x690B, + 0x96B9: 0x5A7F, + 0x96BA: 0x5A18, + 0x96BB: 0x51A5, + 0x96BC: 0x540D, + 0x96BD: 0x547D, + 0x96BE: 0x660E, + 0x96BF: 0x76DF, + 0x96C0: 0x8FF7, + 0x96C1: 0x9298, + 0x96C2: 0x9CF4, + 0x96C3: 0x59EA, + 0x96C4: 0x725D, + 0x96C5: 0x6EC5, + 0x96C6: 0x514D, + 0x96C7: 0x68C9, + 0x96C8: 0x7DBF, + 0x96C9: 0x7DEC, + 0x96CA: 0x9762, + 0x96CB: 0x9EBA, + 0x96CC: 0x6478, + 0x96CD: 0x6A21, + 0x96CE: 0x8302, + 0x96CF: 0x5984, + 0x96D0: 0x5B5F, + 0x96D1: 0x6BDB, + 0x96D2: 0x731B, + 0x96D3: 0x76F2, + 0x96D4: 0x7DB2, + 0x96D5: 0x8017, + 0x96D6: 0x8499, + 0x96D7: 0x5132, + 0x96D8: 0x6728, + 0x96D9: 0x9ED9, + 0x96DA: 0x76EE, + 0x96DB: 0x6762, + 0x96DC: 0x52FF, + 0x96DD: 0x9905, + 0x96DE: 0x5C24, + 0x96DF: 0x623B, + 0x96E0: 0x7C7E, + 0x96E1: 0x8CB0, + 0x96E2: 0x554F, + 0x96E3: 0x60B6, + 0x96E4: 0x7D0B, + 0x96E5: 0x9580, + 0x96E6: 0x5301, + 0x96E7: 0x4E5F, + 0x96E8: 0x51B6, + 0x96E9: 0x591C, + 0x96EA: 0x723A, + 0x96EB: 0x8036, + 0x96EC: 0x91CE, + 0x96ED: 0x5F25, + 0x96EE: 0x77E2, + 0x96EF: 0x5384, + 0x96F0: 0x5F79, + 0x96F1: 0x7D04, + 0x96F2: 0x85AC, + 0x96F3: 0x8A33, + 0x96F4: 0x8E8D, + 0x96F5: 0x9756, + 0x96F6: 0x67F3, + 0x96F7: 0x85AE, + 0x96F8: 0x9453, + 0x96F9: 0x6109, + 0x96FA: 0x6108, + 0x96FB: 0x6CB9, + 0x96FC: 0x7652, + 0x9740: 0x8AED, + 0x9741: 0x8F38, + 0x9742: 0x552F, + 0x9743: 0x4F51, + 0x9744: 0x512A, + 0x9745: 0x52C7, + 0x9746: 0x53CB, + 0x9747: 0x5BA5, + 0x9748: 0x5E7D, + 0x9749: 0x60A0, + 0x974A: 0x6182, + 0x974B: 0x63D6, + 0x974C: 0x6709, + 0x974D: 0x67DA, + 0x974E: 0x6E67, + 0x974F: 0x6D8C, + 0x9750: 0x7336, + 0x9751: 0x7337, + 0x9752: 0x7531, + 0x9753: 0x7950, + 0x9754: 0x88D5, + 0x9755: 0x8A98, + 0x9756: 0x904A, + 0x9757: 0x9091, + 0x9758: 0x90F5, + 0x9759: 0x96C4, + 0x975A: 0x878D, + 0x975B: 0x5915, + 0x975C: 0x4E88, + 0x975D: 0x4F59, + 0x975E: 0x4E0E, + 0x975F: 0x8A89, + 0x9760: 0x8F3F, + 0x9761: 0x9810, + 0x9762: 0x50AD, + 0x9763: 0x5E7C, + 0x9764: 0x5996, + 0x9765: 0x5BB9, + 0x9766: 0x5EB8, + 0x9767: 0x63DA, + 0x9768: 0x63FA, + 0x9769: 0x64C1, + 0x976A: 0x66DC, + 0x976B: 0x694A, + 0x976C: 0x69D8, + 0x976D: 0x6D0B, + 0x976E: 0x6EB6, + 0x976F: 0x7194, + 0x9770: 0x7528, + 0x9771: 0x7AAF, + 0x9772: 0x7F8A, + 0x9773: 0x8000, + 0x9774: 0x8449, + 0x9775: 0x84C9, + 0x9776: 0x8981, + 0x9777: 0x8B21, + 0x9778: 0x8E0A, + 0x9779: 0x9065, + 0x977A: 0x967D, + 0x977B: 0x990A, + 0x977C: 0x617E, + 0x977D: 0x6291, + 0x977E: 0x6B32, + 0x9780: 0x6C83, + 0x9781: 0x6D74, + 0x9782: 0x7FCC, + 0x9783: 0x7FFC, + 0x9784: 0x6DC0, + 0x9785: 0x7F85, + 0x9786: 0x87BA, + 0x9787: 0x88F8, + 0x9788: 0x6765, + 0x9789: 0x83B1, + 0x978A: 0x983C, + 0x978B: 0x96F7, + 0x978C: 0x6D1B, + 0x978D: 0x7D61, + 0x978E: 0x843D, + 0x978F: 0x916A, + 0x9790: 0x4E71, + 0x9791: 0x5375, + 0x9792: 0x5D50, + 0x9793: 0x6B04, + 0x9794: 0x6FEB, + 0x9795: 0x85CD, + 0x9796: 0x862D, + 0x9797: 0x89A7, + 0x9798: 0x5229, + 0x9799: 0x540F, + 0x979A: 0x5C65, + 0x979B: 0x674E, + 0x979C: 0x68A8, + 0x979D: 0x7406, + 0x979E: 0x7483, + 0x979F: 0x75E2, + 0x97A0: 0x88CF, + 0x97A1: 0x88E1, + 0x97A2: 0x91CC, + 0x97A3: 0x96E2, + 0x97A4: 0x9678, + 0x97A5: 0x5F8B, + 0x97A6: 0x7387, + 0x97A7: 0x7ACB, + 0x97A8: 0x844E, + 0x97A9: 0x63A0, + 0x97AA: 0x7565, + 0x97AB: 0x5289, + 0x97AC: 0x6D41, + 0x97AD: 0x6E9C, + 0x97AE: 0x7409, + 0x97AF: 0x7559, + 0x97B0: 0x786B, + 0x97B1: 0x7C92, + 0x97B2: 0x9686, + 0x97B3: 0x7ADC, + 0x97B4: 0x9F8D, + 0x97B5: 0x4FB6, + 0x97B6: 0x616E, + 0x97B7: 0x65C5, + 0x97B8: 0x865C, + 0x97B9: 0x4E86, + 0x97BA: 0x4EAE, + 0x97BB: 0x50DA, + 0x97BC: 0x4E21, + 0x97BD: 0x51CC, + 0x97BE: 0x5BEE, + 0x97BF: 0x6599, + 0x97C0: 0x6881, + 0x97C1: 0x6DBC, + 0x97C2: 0x731F, + 0x97C3: 0x7642, + 0x97C4: 0x77AD, + 0x97C5: 0x7A1C, + 0x97C6: 0x7CE7, + 0x97C7: 0x826F, + 0x97C8: 0x8AD2, + 0x97C9: 0x907C, + 0x97CA: 0x91CF, + 0x97CB: 0x9675, + 0x97CC: 0x9818, + 0x97CD: 0x529B, + 0x97CE: 0x7DD1, + 0x97CF: 0x502B, + 0x97D0: 0x5398, + 0x97D1: 0x6797, + 0x97D2: 0x6DCB, + 0x97D3: 0x71D0, + 0x97D4: 0x7433, + 0x97D5: 0x81E8, + 0x97D6: 0x8F2A, + 0x97D7: 0x96A3, + 0x97D8: 0x9C57, + 0x97D9: 0x9E9F, + 0x97DA: 0x7460, + 0x97DB: 0x5841, + 0x97DC: 0x6D99, + 0x97DD: 0x7D2F, + 0x97DE: 0x985E, + 0x97DF: 0x4EE4, + 0x97E0: 0x4F36, + 0x97E1: 0x4F8B, + 0x97E2: 0x51B7, + 0x97E3: 0x52B1, + 0x97E4: 0x5DBA, + 0x97E5: 0x601C, + 0x97E6: 0x73B2, + 0x97E7: 0x793C, + 0x97E8: 0x82D3, + 0x97E9: 0x9234, + 0x97EA: 0x96B7, + 0x97EB: 0x96F6, + 0x97EC: 0x970A, + 0x97ED: 0x9E97, + 0x97EE: 0x9F62, + 0x97EF: 0x66A6, + 0x97F0: 0x6B74, + 0x97F1: 0x5217, + 0x97F2: 0x52A3, + 0x97F3: 0x70C8, + 0x97F4: 0x88C2, + 0x97F5: 0x5EC9, + 0x97F6: 0x604B, + 0x97F7: 0x6190, + 0x97F8: 0x6F23, + 0x97F9: 0x7149, + 0x97FA: 0x7C3E, + 0x97FB: 0x7DF4, + 0x97FC: 0x806F, + 0x9840: 0x84EE, + 0x9841: 0x9023, + 0x9842: 0x932C, + 0x9843: 0x5442, + 0x9844: 0x9B6F, + 0x9845: 0x6AD3, + 0x9846: 0x7089, + 0x9847: 0x8CC2, + 0x9848: 0x8DEF, + 0x9849: 0x9732, + 0x984A: 0x52B4, + 0x984B: 0x5A41, + 0x984C: 0x5ECA, + 0x984D: 0x5F04, + 0x984E: 0x6717, + 0x984F: 0x697C, + 0x9850: 0x6994, + 0x9851: 0x6D6A, + 0x9852: 0x6F0F, + 0x9853: 0x7262, + 0x9854: 0x72FC, + 0x9855: 0x7BED, + 0x9856: 0x8001, + 0x9857: 0x807E, + 0x9858: 0x874B, + 0x9859: 0x90CE, + 0x985A: 0x516D, + 0x985B: 0x9E93, + 0x985C: 0x7984, + 0x985D: 0x808B, + 0x985E: 0x9332, + 0x985F: 0x8AD6, + 0x9860: 0x502D, + 0x9861: 0x548C, + 0x9862: 0x8A71, + 0x9863: 0x6B6A, + 0x9864: 0x8CC4, + 0x9865: 0x8107, + 0x9866: 0x60D1, + 0x9867: 0x67A0, + 0x9868: 0x9DF2, + 0x9869: 0x4E99, + 0x986A: 0x4E98, + 0x986B: 0x9C10, + 0x986C: 0x8A6B, + 0x986D: 0x85C1, + 0x986E: 0x8568, + 0x986F: 0x6900, + 0x9870: 0x6E7E, + 0x9871: 0x7897, + 0x9872: 0x8155, + 0x989F: 0x5F0C, + 0x98A0: 0x4E10, + 0x98A1: 0x4E15, + 0x98A2: 0x4E2A, + 0x98A3: 0x4E31, + 0x98A4: 0x4E36, + 0x98A5: 0x4E3C, + 0x98A6: 0x4E3F, + 0x98A7: 0x4E42, + 0x98A8: 0x4E56, + 0x98A9: 0x4E58, + 0x98AA: 0x4E82, + 0x98AB: 0x4E85, + 0x98AC: 0x8C6B, + 0x98AD: 0x4E8A, + 0x98AE: 0x8212, + 0x98AF: 0x5F0D, + 0x98B0: 0x4E8E, + 0x98B1: 0x4E9E, + 0x98B2: 0x4E9F, + 0x98B3: 0x4EA0, + 0x98B4: 0x4EA2, + 0x98B5: 0x4EB0, + 0x98B6: 0x4EB3, + 0x98B7: 0x4EB6, + 0x98B8: 0x4ECE, + 0x98B9: 0x4ECD, + 0x98BA: 0x4EC4, + 0x98BB: 0x4EC6, + 0x98BC: 0x4EC2, + 0x98BD: 0x4ED7, + 0x98BE: 0x4EDE, + 0x98BF: 0x4EED, + 0x98C0: 0x4EDF, + 0x98C1: 0x4EF7, + 0x98C2: 0x4F09, + 0x98C3: 0x4F5A, + 0x98C4: 0x4F30, + 0x98C5: 0x4F5B, + 0x98C6: 0x4F5D, + 0x98C7: 0x4F57, + 0x98C8: 0x4F47, + 0x98C9: 0x4F76, + 0x98CA: 0x4F88, + 0x98CB: 0x4F8F, + 0x98CC: 0x4F98, + 0x98CD: 0x4F7B, + 0x98CE: 0x4F69, + 0x98CF: 0x4F70, + 0x98D0: 0x4F91, + 0x98D1: 0x4F6F, + 0x98D2: 0x4F86, + 0x98D3: 0x4F96, + 0x98D4: 0x5118, + 0x98D5: 0x4FD4, + 0x98D6: 0x4FDF, + 0x98D7: 0x4FCE, + 0x98D8: 0x4FD8, + 0x98D9: 0x4FDB, + 0x98DA: 0x4FD1, + 0x98DB: 0x4FDA, + 0x98DC: 0x4FD0, + 0x98DD: 0x4FE4, + 0x98DE: 0x4FE5, + 0x98DF: 0x501A, + 0x98E0: 0x5028, + 0x98E1: 0x5014, + 0x98E2: 0x502A, + 0x98E3: 0x5025, + 0x98E4: 0x5005, + 0x98E5: 0x4F1C, + 0x98E6: 0x4FF6, + 0x98E7: 0x5021, + 0x98E8: 0x5029, + 0x98E9: 0x502C, + 0x98EA: 0x4FFE, + 0x98EB: 0x4FEF, + 0x98EC: 0x5011, + 0x98ED: 0x5006, + 0x98EE: 0x5043, + 0x98EF: 0x5047, + 0x98F0: 0x6703, + 0x98F1: 0x5055, + 0x98F2: 0x5050, + 0x98F3: 0x5048, + 0x98F4: 0x505A, + 0x98F5: 0x5056, + 0x98F6: 0x506C, + 0x98F7: 0x5078, + 0x98F8: 0x5080, + 0x98F9: 0x509A, + 0x98FA: 0x5085, + 0x98FB: 0x50B4, + 0x98FC: 0x50B2, + 0x9940: 0x50C9, + 0x9941: 0x50CA, + 0x9942: 0x50B3, + 0x9943: 0x50C2, + 0x9944: 0x50D6, + 0x9945: 0x50DE, + 0x9946: 0x50E5, + 0x9947: 0x50ED, + 0x9948: 0x50E3, + 0x9949: 0x50EE, + 0x994A: 0x50F9, + 0x994B: 0x50F5, + 0x994C: 0x5109, + 0x994D: 0x5101, + 0x994E: 0x5102, + 0x994F: 0x5116, + 0x9950: 0x5115, + 0x9951: 0x5114, + 0x9952: 0x511A, + 0x9953: 0x5121, + 0x9954: 0x513A, + 0x9955: 0x5137, + 0x9956: 0x513C, + 0x9957: 0x513B, + 0x9958: 0x513F, + 0x9959: 0x5140, + 0x995A: 0x5152, + 0x995B: 0x514C, + 0x995C: 0x5154, + 0x995D: 0x5162, + 0x995E: 0x7AF8, + 0x995F: 0x5169, + 0x9960: 0x516A, + 0x9961: 0x516E, + 0x9962: 0x5180, + 0x9963: 0x5182, + 0x9964: 0x56D8, + 0x9965: 0x518C, + 0x9966: 0x5189, + 0x9967: 0x518F, + 0x9968: 0x5191, + 0x9969: 0x5193, + 0x996A: 0x5195, + 0x996B: 0x5196, + 0x996C: 0x51A4, + 0x996D: 0x51A6, + 0x996E: 0x51A2, + 0x996F: 0x51A9, + 0x9970: 0x51AA, + 0x9971: 0x51AB, + 0x9972: 0x51B3, + 0x9973: 0x51B1, + 0x9974: 0x51B2, + 0x9975: 0x51B0, + 0x9976: 0x51B5, + 0x9977: 0x51BD, + 0x9978: 0x51C5, + 0x9979: 0x51C9, + 0x997A: 0x51DB, + 0x997B: 0x51E0, + 0x997C: 0x8655, + 0x997D: 0x51E9, + 0x997E: 0x51ED, + 0x9980: 0x51F0, + 0x9981: 0x51F5, + 0x9982: 0x51FE, + 0x9983: 0x5204, + 0x9984: 0x520B, + 0x9985: 0x5214, + 0x9986: 0x520E, + 0x9987: 0x5227, + 0x9988: 0x522A, + 0x9989: 0x522E, + 0x998A: 0x5233, + 0x998B: 0x5239, + 0x998C: 0x524F, + 0x998D: 0x5244, + 0x998E: 0x524B, + 0x998F: 0x524C, + 0x9990: 0x525E, + 0x9991: 0x5254, + 0x9992: 0x526A, + 0x9993: 0x5274, + 0x9994: 0x5269, + 0x9995: 0x5273, + 0x9996: 0x527F, + 0x9997: 0x527D, + 0x9998: 0x528D, + 0x9999: 0x5294, + 0x999A: 0x5292, + 0x999B: 0x5271, + 0x999C: 0x5288, + 0x999D: 0x5291, + 0x999E: 0x8FA8, + 0x999F: 0x8FA7, + 0x99A0: 0x52AC, + 0x99A1: 0x52AD, + 0x99A2: 0x52BC, + 0x99A3: 0x52B5, + 0x99A4: 0x52C1, + 0x99A5: 0x52CD, + 0x99A6: 0x52D7, + 0x99A7: 0x52DE, + 0x99A8: 0x52E3, + 0x99A9: 0x52E6, + 0x99AA: 0x98ED, + 0x99AB: 0x52E0, + 0x99AC: 0x52F3, + 0x99AD: 0x52F5, + 0x99AE: 0x52F8, + 0x99AF: 0x52F9, + 0x99B0: 0x5306, + 0x99B1: 0x5308, + 0x99B2: 0x7538, + 0x99B3: 0x530D, + 0x99B4: 0x5310, + 0x99B5: 0x530F, + 0x99B6: 0x5315, + 0x99B7: 0x531A, + 0x99B8: 0x5323, + 0x99B9: 0x532F, + 0x99BA: 0x5331, + 0x99BB: 0x5333, + 0x99BC: 0x5338, + 0x99BD: 0x5340, + 0x99BE: 0x5346, + 0x99BF: 0x5345, + 0x99C0: 0x4E17, + 0x99C1: 0x5349, + 0x99C2: 0x534D, + 0x99C3: 0x51D6, + 0x99C4: 0x535E, + 0x99C5: 0x5369, + 0x99C6: 0x536E, + 0x99C7: 0x5918, + 0x99C8: 0x537B, + 0x99C9: 0x5377, + 0x99CA: 0x5382, + 0x99CB: 0x5396, + 0x99CC: 0x53A0, + 0x99CD: 0x53A6, + 0x99CE: 0x53A5, + 0x99CF: 0x53AE, + 0x99D0: 0x53B0, + 0x99D1: 0x53B6, + 0x99D2: 0x53C3, + 0x99D3: 0x7C12, + 0x99D4: 0x96D9, + 0x99D5: 0x53DF, + 0x99D6: 0x66FC, + 0x99D7: 0x71EE, + 0x99D8: 0x53EE, + 0x99D9: 0x53E8, + 0x99DA: 0x53ED, + 0x99DB: 0x53FA, + 0x99DC: 0x5401, + 0x99DD: 0x543D, + 0x99DE: 0x5440, + 0x99DF: 0x542C, + 0x99E0: 0x542D, + 0x99E1: 0x543C, + 0x99E2: 0x542E, + 0x99E3: 0x5436, + 0x99E4: 0x5429, + 0x99E5: 0x541D, + 0x99E6: 0x544E, + 0x99E7: 0x548F, + 0x99E8: 0x5475, + 0x99E9: 0x548E, + 0x99EA: 0x545F, + 0x99EB: 0x5471, + 0x99EC: 0x5477, + 0x99ED: 0x5470, + 0x99EE: 0x5492, + 0x99EF: 0x547B, + 0x99F0: 0x5480, + 0x99F1: 0x5476, + 0x99F2: 0x5484, + 0x99F3: 0x5490, + 0x99F4: 0x5486, + 0x99F5: 0x54C7, + 0x99F6: 0x54A2, + 0x99F7: 0x54B8, + 0x99F8: 0x54A5, + 0x99F9: 0x54AC, + 0x99FA: 0x54C4, + 0x99FB: 0x54C8, + 0x99FC: 0x54A8, + 0x9A40: 0x54AB, + 0x9A41: 0x54C2, + 0x9A42: 0x54A4, + 0x9A43: 0x54BE, + 0x9A44: 0x54BC, + 0x9A45: 0x54D8, + 0x9A46: 0x54E5, + 0x9A47: 0x54E6, + 0x9A48: 0x550F, + 0x9A49: 0x5514, + 0x9A4A: 0x54FD, + 0x9A4B: 0x54EE, + 0x9A4C: 0x54ED, + 0x9A4D: 0x54FA, + 0x9A4E: 0x54E2, + 0x9A4F: 0x5539, + 0x9A50: 0x5540, + 0x9A51: 0x5563, + 0x9A52: 0x554C, + 0x9A53: 0x552E, + 0x9A54: 0x555C, + 0x9A55: 0x5545, + 0x9A56: 0x5556, + 0x9A57: 0x5557, + 0x9A58: 0x5538, + 0x9A59: 0x5533, + 0x9A5A: 0x555D, + 0x9A5B: 0x5599, + 0x9A5C: 0x5580, + 0x9A5D: 0x54AF, + 0x9A5E: 0x558A, + 0x9A5F: 0x559F, + 0x9A60: 0x557B, + 0x9A61: 0x557E, + 0x9A62: 0x5598, + 0x9A63: 0x559E, + 0x9A64: 0x55AE, + 0x9A65: 0x557C, + 0x9A66: 0x5583, + 0x9A67: 0x55A9, + 0x9A68: 0x5587, + 0x9A69: 0x55A8, + 0x9A6A: 0x55DA, + 0x9A6B: 0x55C5, + 0x9A6C: 0x55DF, + 0x9A6D: 0x55C4, + 0x9A6E: 0x55DC, + 0x9A6F: 0x55E4, + 0x9A70: 0x55D4, + 0x9A71: 0x5614, + 0x9A72: 0x55F7, + 0x9A73: 0x5616, + 0x9A74: 0x55FE, + 0x9A75: 0x55FD, + 0x9A76: 0x561B, + 0x9A77: 0x55F9, + 0x9A78: 0x564E, + 0x9A79: 0x5650, + 0x9A7A: 0x71DF, + 0x9A7B: 0x5634, + 0x9A7C: 0x5636, + 0x9A7D: 0x5632, + 0x9A7E: 0x5638, + 0x9A80: 0x566B, + 0x9A81: 0x5664, + 0x9A82: 0x562F, + 0x9A83: 0x566C, + 0x9A84: 0x566A, + 0x9A85: 0x5686, + 0x9A86: 0x5680, + 0x9A87: 0x568A, + 0x9A88: 0x56A0, + 0x9A89: 0x5694, + 0x9A8A: 0x568F, + 0x9A8B: 0x56A5, + 0x9A8C: 0x56AE, + 0x9A8D: 0x56B6, + 0x9A8E: 0x56B4, + 0x9A8F: 0x56C2, + 0x9A90: 0x56BC, + 0x9A91: 0x56C1, + 0x9A92: 0x56C3, + 0x9A93: 0x56C0, + 0x9A94: 0x56C8, + 0x9A95: 0x56CE, + 0x9A96: 0x56D1, + 0x9A97: 0x56D3, + 0x9A98: 0x56D7, + 0x9A99: 0x56EE, + 0x9A9A: 0x56F9, + 0x9A9B: 0x5700, + 0x9A9C: 0x56FF, + 0x9A9D: 0x5704, + 0x9A9E: 0x5709, + 0x9A9F: 0x5708, + 0x9AA0: 0x570B, + 0x9AA1: 0x570D, + 0x9AA2: 0x5713, + 0x9AA3: 0x5718, + 0x9AA4: 0x5716, + 0x9AA5: 0x55C7, + 0x9AA6: 0x571C, + 0x9AA7: 0x5726, + 0x9AA8: 0x5737, + 0x9AA9: 0x5738, + 0x9AAA: 0x574E, + 0x9AAB: 0x573B, + 0x9AAC: 0x5740, + 0x9AAD: 0x574F, + 0x9AAE: 0x5769, + 0x9AAF: 0x57C0, + 0x9AB0: 0x5788, + 0x9AB1: 0x5761, + 0x9AB2: 0x577F, + 0x9AB3: 0x5789, + 0x9AB4: 0x5793, + 0x9AB5: 0x57A0, + 0x9AB6: 0x57B3, + 0x9AB7: 0x57A4, + 0x9AB8: 0x57AA, + 0x9AB9: 0x57B0, + 0x9ABA: 0x57C3, + 0x9ABB: 0x57C6, + 0x9ABC: 0x57D4, + 0x9ABD: 0x57D2, + 0x9ABE: 0x57D3, + 0x9ABF: 0x580A, + 0x9AC0: 0x57D6, + 0x9AC1: 0x57E3, + 0x9AC2: 0x580B, + 0x9AC3: 0x5819, + 0x9AC4: 0x581D, + 0x9AC5: 0x5872, + 0x9AC6: 0x5821, + 0x9AC7: 0x5862, + 0x9AC8: 0x584B, + 0x9AC9: 0x5870, + 0x9ACA: 0x6BC0, + 0x9ACB: 0x5852, + 0x9ACC: 0x583D, + 0x9ACD: 0x5879, + 0x9ACE: 0x5885, + 0x9ACF: 0x58B9, + 0x9AD0: 0x589F, + 0x9AD1: 0x58AB, + 0x9AD2: 0x58BA, + 0x9AD3: 0x58DE, + 0x9AD4: 0x58BB, + 0x9AD5: 0x58B8, + 0x9AD6: 0x58AE, + 0x9AD7: 0x58C5, + 0x9AD8: 0x58D3, + 0x9AD9: 0x58D1, + 0x9ADA: 0x58D7, + 0x9ADB: 0x58D9, + 0x9ADC: 0x58D8, + 0x9ADD: 0x58E5, + 0x9ADE: 0x58DC, + 0x9ADF: 0x58E4, + 0x9AE0: 0x58DF, + 0x9AE1: 0x58EF, + 0x9AE2: 0x58FA, + 0x9AE3: 0x58F9, + 0x9AE4: 0x58FB, + 0x9AE5: 0x58FC, + 0x9AE6: 0x58FD, + 0x9AE7: 0x5902, + 0x9AE8: 0x590A, + 0x9AE9: 0x5910, + 0x9AEA: 0x591B, + 0x9AEB: 0x68A6, + 0x9AEC: 0x5925, + 0x9AED: 0x592C, + 0x9AEE: 0x592D, + 0x9AEF: 0x5932, + 0x9AF0: 0x5938, + 0x9AF1: 0x593E, + 0x9AF2: 0x7AD2, + 0x9AF3: 0x5955, + 0x9AF4: 0x5950, + 0x9AF5: 0x594E, + 0x9AF6: 0x595A, + 0x9AF7: 0x5958, + 0x9AF8: 0x5962, + 0x9AF9: 0x5960, + 0x9AFA: 0x5967, + 0x9AFB: 0x596C, + 0x9AFC: 0x5969, + 0x9B40: 0x5978, + 0x9B41: 0x5981, + 0x9B42: 0x599D, + 0x9B43: 0x4F5E, + 0x9B44: 0x4FAB, + 0x9B45: 0x59A3, + 0x9B46: 0x59B2, + 0x9B47: 0x59C6, + 0x9B48: 0x59E8, + 0x9B49: 0x59DC, + 0x9B4A: 0x598D, + 0x9B4B: 0x59D9, + 0x9B4C: 0x59DA, + 0x9B4D: 0x5A25, + 0x9B4E: 0x5A1F, + 0x9B4F: 0x5A11, + 0x9B50: 0x5A1C, + 0x9B51: 0x5A09, + 0x9B52: 0x5A1A, + 0x9B53: 0x5A40, + 0x9B54: 0x5A6C, + 0x9B55: 0x5A49, + 0x9B56: 0x5A35, + 0x9B57: 0x5A36, + 0x9B58: 0x5A62, + 0x9B59: 0x5A6A, + 0x9B5A: 0x5A9A, + 0x9B5B: 0x5ABC, + 0x9B5C: 0x5ABE, + 0x9B5D: 0x5ACB, + 0x9B5E: 0x5AC2, + 0x9B5F: 0x5ABD, + 0x9B60: 0x5AE3, + 0x9B61: 0x5AD7, + 0x9B62: 0x5AE6, + 0x9B63: 0x5AE9, + 0x9B64: 0x5AD6, + 0x9B65: 0x5AFA, + 0x9B66: 0x5AFB, + 0x9B67: 0x5B0C, + 0x9B68: 0x5B0B, + 0x9B69: 0x5B16, + 0x9B6A: 0x5B32, + 0x9B6B: 0x5AD0, + 0x9B6C: 0x5B2A, + 0x9B6D: 0x5B36, + 0x9B6E: 0x5B3E, + 0x9B6F: 0x5B43, + 0x9B70: 0x5B45, + 0x9B71: 0x5B40, + 0x9B72: 0x5B51, + 0x9B73: 0x5B55, + 0x9B74: 0x5B5A, + 0x9B75: 0x5B5B, + 0x9B76: 0x5B65, + 0x9B77: 0x5B69, + 0x9B78: 0x5B70, + 0x9B79: 0x5B73, + 0x9B7A: 0x5B75, + 0x9B7B: 0x5B78, + 0x9B7C: 0x6588, + 0x9B7D: 0x5B7A, + 0x9B7E: 0x5B80, + 0x9B80: 0x5B83, + 0x9B81: 0x5BA6, + 0x9B82: 0x5BB8, + 0x9B83: 0x5BC3, + 0x9B84: 0x5BC7, + 0x9B85: 0x5BC9, + 0x9B86: 0x5BD4, + 0x9B87: 0x5BD0, + 0x9B88: 0x5BE4, + 0x9B89: 0x5BE6, + 0x9B8A: 0x5BE2, + 0x9B8B: 0x5BDE, + 0x9B8C: 0x5BE5, + 0x9B8D: 0x5BEB, + 0x9B8E: 0x5BF0, + 0x9B8F: 0x5BF6, + 0x9B90: 0x5BF3, + 0x9B91: 0x5C05, + 0x9B92: 0x5C07, + 0x9B93: 0x5C08, + 0x9B94: 0x5C0D, + 0x9B95: 0x5C13, + 0x9B96: 0x5C20, + 0x9B97: 0x5C22, + 0x9B98: 0x5C28, + 0x9B99: 0x5C38, + 0x9B9A: 0x5C39, + 0x9B9B: 0x5C41, + 0x9B9C: 0x5C46, + 0x9B9D: 0x5C4E, + 0x9B9E: 0x5C53, + 0x9B9F: 0x5C50, + 0x9BA0: 0x5C4F, + 0x9BA1: 0x5B71, + 0x9BA2: 0x5C6C, + 0x9BA3: 0x5C6E, + 0x9BA4: 0x4E62, + 0x9BA5: 0x5C76, + 0x9BA6: 0x5C79, + 0x9BA7: 0x5C8C, + 0x9BA8: 0x5C91, + 0x9BA9: 0x5C94, + 0x9BAA: 0x599B, + 0x9BAB: 0x5CAB, + 0x9BAC: 0x5CBB, + 0x9BAD: 0x5CB6, + 0x9BAE: 0x5CBC, + 0x9BAF: 0x5CB7, + 0x9BB0: 0x5CC5, + 0x9BB1: 0x5CBE, + 0x9BB2: 0x5CC7, + 0x9BB3: 0x5CD9, + 0x9BB4: 0x5CE9, + 0x9BB5: 0x5CFD, + 0x9BB6: 0x5CFA, + 0x9BB7: 0x5CED, + 0x9BB8: 0x5D8C, + 0x9BB9: 0x5CEA, + 0x9BBA: 0x5D0B, + 0x9BBB: 0x5D15, + 0x9BBC: 0x5D17, + 0x9BBD: 0x5D5C, + 0x9BBE: 0x5D1F, + 0x9BBF: 0x5D1B, + 0x9BC0: 0x5D11, + 0x9BC1: 0x5D14, + 0x9BC2: 0x5D22, + 0x9BC3: 0x5D1A, + 0x9BC4: 0x5D19, + 0x9BC5: 0x5D18, + 0x9BC6: 0x5D4C, + 0x9BC7: 0x5D52, + 0x9BC8: 0x5D4E, + 0x9BC9: 0x5D4B, + 0x9BCA: 0x5D6C, + 0x9BCB: 0x5D73, + 0x9BCC: 0x5D76, + 0x9BCD: 0x5D87, + 0x9BCE: 0x5D84, + 0x9BCF: 0x5D82, + 0x9BD0: 0x5DA2, + 0x9BD1: 0x5D9D, + 0x9BD2: 0x5DAC, + 0x9BD3: 0x5DAE, + 0x9BD4: 0x5DBD, + 0x9BD5: 0x5D90, + 0x9BD6: 0x5DB7, + 0x9BD7: 0x5DBC, + 0x9BD8: 0x5DC9, + 0x9BD9: 0x5DCD, + 0x9BDA: 0x5DD3, + 0x9BDB: 0x5DD2, + 0x9BDC: 0x5DD6, + 0x9BDD: 0x5DDB, + 0x9BDE: 0x5DEB, + 0x9BDF: 0x5DF2, + 0x9BE0: 0x5DF5, + 0x9BE1: 0x5E0B, + 0x9BE2: 0x5E1A, + 0x9BE3: 0x5E19, + 0x9BE4: 0x5E11, + 0x9BE5: 0x5E1B, + 0x9BE6: 0x5E36, + 0x9BE7: 0x5E37, + 0x9BE8: 0x5E44, + 0x9BE9: 0x5E43, + 0x9BEA: 0x5E40, + 0x9BEB: 0x5E4E, + 0x9BEC: 0x5E57, + 0x9BED: 0x5E54, + 0x9BEE: 0x5E5F, + 0x9BEF: 0x5E62, + 0x9BF0: 0x5E64, + 0x9BF1: 0x5E47, + 0x9BF2: 0x5E75, + 0x9BF3: 0x5E76, + 0x9BF4: 0x5E7A, + 0x9BF5: 0x9EBC, + 0x9BF6: 0x5E7F, + 0x9BF7: 0x5EA0, + 0x9BF8: 0x5EC1, + 0x9BF9: 0x5EC2, + 0x9BFA: 0x5EC8, + 0x9BFB: 0x5ED0, + 0x9BFC: 0x5ECF, + 0x9C40: 0x5ED6, + 0x9C41: 0x5EE3, + 0x9C42: 0x5EDD, + 0x9C43: 0x5EDA, + 0x9C44: 0x5EDB, + 0x9C45: 0x5EE2, + 0x9C46: 0x5EE1, + 0x9C47: 0x5EE8, + 0x9C48: 0x5EE9, + 0x9C49: 0x5EEC, + 0x9C4A: 0x5EF1, + 0x9C4B: 0x5EF3, + 0x9C4C: 0x5EF0, + 0x9C4D: 0x5EF4, + 0x9C4E: 0x5EF8, + 0x9C4F: 0x5EFE, + 0x9C50: 0x5F03, + 0x9C51: 0x5F09, + 0x9C52: 0x5F5D, + 0x9C53: 0x5F5C, + 0x9C54: 0x5F0B, + 0x9C55: 0x5F11, + 0x9C56: 0x5F16, + 0x9C57: 0x5F29, + 0x9C58: 0x5F2D, + 0x9C59: 0x5F38, + 0x9C5A: 0x5F41, + 0x9C5B: 0x5F48, + 0x9C5C: 0x5F4C, + 0x9C5D: 0x5F4E, + 0x9C5E: 0x5F2F, + 0x9C5F: 0x5F51, + 0x9C60: 0x5F56, + 0x9C61: 0x5F57, + 0x9C62: 0x5F59, + 0x9C63: 0x5F61, + 0x9C64: 0x5F6D, + 0x9C65: 0x5F73, + 0x9C66: 0x5F77, + 0x9C67: 0x5F83, + 0x9C68: 0x5F82, + 0x9C69: 0x5F7F, + 0x9C6A: 0x5F8A, + 0x9C6B: 0x5F88, + 0x9C6C: 0x5F91, + 0x9C6D: 0x5F87, + 0x9C6E: 0x5F9E, + 0x9C6F: 0x5F99, + 0x9C70: 0x5F98, + 0x9C71: 0x5FA0, + 0x9C72: 0x5FA8, + 0x9C73: 0x5FAD, + 0x9C74: 0x5FBC, + 0x9C75: 0x5FD6, + 0x9C76: 0x5FFB, + 0x9C77: 0x5FE4, + 0x9C78: 0x5FF8, + 0x9C79: 0x5FF1, + 0x9C7A: 0x5FDD, + 0x9C7B: 0x60B3, + 0x9C7C: 0x5FFF, + 0x9C7D: 0x6021, + 0x9C7E: 0x6060, + 0x9C80: 0x6019, + 0x9C81: 0x6010, + 0x9C82: 0x6029, + 0x9C83: 0x600E, + 0x9C84: 0x6031, + 0x9C85: 0x601B, + 0x9C86: 0x6015, + 0x9C87: 0x602B, + 0x9C88: 0x6026, + 0x9C89: 0x600F, + 0x9C8A: 0x603A, + 0x9C8B: 0x605A, + 0x9C8C: 0x6041, + 0x9C8D: 0x606A, + 0x9C8E: 0x6077, + 0x9C8F: 0x605F, + 0x9C90: 0x604A, + 0x9C91: 0x6046, + 0x9C92: 0x604D, + 0x9C93: 0x6063, + 0x9C94: 0x6043, + 0x9C95: 0x6064, + 0x9C96: 0x6042, + 0x9C97: 0x606C, + 0x9C98: 0x606B, + 0x9C99: 0x6059, + 0x9C9A: 0x6081, + 0x9C9B: 0x608D, + 0x9C9C: 0x60E7, + 0x9C9D: 0x6083, + 0x9C9E: 0x609A, + 0x9C9F: 0x6084, + 0x9CA0: 0x609B, + 0x9CA1: 0x6096, + 0x9CA2: 0x6097, + 0x9CA3: 0x6092, + 0x9CA4: 0x60A7, + 0x9CA5: 0x608B, + 0x9CA6: 0x60E1, + 0x9CA7: 0x60B8, + 0x9CA8: 0x60E0, + 0x9CA9: 0x60D3, + 0x9CAA: 0x60B4, + 0x9CAB: 0x5FF0, + 0x9CAC: 0x60BD, + 0x9CAD: 0x60C6, + 0x9CAE: 0x60B5, + 0x9CAF: 0x60D8, + 0x9CB0: 0x614D, + 0x9CB1: 0x6115, + 0x9CB2: 0x6106, + 0x9CB3: 0x60F6, + 0x9CB4: 0x60F7, + 0x9CB5: 0x6100, + 0x9CB6: 0x60F4, + 0x9CB7: 0x60FA, + 0x9CB8: 0x6103, + 0x9CB9: 0x6121, + 0x9CBA: 0x60FB, + 0x9CBB: 0x60F1, + 0x9CBC: 0x610D, + 0x9CBD: 0x610E, + 0x9CBE: 0x6147, + 0x9CBF: 0x613E, + 0x9CC0: 0x6128, + 0x9CC1: 0x6127, + 0x9CC2: 0x614A, + 0x9CC3: 0x613F, + 0x9CC4: 0x613C, + 0x9CC5: 0x612C, + 0x9CC6: 0x6134, + 0x9CC7: 0x613D, + 0x9CC8: 0x6142, + 0x9CC9: 0x6144, + 0x9CCA: 0x6173, + 0x9CCB: 0x6177, + 0x9CCC: 0x6158, + 0x9CCD: 0x6159, + 0x9CCE: 0x615A, + 0x9CCF: 0x616B, + 0x9CD0: 0x6174, + 0x9CD1: 0x616F, + 0x9CD2: 0x6165, + 0x9CD3: 0x6171, + 0x9CD4: 0x615F, + 0x9CD5: 0x615D, + 0x9CD6: 0x6153, + 0x9CD7: 0x6175, + 0x9CD8: 0x6199, + 0x9CD9: 0x6196, + 0x9CDA: 0x6187, + 0x9CDB: 0x61AC, + 0x9CDC: 0x6194, + 0x9CDD: 0x619A, + 0x9CDE: 0x618A, + 0x9CDF: 0x6191, + 0x9CE0: 0x61AB, + 0x9CE1: 0x61AE, + 0x9CE2: 0x61CC, + 0x9CE3: 0x61CA, + 0x9CE4: 0x61C9, + 0x9CE5: 0x61F7, + 0x9CE6: 0x61C8, + 0x9CE7: 0x61C3, + 0x9CE8: 0x61C6, + 0x9CE9: 0x61BA, + 0x9CEA: 0x61CB, + 0x9CEB: 0x7F79, + 0x9CEC: 0x61CD, + 0x9CED: 0x61E6, + 0x9CEE: 0x61E3, + 0x9CEF: 0x61F6, + 0x9CF0: 0x61FA, + 0x9CF1: 0x61F4, + 0x9CF2: 0x61FF, + 0x9CF3: 0x61FD, + 0x9CF4: 0x61FC, + 0x9CF5: 0x61FE, + 0x9CF6: 0x6200, + 0x9CF7: 0x6208, + 0x9CF8: 0x6209, + 0x9CF9: 0x620D, + 0x9CFA: 0x620C, + 0x9CFB: 0x6214, + 0x9CFC: 0x621B, + 0x9D40: 0x621E, + 0x9D41: 0x6221, + 0x9D42: 0x622A, + 0x9D43: 0x622E, + 0x9D44: 0x6230, + 0x9D45: 0x6232, + 0x9D46: 0x6233, + 0x9D47: 0x6241, + 0x9D48: 0x624E, + 0x9D49: 0x625E, + 0x9D4A: 0x6263, + 0x9D4B: 0x625B, + 0x9D4C: 0x6260, + 0x9D4D: 0x6268, + 0x9D4E: 0x627C, + 0x9D4F: 0x6282, + 0x9D50: 0x6289, + 0x9D51: 0x627E, + 0x9D52: 0x6292, + 0x9D53: 0x6293, + 0x9D54: 0x6296, + 0x9D55: 0x62D4, + 0x9D56: 0x6283, + 0x9D57: 0x6294, + 0x9D58: 0x62D7, + 0x9D59: 0x62D1, + 0x9D5A: 0x62BB, + 0x9D5B: 0x62CF, + 0x9D5C: 0x62FF, + 0x9D5D: 0x62C6, + 0x9D5E: 0x64D4, + 0x9D5F: 0x62C8, + 0x9D60: 0x62DC, + 0x9D61: 0x62CC, + 0x9D62: 0x62CA, + 0x9D63: 0x62C2, + 0x9D64: 0x62C7, + 0x9D65: 0x629B, + 0x9D66: 0x62C9, + 0x9D67: 0x630C, + 0x9D68: 0x62EE, + 0x9D69: 0x62F1, + 0x9D6A: 0x6327, + 0x9D6B: 0x6302, + 0x9D6C: 0x6308, + 0x9D6D: 0x62EF, + 0x9D6E: 0x62F5, + 0x9D6F: 0x6350, + 0x9D70: 0x633E, + 0x9D71: 0x634D, + 0x9D72: 0x641C, + 0x9D73: 0x634F, + 0x9D74: 0x6396, + 0x9D75: 0x638E, + 0x9D76: 0x6380, + 0x9D77: 0x63AB, + 0x9D78: 0x6376, + 0x9D79: 0x63A3, + 0x9D7A: 0x638F, + 0x9D7B: 0x6389, + 0x9D7C: 0x639F, + 0x9D7D: 0x63B5, + 0x9D7E: 0x636B, + 0x9D80: 0x6369, + 0x9D81: 0x63BE, + 0x9D82: 0x63E9, + 0x9D83: 0x63C0, + 0x9D84: 0x63C6, + 0x9D85: 0x63E3, + 0x9D86: 0x63C9, + 0x9D87: 0x63D2, + 0x9D88: 0x63F6, + 0x9D89: 0x63C4, + 0x9D8A: 0x6416, + 0x9D8B: 0x6434, + 0x9D8C: 0x6406, + 0x9D8D: 0x6413, + 0x9D8E: 0x6426, + 0x9D8F: 0x6436, + 0x9D90: 0x651D, + 0x9D91: 0x6417, + 0x9D92: 0x6428, + 0x9D93: 0x640F, + 0x9D94: 0x6467, + 0x9D95: 0x646F, + 0x9D96: 0x6476, + 0x9D97: 0x644E, + 0x9D98: 0x652A, + 0x9D99: 0x6495, + 0x9D9A: 0x6493, + 0x9D9B: 0x64A5, + 0x9D9C: 0x64A9, + 0x9D9D: 0x6488, + 0x9D9E: 0x64BC, + 0x9D9F: 0x64DA, + 0x9DA0: 0x64D2, + 0x9DA1: 0x64C5, + 0x9DA2: 0x64C7, + 0x9DA3: 0x64BB, + 0x9DA4: 0x64D8, + 0x9DA5: 0x64C2, + 0x9DA6: 0x64F1, + 0x9DA7: 0x64E7, + 0x9DA8: 0x8209, + 0x9DA9: 0x64E0, + 0x9DAA: 0x64E1, + 0x9DAB: 0x62AC, + 0x9DAC: 0x64E3, + 0x9DAD: 0x64EF, + 0x9DAE: 0x652C, + 0x9DAF: 0x64F6, + 0x9DB0: 0x64F4, + 0x9DB1: 0x64F2, + 0x9DB2: 0x64FA, + 0x9DB3: 0x6500, + 0x9DB4: 0x64FD, + 0x9DB5: 0x6518, + 0x9DB6: 0x651C, + 0x9DB7: 0x6505, + 0x9DB8: 0x6524, + 0x9DB9: 0x6523, + 0x9DBA: 0x652B, + 0x9DBB: 0x6534, + 0x9DBC: 0x6535, + 0x9DBD: 0x6537, + 0x9DBE: 0x6536, + 0x9DBF: 0x6538, + 0x9DC0: 0x754B, + 0x9DC1: 0x6548, + 0x9DC2: 0x6556, + 0x9DC3: 0x6555, + 0x9DC4: 0x654D, + 0x9DC5: 0x6558, + 0x9DC6: 0x655E, + 0x9DC7: 0x655D, + 0x9DC8: 0x6572, + 0x9DC9: 0x6578, + 0x9DCA: 0x6582, + 0x9DCB: 0x6583, + 0x9DCC: 0x8B8A, + 0x9DCD: 0x659B, + 0x9DCE: 0x659F, + 0x9DCF: 0x65AB, + 0x9DD0: 0x65B7, + 0x9DD1: 0x65C3, + 0x9DD2: 0x65C6, + 0x9DD3: 0x65C1, + 0x9DD4: 0x65C4, + 0x9DD5: 0x65CC, + 0x9DD6: 0x65D2, + 0x9DD7: 0x65DB, + 0x9DD8: 0x65D9, + 0x9DD9: 0x65E0, + 0x9DDA: 0x65E1, + 0x9DDB: 0x65F1, + 0x9DDC: 0x6772, + 0x9DDD: 0x660A, + 0x9DDE: 0x6603, + 0x9DDF: 0x65FB, + 0x9DE0: 0x6773, + 0x9DE1: 0x6635, + 0x9DE2: 0x6636, + 0x9DE3: 0x6634, + 0x9DE4: 0x661C, + 0x9DE5: 0x664F, + 0x9DE6: 0x6644, + 0x9DE7: 0x6649, + 0x9DE8: 0x6641, + 0x9DE9: 0x665E, + 0x9DEA: 0x665D, + 0x9DEB: 0x6664, + 0x9DEC: 0x6667, + 0x9DED: 0x6668, + 0x9DEE: 0x665F, + 0x9DEF: 0x6662, + 0x9DF0: 0x6670, + 0x9DF1: 0x6683, + 0x9DF2: 0x6688, + 0x9DF3: 0x668E, + 0x9DF4: 0x6689, + 0x9DF5: 0x6684, + 0x9DF6: 0x6698, + 0x9DF7: 0x669D, + 0x9DF8: 0x66C1, + 0x9DF9: 0x66B9, + 0x9DFA: 0x66C9, + 0x9DFB: 0x66BE, + 0x9DFC: 0x66BC, + 0x9E40: 0x66C4, + 0x9E41: 0x66B8, + 0x9E42: 0x66D6, + 0x9E43: 0x66DA, + 0x9E44: 0x66E0, + 0x9E45: 0x663F, + 0x9E46: 0x66E6, + 0x9E47: 0x66E9, + 0x9E48: 0x66F0, + 0x9E49: 0x66F5, + 0x9E4A: 0x66F7, + 0x9E4B: 0x670F, + 0x9E4C: 0x6716, + 0x9E4D: 0x671E, + 0x9E4E: 0x6726, + 0x9E4F: 0x6727, + 0x9E50: 0x9738, + 0x9E51: 0x672E, + 0x9E52: 0x673F, + 0x9E53: 0x6736, + 0x9E54: 0x6741, + 0x9E55: 0x6738, + 0x9E56: 0x6737, + 0x9E57: 0x6746, + 0x9E58: 0x675E, + 0x9E59: 0x6760, + 0x9E5A: 0x6759, + 0x9E5B: 0x6763, + 0x9E5C: 0x6764, + 0x9E5D: 0x6789, + 0x9E5E: 0x6770, + 0x9E5F: 0x67A9, + 0x9E60: 0x677C, + 0x9E61: 0x676A, + 0x9E62: 0x678C, + 0x9E63: 0x678B, + 0x9E64: 0x67A6, + 0x9E65: 0x67A1, + 0x9E66: 0x6785, + 0x9E67: 0x67B7, + 0x9E68: 0x67EF, + 0x9E69: 0x67B4, + 0x9E6A: 0x67EC, + 0x9E6B: 0x67B3, + 0x9E6C: 0x67E9, + 0x9E6D: 0x67B8, + 0x9E6E: 0x67E4, + 0x9E6F: 0x67DE, + 0x9E70: 0x67DD, + 0x9E71: 0x67E2, + 0x9E72: 0x67EE, + 0x9E73: 0x67B9, + 0x9E74: 0x67CE, + 0x9E75: 0x67C6, + 0x9E76: 0x67E7, + 0x9E77: 0x6A9C, + 0x9E78: 0x681E, + 0x9E79: 0x6846, + 0x9E7A: 0x6829, + 0x9E7B: 0x6840, + 0x9E7C: 0x684D, + 0x9E7D: 0x6832, + 0x9E7E: 0x684E, + 0x9E80: 0x68B3, + 0x9E81: 0x682B, + 0x9E82: 0x6859, + 0x9E83: 0x6863, + 0x9E84: 0x6877, + 0x9E85: 0x687F, + 0x9E86: 0x689F, + 0x9E87: 0x688F, + 0x9E88: 0x68AD, + 0x9E89: 0x6894, + 0x9E8A: 0x689D, + 0x9E8B: 0x689B, + 0x9E8C: 0x6883, + 0x9E8D: 0x6AAE, + 0x9E8E: 0x68B9, + 0x9E8F: 0x6874, + 0x9E90: 0x68B5, + 0x9E91: 0x68A0, + 0x9E92: 0x68BA, + 0x9E93: 0x690F, + 0x9E94: 0x688D, + 0x9E95: 0x687E, + 0x9E96: 0x6901, + 0x9E97: 0x68CA, + 0x9E98: 0x6908, + 0x9E99: 0x68D8, + 0x9E9A: 0x6922, + 0x9E9B: 0x6926, + 0x9E9C: 0x68E1, + 0x9E9D: 0x690C, + 0x9E9E: 0x68CD, + 0x9E9F: 0x68D4, + 0x9EA0: 0x68E7, + 0x9EA1: 0x68D5, + 0x9EA2: 0x6936, + 0x9EA3: 0x6912, + 0x9EA4: 0x6904, + 0x9EA5: 0x68D7, + 0x9EA6: 0x68E3, + 0x9EA7: 0x6925, + 0x9EA8: 0x68F9, + 0x9EA9: 0x68E0, + 0x9EAA: 0x68EF, + 0x9EAB: 0x6928, + 0x9EAC: 0x692A, + 0x9EAD: 0x691A, + 0x9EAE: 0x6923, + 0x9EAF: 0x6921, + 0x9EB0: 0x68C6, + 0x9EB1: 0x6979, + 0x9EB2: 0x6977, + 0x9EB3: 0x695C, + 0x9EB4: 0x6978, + 0x9EB5: 0x696B, + 0x9EB6: 0x6954, + 0x9EB7: 0x697E, + 0x9EB8: 0x696E, + 0x9EB9: 0x6939, + 0x9EBA: 0x6974, + 0x9EBB: 0x693D, + 0x9EBC: 0x6959, + 0x9EBD: 0x6930, + 0x9EBE: 0x6961, + 0x9EBF: 0x695E, + 0x9EC0: 0x695D, + 0x9EC1: 0x6981, + 0x9EC2: 0x696A, + 0x9EC3: 0x69B2, + 0x9EC4: 0x69AE, + 0x9EC5: 0x69D0, + 0x9EC6: 0x69BF, + 0x9EC7: 0x69C1, + 0x9EC8: 0x69D3, + 0x9EC9: 0x69BE, + 0x9ECA: 0x69CE, + 0x9ECB: 0x5BE8, + 0x9ECC: 0x69CA, + 0x9ECD: 0x69DD, + 0x9ECE: 0x69BB, + 0x9ECF: 0x69C3, + 0x9ED0: 0x69A7, + 0x9ED1: 0x6A2E, + 0x9ED2: 0x6991, + 0x9ED3: 0x69A0, + 0x9ED4: 0x699C, + 0x9ED5: 0x6995, + 0x9ED6: 0x69B4, + 0x9ED7: 0x69DE, + 0x9ED8: 0x69E8, + 0x9ED9: 0x6A02, + 0x9EDA: 0x6A1B, + 0x9EDB: 0x69FF, + 0x9EDC: 0x6B0A, + 0x9EDD: 0x69F9, + 0x9EDE: 0x69F2, + 0x9EDF: 0x69E7, + 0x9EE0: 0x6A05, + 0x9EE1: 0x69B1, + 0x9EE2: 0x6A1E, + 0x9EE3: 0x69ED, + 0x9EE4: 0x6A14, + 0x9EE5: 0x69EB, + 0x9EE6: 0x6A0A, + 0x9EE7: 0x6A12, + 0x9EE8: 0x6AC1, + 0x9EE9: 0x6A23, + 0x9EEA: 0x6A13, + 0x9EEB: 0x6A44, + 0x9EEC: 0x6A0C, + 0x9EED: 0x6A72, + 0x9EEE: 0x6A36, + 0x9EEF: 0x6A78, + 0x9EF0: 0x6A47, + 0x9EF1: 0x6A62, + 0x9EF2: 0x6A59, + 0x9EF3: 0x6A66, + 0x9EF4: 0x6A48, + 0x9EF5: 0x6A38, + 0x9EF6: 0x6A22, + 0x9EF7: 0x6A90, + 0x9EF8: 0x6A8D, + 0x9EF9: 0x6AA0, + 0x9EFA: 0x6A84, + 0x9EFB: 0x6AA2, + 0x9EFC: 0x6AA3, + 0x9F40: 0x6A97, + 0x9F41: 0x8617, + 0x9F42: 0x6ABB, + 0x9F43: 0x6AC3, + 0x9F44: 0x6AC2, + 0x9F45: 0x6AB8, + 0x9F46: 0x6AB3, + 0x9F47: 0x6AAC, + 0x9F48: 0x6ADE, + 0x9F49: 0x6AD1, + 0x9F4A: 0x6ADF, + 0x9F4B: 0x6AAA, + 0x9F4C: 0x6ADA, + 0x9F4D: 0x6AEA, + 0x9F4E: 0x6AFB, + 0x9F4F: 0x6B05, + 0x9F50: 0x8616, + 0x9F51: 0x6AFA, + 0x9F52: 0x6B12, + 0x9F53: 0x6B16, + 0x9F54: 0x9B31, + 0x9F55: 0x6B1F, + 0x9F56: 0x6B38, + 0x9F57: 0x6B37, + 0x9F58: 0x76DC, + 0x9F59: 0x6B39, + 0x9F5A: 0x98EE, + 0x9F5B: 0x6B47, + 0x9F5C: 0x6B43, + 0x9F5D: 0x6B49, + 0x9F5E: 0x6B50, + 0x9F5F: 0x6B59, + 0x9F60: 0x6B54, + 0x9F61: 0x6B5B, + 0x9F62: 0x6B5F, + 0x9F63: 0x6B61, + 0x9F64: 0x6B78, + 0x9F65: 0x6B79, + 0x9F66: 0x6B7F, + 0x9F67: 0x6B80, + 0x9F68: 0x6B84, + 0x9F69: 0x6B83, + 0x9F6A: 0x6B8D, + 0x9F6B: 0x6B98, + 0x9F6C: 0x6B95, + 0x9F6D: 0x6B9E, + 0x9F6E: 0x6BA4, + 0x9F6F: 0x6BAA, + 0x9F70: 0x6BAB, + 0x9F71: 0x6BAF, + 0x9F72: 0x6BB2, + 0x9F73: 0x6BB1, + 0x9F74: 0x6BB3, + 0x9F75: 0x6BB7, + 0x9F76: 0x6BBC, + 0x9F77: 0x6BC6, + 0x9F78: 0x6BCB, + 0x9F79: 0x6BD3, + 0x9F7A: 0x6BDF, + 0x9F7B: 0x6BEC, + 0x9F7C: 0x6BEB, + 0x9F7D: 0x6BF3, + 0x9F7E: 0x6BEF, + 0x9F80: 0x9EBE, + 0x9F81: 0x6C08, + 0x9F82: 0x6C13, + 0x9F83: 0x6C14, + 0x9F84: 0x6C1B, + 0x9F85: 0x6C24, + 0x9F86: 0x6C23, + 0x9F87: 0x6C5E, + 0x9F88: 0x6C55, + 0x9F89: 0x6C62, + 0x9F8A: 0x6C6A, + 0x9F8B: 0x6C82, + 0x9F8C: 0x6C8D, + 0x9F8D: 0x6C9A, + 0x9F8E: 0x6C81, + 0x9F8F: 0x6C9B, + 0x9F90: 0x6C7E, + 0x9F91: 0x6C68, + 0x9F92: 0x6C73, + 0x9F93: 0x6C92, + 0x9F94: 0x6C90, + 0x9F95: 0x6CC4, + 0x9F96: 0x6CF1, + 0x9F97: 0x6CD3, + 0x9F98: 0x6CBD, + 0x9F99: 0x6CD7, + 0x9F9A: 0x6CC5, + 0x9F9B: 0x6CDD, + 0x9F9C: 0x6CAE, + 0x9F9D: 0x6CB1, + 0x9F9E: 0x6CBE, + 0x9F9F: 0x6CBA, + 0x9FA0: 0x6CDB, + 0x9FA1: 0x6CEF, + 0x9FA2: 0x6CD9, + 0x9FA3: 0x6CEA, + 0x9FA4: 0x6D1F, + 0x9FA5: 0x884D, + 0x9FA6: 0x6D36, + 0x9FA7: 0x6D2B, + 0x9FA8: 0x6D3D, + 0x9FA9: 0x6D38, + 0x9FAA: 0x6D19, + 0x9FAB: 0x6D35, + 0x9FAC: 0x6D33, + 0x9FAD: 0x6D12, + 0x9FAE: 0x6D0C, + 0x9FAF: 0x6D63, + 0x9FB0: 0x6D93, + 0x9FB1: 0x6D64, + 0x9FB2: 0x6D5A, + 0x9FB3: 0x6D79, + 0x9FB4: 0x6D59, + 0x9FB5: 0x6D8E, + 0x9FB6: 0x6D95, + 0x9FB7: 0x6FE4, + 0x9FB8: 0x6D85, + 0x9FB9: 0x6DF9, + 0x9FBA: 0x6E15, + 0x9FBB: 0x6E0A, + 0x9FBC: 0x6DB5, + 0x9FBD: 0x6DC7, + 0x9FBE: 0x6DE6, + 0x9FBF: 0x6DB8, + 0x9FC0: 0x6DC6, + 0x9FC1: 0x6DEC, + 0x9FC2: 0x6DDE, + 0x9FC3: 0x6DCC, + 0x9FC4: 0x6DE8, + 0x9FC5: 0x6DD2, + 0x9FC6: 0x6DC5, + 0x9FC7: 0x6DFA, + 0x9FC8: 0x6DD9, + 0x9FC9: 0x6DE4, + 0x9FCA: 0x6DD5, + 0x9FCB: 0x6DEA, + 0x9FCC: 0x6DEE, + 0x9FCD: 0x6E2D, + 0x9FCE: 0x6E6E, + 0x9FCF: 0x6E2E, + 0x9FD0: 0x6E19, + 0x9FD1: 0x6E72, + 0x9FD2: 0x6E5F, + 0x9FD3: 0x6E3E, + 0x9FD4: 0x6E23, + 0x9FD5: 0x6E6B, + 0x9FD6: 0x6E2B, + 0x9FD7: 0x6E76, + 0x9FD8: 0x6E4D, + 0x9FD9: 0x6E1F, + 0x9FDA: 0x6E43, + 0x9FDB: 0x6E3A, + 0x9FDC: 0x6E4E, + 0x9FDD: 0x6E24, + 0x9FDE: 0x6EFF, + 0x9FDF: 0x6E1D, + 0x9FE0: 0x6E38, + 0x9FE1: 0x6E82, + 0x9FE2: 0x6EAA, + 0x9FE3: 0x6E98, + 0x9FE4: 0x6EC9, + 0x9FE5: 0x6EB7, + 0x9FE6: 0x6ED3, + 0x9FE7: 0x6EBD, + 0x9FE8: 0x6EAF, + 0x9FE9: 0x6EC4, + 0x9FEA: 0x6EB2, + 0x9FEB: 0x6ED4, + 0x9FEC: 0x6ED5, + 0x9FED: 0x6E8F, + 0x9FEE: 0x6EA5, + 0x9FEF: 0x6EC2, + 0x9FF0: 0x6E9F, + 0x9FF1: 0x6F41, + 0x9FF2: 0x6F11, + 0x9FF3: 0x704C, + 0x9FF4: 0x6EEC, + 0x9FF5: 0x6EF8, + 0x9FF6: 0x6EFE, + 0x9FF7: 0x6F3F, + 0x9FF8: 0x6EF2, + 0x9FF9: 0x6F31, + 0x9FFA: 0x6EEF, + 0x9FFB: 0x6F32, + 0x9FFC: 0x6ECC, + 0xA1: 0xFF61, + 0xA2: 0xFF62, + 0xA3: 0xFF63, + 0xA4: 0xFF64, + 0xA5: 0xFF65, + 0xA6: 0xFF66, + 0xA7: 0xFF67, + 0xA8: 0xFF68, + 0xA9: 0xFF69, + 0xAA: 0xFF6A, + 0xAB: 0xFF6B, + 0xAC: 0xFF6C, + 0xAD: 0xFF6D, + 0xAE: 0xFF6E, + 0xAF: 0xFF6F, + 0xB0: 0xFF70, + 0xB1: 0xFF71, + 0xB2: 0xFF72, + 0xB3: 0xFF73, + 0xB4: 0xFF74, + 0xB5: 0xFF75, + 0xB6: 0xFF76, + 0xB7: 0xFF77, + 0xB8: 0xFF78, + 0xB9: 0xFF79, + 0xBA: 0xFF7A, + 0xBB: 0xFF7B, + 0xBC: 0xFF7C, + 0xBD: 0xFF7D, + 0xBE: 0xFF7E, + 0xBF: 0xFF7F, + 0xC0: 0xFF80, + 0xC1: 0xFF81, + 0xC2: 0xFF82, + 0xC3: 0xFF83, + 0xC4: 0xFF84, + 0xC5: 0xFF85, + 0xC6: 0xFF86, + 0xC7: 0xFF87, + 0xC8: 0xFF88, + 0xC9: 0xFF89, + 0xCA: 0xFF8A, + 0xCB: 0xFF8B, + 0xCC: 0xFF8C, + 0xCD: 0xFF8D, + 0xCE: 0xFF8E, + 0xCF: 0xFF8F, + 0xD0: 0xFF90, + 0xD1: 0xFF91, + 0xD2: 0xFF92, + 0xD3: 0xFF93, + 0xD4: 0xFF94, + 0xD5: 0xFF95, + 0xD6: 0xFF96, + 0xD7: 0xFF97, + 0xD8: 0xFF98, + 0xD9: 0xFF99, + 0xDA: 0xFF9A, + 0xDB: 0xFF9B, + 0xDC: 0xFF9C, + 0xDD: 0xFF9D, + 0xDE: 0xFF9E, + 0xDF: 0xFF9F, + 0xE040: 0x6F3E, + 0xE041: 0x6F13, + 0xE042: 0x6EF7, + 0xE043: 0x6F86, + 0xE044: 0x6F7A, + 0xE045: 0x6F78, + 0xE046: 0x6F81, + 0xE047: 0x6F80, + 0xE048: 0x6F6F, + 0xE049: 0x6F5B, + 0xE04A: 0x6FF3, + 0xE04B: 0x6F6D, + 0xE04C: 0x6F82, + 0xE04D: 0x6F7C, + 0xE04E: 0x6F58, + 0xE04F: 0x6F8E, + 0xE050: 0x6F91, + 0xE051: 0x6FC2, + 0xE052: 0x6F66, + 0xE053: 0x6FB3, + 0xE054: 0x6FA3, + 0xE055: 0x6FA1, + 0xE056: 0x6FA4, + 0xE057: 0x6FB9, + 0xE058: 0x6FC6, + 0xE059: 0x6FAA, + 0xE05A: 0x6FDF, + 0xE05B: 0x6FD5, + 0xE05C: 0x6FEC, + 0xE05D: 0x6FD4, + 0xE05E: 0x6FD8, + 0xE05F: 0x6FF1, + 0xE060: 0x6FEE, + 0xE061: 0x6FDB, + 0xE062: 0x7009, + 0xE063: 0x700B, + 0xE064: 0x6FFA, + 0xE065: 0x7011, + 0xE066: 0x7001, + 0xE067: 0x700F, + 0xE068: 0x6FFE, + 0xE069: 0x701B, + 0xE06A: 0x701A, + 0xE06B: 0x6F74, + 0xE06C: 0x701D, + 0xE06D: 0x7018, + 0xE06E: 0x701F, + 0xE06F: 0x7030, + 0xE070: 0x703E, + 0xE071: 0x7032, + 0xE072: 0x7051, + 0xE073: 0x7063, + 0xE074: 0x7099, + 0xE075: 0x7092, + 0xE076: 0x70AF, + 0xE077: 0x70F1, + 0xE078: 0x70AC, + 0xE079: 0x70B8, + 0xE07A: 0x70B3, + 0xE07B: 0x70AE, + 0xE07C: 0x70DF, + 0xE07D: 0x70CB, + 0xE07E: 0x70DD, + 0xE080: 0x70D9, + 0xE081: 0x7109, + 0xE082: 0x70FD, + 0xE083: 0x711C, + 0xE084: 0x7119, + 0xE085: 0x7165, + 0xE086: 0x7155, + 0xE087: 0x7188, + 0xE088: 0x7166, + 0xE089: 0x7162, + 0xE08A: 0x714C, + 0xE08B: 0x7156, + 0xE08C: 0x716C, + 0xE08D: 0x718F, + 0xE08E: 0x71FB, + 0xE08F: 0x7184, + 0xE090: 0x7195, + 0xE091: 0x71A8, + 0xE092: 0x71AC, + 0xE093: 0x71D7, + 0xE094: 0x71B9, + 0xE095: 0x71BE, + 0xE096: 0x71D2, + 0xE097: 0x71C9, + 0xE098: 0x71D4, + 0xE099: 0x71CE, + 0xE09A: 0x71E0, + 0xE09B: 0x71EC, + 0xE09C: 0x71E7, + 0xE09D: 0x71F5, + 0xE09E: 0x71FC, + 0xE09F: 0x71F9, + 0xE0A0: 0x71FF, + 0xE0A1: 0x720D, + 0xE0A2: 0x7210, + 0xE0A3: 0x721B, + 0xE0A4: 0x7228, + 0xE0A5: 0x722D, + 0xE0A6: 0x722C, + 0xE0A7: 0x7230, + 0xE0A8: 0x7232, + 0xE0A9: 0x723B, + 0xE0AA: 0x723C, + 0xE0AB: 0x723F, + 0xE0AC: 0x7240, + 0xE0AD: 0x7246, + 0xE0AE: 0x724B, + 0xE0AF: 0x7258, + 0xE0B0: 0x7274, + 0xE0B1: 0x727E, + 0xE0B2: 0x7282, + 0xE0B3: 0x7281, + 0xE0B4: 0x7287, + 0xE0B5: 0x7292, + 0xE0B6: 0x7296, + 0xE0B7: 0x72A2, + 0xE0B8: 0x72A7, + 0xE0B9: 0x72B9, + 0xE0BA: 0x72B2, + 0xE0BB: 0x72C3, + 0xE0BC: 0x72C6, + 0xE0BD: 0x72C4, + 0xE0BE: 0x72CE, + 0xE0BF: 0x72D2, + 0xE0C0: 0x72E2, + 0xE0C1: 0x72E0, + 0xE0C2: 0x72E1, + 0xE0C3: 0x72F9, + 0xE0C4: 0x72F7, + 0xE0C5: 0x500F, + 0xE0C6: 0x7317, + 0xE0C7: 0x730A, + 0xE0C8: 0x731C, + 0xE0C9: 0x7316, + 0xE0CA: 0x731D, + 0xE0CB: 0x7334, + 0xE0CC: 0x732F, + 0xE0CD: 0x7329, + 0xE0CE: 0x7325, + 0xE0CF: 0x733E, + 0xE0D0: 0x734E, + 0xE0D1: 0x734F, + 0xE0D2: 0x9ED8, + 0xE0D3: 0x7357, + 0xE0D4: 0x736A, + 0xE0D5: 0x7368, + 0xE0D6: 0x7370, + 0xE0D7: 0x7378, + 0xE0D8: 0x7375, + 0xE0D9: 0x737B, + 0xE0DA: 0x737A, + 0xE0DB: 0x73C8, + 0xE0DC: 0x73B3, + 0xE0DD: 0x73CE, + 0xE0DE: 0x73BB, + 0xE0DF: 0x73C0, + 0xE0E0: 0x73E5, + 0xE0E1: 0x73EE, + 0xE0E2: 0x73DE, + 0xE0E3: 0x74A2, + 0xE0E4: 0x7405, + 0xE0E5: 0x746F, + 0xE0E6: 0x7425, + 0xE0E7: 0x73F8, + 0xE0E8: 0x7432, + 0xE0E9: 0x743A, + 0xE0EA: 0x7455, + 0xE0EB: 0x743F, + 0xE0EC: 0x745F, + 0xE0ED: 0x7459, + 0xE0EE: 0x7441, + 0xE0EF: 0x745C, + 0xE0F0: 0x7469, + 0xE0F1: 0x7470, + 0xE0F2: 0x7463, + 0xE0F3: 0x746A, + 0xE0F4: 0x7476, + 0xE0F5: 0x747E, + 0xE0F6: 0x748B, + 0xE0F7: 0x749E, + 0xE0F8: 0x74A7, + 0xE0F9: 0x74CA, + 0xE0FA: 0x74CF, + 0xE0FB: 0x74D4, + 0xE0FC: 0x73F1, + 0xE140: 0x74E0, + 0xE141: 0x74E3, + 0xE142: 0x74E7, + 0xE143: 0x74E9, + 0xE144: 0x74EE, + 0xE145: 0x74F2, + 0xE146: 0x74F0, + 0xE147: 0x74F1, + 0xE148: 0x74F8, + 0xE149: 0x74F7, + 0xE14A: 0x7504, + 0xE14B: 0x7503, + 0xE14C: 0x7505, + 0xE14D: 0x750C, + 0xE14E: 0x750E, + 0xE14F: 0x750D, + 0xE150: 0x7515, + 0xE151: 0x7513, + 0xE152: 0x751E, + 0xE153: 0x7526, + 0xE154: 0x752C, + 0xE155: 0x753C, + 0xE156: 0x7544, + 0xE157: 0x754D, + 0xE158: 0x754A, + 0xE159: 0x7549, + 0xE15A: 0x755B, + 0xE15B: 0x7546, + 0xE15C: 0x755A, + 0xE15D: 0x7569, + 0xE15E: 0x7564, + 0xE15F: 0x7567, + 0xE160: 0x756B, + 0xE161: 0x756D, + 0xE162: 0x7578, + 0xE163: 0x7576, + 0xE164: 0x7586, + 0xE165: 0x7587, + 0xE166: 0x7574, + 0xE167: 0x758A, + 0xE168: 0x7589, + 0xE169: 0x7582, + 0xE16A: 0x7594, + 0xE16B: 0x759A, + 0xE16C: 0x759D, + 0xE16D: 0x75A5, + 0xE16E: 0x75A3, + 0xE16F: 0x75C2, + 0xE170: 0x75B3, + 0xE171: 0x75C3, + 0xE172: 0x75B5, + 0xE173: 0x75BD, + 0xE174: 0x75B8, + 0xE175: 0x75BC, + 0xE176: 0x75B1, + 0xE177: 0x75CD, + 0xE178: 0x75CA, + 0xE179: 0x75D2, + 0xE17A: 0x75D9, + 0xE17B: 0x75E3, + 0xE17C: 0x75DE, + 0xE17D: 0x75FE, + 0xE17E: 0x75FF, + 0xE180: 0x75FC, + 0xE181: 0x7601, + 0xE182: 0x75F0, + 0xE183: 0x75FA, + 0xE184: 0x75F2, + 0xE185: 0x75F3, + 0xE186: 0x760B, + 0xE187: 0x760D, + 0xE188: 0x7609, + 0xE189: 0x761F, + 0xE18A: 0x7627, + 0xE18B: 0x7620, + 0xE18C: 0x7621, + 0xE18D: 0x7622, + 0xE18E: 0x7624, + 0xE18F: 0x7634, + 0xE190: 0x7630, + 0xE191: 0x763B, + 0xE192: 0x7647, + 0xE193: 0x7648, + 0xE194: 0x7646, + 0xE195: 0x765C, + 0xE196: 0x7658, + 0xE197: 0x7661, + 0xE198: 0x7662, + 0xE199: 0x7668, + 0xE19A: 0x7669, + 0xE19B: 0x766A, + 0xE19C: 0x7667, + 0xE19D: 0x766C, + 0xE19E: 0x7670, + 0xE19F: 0x7672, + 0xE1A0: 0x7676, + 0xE1A1: 0x7678, + 0xE1A2: 0x767C, + 0xE1A3: 0x7680, + 0xE1A4: 0x7683, + 0xE1A5: 0x7688, + 0xE1A6: 0x768B, + 0xE1A7: 0x768E, + 0xE1A8: 0x7696, + 0xE1A9: 0x7693, + 0xE1AA: 0x7699, + 0xE1AB: 0x769A, + 0xE1AC: 0x76B0, + 0xE1AD: 0x76B4, + 0xE1AE: 0x76B8, + 0xE1AF: 0x76B9, + 0xE1B0: 0x76BA, + 0xE1B1: 0x76C2, + 0xE1B2: 0x76CD, + 0xE1B3: 0x76D6, + 0xE1B4: 0x76D2, + 0xE1B5: 0x76DE, + 0xE1B6: 0x76E1, + 0xE1B7: 0x76E5, + 0xE1B8: 0x76E7, + 0xE1B9: 0x76EA, + 0xE1BA: 0x862F, + 0xE1BB: 0x76FB, + 0xE1BC: 0x7708, + 0xE1BD: 0x7707, + 0xE1BE: 0x7704, + 0xE1BF: 0x7729, + 0xE1C0: 0x7724, + 0xE1C1: 0x771E, + 0xE1C2: 0x7725, + 0xE1C3: 0x7726, + 0xE1C4: 0x771B, + 0xE1C5: 0x7737, + 0xE1C6: 0x7738, + 0xE1C7: 0x7747, + 0xE1C8: 0x775A, + 0xE1C9: 0x7768, + 0xE1CA: 0x776B, + 0xE1CB: 0x775B, + 0xE1CC: 0x7765, + 0xE1CD: 0x777F, + 0xE1CE: 0x777E, + 0xE1CF: 0x7779, + 0xE1D0: 0x778E, + 0xE1D1: 0x778B, + 0xE1D2: 0x7791, + 0xE1D3: 0x77A0, + 0xE1D4: 0x779E, + 0xE1D5: 0x77B0, + 0xE1D6: 0x77B6, + 0xE1D7: 0x77B9, + 0xE1D8: 0x77BF, + 0xE1D9: 0x77BC, + 0xE1DA: 0x77BD, + 0xE1DB: 0x77BB, + 0xE1DC: 0x77C7, + 0xE1DD: 0x77CD, + 0xE1DE: 0x77D7, + 0xE1DF: 0x77DA, + 0xE1E0: 0x77DC, + 0xE1E1: 0x77E3, + 0xE1E2: 0x77EE, + 0xE1E3: 0x77FC, + 0xE1E4: 0x780C, + 0xE1E5: 0x7812, + 0xE1E6: 0x7926, + 0xE1E7: 0x7820, + 0xE1E8: 0x792A, + 0xE1E9: 0x7845, + 0xE1EA: 0x788E, + 0xE1EB: 0x7874, + 0xE1EC: 0x7886, + 0xE1ED: 0x787C, + 0xE1EE: 0x789A, + 0xE1EF: 0x788C, + 0xE1F0: 0x78A3, + 0xE1F1: 0x78B5, + 0xE1F2: 0x78AA, + 0xE1F3: 0x78AF, + 0xE1F4: 0x78D1, + 0xE1F5: 0x78C6, + 0xE1F6: 0x78CB, + 0xE1F7: 0x78D4, + 0xE1F8: 0x78BE, + 0xE1F9: 0x78BC, + 0xE1FA: 0x78C5, + 0xE1FB: 0x78CA, + 0xE1FC: 0x78EC, + 0xE240: 0x78E7, + 0xE241: 0x78DA, + 0xE242: 0x78FD, + 0xE243: 0x78F4, + 0xE244: 0x7907, + 0xE245: 0x7912, + 0xE246: 0x7911, + 0xE247: 0x7919, + 0xE248: 0x792C, + 0xE249: 0x792B, + 0xE24A: 0x7940, + 0xE24B: 0x7960, + 0xE24C: 0x7957, + 0xE24D: 0x795F, + 0xE24E: 0x795A, + 0xE24F: 0x7955, + 0xE250: 0x7953, + 0xE251: 0x797A, + 0xE252: 0x797F, + 0xE253: 0x798A, + 0xE254: 0x799D, + 0xE255: 0x79A7, + 0xE256: 0x9F4B, + 0xE257: 0x79AA, + 0xE258: 0x79AE, + 0xE259: 0x79B3, + 0xE25A: 0x79B9, + 0xE25B: 0x79BA, + 0xE25C: 0x79C9, + 0xE25D: 0x79D5, + 0xE25E: 0x79E7, + 0xE25F: 0x79EC, + 0xE260: 0x79E1, + 0xE261: 0x79E3, + 0xE262: 0x7A08, + 0xE263: 0x7A0D, + 0xE264: 0x7A18, + 0xE265: 0x7A19, + 0xE266: 0x7A20, + 0xE267: 0x7A1F, + 0xE268: 0x7980, + 0xE269: 0x7A31, + 0xE26A: 0x7A3B, + 0xE26B: 0x7A3E, + 0xE26C: 0x7A37, + 0xE26D: 0x7A43, + 0xE26E: 0x7A57, + 0xE26F: 0x7A49, + 0xE270: 0x7A61, + 0xE271: 0x7A62, + 0xE272: 0x7A69, + 0xE273: 0x9F9D, + 0xE274: 0x7A70, + 0xE275: 0x7A79, + 0xE276: 0x7A7D, + 0xE277: 0x7A88, + 0xE278: 0x7A97, + 0xE279: 0x7A95, + 0xE27A: 0x7A98, + 0xE27B: 0x7A96, + 0xE27C: 0x7AA9, + 0xE27D: 0x7AC8, + 0xE27E: 0x7AB0, + 0xE280: 0x7AB6, + 0xE281: 0x7AC5, + 0xE282: 0x7AC4, + 0xE283: 0x7ABF, + 0xE284: 0x9083, + 0xE285: 0x7AC7, + 0xE286: 0x7ACA, + 0xE287: 0x7ACD, + 0xE288: 0x7ACF, + 0xE289: 0x7AD5, + 0xE28A: 0x7AD3, + 0xE28B: 0x7AD9, + 0xE28C: 0x7ADA, + 0xE28D: 0x7ADD, + 0xE28E: 0x7AE1, + 0xE28F: 0x7AE2, + 0xE290: 0x7AE6, + 0xE291: 0x7AED, + 0xE292: 0x7AF0, + 0xE293: 0x7B02, + 0xE294: 0x7B0F, + 0xE295: 0x7B0A, + 0xE296: 0x7B06, + 0xE297: 0x7B33, + 0xE298: 0x7B18, + 0xE299: 0x7B19, + 0xE29A: 0x7B1E, + 0xE29B: 0x7B35, + 0xE29C: 0x7B28, + 0xE29D: 0x7B36, + 0xE29E: 0x7B50, + 0xE29F: 0x7B7A, + 0xE2A0: 0x7B04, + 0xE2A1: 0x7B4D, + 0xE2A2: 0x7B0B, + 0xE2A3: 0x7B4C, + 0xE2A4: 0x7B45, + 0xE2A5: 0x7B75, + 0xE2A6: 0x7B65, + 0xE2A7: 0x7B74, + 0xE2A8: 0x7B67, + 0xE2A9: 0x7B70, + 0xE2AA: 0x7B71, + 0xE2AB: 0x7B6C, + 0xE2AC: 0x7B6E, + 0xE2AD: 0x7B9D, + 0xE2AE: 0x7B98, + 0xE2AF: 0x7B9F, + 0xE2B0: 0x7B8D, + 0xE2B1: 0x7B9C, + 0xE2B2: 0x7B9A, + 0xE2B3: 0x7B8B, + 0xE2B4: 0x7B92, + 0xE2B5: 0x7B8F, + 0xE2B6: 0x7B5D, + 0xE2B7: 0x7B99, + 0xE2B8: 0x7BCB, + 0xE2B9: 0x7BC1, + 0xE2BA: 0x7BCC, + 0xE2BB: 0x7BCF, + 0xE2BC: 0x7BB4, + 0xE2BD: 0x7BC6, + 0xE2BE: 0x7BDD, + 0xE2BF: 0x7BE9, + 0xE2C0: 0x7C11, + 0xE2C1: 0x7C14, + 0xE2C2: 0x7BE6, + 0xE2C3: 0x7BE5, + 0xE2C4: 0x7C60, + 0xE2C5: 0x7C00, + 0xE2C6: 0x7C07, + 0xE2C7: 0x7C13, + 0xE2C8: 0x7BF3, + 0xE2C9: 0x7BF7, + 0xE2CA: 0x7C17, + 0xE2CB: 0x7C0D, + 0xE2CC: 0x7BF6, + 0xE2CD: 0x7C23, + 0xE2CE: 0x7C27, + 0xE2CF: 0x7C2A, + 0xE2D0: 0x7C1F, + 0xE2D1: 0x7C37, + 0xE2D2: 0x7C2B, + 0xE2D3: 0x7C3D, + 0xE2D4: 0x7C4C, + 0xE2D5: 0x7C43, + 0xE2D6: 0x7C54, + 0xE2D7: 0x7C4F, + 0xE2D8: 0x7C40, + 0xE2D9: 0x7C50, + 0xE2DA: 0x7C58, + 0xE2DB: 0x7C5F, + 0xE2DC: 0x7C64, + 0xE2DD: 0x7C56, + 0xE2DE: 0x7C65, + 0xE2DF: 0x7C6C, + 0xE2E0: 0x7C75, + 0xE2E1: 0x7C83, + 0xE2E2: 0x7C90, + 0xE2E3: 0x7CA4, + 0xE2E4: 0x7CAD, + 0xE2E5: 0x7CA2, + 0xE2E6: 0x7CAB, + 0xE2E7: 0x7CA1, + 0xE2E8: 0x7CA8, + 0xE2E9: 0x7CB3, + 0xE2EA: 0x7CB2, + 0xE2EB: 0x7CB1, + 0xE2EC: 0x7CAE, + 0xE2ED: 0x7CB9, + 0xE2EE: 0x7CBD, + 0xE2EF: 0x7CC0, + 0xE2F0: 0x7CC5, + 0xE2F1: 0x7CC2, + 0xE2F2: 0x7CD8, + 0xE2F3: 0x7CD2, + 0xE2F4: 0x7CDC, + 0xE2F5: 0x7CE2, + 0xE2F6: 0x9B3B, + 0xE2F7: 0x7CEF, + 0xE2F8: 0x7CF2, + 0xE2F9: 0x7CF4, + 0xE2FA: 0x7CF6, + 0xE2FB: 0x7CFA, + 0xE2FC: 0x7D06, + 0xE340: 0x7D02, + 0xE341: 0x7D1C, + 0xE342: 0x7D15, + 0xE343: 0x7D0A, + 0xE344: 0x7D45, + 0xE345: 0x7D4B, + 0xE346: 0x7D2E, + 0xE347: 0x7D32, + 0xE348: 0x7D3F, + 0xE349: 0x7D35, + 0xE34A: 0x7D46, + 0xE34B: 0x7D73, + 0xE34C: 0x7D56, + 0xE34D: 0x7D4E, + 0xE34E: 0x7D72, + 0xE34F: 0x7D68, + 0xE350: 0x7D6E, + 0xE351: 0x7D4F, + 0xE352: 0x7D63, + 0xE353: 0x7D93, + 0xE354: 0x7D89, + 0xE355: 0x7D5B, + 0xE356: 0x7D8F, + 0xE357: 0x7D7D, + 0xE358: 0x7D9B, + 0xE359: 0x7DBA, + 0xE35A: 0x7DAE, + 0xE35B: 0x7DA3, + 0xE35C: 0x7DB5, + 0xE35D: 0x7DC7, + 0xE35E: 0x7DBD, + 0xE35F: 0x7DAB, + 0xE360: 0x7E3D, + 0xE361: 0x7DA2, + 0xE362: 0x7DAF, + 0xE363: 0x7DDC, + 0xE364: 0x7DB8, + 0xE365: 0x7D9F, + 0xE366: 0x7DB0, + 0xE367: 0x7DD8, + 0xE368: 0x7DDD, + 0xE369: 0x7DE4, + 0xE36A: 0x7DDE, + 0xE36B: 0x7DFB, + 0xE36C: 0x7DF2, + 0xE36D: 0x7DE1, + 0xE36E: 0x7E05, + 0xE36F: 0x7E0A, + 0xE370: 0x7E23, + 0xE371: 0x7E21, + 0xE372: 0x7E12, + 0xE373: 0x7E31, + 0xE374: 0x7E1F, + 0xE375: 0x7E09, + 0xE376: 0x7E0B, + 0xE377: 0x7E22, + 0xE378: 0x7E46, + 0xE379: 0x7E66, + 0xE37A: 0x7E3B, + 0xE37B: 0x7E35, + 0xE37C: 0x7E39, + 0xE37D: 0x7E43, + 0xE37E: 0x7E37, + 0xE380: 0x7E32, + 0xE381: 0x7E3A, + 0xE382: 0x7E67, + 0xE383: 0x7E5D, + 0xE384: 0x7E56, + 0xE385: 0x7E5E, + 0xE386: 0x7E59, + 0xE387: 0x7E5A, + 0xE388: 0x7E79, + 0xE389: 0x7E6A, + 0xE38A: 0x7E69, + 0xE38B: 0x7E7C, + 0xE38C: 0x7E7B, + 0xE38D: 0x7E83, + 0xE38E: 0x7DD5, + 0xE38F: 0x7E7D, + 0xE390: 0x8FAE, + 0xE391: 0x7E7F, + 0xE392: 0x7E88, + 0xE393: 0x7E89, + 0xE394: 0x7E8C, + 0xE395: 0x7E92, + 0xE396: 0x7E90, + 0xE397: 0x7E93, + 0xE398: 0x7E94, + 0xE399: 0x7E96, + 0xE39A: 0x7E8E, + 0xE39B: 0x7E9B, + 0xE39C: 0x7E9C, + 0xE39D: 0x7F38, + 0xE39E: 0x7F3A, + 0xE39F: 0x7F45, + 0xE3A0: 0x7F4C, + 0xE3A1: 0x7F4D, + 0xE3A2: 0x7F4E, + 0xE3A3: 0x7F50, + 0xE3A4: 0x7F51, + 0xE3A5: 0x7F55, + 0xE3A6: 0x7F54, + 0xE3A7: 0x7F58, + 0xE3A8: 0x7F5F, + 0xE3A9: 0x7F60, + 0xE3AA: 0x7F68, + 0xE3AB: 0x7F69, + 0xE3AC: 0x7F67, + 0xE3AD: 0x7F78, + 0xE3AE: 0x7F82, + 0xE3AF: 0x7F86, + 0xE3B0: 0x7F83, + 0xE3B1: 0x7F88, + 0xE3B2: 0x7F87, + 0xE3B3: 0x7F8C, + 0xE3B4: 0x7F94, + 0xE3B5: 0x7F9E, + 0xE3B6: 0x7F9D, + 0xE3B7: 0x7F9A, + 0xE3B8: 0x7FA3, + 0xE3B9: 0x7FAF, + 0xE3BA: 0x7FB2, + 0xE3BB: 0x7FB9, + 0xE3BC: 0x7FAE, + 0xE3BD: 0x7FB6, + 0xE3BE: 0x7FB8, + 0xE3BF: 0x8B71, + 0xE3C0: 0x7FC5, + 0xE3C1: 0x7FC6, + 0xE3C2: 0x7FCA, + 0xE3C3: 0x7FD5, + 0xE3C4: 0x7FD4, + 0xE3C5: 0x7FE1, + 0xE3C6: 0x7FE6, + 0xE3C7: 0x7FE9, + 0xE3C8: 0x7FF3, + 0xE3C9: 0x7FF9, + 0xE3CA: 0x98DC, + 0xE3CB: 0x8006, + 0xE3CC: 0x8004, + 0xE3CD: 0x800B, + 0xE3CE: 0x8012, + 0xE3CF: 0x8018, + 0xE3D0: 0x8019, + 0xE3D1: 0x801C, + 0xE3D2: 0x8021, + 0xE3D3: 0x8028, + 0xE3D4: 0x803F, + 0xE3D5: 0x803B, + 0xE3D6: 0x804A, + 0xE3D7: 0x8046, + 0xE3D8: 0x8052, + 0xE3D9: 0x8058, + 0xE3DA: 0x805A, + 0xE3DB: 0x805F, + 0xE3DC: 0x8062, + 0xE3DD: 0x8068, + 0xE3DE: 0x8073, + 0xE3DF: 0x8072, + 0xE3E0: 0x8070, + 0xE3E1: 0x8076, + 0xE3E2: 0x8079, + 0xE3E3: 0x807D, + 0xE3E4: 0x807F, + 0xE3E5: 0x8084, + 0xE3E6: 0x8086, + 0xE3E7: 0x8085, + 0xE3E8: 0x809B, + 0xE3E9: 0x8093, + 0xE3EA: 0x809A, + 0xE3EB: 0x80AD, + 0xE3EC: 0x5190, + 0xE3ED: 0x80AC, + 0xE3EE: 0x80DB, + 0xE3EF: 0x80E5, + 0xE3F0: 0x80D9, + 0xE3F1: 0x80DD, + 0xE3F2: 0x80C4, + 0xE3F3: 0x80DA, + 0xE3F4: 0x80D6, + 0xE3F5: 0x8109, + 0xE3F6: 0x80EF, + 0xE3F7: 0x80F1, + 0xE3F8: 0x811B, + 0xE3F9: 0x8129, + 0xE3FA: 0x8123, + 0xE3FB: 0x812F, + 0xE3FC: 0x814B, + 0xE440: 0x968B, + 0xE441: 0x8146, + 0xE442: 0x813E, + 0xE443: 0x8153, + 0xE444: 0x8151, + 0xE445: 0x80FC, + 0xE446: 0x8171, + 0xE447: 0x816E, + 0xE448: 0x8165, + 0xE449: 0x8166, + 0xE44A: 0x8174, + 0xE44B: 0x8183, + 0xE44C: 0x8188, + 0xE44D: 0x818A, + 0xE44E: 0x8180, + 0xE44F: 0x8182, + 0xE450: 0x81A0, + 0xE451: 0x8195, + 0xE452: 0x81A4, + 0xE453: 0x81A3, + 0xE454: 0x815F, + 0xE455: 0x8193, + 0xE456: 0x81A9, + 0xE457: 0x81B0, + 0xE458: 0x81B5, + 0xE459: 0x81BE, + 0xE45A: 0x81B8, + 0xE45B: 0x81BD, + 0xE45C: 0x81C0, + 0xE45D: 0x81C2, + 0xE45E: 0x81BA, + 0xE45F: 0x81C9, + 0xE460: 0x81CD, + 0xE461: 0x81D1, + 0xE462: 0x81D9, + 0xE463: 0x81D8, + 0xE464: 0x81C8, + 0xE465: 0x81DA, + 0xE466: 0x81DF, + 0xE467: 0x81E0, + 0xE468: 0x81E7, + 0xE469: 0x81FA, + 0xE46A: 0x81FB, + 0xE46B: 0x81FE, + 0xE46C: 0x8201, + 0xE46D: 0x8202, + 0xE46E: 0x8205, + 0xE46F: 0x8207, + 0xE470: 0x820A, + 0xE471: 0x820D, + 0xE472: 0x8210, + 0xE473: 0x8216, + 0xE474: 0x8229, + 0xE475: 0x822B, + 0xE476: 0x8238, + 0xE477: 0x8233, + 0xE478: 0x8240, + 0xE479: 0x8259, + 0xE47A: 0x8258, + 0xE47B: 0x825D, + 0xE47C: 0x825A, + 0xE47D: 0x825F, + 0xE47E: 0x8264, + 0xE480: 0x8262, + 0xE481: 0x8268, + 0xE482: 0x826A, + 0xE483: 0x826B, + 0xE484: 0x822E, + 0xE485: 0x8271, + 0xE486: 0x8277, + 0xE487: 0x8278, + 0xE488: 0x827E, + 0xE489: 0x828D, + 0xE48A: 0x8292, + 0xE48B: 0x82AB, + 0xE48C: 0x829F, + 0xE48D: 0x82BB, + 0xE48E: 0x82AC, + 0xE48F: 0x82E1, + 0xE490: 0x82E3, + 0xE491: 0x82DF, + 0xE492: 0x82D2, + 0xE493: 0x82F4, + 0xE494: 0x82F3, + 0xE495: 0x82FA, + 0xE496: 0x8393, + 0xE497: 0x8303, + 0xE498: 0x82FB, + 0xE499: 0x82F9, + 0xE49A: 0x82DE, + 0xE49B: 0x8306, + 0xE49C: 0x82DC, + 0xE49D: 0x8309, + 0xE49E: 0x82D9, + 0xE49F: 0x8335, + 0xE4A0: 0x8334, + 0xE4A1: 0x8316, + 0xE4A2: 0x8332, + 0xE4A3: 0x8331, + 0xE4A4: 0x8340, + 0xE4A5: 0x8339, + 0xE4A6: 0x8350, + 0xE4A7: 0x8345, + 0xE4A8: 0x832F, + 0xE4A9: 0x832B, + 0xE4AA: 0x8317, + 0xE4AB: 0x8318, + 0xE4AC: 0x8385, + 0xE4AD: 0x839A, + 0xE4AE: 0x83AA, + 0xE4AF: 0x839F, + 0xE4B0: 0x83A2, + 0xE4B1: 0x8396, + 0xE4B2: 0x8323, + 0xE4B3: 0x838E, + 0xE4B4: 0x8387, + 0xE4B5: 0x838A, + 0xE4B6: 0x837C, + 0xE4B7: 0x83B5, + 0xE4B8: 0x8373, + 0xE4B9: 0x8375, + 0xE4BA: 0x83A0, + 0xE4BB: 0x8389, + 0xE4BC: 0x83A8, + 0xE4BD: 0x83F4, + 0xE4BE: 0x8413, + 0xE4BF: 0x83EB, + 0xE4C0: 0x83CE, + 0xE4C1: 0x83FD, + 0xE4C2: 0x8403, + 0xE4C3: 0x83D8, + 0xE4C4: 0x840B, + 0xE4C5: 0x83C1, + 0xE4C6: 0x83F7, + 0xE4C7: 0x8407, + 0xE4C8: 0x83E0, + 0xE4C9: 0x83F2, + 0xE4CA: 0x840D, + 0xE4CB: 0x8422, + 0xE4CC: 0x8420, + 0xE4CD: 0x83BD, + 0xE4CE: 0x8438, + 0xE4CF: 0x8506, + 0xE4D0: 0x83FB, + 0xE4D1: 0x846D, + 0xE4D2: 0x842A, + 0xE4D3: 0x843C, + 0xE4D4: 0x855A, + 0xE4D5: 0x8484, + 0xE4D6: 0x8477, + 0xE4D7: 0x846B, + 0xE4D8: 0x84AD, + 0xE4D9: 0x846E, + 0xE4DA: 0x8482, + 0xE4DB: 0x8469, + 0xE4DC: 0x8446, + 0xE4DD: 0x842C, + 0xE4DE: 0x846F, + 0xE4DF: 0x8479, + 0xE4E0: 0x8435, + 0xE4E1: 0x84CA, + 0xE4E2: 0x8462, + 0xE4E3: 0x84B9, + 0xE4E4: 0x84BF, + 0xE4E5: 0x849F, + 0xE4E6: 0x84D9, + 0xE4E7: 0x84CD, + 0xE4E8: 0x84BB, + 0xE4E9: 0x84DA, + 0xE4EA: 0x84D0, + 0xE4EB: 0x84C1, + 0xE4EC: 0x84C6, + 0xE4ED: 0x84D6, + 0xE4EE: 0x84A1, + 0xE4EF: 0x8521, + 0xE4F0: 0x84FF, + 0xE4F1: 0x84F4, + 0xE4F2: 0x8517, + 0xE4F3: 0x8518, + 0xE4F4: 0x852C, + 0xE4F5: 0x851F, + 0xE4F6: 0x8515, + 0xE4F7: 0x8514, + 0xE4F8: 0x84FC, + 0xE4F9: 0x8540, + 0xE4FA: 0x8563, + 0xE4FB: 0x8558, + 0xE4FC: 0x8548, + 0xE540: 0x8541, + 0xE541: 0x8602, + 0xE542: 0x854B, + 0xE543: 0x8555, + 0xE544: 0x8580, + 0xE545: 0x85A4, + 0xE546: 0x8588, + 0xE547: 0x8591, + 0xE548: 0x858A, + 0xE549: 0x85A8, + 0xE54A: 0x856D, + 0xE54B: 0x8594, + 0xE54C: 0x859B, + 0xE54D: 0x85EA, + 0xE54E: 0x8587, + 0xE54F: 0x859C, + 0xE550: 0x8577, + 0xE551: 0x857E, + 0xE552: 0x8590, + 0xE553: 0x85C9, + 0xE554: 0x85BA, + 0xE555: 0x85CF, + 0xE556: 0x85B9, + 0xE557: 0x85D0, + 0xE558: 0x85D5, + 0xE559: 0x85DD, + 0xE55A: 0x85E5, + 0xE55B: 0x85DC, + 0xE55C: 0x85F9, + 0xE55D: 0x860A, + 0xE55E: 0x8613, + 0xE55F: 0x860B, + 0xE560: 0x85FE, + 0xE561: 0x85FA, + 0xE562: 0x8606, + 0xE563: 0x8622, + 0xE564: 0x861A, + 0xE565: 0x8630, + 0xE566: 0x863F, + 0xE567: 0x864D, + 0xE568: 0x4E55, + 0xE569: 0x8654, + 0xE56A: 0x865F, + 0xE56B: 0x8667, + 0xE56C: 0x8671, + 0xE56D: 0x8693, + 0xE56E: 0x86A3, + 0xE56F: 0x86A9, + 0xE570: 0x86AA, + 0xE571: 0x868B, + 0xE572: 0x868C, + 0xE573: 0x86B6, + 0xE574: 0x86AF, + 0xE575: 0x86C4, + 0xE576: 0x86C6, + 0xE577: 0x86B0, + 0xE578: 0x86C9, + 0xE579: 0x8823, + 0xE57A: 0x86AB, + 0xE57B: 0x86D4, + 0xE57C: 0x86DE, + 0xE57D: 0x86E9, + 0xE57E: 0x86EC, + 0xE580: 0x86DF, + 0xE581: 0x86DB, + 0xE582: 0x86EF, + 0xE583: 0x8712, + 0xE584: 0x8706, + 0xE585: 0x8708, + 0xE586: 0x8700, + 0xE587: 0x8703, + 0xE588: 0x86FB, + 0xE589: 0x8711, + 0xE58A: 0x8709, + 0xE58B: 0x870D, + 0xE58C: 0x86F9, + 0xE58D: 0x870A, + 0xE58E: 0x8734, + 0xE58F: 0x873F, + 0xE590: 0x8737, + 0xE591: 0x873B, + 0xE592: 0x8725, + 0xE593: 0x8729, + 0xE594: 0x871A, + 0xE595: 0x8760, + 0xE596: 0x875F, + 0xE597: 0x8778, + 0xE598: 0x874C, + 0xE599: 0x874E, + 0xE59A: 0x8774, + 0xE59B: 0x8757, + 0xE59C: 0x8768, + 0xE59D: 0x876E, + 0xE59E: 0x8759, + 0xE59F: 0x8753, + 0xE5A0: 0x8763, + 0xE5A1: 0x876A, + 0xE5A2: 0x8805, + 0xE5A3: 0x87A2, + 0xE5A4: 0x879F, + 0xE5A5: 0x8782, + 0xE5A6: 0x87AF, + 0xE5A7: 0x87CB, + 0xE5A8: 0x87BD, + 0xE5A9: 0x87C0, + 0xE5AA: 0x87D0, + 0xE5AB: 0x96D6, + 0xE5AC: 0x87AB, + 0xE5AD: 0x87C4, + 0xE5AE: 0x87B3, + 0xE5AF: 0x87C7, + 0xE5B0: 0x87C6, + 0xE5B1: 0x87BB, + 0xE5B2: 0x87EF, + 0xE5B3: 0x87F2, + 0xE5B4: 0x87E0, + 0xE5B5: 0x880F, + 0xE5B6: 0x880D, + 0xE5B7: 0x87FE, + 0xE5B8: 0x87F6, + 0xE5B9: 0x87F7, + 0xE5BA: 0x880E, + 0xE5BB: 0x87D2, + 0xE5BC: 0x8811, + 0xE5BD: 0x8816, + 0xE5BE: 0x8815, + 0xE5BF: 0x8822, + 0xE5C0: 0x8821, + 0xE5C1: 0x8831, + 0xE5C2: 0x8836, + 0xE5C3: 0x8839, + 0xE5C4: 0x8827, + 0xE5C5: 0x883B, + 0xE5C6: 0x8844, + 0xE5C7: 0x8842, + 0xE5C8: 0x8852, + 0xE5C9: 0x8859, + 0xE5CA: 0x885E, + 0xE5CB: 0x8862, + 0xE5CC: 0x886B, + 0xE5CD: 0x8881, + 0xE5CE: 0x887E, + 0xE5CF: 0x889E, + 0xE5D0: 0x8875, + 0xE5D1: 0x887D, + 0xE5D2: 0x88B5, + 0xE5D3: 0x8872, + 0xE5D4: 0x8882, + 0xE5D5: 0x8897, + 0xE5D6: 0x8892, + 0xE5D7: 0x88AE, + 0xE5D8: 0x8899, + 0xE5D9: 0x88A2, + 0xE5DA: 0x888D, + 0xE5DB: 0x88A4, + 0xE5DC: 0x88B0, + 0xE5DD: 0x88BF, + 0xE5DE: 0x88B1, + 0xE5DF: 0x88C3, + 0xE5E0: 0x88C4, + 0xE5E1: 0x88D4, + 0xE5E2: 0x88D8, + 0xE5E3: 0x88D9, + 0xE5E4: 0x88DD, + 0xE5E5: 0x88F9, + 0xE5E6: 0x8902, + 0xE5E7: 0x88FC, + 0xE5E8: 0x88F4, + 0xE5E9: 0x88E8, + 0xE5EA: 0x88F2, + 0xE5EB: 0x8904, + 0xE5EC: 0x890C, + 0xE5ED: 0x890A, + 0xE5EE: 0x8913, + 0xE5EF: 0x8943, + 0xE5F0: 0x891E, + 0xE5F1: 0x8925, + 0xE5F2: 0x892A, + 0xE5F3: 0x892B, + 0xE5F4: 0x8941, + 0xE5F5: 0x8944, + 0xE5F6: 0x893B, + 0xE5F7: 0x8936, + 0xE5F8: 0x8938, + 0xE5F9: 0x894C, + 0xE5FA: 0x891D, + 0xE5FB: 0x8960, + 0xE5FC: 0x895E, + 0xE640: 0x8966, + 0xE641: 0x8964, + 0xE642: 0x896D, + 0xE643: 0x896A, + 0xE644: 0x896F, + 0xE645: 0x8974, + 0xE646: 0x8977, + 0xE647: 0x897E, + 0xE648: 0x8983, + 0xE649: 0x8988, + 0xE64A: 0x898A, + 0xE64B: 0x8993, + 0xE64C: 0x8998, + 0xE64D: 0x89A1, + 0xE64E: 0x89A9, + 0xE64F: 0x89A6, + 0xE650: 0x89AC, + 0xE651: 0x89AF, + 0xE652: 0x89B2, + 0xE653: 0x89BA, + 0xE654: 0x89BD, + 0xE655: 0x89BF, + 0xE656: 0x89C0, + 0xE657: 0x89DA, + 0xE658: 0x89DC, + 0xE659: 0x89DD, + 0xE65A: 0x89E7, + 0xE65B: 0x89F4, + 0xE65C: 0x89F8, + 0xE65D: 0x8A03, + 0xE65E: 0x8A16, + 0xE65F: 0x8A10, + 0xE660: 0x8A0C, + 0xE661: 0x8A1B, + 0xE662: 0x8A1D, + 0xE663: 0x8A25, + 0xE664: 0x8A36, + 0xE665: 0x8A41, + 0xE666: 0x8A5B, + 0xE667: 0x8A52, + 0xE668: 0x8A46, + 0xE669: 0x8A48, + 0xE66A: 0x8A7C, + 0xE66B: 0x8A6D, + 0xE66C: 0x8A6C, + 0xE66D: 0x8A62, + 0xE66E: 0x8A85, + 0xE66F: 0x8A82, + 0xE670: 0x8A84, + 0xE671: 0x8AA8, + 0xE672: 0x8AA1, + 0xE673: 0x8A91, + 0xE674: 0x8AA5, + 0xE675: 0x8AA6, + 0xE676: 0x8A9A, + 0xE677: 0x8AA3, + 0xE678: 0x8AC4, + 0xE679: 0x8ACD, + 0xE67A: 0x8AC2, + 0xE67B: 0x8ADA, + 0xE67C: 0x8AEB, + 0xE67D: 0x8AF3, + 0xE67E: 0x8AE7, + 0xE680: 0x8AE4, + 0xE681: 0x8AF1, + 0xE682: 0x8B14, + 0xE683: 0x8AE0, + 0xE684: 0x8AE2, + 0xE685: 0x8AF7, + 0xE686: 0x8ADE, + 0xE687: 0x8ADB, + 0xE688: 0x8B0C, + 0xE689: 0x8B07, + 0xE68A: 0x8B1A, + 0xE68B: 0x8AE1, + 0xE68C: 0x8B16, + 0xE68D: 0x8B10, + 0xE68E: 0x8B17, + 0xE68F: 0x8B20, + 0xE690: 0x8B33, + 0xE691: 0x97AB, + 0xE692: 0x8B26, + 0xE693: 0x8B2B, + 0xE694: 0x8B3E, + 0xE695: 0x8B28, + 0xE696: 0x8B41, + 0xE697: 0x8B4C, + 0xE698: 0x8B4F, + 0xE699: 0x8B4E, + 0xE69A: 0x8B49, + 0xE69B: 0x8B56, + 0xE69C: 0x8B5B, + 0xE69D: 0x8B5A, + 0xE69E: 0x8B6B, + 0xE69F: 0x8B5F, + 0xE6A0: 0x8B6C, + 0xE6A1: 0x8B6F, + 0xE6A2: 0x8B74, + 0xE6A3: 0x8B7D, + 0xE6A4: 0x8B80, + 0xE6A5: 0x8B8C, + 0xE6A6: 0x8B8E, + 0xE6A7: 0x8B92, + 0xE6A8: 0x8B93, + 0xE6A9: 0x8B96, + 0xE6AA: 0x8B99, + 0xE6AB: 0x8B9A, + 0xE6AC: 0x8C3A, + 0xE6AD: 0x8C41, + 0xE6AE: 0x8C3F, + 0xE6AF: 0x8C48, + 0xE6B0: 0x8C4C, + 0xE6B1: 0x8C4E, + 0xE6B2: 0x8C50, + 0xE6B3: 0x8C55, + 0xE6B4: 0x8C62, + 0xE6B5: 0x8C6C, + 0xE6B6: 0x8C78, + 0xE6B7: 0x8C7A, + 0xE6B8: 0x8C82, + 0xE6B9: 0x8C89, + 0xE6BA: 0x8C85, + 0xE6BB: 0x8C8A, + 0xE6BC: 0x8C8D, + 0xE6BD: 0x8C8E, + 0xE6BE: 0x8C94, + 0xE6BF: 0x8C7C, + 0xE6C0: 0x8C98, + 0xE6C1: 0x621D, + 0xE6C2: 0x8CAD, + 0xE6C3: 0x8CAA, + 0xE6C4: 0x8CBD, + 0xE6C5: 0x8CB2, + 0xE6C6: 0x8CB3, + 0xE6C7: 0x8CAE, + 0xE6C8: 0x8CB6, + 0xE6C9: 0x8CC8, + 0xE6CA: 0x8CC1, + 0xE6CB: 0x8CE4, + 0xE6CC: 0x8CE3, + 0xE6CD: 0x8CDA, + 0xE6CE: 0x8CFD, + 0xE6CF: 0x8CFA, + 0xE6D0: 0x8CFB, + 0xE6D1: 0x8D04, + 0xE6D2: 0x8D05, + 0xE6D3: 0x8D0A, + 0xE6D4: 0x8D07, + 0xE6D5: 0x8D0F, + 0xE6D6: 0x8D0D, + 0xE6D7: 0x8D10, + 0xE6D8: 0x9F4E, + 0xE6D9: 0x8D13, + 0xE6DA: 0x8CCD, + 0xE6DB: 0x8D14, + 0xE6DC: 0x8D16, + 0xE6DD: 0x8D67, + 0xE6DE: 0x8D6D, + 0xE6DF: 0x8D71, + 0xE6E0: 0x8D73, + 0xE6E1: 0x8D81, + 0xE6E2: 0x8D99, + 0xE6E3: 0x8DC2, + 0xE6E4: 0x8DBE, + 0xE6E5: 0x8DBA, + 0xE6E6: 0x8DCF, + 0xE6E7: 0x8DDA, + 0xE6E8: 0x8DD6, + 0xE6E9: 0x8DCC, + 0xE6EA: 0x8DDB, + 0xE6EB: 0x8DCB, + 0xE6EC: 0x8DEA, + 0xE6ED: 0x8DEB, + 0xE6EE: 0x8DDF, + 0xE6EF: 0x8DE3, + 0xE6F0: 0x8DFC, + 0xE6F1: 0x8E08, + 0xE6F2: 0x8E09, + 0xE6F3: 0x8DFF, + 0xE6F4: 0x8E1D, + 0xE6F5: 0x8E1E, + 0xE6F6: 0x8E10, + 0xE6F7: 0x8E1F, + 0xE6F8: 0x8E42, + 0xE6F9: 0x8E35, + 0xE6FA: 0x8E30, + 0xE6FB: 0x8E34, + 0xE6FC: 0x8E4A, + 0xE740: 0x8E47, + 0xE741: 0x8E49, + 0xE742: 0x8E4C, + 0xE743: 0x8E50, + 0xE744: 0x8E48, + 0xE745: 0x8E59, + 0xE746: 0x8E64, + 0xE747: 0x8E60, + 0xE748: 0x8E2A, + 0xE749: 0x8E63, + 0xE74A: 0x8E55, + 0xE74B: 0x8E76, + 0xE74C: 0x8E72, + 0xE74D: 0x8E7C, + 0xE74E: 0x8E81, + 0xE74F: 0x8E87, + 0xE750: 0x8E85, + 0xE751: 0x8E84, + 0xE752: 0x8E8B, + 0xE753: 0x8E8A, + 0xE754: 0x8E93, + 0xE755: 0x8E91, + 0xE756: 0x8E94, + 0xE757: 0x8E99, + 0xE758: 0x8EAA, + 0xE759: 0x8EA1, + 0xE75A: 0x8EAC, + 0xE75B: 0x8EB0, + 0xE75C: 0x8EC6, + 0xE75D: 0x8EB1, + 0xE75E: 0x8EBE, + 0xE75F: 0x8EC5, + 0xE760: 0x8EC8, + 0xE761: 0x8ECB, + 0xE762: 0x8EDB, + 0xE763: 0x8EE3, + 0xE764: 0x8EFC, + 0xE765: 0x8EFB, + 0xE766: 0x8EEB, + 0xE767: 0x8EFE, + 0xE768: 0x8F0A, + 0xE769: 0x8F05, + 0xE76A: 0x8F15, + 0xE76B: 0x8F12, + 0xE76C: 0x8F19, + 0xE76D: 0x8F13, + 0xE76E: 0x8F1C, + 0xE76F: 0x8F1F, + 0xE770: 0x8F1B, + 0xE771: 0x8F0C, + 0xE772: 0x8F26, + 0xE773: 0x8F33, + 0xE774: 0x8F3B, + 0xE775: 0x8F39, + 0xE776: 0x8F45, + 0xE777: 0x8F42, + 0xE778: 0x8F3E, + 0xE779: 0x8F4C, + 0xE77A: 0x8F49, + 0xE77B: 0x8F46, + 0xE77C: 0x8F4E, + 0xE77D: 0x8F57, + 0xE77E: 0x8F5C, + 0xE780: 0x8F62, + 0xE781: 0x8F63, + 0xE782: 0x8F64, + 0xE783: 0x8F9C, + 0xE784: 0x8F9F, + 0xE785: 0x8FA3, + 0xE786: 0x8FAD, + 0xE787: 0x8FAF, + 0xE788: 0x8FB7, + 0xE789: 0x8FDA, + 0xE78A: 0x8FE5, + 0xE78B: 0x8FE2, + 0xE78C: 0x8FEA, + 0xE78D: 0x8FEF, + 0xE78E: 0x9087, + 0xE78F: 0x8FF4, + 0xE790: 0x9005, + 0xE791: 0x8FF9, + 0xE792: 0x8FFA, + 0xE793: 0x9011, + 0xE794: 0x9015, + 0xE795: 0x9021, + 0xE796: 0x900D, + 0xE797: 0x901E, + 0xE798: 0x9016, + 0xE799: 0x900B, + 0xE79A: 0x9027, + 0xE79B: 0x9036, + 0xE79C: 0x9035, + 0xE79D: 0x9039, + 0xE79E: 0x8FF8, + 0xE79F: 0x904F, + 0xE7A0: 0x9050, + 0xE7A1: 0x9051, + 0xE7A2: 0x9052, + 0xE7A3: 0x900E, + 0xE7A4: 0x9049, + 0xE7A5: 0x903E, + 0xE7A6: 0x9056, + 0xE7A7: 0x9058, + 0xE7A8: 0x905E, + 0xE7A9: 0x9068, + 0xE7AA: 0x906F, + 0xE7AB: 0x9076, + 0xE7AC: 0x96A8, + 0xE7AD: 0x9072, + 0xE7AE: 0x9082, + 0xE7AF: 0x907D, + 0xE7B0: 0x9081, + 0xE7B1: 0x9080, + 0xE7B2: 0x908A, + 0xE7B3: 0x9089, + 0xE7B4: 0x908F, + 0xE7B5: 0x90A8, + 0xE7B6: 0x90AF, + 0xE7B7: 0x90B1, + 0xE7B8: 0x90B5, + 0xE7B9: 0x90E2, + 0xE7BA: 0x90E4, + 0xE7BB: 0x6248, + 0xE7BC: 0x90DB, + 0xE7BD: 0x9102, + 0xE7BE: 0x9112, + 0xE7BF: 0x9119, + 0xE7C0: 0x9132, + 0xE7C1: 0x9130, + 0xE7C2: 0x914A, + 0xE7C3: 0x9156, + 0xE7C4: 0x9158, + 0xE7C5: 0x9163, + 0xE7C6: 0x9165, + 0xE7C7: 0x9169, + 0xE7C8: 0x9173, + 0xE7C9: 0x9172, + 0xE7CA: 0x918B, + 0xE7CB: 0x9189, + 0xE7CC: 0x9182, + 0xE7CD: 0x91A2, + 0xE7CE: 0x91AB, + 0xE7CF: 0x91AF, + 0xE7D0: 0x91AA, + 0xE7D1: 0x91B5, + 0xE7D2: 0x91B4, + 0xE7D3: 0x91BA, + 0xE7D4: 0x91C0, + 0xE7D5: 0x91C1, + 0xE7D6: 0x91C9, + 0xE7D7: 0x91CB, + 0xE7D8: 0x91D0, + 0xE7D9: 0x91D6, + 0xE7DA: 0x91DF, + 0xE7DB: 0x91E1, + 0xE7DC: 0x91DB, + 0xE7DD: 0x91FC, + 0xE7DE: 0x91F5, + 0xE7DF: 0x91F6, + 0xE7E0: 0x921E, + 0xE7E1: 0x91FF, + 0xE7E2: 0x9214, + 0xE7E3: 0x922C, + 0xE7E4: 0x9215, + 0xE7E5: 0x9211, + 0xE7E6: 0x925E, + 0xE7E7: 0x9257, + 0xE7E8: 0x9245, + 0xE7E9: 0x9249, + 0xE7EA: 0x9264, + 0xE7EB: 0x9248, + 0xE7EC: 0x9295, + 0xE7ED: 0x923F, + 0xE7EE: 0x924B, + 0xE7EF: 0x9250, + 0xE7F0: 0x929C, + 0xE7F1: 0x9296, + 0xE7F2: 0x9293, + 0xE7F3: 0x929B, + 0xE7F4: 0x925A, + 0xE7F5: 0x92CF, + 0xE7F6: 0x92B9, + 0xE7F7: 0x92B7, + 0xE7F8: 0x92E9, + 0xE7F9: 0x930F, + 0xE7FA: 0x92FA, + 0xE7FB: 0x9344, + 0xE7FC: 0x932E, + 0xE840: 0x9319, + 0xE841: 0x9322, + 0xE842: 0x931A, + 0xE843: 0x9323, + 0xE844: 0x933A, + 0xE845: 0x9335, + 0xE846: 0x933B, + 0xE847: 0x935C, + 0xE848: 0x9360, + 0xE849: 0x937C, + 0xE84A: 0x936E, + 0xE84B: 0x9356, + 0xE84C: 0x93B0, + 0xE84D: 0x93AC, + 0xE84E: 0x93AD, + 0xE84F: 0x9394, + 0xE850: 0x93B9, + 0xE851: 0x93D6, + 0xE852: 0x93D7, + 0xE853: 0x93E8, + 0xE854: 0x93E5, + 0xE855: 0x93D8, + 0xE856: 0x93C3, + 0xE857: 0x93DD, + 0xE858: 0x93D0, + 0xE859: 0x93C8, + 0xE85A: 0x93E4, + 0xE85B: 0x941A, + 0xE85C: 0x9414, + 0xE85D: 0x9413, + 0xE85E: 0x9403, + 0xE85F: 0x9407, + 0xE860: 0x9410, + 0xE861: 0x9436, + 0xE862: 0x942B, + 0xE863: 0x9435, + 0xE864: 0x9421, + 0xE865: 0x943A, + 0xE866: 0x9441, + 0xE867: 0x9452, + 0xE868: 0x9444, + 0xE869: 0x945B, + 0xE86A: 0x9460, + 0xE86B: 0x9462, + 0xE86C: 0x945E, + 0xE86D: 0x946A, + 0xE86E: 0x9229, + 0xE86F: 0x9470, + 0xE870: 0x9475, + 0xE871: 0x9477, + 0xE872: 0x947D, + 0xE873: 0x945A, + 0xE874: 0x947C, + 0xE875: 0x947E, + 0xE876: 0x9481, + 0xE877: 0x947F, + 0xE878: 0x9582, + 0xE879: 0x9587, + 0xE87A: 0x958A, + 0xE87B: 0x9594, + 0xE87C: 0x9596, + 0xE87D: 0x9598, + 0xE87E: 0x9599, + 0xE880: 0x95A0, + 0xE881: 0x95A8, + 0xE882: 0x95A7, + 0xE883: 0x95AD, + 0xE884: 0x95BC, + 0xE885: 0x95BB, + 0xE886: 0x95B9, + 0xE887: 0x95BE, + 0xE888: 0x95CA, + 0xE889: 0x6FF6, + 0xE88A: 0x95C3, + 0xE88B: 0x95CD, + 0xE88C: 0x95CC, + 0xE88D: 0x95D5, + 0xE88E: 0x95D4, + 0xE88F: 0x95D6, + 0xE890: 0x95DC, + 0xE891: 0x95E1, + 0xE892: 0x95E5, + 0xE893: 0x95E2, + 0xE894: 0x9621, + 0xE895: 0x9628, + 0xE896: 0x962E, + 0xE897: 0x962F, + 0xE898: 0x9642, + 0xE899: 0x964C, + 0xE89A: 0x964F, + 0xE89B: 0x964B, + 0xE89C: 0x9677, + 0xE89D: 0x965C, + 0xE89E: 0x965E, + 0xE89F: 0x965D, + 0xE8A0: 0x965F, + 0xE8A1: 0x9666, + 0xE8A2: 0x9672, + 0xE8A3: 0x966C, + 0xE8A4: 0x968D, + 0xE8A5: 0x9698, + 0xE8A6: 0x9695, + 0xE8A7: 0x9697, + 0xE8A8: 0x96AA, + 0xE8A9: 0x96A7, + 0xE8AA: 0x96B1, + 0xE8AB: 0x96B2, + 0xE8AC: 0x96B0, + 0xE8AD: 0x96B4, + 0xE8AE: 0x96B6, + 0xE8AF: 0x96B8, + 0xE8B0: 0x96B9, + 0xE8B1: 0x96CE, + 0xE8B2: 0x96CB, + 0xE8B3: 0x96C9, + 0xE8B4: 0x96CD, + 0xE8B5: 0x894D, + 0xE8B6: 0x96DC, + 0xE8B7: 0x970D, + 0xE8B8: 0x96D5, + 0xE8B9: 0x96F9, + 0xE8BA: 0x9704, + 0xE8BB: 0x9706, + 0xE8BC: 0x9708, + 0xE8BD: 0x9713, + 0xE8BE: 0x970E, + 0xE8BF: 0x9711, + 0xE8C0: 0x970F, + 0xE8C1: 0x9716, + 0xE8C2: 0x9719, + 0xE8C3: 0x9724, + 0xE8C4: 0x972A, + 0xE8C5: 0x9730, + 0xE8C6: 0x9739, + 0xE8C7: 0x973D, + 0xE8C8: 0x973E, + 0xE8C9: 0x9744, + 0xE8CA: 0x9746, + 0xE8CB: 0x9748, + 0xE8CC: 0x9742, + 0xE8CD: 0x9749, + 0xE8CE: 0x975C, + 0xE8CF: 0x9760, + 0xE8D0: 0x9764, + 0xE8D1: 0x9766, + 0xE8D2: 0x9768, + 0xE8D3: 0x52D2, + 0xE8D4: 0x976B, + 0xE8D5: 0x9771, + 0xE8D6: 0x9779, + 0xE8D7: 0x9785, + 0xE8D8: 0x977C, + 0xE8D9: 0x9781, + 0xE8DA: 0x977A, + 0xE8DB: 0x9786, + 0xE8DC: 0x978B, + 0xE8DD: 0x978F, + 0xE8DE: 0x9790, + 0xE8DF: 0x979C, + 0xE8E0: 0x97A8, + 0xE8E1: 0x97A6, + 0xE8E2: 0x97A3, + 0xE8E3: 0x97B3, + 0xE8E4: 0x97B4, + 0xE8E5: 0x97C3, + 0xE8E6: 0x97C6, + 0xE8E7: 0x97C8, + 0xE8E8: 0x97CB, + 0xE8E9: 0x97DC, + 0xE8EA: 0x97ED, + 0xE8EB: 0x9F4F, + 0xE8EC: 0x97F2, + 0xE8ED: 0x7ADF, + 0xE8EE: 0x97F6, + 0xE8EF: 0x97F5, + 0xE8F0: 0x980F, + 0xE8F1: 0x980C, + 0xE8F2: 0x9838, + 0xE8F3: 0x9824, + 0xE8F4: 0x9821, + 0xE8F5: 0x9837, + 0xE8F6: 0x983D, + 0xE8F7: 0x9846, + 0xE8F8: 0x984F, + 0xE8F9: 0x984B, + 0xE8FA: 0x986B, + 0xE8FB: 0x986F, + 0xE8FC: 0x9870, + 0xE940: 0x9871, + 0xE941: 0x9874, + 0xE942: 0x9873, + 0xE943: 0x98AA, + 0xE944: 0x98AF, + 0xE945: 0x98B1, + 0xE946: 0x98B6, + 0xE947: 0x98C4, + 0xE948: 0x98C3, + 0xE949: 0x98C6, + 0xE94A: 0x98E9, + 0xE94B: 0x98EB, + 0xE94C: 0x9903, + 0xE94D: 0x9909, + 0xE94E: 0x9912, + 0xE94F: 0x9914, + 0xE950: 0x9918, + 0xE951: 0x9921, + 0xE952: 0x991D, + 0xE953: 0x991E, + 0xE954: 0x9924, + 0xE955: 0x9920, + 0xE956: 0x992C, + 0xE957: 0x992E, + 0xE958: 0x993D, + 0xE959: 0x993E, + 0xE95A: 0x9942, + 0xE95B: 0x9949, + 0xE95C: 0x9945, + 0xE95D: 0x9950, + 0xE95E: 0x994B, + 0xE95F: 0x9951, + 0xE960: 0x9952, + 0xE961: 0x994C, + 0xE962: 0x9955, + 0xE963: 0x9997, + 0xE964: 0x9998, + 0xE965: 0x99A5, + 0xE966: 0x99AD, + 0xE967: 0x99AE, + 0xE968: 0x99BC, + 0xE969: 0x99DF, + 0xE96A: 0x99DB, + 0xE96B: 0x99DD, + 0xE96C: 0x99D8, + 0xE96D: 0x99D1, + 0xE96E: 0x99ED, + 0xE96F: 0x99EE, + 0xE970: 0x99F1, + 0xE971: 0x99F2, + 0xE972: 0x99FB, + 0xE973: 0x99F8, + 0xE974: 0x9A01, + 0xE975: 0x9A0F, + 0xE976: 0x9A05, + 0xE977: 0x99E2, + 0xE978: 0x9A19, + 0xE979: 0x9A2B, + 0xE97A: 0x9A37, + 0xE97B: 0x9A45, + 0xE97C: 0x9A42, + 0xE97D: 0x9A40, + 0xE97E: 0x9A43, + 0xE980: 0x9A3E, + 0xE981: 0x9A55, + 0xE982: 0x9A4D, + 0xE983: 0x9A5B, + 0xE984: 0x9A57, + 0xE985: 0x9A5F, + 0xE986: 0x9A62, + 0xE987: 0x9A65, + 0xE988: 0x9A64, + 0xE989: 0x9A69, + 0xE98A: 0x9A6B, + 0xE98B: 0x9A6A, + 0xE98C: 0x9AAD, + 0xE98D: 0x9AB0, + 0xE98E: 0x9ABC, + 0xE98F: 0x9AC0, + 0xE990: 0x9ACF, + 0xE991: 0x9AD1, + 0xE992: 0x9AD3, + 0xE993: 0x9AD4, + 0xE994: 0x9ADE, + 0xE995: 0x9ADF, + 0xE996: 0x9AE2, + 0xE997: 0x9AE3, + 0xE998: 0x9AE6, + 0xE999: 0x9AEF, + 0xE99A: 0x9AEB, + 0xE99B: 0x9AEE, + 0xE99C: 0x9AF4, + 0xE99D: 0x9AF1, + 0xE99E: 0x9AF7, + 0xE99F: 0x9AFB, + 0xE9A0: 0x9B06, + 0xE9A1: 0x9B18, + 0xE9A2: 0x9B1A, + 0xE9A3: 0x9B1F, + 0xE9A4: 0x9B22, + 0xE9A5: 0x9B23, + 0xE9A6: 0x9B25, + 0xE9A7: 0x9B27, + 0xE9A8: 0x9B28, + 0xE9A9: 0x9B29, + 0xE9AA: 0x9B2A, + 0xE9AB: 0x9B2E, + 0xE9AC: 0x9B2F, + 0xE9AD: 0x9B32, + 0xE9AE: 0x9B44, + 0xE9AF: 0x9B43, + 0xE9B0: 0x9B4F, + 0xE9B1: 0x9B4D, + 0xE9B2: 0x9B4E, + 0xE9B3: 0x9B51, + 0xE9B4: 0x9B58, + 0xE9B5: 0x9B74, + 0xE9B6: 0x9B93, + 0xE9B7: 0x9B83, + 0xE9B8: 0x9B91, + 0xE9B9: 0x9B96, + 0xE9BA: 0x9B97, + 0xE9BB: 0x9B9F, + 0xE9BC: 0x9BA0, + 0xE9BD: 0x9BA8, + 0xE9BE: 0x9BB4, + 0xE9BF: 0x9BC0, + 0xE9C0: 0x9BCA, + 0xE9C1: 0x9BB9, + 0xE9C2: 0x9BC6, + 0xE9C3: 0x9BCF, + 0xE9C4: 0x9BD1, + 0xE9C5: 0x9BD2, + 0xE9C6: 0x9BE3, + 0xE9C7: 0x9BE2, + 0xE9C8: 0x9BE4, + 0xE9C9: 0x9BD4, + 0xE9CA: 0x9BE1, + 0xE9CB: 0x9C3A, + 0xE9CC: 0x9BF2, + 0xE9CD: 0x9BF1, + 0xE9CE: 0x9BF0, + 0xE9CF: 0x9C15, + 0xE9D0: 0x9C14, + 0xE9D1: 0x9C09, + 0xE9D2: 0x9C13, + 0xE9D3: 0x9C0C, + 0xE9D4: 0x9C06, + 0xE9D5: 0x9C08, + 0xE9D6: 0x9C12, + 0xE9D7: 0x9C0A, + 0xE9D8: 0x9C04, + 0xE9D9: 0x9C2E, + 0xE9DA: 0x9C1B, + 0xE9DB: 0x9C25, + 0xE9DC: 0x9C24, + 0xE9DD: 0x9C21, + 0xE9DE: 0x9C30, + 0xE9DF: 0x9C47, + 0xE9E0: 0x9C32, + 0xE9E1: 0x9C46, + 0xE9E2: 0x9C3E, + 0xE9E3: 0x9C5A, + 0xE9E4: 0x9C60, + 0xE9E5: 0x9C67, + 0xE9E6: 0x9C76, + 0xE9E7: 0x9C78, + 0xE9E8: 0x9CE7, + 0xE9E9: 0x9CEC, + 0xE9EA: 0x9CF0, + 0xE9EB: 0x9D09, + 0xE9EC: 0x9D08, + 0xE9ED: 0x9CEB, + 0xE9EE: 0x9D03, + 0xE9EF: 0x9D06, + 0xE9F0: 0x9D2A, + 0xE9F1: 0x9D26, + 0xE9F2: 0x9DAF, + 0xE9F3: 0x9D23, + 0xE9F4: 0x9D1F, + 0xE9F5: 0x9D44, + 0xE9F6: 0x9D15, + 0xE9F7: 0x9D12, + 0xE9F8: 0x9D41, + 0xE9F9: 0x9D3F, + 0xE9FA: 0x9D3E, + 0xE9FB: 0x9D46, + 0xE9FC: 0x9D48, + 0xEA40: 0x9D5D, + 0xEA41: 0x9D5E, + 0xEA42: 0x9D64, + 0xEA43: 0x9D51, + 0xEA44: 0x9D50, + 0xEA45: 0x9D59, + 0xEA46: 0x9D72, + 0xEA47: 0x9D89, + 0xEA48: 0x9D87, + 0xEA49: 0x9DAB, + 0xEA4A: 0x9D6F, + 0xEA4B: 0x9D7A, + 0xEA4C: 0x9D9A, + 0xEA4D: 0x9DA4, + 0xEA4E: 0x9DA9, + 0xEA4F: 0x9DB2, + 0xEA50: 0x9DC4, + 0xEA51: 0x9DC1, + 0xEA52: 0x9DBB, + 0xEA53: 0x9DB8, + 0xEA54: 0x9DBA, + 0xEA55: 0x9DC6, + 0xEA56: 0x9DCF, + 0xEA57: 0x9DC2, + 0xEA58: 0x9DD9, + 0xEA59: 0x9DD3, + 0xEA5A: 0x9DF8, + 0xEA5B: 0x9DE6, + 0xEA5C: 0x9DED, + 0xEA5D: 0x9DEF, + 0xEA5E: 0x9DFD, + 0xEA5F: 0x9E1A, + 0xEA60: 0x9E1B, + 0xEA61: 0x9E1E, + 0xEA62: 0x9E75, + 0xEA63: 0x9E79, + 0xEA64: 0x9E7D, + 0xEA65: 0x9E81, + 0xEA66: 0x9E88, + 0xEA67: 0x9E8B, + 0xEA68: 0x9E8C, + 0xEA69: 0x9E92, + 0xEA6A: 0x9E95, + 0xEA6B: 0x9E91, + 0xEA6C: 0x9E9D, + 0xEA6D: 0x9EA5, + 0xEA6E: 0x9EA9, + 0xEA6F: 0x9EB8, + 0xEA70: 0x9EAA, + 0xEA71: 0x9EAD, + 0xEA72: 0x9761, + 0xEA73: 0x9ECC, + 0xEA74: 0x9ECE, + 0xEA75: 0x9ECF, + 0xEA76: 0x9ED0, + 0xEA77: 0x9ED4, + 0xEA78: 0x9EDC, + 0xEA79: 0x9EDE, + 0xEA7A: 0x9EDD, + 0xEA7B: 0x9EE0, + 0xEA7C: 0x9EE5, + 0xEA7D: 0x9EE8, + 0xEA7E: 0x9EEF, + 0xEA80: 0x9EF4, + 0xEA81: 0x9EF6, + 0xEA82: 0x9EF7, + 0xEA83: 0x9EF9, + 0xEA84: 0x9EFB, + 0xEA85: 0x9EFC, + 0xEA86: 0x9EFD, + 0xEA87: 0x9F07, + 0xEA88: 0x9F08, + 0xEA89: 0x76B7, + 0xEA8A: 0x9F15, + 0xEA8B: 0x9F21, + 0xEA8C: 0x9F2C, + 0xEA8D: 0x9F3E, + 0xEA8E: 0x9F4A, + 0xEA8F: 0x9F52, + 0xEA90: 0x9F54, + 0xEA91: 0x9F63, + 0xEA92: 0x9F5F, + 0xEA93: 0x9F60, + 0xEA94: 0x9F61, + 0xEA95: 0x9F66, + 0xEA96: 0x9F67, + 0xEA97: 0x9F6C, + 0xEA98: 0x9F6A, + 0xEA99: 0x9F77, + 0xEA9A: 0x9F72, + 0xEA9B: 0x9F76, + 0xEA9C: 0x9F95, + 0xEA9D: 0x9F9C, + 0xEA9E: 0x9FA0, + 0xEA9F: 0x582F, + 0xEAA0: 0x69C7, + 0xEAA1: 0x9059, + 0xEAA2: 0x7464, + 0xEAA3: 0x51DC, + 0xEAA4: 0x7199, +}; + + +/***/ }), +/* 9 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +var GenericGF_1 = __webpack_require__(1); +var GenericGFPoly_1 = __webpack_require__(2); +function runEuclideanAlgorithm(field, a, b, R) { + var _a; + // Assume a's degree is >= b's + if (a.degree() < b.degree()) { + _a = [b, a], a = _a[0], b = _a[1]; + } + var rLast = a; + var r = b; + var tLast = field.zero; + var t = field.one; + // Run Euclidean algorithm until r's degree is less than R/2 + while (r.degree() >= R / 2) { + var rLastLast = rLast; + var tLastLast = tLast; + rLast = r; + tLast = t; + // Divide rLastLast by rLast, with quotient in q and remainder in r + if (rLast.isZero()) { + // Euclidean algorithm already terminated? + return null; + } + r = rLastLast; + var q = field.zero; + var denominatorLeadingTerm = rLast.getCoefficient(rLast.degree()); + var dltInverse = field.inverse(denominatorLeadingTerm); + while (r.degree() >= rLast.degree() && !r.isZero()) { + var degreeDiff = r.degree() - rLast.degree(); + var scale = field.multiply(r.getCoefficient(r.degree()), dltInverse); + q = q.addOrSubtract(field.buildMonomial(degreeDiff, scale)); + r = r.addOrSubtract(rLast.multiplyByMonomial(degreeDiff, scale)); + } + t = q.multiplyPoly(tLast).addOrSubtract(tLastLast); + if (r.degree() >= rLast.degree()) { + return null; + } + } + var sigmaTildeAtZero = t.getCoefficient(0); + if (sigmaTildeAtZero === 0) { + return null; + } + var inverse = field.inverse(sigmaTildeAtZero); + return [t.multiply(inverse), r.multiply(inverse)]; +} +function findErrorLocations(field, errorLocator) { + // This is a direct application of Chien's search + var numErrors = errorLocator.degree(); + if (numErrors === 1) { + return [errorLocator.getCoefficient(1)]; + } + var result = new Array(numErrors); + var errorCount = 0; + for (var i = 1; i < field.size && errorCount < numErrors; i++) { + if (errorLocator.evaluateAt(i) === 0) { + result[errorCount] = field.inverse(i); + errorCount++; + } + } + if (errorCount !== numErrors) { + return null; + } + return result; +} +function findErrorMagnitudes(field, errorEvaluator, errorLocations) { + // This is directly applying Forney's Formula + var s = errorLocations.length; + var result = new Array(s); + for (var i = 0; i < s; i++) { + var xiInverse = field.inverse(errorLocations[i]); + var denominator = 1; + for (var j = 0; j < s; j++) { + if (i !== j) { + denominator = field.multiply(denominator, GenericGF_1.addOrSubtractGF(1, field.multiply(errorLocations[j], xiInverse))); + } + } + result[i] = field.multiply(errorEvaluator.evaluateAt(xiInverse), field.inverse(denominator)); + if (field.generatorBase !== 0) { + result[i] = field.multiply(result[i], xiInverse); + } + } + return result; +} +function decode(bytes, twoS) { + var outputBytes = new Uint8ClampedArray(bytes.length); + outputBytes.set(bytes); + var field = new GenericGF_1.default(0x011D, 256, 0); // x^8 + x^4 + x^3 + x^2 + 1 + var poly = new GenericGFPoly_1.default(field, outputBytes); + var syndromeCoefficients = new Uint8ClampedArray(twoS); + var error = false; + for (var s = 0; s < twoS; s++) { + var evaluation = poly.evaluateAt(field.exp(s + field.generatorBase)); + syndromeCoefficients[syndromeCoefficients.length - 1 - s] = evaluation; + if (evaluation !== 0) { + error = true; + } + } + if (!error) { + return outputBytes; + } + var syndrome = new GenericGFPoly_1.default(field, syndromeCoefficients); + var sigmaOmega = runEuclideanAlgorithm(field, field.buildMonomial(twoS, 1), syndrome, twoS); + if (sigmaOmega === null) { + return null; + } + var errorLocations = findErrorLocations(field, sigmaOmega[0]); + if (errorLocations == null) { + return null; + } + var errorMagnitudes = findErrorMagnitudes(field, sigmaOmega[1], errorLocations); + for (var i = 0; i < errorLocations.length; i++) { + var position = outputBytes.length - 1 - field.log(errorLocations[i]); + if (position < 0) { + return null; + } + outputBytes[position] = GenericGF_1.addOrSubtractGF(outputBytes[position], errorMagnitudes[i]); + } + return outputBytes; +} +exports.decode = decode; + + +/***/ }), +/* 10 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +exports.VERSIONS = [ + { + infoBits: null, + versionNumber: 1, + alignmentPatternCenters: [], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 7, + ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 19 }], + }, + { + ecCodewordsPerBlock: 10, + ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 16 }], + }, + { + ecCodewordsPerBlock: 13, + ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 13 }], + }, + { + ecCodewordsPerBlock: 17, + ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 9 }], + }, + ], + }, + { + infoBits: null, + versionNumber: 2, + alignmentPatternCenters: [6, 18], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 10, + ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 34 }], + }, + { + ecCodewordsPerBlock: 16, + ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 28 }], + }, + { + ecCodewordsPerBlock: 22, + ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 22 }], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 16 }], + }, + ], + }, + { + infoBits: null, + versionNumber: 3, + alignmentPatternCenters: [6, 22], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 15, + ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 55 }], + }, + { + ecCodewordsPerBlock: 26, + ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 44 }], + }, + { + ecCodewordsPerBlock: 18, + ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 17 }], + }, + { + ecCodewordsPerBlock: 22, + ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 13 }], + }, + ], + }, + { + infoBits: null, + versionNumber: 4, + alignmentPatternCenters: [6, 26], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 20, + ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 80 }], + }, + { + ecCodewordsPerBlock: 18, + ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 32 }], + }, + { + ecCodewordsPerBlock: 26, + ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 24 }], + }, + { + ecCodewordsPerBlock: 16, + ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 9 }], + }, + ], + }, + { + infoBits: null, + versionNumber: 5, + alignmentPatternCenters: [6, 30], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 26, + ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 108 }], + }, + { + ecCodewordsPerBlock: 24, + ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 43 }], + }, + { + ecCodewordsPerBlock: 18, + ecBlocks: [ + { numBlocks: 2, dataCodewordsPerBlock: 15 }, + { numBlocks: 2, dataCodewordsPerBlock: 16 }, + ], + }, + { + ecCodewordsPerBlock: 22, + ecBlocks: [ + { numBlocks: 2, dataCodewordsPerBlock: 11 }, + { numBlocks: 2, dataCodewordsPerBlock: 12 }, + ], + }, + ], + }, + { + infoBits: null, + versionNumber: 6, + alignmentPatternCenters: [6, 34], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 18, + ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 68 }], + }, + { + ecCodewordsPerBlock: 16, + ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 27 }], + }, + { + ecCodewordsPerBlock: 24, + ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 19 }], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 15 }], + }, + ], + }, + { + infoBits: 0x07C94, + versionNumber: 7, + alignmentPatternCenters: [6, 22, 38], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 20, + ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 78 }], + }, + { + ecCodewordsPerBlock: 18, + ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 31 }], + }, + { + ecCodewordsPerBlock: 18, + ecBlocks: [ + { numBlocks: 2, dataCodewordsPerBlock: 14 }, + { numBlocks: 4, dataCodewordsPerBlock: 15 }, + ], + }, + { + ecCodewordsPerBlock: 26, + ecBlocks: [ + { numBlocks: 4, dataCodewordsPerBlock: 13 }, + { numBlocks: 1, dataCodewordsPerBlock: 14 }, + ], + }, + ], + }, + { + infoBits: 0x085BC, + versionNumber: 8, + alignmentPatternCenters: [6, 24, 42], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 24, + ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 97 }], + }, + { + ecCodewordsPerBlock: 22, + ecBlocks: [ + { numBlocks: 2, dataCodewordsPerBlock: 38 }, + { numBlocks: 2, dataCodewordsPerBlock: 39 }, + ], + }, + { + ecCodewordsPerBlock: 22, + ecBlocks: [ + { numBlocks: 4, dataCodewordsPerBlock: 18 }, + { numBlocks: 2, dataCodewordsPerBlock: 19 }, + ], + }, + { + ecCodewordsPerBlock: 26, + ecBlocks: [ + { numBlocks: 4, dataCodewordsPerBlock: 14 }, + { numBlocks: 2, dataCodewordsPerBlock: 15 }, + ], + }, + ], + }, + { + infoBits: 0x09A99, + versionNumber: 9, + alignmentPatternCenters: [6, 26, 46], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 30, + ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 116 }], + }, + { + ecCodewordsPerBlock: 22, + ecBlocks: [ + { numBlocks: 3, dataCodewordsPerBlock: 36 }, + { numBlocks: 2, dataCodewordsPerBlock: 37 }, + ], + }, + { + ecCodewordsPerBlock: 20, + ecBlocks: [ + { numBlocks: 4, dataCodewordsPerBlock: 16 }, + { numBlocks: 4, dataCodewordsPerBlock: 17 }, + ], + }, + { + ecCodewordsPerBlock: 24, + ecBlocks: [ + { numBlocks: 4, dataCodewordsPerBlock: 12 }, + { numBlocks: 4, dataCodewordsPerBlock: 13 }, + ], + }, + ], + }, + { + infoBits: 0x0A4D3, + versionNumber: 10, + alignmentPatternCenters: [6, 28, 50], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 18, + ecBlocks: [ + { numBlocks: 2, dataCodewordsPerBlock: 68 }, + { numBlocks: 2, dataCodewordsPerBlock: 69 }, + ], + }, + { + ecCodewordsPerBlock: 26, + ecBlocks: [ + { numBlocks: 4, dataCodewordsPerBlock: 43 }, + { numBlocks: 1, dataCodewordsPerBlock: 44 }, + ], + }, + { + ecCodewordsPerBlock: 24, + ecBlocks: [ + { numBlocks: 6, dataCodewordsPerBlock: 19 }, + { numBlocks: 2, dataCodewordsPerBlock: 20 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 6, dataCodewordsPerBlock: 15 }, + { numBlocks: 2, dataCodewordsPerBlock: 16 }, + ], + }, + ], + }, + { + infoBits: 0x0BBF6, + versionNumber: 11, + alignmentPatternCenters: [6, 30, 54], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 20, + ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 81 }], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 1, dataCodewordsPerBlock: 50 }, + { numBlocks: 4, dataCodewordsPerBlock: 51 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 4, dataCodewordsPerBlock: 22 }, + { numBlocks: 4, dataCodewordsPerBlock: 23 }, + ], + }, + { + ecCodewordsPerBlock: 24, + ecBlocks: [ + { numBlocks: 3, dataCodewordsPerBlock: 12 }, + { numBlocks: 8, dataCodewordsPerBlock: 13 }, + ], + }, + ], + }, + { + infoBits: 0x0C762, + versionNumber: 12, + alignmentPatternCenters: [6, 32, 58], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 24, + ecBlocks: [ + { numBlocks: 2, dataCodewordsPerBlock: 92 }, + { numBlocks: 2, dataCodewordsPerBlock: 93 }, + ], + }, + { + ecCodewordsPerBlock: 22, + ecBlocks: [ + { numBlocks: 6, dataCodewordsPerBlock: 36 }, + { numBlocks: 2, dataCodewordsPerBlock: 37 }, + ], + }, + { + ecCodewordsPerBlock: 26, + ecBlocks: [ + { numBlocks: 4, dataCodewordsPerBlock: 20 }, + { numBlocks: 6, dataCodewordsPerBlock: 21 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 7, dataCodewordsPerBlock: 14 }, + { numBlocks: 4, dataCodewordsPerBlock: 15 }, + ], + }, + ], + }, + { + infoBits: 0x0D847, + versionNumber: 13, + alignmentPatternCenters: [6, 34, 62], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 26, + ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 107 }], + }, + { + ecCodewordsPerBlock: 22, + ecBlocks: [ + { numBlocks: 8, dataCodewordsPerBlock: 37 }, + { numBlocks: 1, dataCodewordsPerBlock: 38 }, + ], + }, + { + ecCodewordsPerBlock: 24, + ecBlocks: [ + { numBlocks: 8, dataCodewordsPerBlock: 20 }, + { numBlocks: 4, dataCodewordsPerBlock: 21 }, + ], + }, + { + ecCodewordsPerBlock: 22, + ecBlocks: [ + { numBlocks: 12, dataCodewordsPerBlock: 11 }, + { numBlocks: 4, dataCodewordsPerBlock: 12 }, + ], + }, + ], + }, + { + infoBits: 0x0E60D, + versionNumber: 14, + alignmentPatternCenters: [6, 26, 46, 66], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 3, dataCodewordsPerBlock: 115 }, + { numBlocks: 1, dataCodewordsPerBlock: 116 }, + ], + }, + { + ecCodewordsPerBlock: 24, + ecBlocks: [ + { numBlocks: 4, dataCodewordsPerBlock: 40 }, + { numBlocks: 5, dataCodewordsPerBlock: 41 }, + ], + }, + { + ecCodewordsPerBlock: 20, + ecBlocks: [ + { numBlocks: 11, dataCodewordsPerBlock: 16 }, + { numBlocks: 5, dataCodewordsPerBlock: 17 }, + ], + }, + { + ecCodewordsPerBlock: 24, + ecBlocks: [ + { numBlocks: 11, dataCodewordsPerBlock: 12 }, + { numBlocks: 5, dataCodewordsPerBlock: 13 }, + ], + }, + ], + }, + { + infoBits: 0x0F928, + versionNumber: 15, + alignmentPatternCenters: [6, 26, 48, 70], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 22, + ecBlocks: [ + { numBlocks: 5, dataCodewordsPerBlock: 87 }, + { numBlocks: 1, dataCodewordsPerBlock: 88 }, + ], + }, + { + ecCodewordsPerBlock: 24, + ecBlocks: [ + { numBlocks: 5, dataCodewordsPerBlock: 41 }, + { numBlocks: 5, dataCodewordsPerBlock: 42 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 5, dataCodewordsPerBlock: 24 }, + { numBlocks: 7, dataCodewordsPerBlock: 25 }, + ], + }, + { + ecCodewordsPerBlock: 24, + ecBlocks: [ + { numBlocks: 11, dataCodewordsPerBlock: 12 }, + { numBlocks: 7, dataCodewordsPerBlock: 13 }, + ], + }, + ], + }, + { + infoBits: 0x10B78, + versionNumber: 16, + alignmentPatternCenters: [6, 26, 50, 74], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 24, + ecBlocks: [ + { numBlocks: 5, dataCodewordsPerBlock: 98 }, + { numBlocks: 1, dataCodewordsPerBlock: 99 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 7, dataCodewordsPerBlock: 45 }, + { numBlocks: 3, dataCodewordsPerBlock: 46 }, + ], + }, + { + ecCodewordsPerBlock: 24, + ecBlocks: [ + { numBlocks: 15, dataCodewordsPerBlock: 19 }, + { numBlocks: 2, dataCodewordsPerBlock: 20 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 3, dataCodewordsPerBlock: 15 }, + { numBlocks: 13, dataCodewordsPerBlock: 16 }, + ], + }, + ], + }, + { + infoBits: 0x1145D, + versionNumber: 17, + alignmentPatternCenters: [6, 30, 54, 78], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 1, dataCodewordsPerBlock: 107 }, + { numBlocks: 5, dataCodewordsPerBlock: 108 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 10, dataCodewordsPerBlock: 46 }, + { numBlocks: 1, dataCodewordsPerBlock: 47 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 1, dataCodewordsPerBlock: 22 }, + { numBlocks: 15, dataCodewordsPerBlock: 23 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 2, dataCodewordsPerBlock: 14 }, + { numBlocks: 17, dataCodewordsPerBlock: 15 }, + ], + }, + ], + }, + { + infoBits: 0x12A17, + versionNumber: 18, + alignmentPatternCenters: [6, 30, 56, 82], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 5, dataCodewordsPerBlock: 120 }, + { numBlocks: 1, dataCodewordsPerBlock: 121 }, + ], + }, + { + ecCodewordsPerBlock: 26, + ecBlocks: [ + { numBlocks: 9, dataCodewordsPerBlock: 43 }, + { numBlocks: 4, dataCodewordsPerBlock: 44 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 17, dataCodewordsPerBlock: 22 }, + { numBlocks: 1, dataCodewordsPerBlock: 23 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 2, dataCodewordsPerBlock: 14 }, + { numBlocks: 19, dataCodewordsPerBlock: 15 }, + ], + }, + ], + }, + { + infoBits: 0x13532, + versionNumber: 19, + alignmentPatternCenters: [6, 30, 58, 86], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 3, dataCodewordsPerBlock: 113 }, + { numBlocks: 4, dataCodewordsPerBlock: 114 }, + ], + }, + { + ecCodewordsPerBlock: 26, + ecBlocks: [ + { numBlocks: 3, dataCodewordsPerBlock: 44 }, + { numBlocks: 11, dataCodewordsPerBlock: 45 }, + ], + }, + { + ecCodewordsPerBlock: 26, + ecBlocks: [ + { numBlocks: 17, dataCodewordsPerBlock: 21 }, + { numBlocks: 4, dataCodewordsPerBlock: 22 }, + ], + }, + { + ecCodewordsPerBlock: 26, + ecBlocks: [ + { numBlocks: 9, dataCodewordsPerBlock: 13 }, + { numBlocks: 16, dataCodewordsPerBlock: 14 }, + ], + }, + ], + }, + { + infoBits: 0x149A6, + versionNumber: 20, + alignmentPatternCenters: [6, 34, 62, 90], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 3, dataCodewordsPerBlock: 107 }, + { numBlocks: 5, dataCodewordsPerBlock: 108 }, + ], + }, + { + ecCodewordsPerBlock: 26, + ecBlocks: [ + { numBlocks: 3, dataCodewordsPerBlock: 41 }, + { numBlocks: 13, dataCodewordsPerBlock: 42 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 15, dataCodewordsPerBlock: 24 }, + { numBlocks: 5, dataCodewordsPerBlock: 25 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 15, dataCodewordsPerBlock: 15 }, + { numBlocks: 10, dataCodewordsPerBlock: 16 }, + ], + }, + ], + }, + { + infoBits: 0x15683, + versionNumber: 21, + alignmentPatternCenters: [6, 28, 50, 72, 94], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 4, dataCodewordsPerBlock: 116 }, + { numBlocks: 4, dataCodewordsPerBlock: 117 }, + ], + }, + { + ecCodewordsPerBlock: 26, + ecBlocks: [{ numBlocks: 17, dataCodewordsPerBlock: 42 }], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 17, dataCodewordsPerBlock: 22 }, + { numBlocks: 6, dataCodewordsPerBlock: 23 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 19, dataCodewordsPerBlock: 16 }, + { numBlocks: 6, dataCodewordsPerBlock: 17 }, + ], + }, + ], + }, + { + infoBits: 0x168C9, + versionNumber: 22, + alignmentPatternCenters: [6, 26, 50, 74, 98], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 2, dataCodewordsPerBlock: 111 }, + { numBlocks: 7, dataCodewordsPerBlock: 112 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [{ numBlocks: 17, dataCodewordsPerBlock: 46 }], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 7, dataCodewordsPerBlock: 24 }, + { numBlocks: 16, dataCodewordsPerBlock: 25 }, + ], + }, + { + ecCodewordsPerBlock: 24, + ecBlocks: [{ numBlocks: 34, dataCodewordsPerBlock: 13 }], + }, + ], + }, + { + infoBits: 0x177EC, + versionNumber: 23, + alignmentPatternCenters: [6, 30, 54, 74, 102], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 4, dataCodewordsPerBlock: 121 }, + { numBlocks: 5, dataCodewordsPerBlock: 122 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 4, dataCodewordsPerBlock: 47 }, + { numBlocks: 14, dataCodewordsPerBlock: 48 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 11, dataCodewordsPerBlock: 24 }, + { numBlocks: 14, dataCodewordsPerBlock: 25 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 16, dataCodewordsPerBlock: 15 }, + { numBlocks: 14, dataCodewordsPerBlock: 16 }, + ], + }, + ], + }, + { + infoBits: 0x18EC4, + versionNumber: 24, + alignmentPatternCenters: [6, 28, 54, 80, 106], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 6, dataCodewordsPerBlock: 117 }, + { numBlocks: 4, dataCodewordsPerBlock: 118 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 6, dataCodewordsPerBlock: 45 }, + { numBlocks: 14, dataCodewordsPerBlock: 46 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 11, dataCodewordsPerBlock: 24 }, + { numBlocks: 16, dataCodewordsPerBlock: 25 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 30, dataCodewordsPerBlock: 16 }, + { numBlocks: 2, dataCodewordsPerBlock: 17 }, + ], + }, + ], + }, + { + infoBits: 0x191E1, + versionNumber: 25, + alignmentPatternCenters: [6, 32, 58, 84, 110], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 26, + ecBlocks: [ + { numBlocks: 8, dataCodewordsPerBlock: 106 }, + { numBlocks: 4, dataCodewordsPerBlock: 107 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 8, dataCodewordsPerBlock: 47 }, + { numBlocks: 13, dataCodewordsPerBlock: 48 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 7, dataCodewordsPerBlock: 24 }, + { numBlocks: 22, dataCodewordsPerBlock: 25 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 22, dataCodewordsPerBlock: 15 }, + { numBlocks: 13, dataCodewordsPerBlock: 16 }, + ], + }, + ], + }, + { + infoBits: 0x1AFAB, + versionNumber: 26, + alignmentPatternCenters: [6, 30, 58, 86, 114], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 10, dataCodewordsPerBlock: 114 }, + { numBlocks: 2, dataCodewordsPerBlock: 115 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 19, dataCodewordsPerBlock: 46 }, + { numBlocks: 4, dataCodewordsPerBlock: 47 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 28, dataCodewordsPerBlock: 22 }, + { numBlocks: 6, dataCodewordsPerBlock: 23 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 33, dataCodewordsPerBlock: 16 }, + { numBlocks: 4, dataCodewordsPerBlock: 17 }, + ], + }, + ], + }, + { + infoBits: 0x1B08E, + versionNumber: 27, + alignmentPatternCenters: [6, 34, 62, 90, 118], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 8, dataCodewordsPerBlock: 122 }, + { numBlocks: 4, dataCodewordsPerBlock: 123 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 22, dataCodewordsPerBlock: 45 }, + { numBlocks: 3, dataCodewordsPerBlock: 46 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 8, dataCodewordsPerBlock: 23 }, + { numBlocks: 26, dataCodewordsPerBlock: 24 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 12, dataCodewordsPerBlock: 15 }, + { numBlocks: 28, dataCodewordsPerBlock: 16 }, + ], + }, + ], + }, + { + infoBits: 0x1CC1A, + versionNumber: 28, + alignmentPatternCenters: [6, 26, 50, 74, 98, 122], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 3, dataCodewordsPerBlock: 117 }, + { numBlocks: 10, dataCodewordsPerBlock: 118 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 3, dataCodewordsPerBlock: 45 }, + { numBlocks: 23, dataCodewordsPerBlock: 46 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 4, dataCodewordsPerBlock: 24 }, + { numBlocks: 31, dataCodewordsPerBlock: 25 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 11, dataCodewordsPerBlock: 15 }, + { numBlocks: 31, dataCodewordsPerBlock: 16 }, + ], + }, + ], + }, + { + infoBits: 0x1D33F, + versionNumber: 29, + alignmentPatternCenters: [6, 30, 54, 78, 102, 126], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 7, dataCodewordsPerBlock: 116 }, + { numBlocks: 7, dataCodewordsPerBlock: 117 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 21, dataCodewordsPerBlock: 45 }, + { numBlocks: 7, dataCodewordsPerBlock: 46 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 1, dataCodewordsPerBlock: 23 }, + { numBlocks: 37, dataCodewordsPerBlock: 24 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 19, dataCodewordsPerBlock: 15 }, + { numBlocks: 26, dataCodewordsPerBlock: 16 }, + ], + }, + ], + }, + { + infoBits: 0x1ED75, + versionNumber: 30, + alignmentPatternCenters: [6, 26, 52, 78, 104, 130], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 5, dataCodewordsPerBlock: 115 }, + { numBlocks: 10, dataCodewordsPerBlock: 116 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 19, dataCodewordsPerBlock: 47 }, + { numBlocks: 10, dataCodewordsPerBlock: 48 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 15, dataCodewordsPerBlock: 24 }, + { numBlocks: 25, dataCodewordsPerBlock: 25 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 23, dataCodewordsPerBlock: 15 }, + { numBlocks: 25, dataCodewordsPerBlock: 16 }, + ], + }, + ], + }, + { + infoBits: 0x1F250, + versionNumber: 31, + alignmentPatternCenters: [6, 30, 56, 82, 108, 134], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 13, dataCodewordsPerBlock: 115 }, + { numBlocks: 3, dataCodewordsPerBlock: 116 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 2, dataCodewordsPerBlock: 46 }, + { numBlocks: 29, dataCodewordsPerBlock: 47 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 42, dataCodewordsPerBlock: 24 }, + { numBlocks: 1, dataCodewordsPerBlock: 25 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 23, dataCodewordsPerBlock: 15 }, + { numBlocks: 28, dataCodewordsPerBlock: 16 }, + ], + }, + ], + }, + { + infoBits: 0x209D5, + versionNumber: 32, + alignmentPatternCenters: [6, 34, 60, 86, 112, 138], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 30, + ecBlocks: [{ numBlocks: 17, dataCodewordsPerBlock: 115 }], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 10, dataCodewordsPerBlock: 46 }, + { numBlocks: 23, dataCodewordsPerBlock: 47 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 10, dataCodewordsPerBlock: 24 }, + { numBlocks: 35, dataCodewordsPerBlock: 25 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 19, dataCodewordsPerBlock: 15 }, + { numBlocks: 35, dataCodewordsPerBlock: 16 }, + ], + }, + ], + }, + { + infoBits: 0x216F0, + versionNumber: 33, + alignmentPatternCenters: [6, 30, 58, 86, 114, 142], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 17, dataCodewordsPerBlock: 115 }, + { numBlocks: 1, dataCodewordsPerBlock: 116 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 14, dataCodewordsPerBlock: 46 }, + { numBlocks: 21, dataCodewordsPerBlock: 47 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 29, dataCodewordsPerBlock: 24 }, + { numBlocks: 19, dataCodewordsPerBlock: 25 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 11, dataCodewordsPerBlock: 15 }, + { numBlocks: 46, dataCodewordsPerBlock: 16 }, + ], + }, + ], + }, + { + infoBits: 0x228BA, + versionNumber: 34, + alignmentPatternCenters: [6, 34, 62, 90, 118, 146], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 13, dataCodewordsPerBlock: 115 }, + { numBlocks: 6, dataCodewordsPerBlock: 116 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 14, dataCodewordsPerBlock: 46 }, + { numBlocks: 23, dataCodewordsPerBlock: 47 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 44, dataCodewordsPerBlock: 24 }, + { numBlocks: 7, dataCodewordsPerBlock: 25 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 59, dataCodewordsPerBlock: 16 }, + { numBlocks: 1, dataCodewordsPerBlock: 17 }, + ], + }, + ], + }, + { + infoBits: 0x2379F, + versionNumber: 35, + alignmentPatternCenters: [6, 30, 54, 78, 102, 126, 150], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 12, dataCodewordsPerBlock: 121 }, + { numBlocks: 7, dataCodewordsPerBlock: 122 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 12, dataCodewordsPerBlock: 47 }, + { numBlocks: 26, dataCodewordsPerBlock: 48 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 39, dataCodewordsPerBlock: 24 }, + { numBlocks: 14, dataCodewordsPerBlock: 25 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 22, dataCodewordsPerBlock: 15 }, + { numBlocks: 41, dataCodewordsPerBlock: 16 }, + ], + }, + ], + }, + { + infoBits: 0x24B0B, + versionNumber: 36, + alignmentPatternCenters: [6, 24, 50, 76, 102, 128, 154], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 6, dataCodewordsPerBlock: 121 }, + { numBlocks: 14, dataCodewordsPerBlock: 122 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 6, dataCodewordsPerBlock: 47 }, + { numBlocks: 34, dataCodewordsPerBlock: 48 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 46, dataCodewordsPerBlock: 24 }, + { numBlocks: 10, dataCodewordsPerBlock: 25 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 2, dataCodewordsPerBlock: 15 }, + { numBlocks: 64, dataCodewordsPerBlock: 16 }, + ], + }, + ], + }, + { + infoBits: 0x2542E, + versionNumber: 37, + alignmentPatternCenters: [6, 28, 54, 80, 106, 132, 158], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 17, dataCodewordsPerBlock: 122 }, + { numBlocks: 4, dataCodewordsPerBlock: 123 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 29, dataCodewordsPerBlock: 46 }, + { numBlocks: 14, dataCodewordsPerBlock: 47 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 49, dataCodewordsPerBlock: 24 }, + { numBlocks: 10, dataCodewordsPerBlock: 25 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 24, dataCodewordsPerBlock: 15 }, + { numBlocks: 46, dataCodewordsPerBlock: 16 }, + ], + }, + ], + }, + { + infoBits: 0x26A64, + versionNumber: 38, + alignmentPatternCenters: [6, 32, 58, 84, 110, 136, 162], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 4, dataCodewordsPerBlock: 122 }, + { numBlocks: 18, dataCodewordsPerBlock: 123 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 13, dataCodewordsPerBlock: 46 }, + { numBlocks: 32, dataCodewordsPerBlock: 47 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 48, dataCodewordsPerBlock: 24 }, + { numBlocks: 14, dataCodewordsPerBlock: 25 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 42, dataCodewordsPerBlock: 15 }, + { numBlocks: 32, dataCodewordsPerBlock: 16 }, + ], + }, + ], + }, + { + infoBits: 0x27541, + versionNumber: 39, + alignmentPatternCenters: [6, 26, 54, 82, 110, 138, 166], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 20, dataCodewordsPerBlock: 117 }, + { numBlocks: 4, dataCodewordsPerBlock: 118 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 40, dataCodewordsPerBlock: 47 }, + { numBlocks: 7, dataCodewordsPerBlock: 48 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 43, dataCodewordsPerBlock: 24 }, + { numBlocks: 22, dataCodewordsPerBlock: 25 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 10, dataCodewordsPerBlock: 15 }, + { numBlocks: 67, dataCodewordsPerBlock: 16 }, + ], + }, + ], + }, + { + infoBits: 0x28C69, + versionNumber: 40, + alignmentPatternCenters: [6, 30, 58, 86, 114, 142, 170], + errorCorrectionLevels: [ + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 19, dataCodewordsPerBlock: 118 }, + { numBlocks: 6, dataCodewordsPerBlock: 119 }, + ], + }, + { + ecCodewordsPerBlock: 28, + ecBlocks: [ + { numBlocks: 18, dataCodewordsPerBlock: 47 }, + { numBlocks: 31, dataCodewordsPerBlock: 48 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 34, dataCodewordsPerBlock: 24 }, + { numBlocks: 34, dataCodewordsPerBlock: 25 }, + ], + }, + { + ecCodewordsPerBlock: 30, + ecBlocks: [ + { numBlocks: 20, dataCodewordsPerBlock: 15 }, + { numBlocks: 61, dataCodewordsPerBlock: 16 }, + ], + }, + ], + }, +]; + + +/***/ }), +/* 11 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +var BitMatrix_1 = __webpack_require__(0); +function squareToQuadrilateral(p1, p2, p3, p4) { + var dx3 = p1.x - p2.x + p3.x - p4.x; + var dy3 = p1.y - p2.y + p3.y - p4.y; + if (dx3 === 0 && dy3 === 0) { // Affine + return { + a11: p2.x - p1.x, + a12: p2.y - p1.y, + a13: 0, + a21: p3.x - p2.x, + a22: p3.y - p2.y, + a23: 0, + a31: p1.x, + a32: p1.y, + a33: 1, + }; + } + else { + var dx1 = p2.x - p3.x; + var dx2 = p4.x - p3.x; + var dy1 = p2.y - p3.y; + var dy2 = p4.y - p3.y; + var denominator = dx1 * dy2 - dx2 * dy1; + var a13 = (dx3 * dy2 - dx2 * dy3) / denominator; + var a23 = (dx1 * dy3 - dx3 * dy1) / denominator; + return { + a11: p2.x - p1.x + a13 * p2.x, + a12: p2.y - p1.y + a13 * p2.y, + a13: a13, + a21: p4.x - p1.x + a23 * p4.x, + a22: p4.y - p1.y + a23 * p4.y, + a23: a23, + a31: p1.x, + a32: p1.y, + a33: 1, + }; + } +} +function quadrilateralToSquare(p1, p2, p3, p4) { + // Here, the adjoint serves as the inverse: + var sToQ = squareToQuadrilateral(p1, p2, p3, p4); + return { + a11: sToQ.a22 * sToQ.a33 - sToQ.a23 * sToQ.a32, + a12: sToQ.a13 * sToQ.a32 - sToQ.a12 * sToQ.a33, + a13: sToQ.a12 * sToQ.a23 - sToQ.a13 * sToQ.a22, + a21: sToQ.a23 * sToQ.a31 - sToQ.a21 * sToQ.a33, + a22: sToQ.a11 * sToQ.a33 - sToQ.a13 * sToQ.a31, + a23: sToQ.a13 * sToQ.a21 - sToQ.a11 * sToQ.a23, + a31: sToQ.a21 * sToQ.a32 - sToQ.a22 * sToQ.a31, + a32: sToQ.a12 * sToQ.a31 - sToQ.a11 * sToQ.a32, + a33: sToQ.a11 * sToQ.a22 - sToQ.a12 * sToQ.a21, + }; +} +function times(a, b) { + return { + a11: a.a11 * b.a11 + a.a21 * b.a12 + a.a31 * b.a13, + a12: a.a12 * b.a11 + a.a22 * b.a12 + a.a32 * b.a13, + a13: a.a13 * b.a11 + a.a23 * b.a12 + a.a33 * b.a13, + a21: a.a11 * b.a21 + a.a21 * b.a22 + a.a31 * b.a23, + a22: a.a12 * b.a21 + a.a22 * b.a22 + a.a32 * b.a23, + a23: a.a13 * b.a21 + a.a23 * b.a22 + a.a33 * b.a23, + a31: a.a11 * b.a31 + a.a21 * b.a32 + a.a31 * b.a33, + a32: a.a12 * b.a31 + a.a22 * b.a32 + a.a32 * b.a33, + a33: a.a13 * b.a31 + a.a23 * b.a32 + a.a33 * b.a33, + }; +} +function extract(image, location) { + var qToS = quadrilateralToSquare({ x: 3.5, y: 3.5 }, { x: location.dimension - 3.5, y: 3.5 }, { x: location.dimension - 6.5, y: location.dimension - 6.5 }, { x: 3.5, y: location.dimension - 3.5 }); + var sToQ = squareToQuadrilateral(location.topLeft, location.topRight, location.alignmentPattern, location.bottomLeft); + var transform = times(sToQ, qToS); + var matrix = BitMatrix_1.BitMatrix.createEmpty(location.dimension, location.dimension); + var mappingFunction = function (x, y) { + var denominator = transform.a13 * x + transform.a23 * y + transform.a33; + return { + x: (transform.a11 * x + transform.a21 * y + transform.a31) / denominator, + y: (transform.a12 * x + transform.a22 * y + transform.a32) / denominator, + }; + }; + for (var y = 0; y < location.dimension; y++) { + for (var x = 0; x < location.dimension; x++) { + var xValue = x + 0.5; + var yValue = y + 0.5; + var sourcePixel = mappingFunction(xValue, yValue); + matrix.set(x, y, image.get(Math.floor(sourcePixel.x), Math.floor(sourcePixel.y))); + } + } + return { + matrix: matrix, + mappingFunction: mappingFunction, + }; +} +exports.extract = extract; + + +/***/ }), +/* 12 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +var MAX_FINDERPATTERNS_TO_SEARCH = 4; +var MIN_QUAD_RATIO = 0.5; +var MAX_QUAD_RATIO = 1.5; +var distance = function (a, b) { return Math.sqrt(Math.pow((b.x - a.x), 2) + Math.pow((b.y - a.y), 2)); }; +function sum(values) { + return values.reduce(function (a, b) { return a + b; }); +} +// Takes three finder patterns and organizes them into topLeft, topRight, etc +function reorderFinderPatterns(pattern1, pattern2, pattern3) { + var _a, _b, _c, _d; + // Find distances between pattern centers + var oneTwoDistance = distance(pattern1, pattern2); + var twoThreeDistance = distance(pattern2, pattern3); + var oneThreeDistance = distance(pattern1, pattern3); + var bottomLeft; + var topLeft; + var topRight; + // Assume one closest to other two is B; A and C will just be guesses at first + if (twoThreeDistance >= oneTwoDistance && twoThreeDistance >= oneThreeDistance) { + _a = [pattern2, pattern1, pattern3], bottomLeft = _a[0], topLeft = _a[1], topRight = _a[2]; + } + else if (oneThreeDistance >= twoThreeDistance && oneThreeDistance >= oneTwoDistance) { + _b = [pattern1, pattern2, pattern3], bottomLeft = _b[0], topLeft = _b[1], topRight = _b[2]; + } + else { + _c = [pattern1, pattern3, pattern2], bottomLeft = _c[0], topLeft = _c[1], topRight = _c[2]; + } + // Use cross product to figure out whether bottomLeft (A) and topRight (C) are correct or flipped in relation to topLeft (B) + // This asks whether BC x BA has a positive z component, which is the arrangement we want. If it's negative, then + // we've got it flipped around and should swap topRight and bottomLeft. + if (((topRight.x - topLeft.x) * (bottomLeft.y - topLeft.y)) - ((topRight.y - topLeft.y) * (bottomLeft.x - topLeft.x)) < 0) { + _d = [topRight, bottomLeft], bottomLeft = _d[0], topRight = _d[1]; + } + return { bottomLeft: bottomLeft, topLeft: topLeft, topRight: topRight }; +} +// Computes the dimension (number of modules on a side) of the QR Code based on the position of the finder patterns +function computeDimension(topLeft, topRight, bottomLeft, matrix) { + var moduleSize = (sum(countBlackWhiteRun(topLeft, bottomLeft, matrix, 5)) / 7 + // Divide by 7 since the ratio is 1:1:3:1:1 + sum(countBlackWhiteRun(topLeft, topRight, matrix, 5)) / 7 + + sum(countBlackWhiteRun(bottomLeft, topLeft, matrix, 5)) / 7 + + sum(countBlackWhiteRun(topRight, topLeft, matrix, 5)) / 7) / 4; + if (moduleSize < 1) { + throw new Error("Invalid module size"); + } + var topDimension = Math.round(distance(topLeft, topRight) / moduleSize); + var sideDimension = Math.round(distance(topLeft, bottomLeft) / moduleSize); + var dimension = Math.floor((topDimension + sideDimension) / 2) + 7; + switch (dimension % 4) { + case 0: + dimension++; + break; + case 2: + dimension--; + break; + } + return { dimension: dimension, moduleSize: moduleSize }; +} +// Takes an origin point and an end point and counts the sizes of the black white run from the origin towards the end point. +// Returns an array of elements, representing the pixel size of the black white run. +// Uses a variant of http://en.wikipedia.org/wiki/Bresenham's_line_algorithm +function countBlackWhiteRunTowardsPoint(origin, end, matrix, length) { + var switchPoints = [{ x: Math.floor(origin.x), y: Math.floor(origin.y) }]; + var steep = Math.abs(end.y - origin.y) > Math.abs(end.x - origin.x); + var fromX; + var fromY; + var toX; + var toY; + if (steep) { + fromX = Math.floor(origin.y); + fromY = Math.floor(origin.x); + toX = Math.floor(end.y); + toY = Math.floor(end.x); + } + else { + fromX = Math.floor(origin.x); + fromY = Math.floor(origin.y); + toX = Math.floor(end.x); + toY = Math.floor(end.y); + } + var dx = Math.abs(toX - fromX); + var dy = Math.abs(toY - fromY); + var error = Math.floor(-dx / 2); + var xStep = fromX < toX ? 1 : -1; + var yStep = fromY < toY ? 1 : -1; + var currentPixel = true; + // Loop up until x == toX, but not beyond + for (var x = fromX, y = fromY; x !== toX + xStep; x += xStep) { + // Does current pixel mean we have moved white to black or vice versa? + // Scanning black in state 0,2 and white in state 1, so if we find the wrong + // color, advance to next state or end if we are in state 2 already + var realX = steep ? y : x; + var realY = steep ? x : y; + if (matrix.get(realX, realY) !== currentPixel) { + currentPixel = !currentPixel; + switchPoints.push({ x: realX, y: realY }); + if (switchPoints.length === length + 1) { + break; + } + } + error += dy; + if (error > 0) { + if (y === toY) { + break; + } + y += yStep; + error -= dx; + } + } + var distances = []; + for (var i = 0; i < length; i++) { + if (switchPoints[i] && switchPoints[i + 1]) { + distances.push(distance(switchPoints[i], switchPoints[i + 1])); + } + else { + distances.push(0); + } + } + return distances; +} +// Takes an origin point and an end point and counts the sizes of the black white run in the origin point +// along the line that intersects with the end point. Returns an array of elements, representing the pixel sizes +// of the black white run. Takes a length which represents the number of switches from black to white to look for. +function countBlackWhiteRun(origin, end, matrix, length) { + var _a; + var rise = end.y - origin.y; + var run = end.x - origin.x; + var towardsEnd = countBlackWhiteRunTowardsPoint(origin, end, matrix, Math.ceil(length / 2)); + var awayFromEnd = countBlackWhiteRunTowardsPoint(origin, { x: origin.x - run, y: origin.y - rise }, matrix, Math.ceil(length / 2)); + var middleValue = towardsEnd.shift() + awayFromEnd.shift() - 1; // Substract one so we don't double count a pixel + return (_a = awayFromEnd.concat(middleValue)).concat.apply(_a, towardsEnd); +} +// Takes in a black white run and an array of expected ratios. Returns the average size of the run as well as the "error" - +// that is the amount the run diverges from the expected ratio +function scoreBlackWhiteRun(sequence, ratios) { + var averageSize = sum(sequence) / sum(ratios); + var error = 0; + ratios.forEach(function (ratio, i) { + error += Math.pow((sequence[i] - ratio * averageSize), 2); + }); + return { averageSize: averageSize, error: error }; +} +// Takes an X,Y point and an array of sizes and scores the point against those ratios. +// For example for a finder pattern takes the ratio list of 1:1:3:1:1 and checks horizontal, vertical and diagonal ratios +// against that. +function scorePattern(point, ratios, matrix) { + try { + var horizontalRun = countBlackWhiteRun(point, { x: -1, y: point.y }, matrix, ratios.length); + var verticalRun = countBlackWhiteRun(point, { x: point.x, y: -1 }, matrix, ratios.length); + var topLeftPoint = { + x: Math.max(0, point.x - point.y) - 1, + y: Math.max(0, point.y - point.x) - 1, + }; + var topLeftBottomRightRun = countBlackWhiteRun(point, topLeftPoint, matrix, ratios.length); + var bottomLeftPoint = { + x: Math.min(matrix.width, point.x + point.y) + 1, + y: Math.min(matrix.height, point.y + point.x) + 1, + }; + var bottomLeftTopRightRun = countBlackWhiteRun(point, bottomLeftPoint, matrix, ratios.length); + var horzError = scoreBlackWhiteRun(horizontalRun, ratios); + var vertError = scoreBlackWhiteRun(verticalRun, ratios); + var diagDownError = scoreBlackWhiteRun(topLeftBottomRightRun, ratios); + var diagUpError = scoreBlackWhiteRun(bottomLeftTopRightRun, ratios); + var ratioError = Math.sqrt(horzError.error * horzError.error + + vertError.error * vertError.error + + diagDownError.error * diagDownError.error + + diagUpError.error * diagUpError.error); + var avgSize = (horzError.averageSize + vertError.averageSize + diagDownError.averageSize + diagUpError.averageSize) / 4; + var sizeError = (Math.pow((horzError.averageSize - avgSize), 2) + + Math.pow((vertError.averageSize - avgSize), 2) + + Math.pow((diagDownError.averageSize - avgSize), 2) + + Math.pow((diagUpError.averageSize - avgSize), 2)) / avgSize; + return ratioError + sizeError; + } + catch (_a) { + return Infinity; + } +} +function recenterLocation(matrix, p) { + var leftX = Math.round(p.x); + while (matrix.get(leftX, Math.round(p.y))) { + leftX--; + } + var rightX = Math.round(p.x); + while (matrix.get(rightX, Math.round(p.y))) { + rightX++; + } + var x = (leftX + rightX) / 2; + var topY = Math.round(p.y); + while (matrix.get(Math.round(x), topY)) { + topY--; + } + var bottomY = Math.round(p.y); + while (matrix.get(Math.round(x), bottomY)) { + bottomY++; + } + var y = (topY + bottomY) / 2; + return { x: x, y: y }; +} +function locate(matrix) { + var finderPatternQuads = []; + var activeFinderPatternQuads = []; + var alignmentPatternQuads = []; + var activeAlignmentPatternQuads = []; + var _loop_1 = function (y) { + var length_1 = 0; + var lastBit = false; + var scans = [0, 0, 0, 0, 0]; + var _loop_2 = function (x) { + var v = matrix.get(x, y); + if (v === lastBit) { + length_1++; + } + else { + scans = [scans[1], scans[2], scans[3], scans[4], length_1]; + length_1 = 1; + lastBit = v; + // Do the last 5 color changes ~ match the expected ratio for a finder pattern? 1:1:3:1:1 of b:w:b:w:b + var averageFinderPatternBlocksize = sum(scans) / 7; + var validFinderPattern = Math.abs(scans[0] - averageFinderPatternBlocksize) < averageFinderPatternBlocksize && + Math.abs(scans[1] - averageFinderPatternBlocksize) < averageFinderPatternBlocksize && + Math.abs(scans[2] - 3 * averageFinderPatternBlocksize) < 3 * averageFinderPatternBlocksize && + Math.abs(scans[3] - averageFinderPatternBlocksize) < averageFinderPatternBlocksize && + Math.abs(scans[4] - averageFinderPatternBlocksize) < averageFinderPatternBlocksize && + !v; // And make sure the current pixel is white since finder patterns are bordered in white + // Do the last 3 color changes ~ match the expected ratio for an alignment pattern? 1:1:1 of w:b:w + var averageAlignmentPatternBlocksize = sum(scans.slice(-3)) / 3; + var validAlignmentPattern = Math.abs(scans[2] - averageAlignmentPatternBlocksize) < averageAlignmentPatternBlocksize && + Math.abs(scans[3] - averageAlignmentPatternBlocksize) < averageAlignmentPatternBlocksize && + Math.abs(scans[4] - averageAlignmentPatternBlocksize) < averageAlignmentPatternBlocksize && + v; // Is the current pixel black since alignment patterns are bordered in black + if (validFinderPattern) { + // Compute the start and end x values of the large center black square + var endX_1 = x - scans[3] - scans[4]; + var startX_1 = endX_1 - scans[2]; + var line = { startX: startX_1, endX: endX_1, y: y }; + // Is there a quad directly above the current spot? If so, extend it with the new line. Otherwise, create a new quad with + // that line as the starting point. + var matchingQuads = activeFinderPatternQuads.filter(function (q) { + return (startX_1 >= q.bottom.startX && startX_1 <= q.bottom.endX) || + (endX_1 >= q.bottom.startX && startX_1 <= q.bottom.endX) || + (startX_1 <= q.bottom.startX && endX_1 >= q.bottom.endX && ((scans[2] / (q.bottom.endX - q.bottom.startX)) < MAX_QUAD_RATIO && + (scans[2] / (q.bottom.endX - q.bottom.startX)) > MIN_QUAD_RATIO)); + }); + if (matchingQuads.length > 0) { + matchingQuads[0].bottom = line; + } + else { + activeFinderPatternQuads.push({ top: line, bottom: line }); + } + } + if (validAlignmentPattern) { + // Compute the start and end x values of the center black square + var endX_2 = x - scans[4]; + var startX_2 = endX_2 - scans[3]; + var line = { startX: startX_2, y: y, endX: endX_2 }; + // Is there a quad directly above the current spot? If so, extend it with the new line. Otherwise, create a new quad with + // that line as the starting point. + var matchingQuads = activeAlignmentPatternQuads.filter(function (q) { + return (startX_2 >= q.bottom.startX && startX_2 <= q.bottom.endX) || + (endX_2 >= q.bottom.startX && startX_2 <= q.bottom.endX) || + (startX_2 <= q.bottom.startX && endX_2 >= q.bottom.endX && ((scans[2] / (q.bottom.endX - q.bottom.startX)) < MAX_QUAD_RATIO && + (scans[2] / (q.bottom.endX - q.bottom.startX)) > MIN_QUAD_RATIO)); + }); + if (matchingQuads.length > 0) { + matchingQuads[0].bottom = line; + } + else { + activeAlignmentPatternQuads.push({ top: line, bottom: line }); + } + } + } + }; + for (var x = -1; x <= matrix.width; x++) { + _loop_2(x); + } + finderPatternQuads.push.apply(finderPatternQuads, activeFinderPatternQuads.filter(function (q) { return q.bottom.y !== y && q.bottom.y - q.top.y >= 2; })); + activeFinderPatternQuads = activeFinderPatternQuads.filter(function (q) { return q.bottom.y === y; }); + alignmentPatternQuads.push.apply(alignmentPatternQuads, activeAlignmentPatternQuads.filter(function (q) { return q.bottom.y !== y; })); + activeAlignmentPatternQuads = activeAlignmentPatternQuads.filter(function (q) { return q.bottom.y === y; }); + }; + for (var y = 0; y <= matrix.height; y++) { + _loop_1(y); + } + finderPatternQuads.push.apply(finderPatternQuads, activeFinderPatternQuads.filter(function (q) { return q.bottom.y - q.top.y >= 2; })); + alignmentPatternQuads.push.apply(alignmentPatternQuads, activeAlignmentPatternQuads); + var finderPatternGroups = finderPatternQuads + .filter(function (q) { return q.bottom.y - q.top.y >= 2; }) // All quads must be at least 2px tall since the center square is larger than a block + .map(function (q) { + var x = (q.top.startX + q.top.endX + q.bottom.startX + q.bottom.endX) / 4; + var y = (q.top.y + q.bottom.y + 1) / 2; + if (!matrix.get(Math.round(x), Math.round(y))) { + return; + } + var lengths = [q.top.endX - q.top.startX, q.bottom.endX - q.bottom.startX, q.bottom.y - q.top.y + 1]; + var size = sum(lengths) / lengths.length; + var score = scorePattern({ x: Math.round(x), y: Math.round(y) }, [1, 1, 3, 1, 1], matrix); + return { score: score, x: x, y: y, size: size }; + }) + .filter(function (q) { return !!q; }) // Filter out any rejected quads from above + .sort(function (a, b) { return a.score - b.score; }) + // Now take the top finder pattern options and try to find 2 other options with a similar size. + .map(function (point, i, finderPatterns) { + if (i > MAX_FINDERPATTERNS_TO_SEARCH) { + return null; + } + var otherPoints = finderPatterns + .filter(function (p, ii) { return i !== ii; }) + .map(function (p) { return ({ x: p.x, y: p.y, score: p.score + (Math.pow((p.size - point.size), 2)) / point.size, size: p.size }); }) + .sort(function (a, b) { return a.score - b.score; }); + if (otherPoints.length < 2) { + return null; + } + var score = point.score + otherPoints[0].score + otherPoints[1].score; + return { points: [point].concat(otherPoints.slice(0, 2)), score: score }; + }) + .filter(function (q) { return !!q; }) // Filter out any rejected finder patterns from above + .sort(function (a, b) { return a.score - b.score; }); + if (finderPatternGroups.length === 0) { + return null; + } + var _a = reorderFinderPatterns(finderPatternGroups[0].points[0], finderPatternGroups[0].points[1], finderPatternGroups[0].points[2]), topRight = _a.topRight, topLeft = _a.topLeft, bottomLeft = _a.bottomLeft; + var alignment = findAlignmentPattern(matrix, alignmentPatternQuads, topRight, topLeft, bottomLeft); + var result = []; + if (alignment) { + result.push({ + alignmentPattern: { x: alignment.alignmentPattern.x, y: alignment.alignmentPattern.y }, + bottomLeft: { x: bottomLeft.x, y: bottomLeft.y }, + dimension: alignment.dimension, + topLeft: { x: topLeft.x, y: topLeft.y }, + topRight: { x: topRight.x, y: topRight.y }, + }); + } + // We normally use the center of the quads as the location of the tracking points, which is optimal for most cases and will account + // for a skew in the image. However, In some cases, a slight skew might not be real and instead be caused by image compression + // errors and/or low resolution. For those cases, we'd be better off centering the point exactly in the middle of the black area. We + // compute and return the location data for the naively centered points as it is little additional work and allows for multiple + // attempts at decoding harder images. + var midTopRight = recenterLocation(matrix, topRight); + var midTopLeft = recenterLocation(matrix, topLeft); + var midBottomLeft = recenterLocation(matrix, bottomLeft); + var centeredAlignment = findAlignmentPattern(matrix, alignmentPatternQuads, midTopRight, midTopLeft, midBottomLeft); + if (centeredAlignment) { + result.push({ + alignmentPattern: { x: centeredAlignment.alignmentPattern.x, y: centeredAlignment.alignmentPattern.y }, + bottomLeft: { x: midBottomLeft.x, y: midBottomLeft.y }, + topLeft: { x: midTopLeft.x, y: midTopLeft.y }, + topRight: { x: midTopRight.x, y: midTopRight.y }, + dimension: centeredAlignment.dimension, + }); + } + if (result.length === 0) { + return null; + } + return result; +} +exports.locate = locate; +function findAlignmentPattern(matrix, alignmentPatternQuads, topRight, topLeft, bottomLeft) { + var _a; + // Now that we've found the three finder patterns we can determine the blockSize and the size of the QR code. + // We'll use these to help find the alignment pattern but also later when we do the extraction. + var dimension; + var moduleSize; + try { + (_a = computeDimension(topLeft, topRight, bottomLeft, matrix), dimension = _a.dimension, moduleSize = _a.moduleSize); + } + catch (e) { + return null; + } + // Now find the alignment pattern + var bottomRightFinderPattern = { + x: topRight.x - topLeft.x + bottomLeft.x, + y: topRight.y - topLeft.y + bottomLeft.y, + }; + var modulesBetweenFinderPatterns = ((distance(topLeft, bottomLeft) + distance(topLeft, topRight)) / 2 / moduleSize); + var correctionToTopLeft = 1 - (3 / modulesBetweenFinderPatterns); + var expectedAlignmentPattern = { + x: topLeft.x + correctionToTopLeft * (bottomRightFinderPattern.x - topLeft.x), + y: topLeft.y + correctionToTopLeft * (bottomRightFinderPattern.y - topLeft.y), + }; + var alignmentPatterns = alignmentPatternQuads + .map(function (q) { + var x = (q.top.startX + q.top.endX + q.bottom.startX + q.bottom.endX) / 4; + var y = (q.top.y + q.bottom.y + 1) / 2; + if (!matrix.get(Math.floor(x), Math.floor(y))) { + return; + } + var sizeScore = scorePattern({ x: Math.floor(x), y: Math.floor(y) }, [1, 1, 1], matrix); + var score = sizeScore + distance({ x: x, y: y }, expectedAlignmentPattern); + return { x: x, y: y, score: score }; + }) + .filter(function (v) { return !!v; }) + .sort(function (a, b) { return a.score - b.score; }); + // If there are less than 15 modules between finder patterns it's a version 1 QR code and as such has no alignmemnt pattern + // so we can only use our best guess. + var alignmentPattern = modulesBetweenFinderPatterns >= 15 && alignmentPatterns.length ? alignmentPatterns[0] : expectedAlignmentPattern; + return { alignmentPattern: alignmentPattern, dimension: dimension }; +} + + +/***/ }) +/******/ ])["default"]; +}); \ No newline at end of file diff --git a/assets/js/script.js b/assets/js/script.js new file mode 100755 index 0000000..b8bf188 --- /dev/null +++ b/assets/js/script.js @@ -0,0 +1,1402 @@ +let { e2ee } = await import(`./e2ee.js?r=${revision}`); +let { ws } = await import(`./ws.js?r=${revision}`); +let { ui } = await import(`./ui.js?r=${revision}`); +let { stream } = await import(`./stream.js?r=${revision}`); +let { listeners } = await import(`./listeners.js?r=${revision}`); + +function log(string) { + console.log(string); +} + +export class HNSChat { + constructor() { + window.hnschat = this; + + try { + this.varo = new Varo(); + } + catch {} + + this.mobile = false; + + this.host = window.location.host; + this.hash = window.location.hash.substring(1); + this.page; + this.data; + + this.ui = new ui(this); + this.ws = new ws(this); + this.listeners = new listeners(this); + this.e2ee = new e2ee(); + + this.streamURL = "https://media.hns.chat/stream"; + this.stream; + + this.isActive = true; + + this.keys; + this.session; + this.domain; + this.domains; + this.staked; + this.conversation; + this.settings; + this.messages = []; + this.seen = {}; + + this.users; + + this.channels; + this.pms; + + this.tab = "channels"; + + this.timeFormat = "g:i A"; + this.dateFormat = "F jS, Y"; + + this.gotChannels; + this.gotPms; + this.gotMentions; + + this.loadingMessages; + this.replying; + this.queued = []; + + this.typing; + this.typingSent; + this.typingDelay = 2; + this.typingSendDelay = 1; + this.lastTyped; + this.typers = {}; + + this.active = []; + + this.avatars = {}; + + this.action = "\x01ACTION"; + + this.commands = ["me", "shrug", "slap"]; + + this.hasBob; + + this.init(); + } + + varoLoaded() { + if (typeof this.varo !== "undefined") { + return true; + } + return false + } + + getPage() { + let pathname = document.location.pathname; + let match = pathname.match(/\/(?.+?)(?:\/(?.+)|$)/); + if (match) { + let groups = match.groups; + + if (groups.page) { + this.page = groups.page; + } + if (groups.data) { + this.data = groups.data; + } + } + else { + this.page = "chat"; + } + } + + async api(data) { + if (this.session) { + data.session = this.session; + } + + let output = new Promise(function(resolve) { + $.post("/api", JSON.stringify(data), function(response){ + if (response) { + let json = JSON.parse(response); + resolve(json); + } + }); + }); + + return await output; + } + + time() { + return Math.floor(Date.now() / 1000); + } + + handlePush(init=false) { + if (localStorage.handlePush) { + try { + let info = JSON.parse(localStorage.handlePush); + + localStorage.setItem("domain", info.domain); + localStorage.setItem("conversation", info.conversation); + + if (!init) { + if (this.domain !== info.domain) { + this.changeDomain(info.domain); + } + this.changeConversation(info.conversation); + } + } + catch {} + } + localStorage.removeItem("handlePush"); + } + + async init() { + this.handlePush(true); + + this.getPage(); + switch (this.page) { + case "sync": + this.loadSync(); + break; + + case "buy": + break; + + default: + try { + this.keys = JSON.parse(localStorage.keys); + } + catch { + this.e2ee.generateKeys().then(r => { + this.keys = r; + localStorage.setItem("keys", JSON.stringify(this.keys)); + }); + } + + if (this.hash) { + localStorage.setItem("hash", this.hash); + history.pushState("", document.title, window.location.pathname + window.location.search); + } + else { + this.hash = localStorage.hash; + } + + this.mobile = localStorage.mobile || false; + + this.session = localStorage.session; + this.domain = localStorage.domain; + this.conversation = localStorage.conversation; + + try { + this.settings = JSON.parse(localStorage.settings); + this.loadSettings(); + } + catch { + this.settings = {}; + } + + this.firstLaunch = localStorage.firstLaunch; + if (!this.firstLaunch) { + localStorage.setItem("firstLaunch", this.time()); + } + + await this.startSession(); + await this.setPublicKey(); + await this.ws.connect(); + break; + } + + switch (this.page) { + case "chat": + this.stream = new stream(this); + this.ui.setConversationTab(); + this.ui.setupSync(); + this.ui.setupNotifications(); + break; + } + + if (typeof bob3 != "undefined") { + this.hasBob = true; + this.ui.hasBob(); + } + } + + loadSettings() { + Object.keys(this.settings).forEach((setting, k) => { + let value = this.settings[setting]; + switch (setting) { + case "chatDisplayMode": + this.ui.chatDisplayMode(value); + break; + + default: + this.ui.root.style.setProperty(`--${setting}`, value); + break; + } + }); + } + + loadSync() { + let hash = this.hash; + let db64 = this.db64(hash); + let json = JSON.parse(db64); + this.session = json.session; + localStorage.setItem("session", this.session); + + if (json.settings) { + this.settings = json.settings; + localStorage.setItem("settings", JSON.stringify(this.settings)); + } + + let data = { + action: "getPublicKey" + } + this.api(data).then(r => { + if (r.success) { + let pubkey = JSON.parse(r.pubkey); + this.e2ee.importKey(pubkey.x, pubkey.y, json.privkey).then(privkey => { + this.keys = { + privateKeyJwk: privkey, + publicKeyJwk: pubkey + }; + + localStorage.setItem("keys", JSON.stringify(this.keys)); + this.ui.openURL("/"); + }); + } + }); + } + + db64(str) { + str = (str + '==='.slice((str.length + 3) % 4)).replace(/-/g, '+').replace(/_/g, '/'); + return atob(str); + } + + b64(str) { + str.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ''); + return btoa(str); + } + + syncLink() { + let data = { + session: this.session, + privkey: this.keys.privateKeyJwk.d, + settings: this.settings + } + + let json = JSON.stringify(data); + let encoded = this.b64(json); + let link = "https://"+this.host+"/sync#"+encoded; + + return link; + } + + regex(pattern, string) { + return [...string.matchAll(pattern)]; + } + + rtrim(str, chr) { + let rgxtrim = (!chr) ? new RegExp('\\s+$') : new RegExp(chr+'+$'); + return str.replace(rgxtrim, ''); + } + + replaceRange(s, start, end, substitute) { + let before = s.substr(0, start); + let after = s.substr(end, (s.length -end)); + + return before+substitute+after; + } + + sorted(array, by) { + return array.sort((a, b) => a[by].localeCompare(b[by])); + } + + isKey(e, key) { + if (this.key(e) == key) { + return true + } + return false; + } + + key(e) { + return e.which || e.keyCode; + } + + keyName(e) { + return e.key; + } + + setPublicKey() { + let data = { + action: "setPublicKey", + pubkey: JSON.stringify(this.keys.publicKeyJwk) + }; + + return this.api(data); + } + + async startSession() { + if (this.session) { + return; + } + + let data = { + "action": "startSession" + }; + + return this.api(data).then(r => { + this.session = r.session; + localStorage.setItem("session", r.session); + }); + } + + sendDomain() { + if (!this.domain) { + if (this.domains.length) { + this.domain = this.domains[0].id; + localStorage.setItem("domain", this.domain); + } + else { + this.ui.openURL("/id"); + return; + } + } + this.ws.send(`DOMAIN ${this.domain}`); + } + + message(data) { + let message = data.toString(); + let parsed = message.match(/(?[A-Z]+)(\s(?.+))?/); + this.handle(parsed.groups); + } + + async handle(parsed) { + let command = parsed.command; + let body = parsed.body; + let push = false; + + if (body) { + try { + body = JSON.parse(body); + + for (var k in body) { + try { + body[k] = JSON.parse(body[k]); + } + catch {} + + for (var i in body[k]) { + try { + body[k][i] = JSON.parse(body[k][i]); + } + catch {} + } + } + } + catch {} + } + + switch (command) { + case "SUCCESS": + switch (body.type) { + case "ADDDOMAIN": + case "ADDSLD": + this.ui.enableButton(body.type); + this.ui.handleSuccess(body); + break; + + case "DELETEDOMAIN": + this.ui.removeDomain(body.id); + break; + + case "VERIFYDOMAIN": + this.ui.handleSuccess(body); + break; + + case "GETADDRESS": + this.ui.paymentResponse(body); + break; + } + break; + + case "ERROR": + switch (body.type) { + case "ADDDOMAIN": + this.ui.errorResponse(body); + break; + + case "ADDSLD": + this.ui.enableButton(body.type); + this.ui.errorResponse(body); + break; + + case "MESSAGES": + this.ui.setUserList(); + this.ui.messagesLoading(false); + this.ui.setGatedView(body); + this.ui.markEmptyIfNeeded(); + this.loadingMessages = false; + break; + + case "DOMAIN": + this.domain = null; + this.sendDomain(); + break; + + case "PM": + if (body.id) { + let otherUser = this.otherUserFromPM(body.id); + let queuedMessage = this.queuedMessage(otherUser.domain); + if (queuedMessage) { + this.ui.changeConversation(body.id); + this.ui.close(); + } + } + else { + this.ui.errorResponse(body); + } + break; + + case "GETADDRESS": + this.ui.paymentResponse(body); + break; + } + break; + + case "IDENTIFIED": + if (this.page !== "sync") { + if (body.seen) { + this.seen = body.seen; + } + this.ws.send("DOMAINS"); + } + break; + + case "DOMAINS": + this.domains = body; + this.ui.domains(this.domains); + + switch (this.page) { + case "chat": + this.sendDomain(); + break; + + case "id": + case "invite": + this.ws.send(`STAKED`); + break; + } + break; + + case "STAKED": + this.staked = body; + this.ui.stakedDomains(body); + break; + + case "DOMAIN": + this.ui.updateDomainSelect(); + this.ws.send("USERS"); + break; + + case "USERS": + $.each(body, (k, user) => { + body[k].domain = body[k].domain.toString(); + }); + this.users = body; + this.ws.send(`PING`); + this.ws.send(`CHANNELS`); + this.ws.send(`PMS`); + break; + + case "USER": + this.users = this.users.filter(u => { + return u.id != body.id; + }); + + body.domain = body.domain.toString(); + this.users.push(body); + + if (body.id !== this.domain) { + let pm = this.pmWithUser(body.id); + if (pm) { + this.makeSecret(pm); + } + } + + this.ui.setUserList(); + this.ui.updateConversations(); + break; + + case "CHANNELS": + this.ui.clear("channels"); + this.channels = body; + if (this.channels.length) { + let sorted = this.channels.sort((a, b) => { + if (("activity" in a) && !("activity" in b)) { + return 1; + } + if (("activity" in b) && !("activity" in a)) { + return -1; + } + if (!("activity" in a) && !("activity" in b)) { + return 0; + } + return a.activity - b.activity; + }); + $.each(sorted.reverse(), (k, channel) => { + this.ui.conversation("channels", channel); + }); + } + this.ui.updateConversations(); + this.gotChannels = true; + this.ws.send(`MENTIONS`); + this.ready(true); + break; + + case "CHANNEL": + this.channels.push(body); + this.ui.conversation("channels", body); + this.ui.updateConversations(); + break; + + case "PMS": + this.ui.clear("pms"); + this.pms = body; + if (this.pms.length) { + let sorted = this.pms.sort((a, b) => { + return b.activity - a.activity; + }); + $.each(sorted, (k, conversation) => { + this.makeSecret(conversation).then((key) => { + this.ui.conversation("pms", conversation); + + if (k == this.pms.length - 1) { + this.ui.updateConversations(); + this.gotPms = true; + this.ready(true); + } + }); + }); + } + else { + this.ui.updateConversations(); + this.gotPms = true; + this.ready(true); + } + break; + + case "PM": + this.pms.push(body); + this.makeSecret(body).then((key) => { + this.ui.conversation("pms", body); + + let otherUser = this.otherUserFromPM(body.id); + let queuedMessage = this.queuedMessage(otherUser.domain); + if (queuedMessage) { + this.ui.changeConversation(body.id); + this.ui.close(); + } + }); + break; + + case "MESSAGES": + this.ui.setUserList(); + this.ui.insertMessages(body, true).then(() => { + this.ui.messagesLoading(false); + + if (body.at) { + this.ui.scrollToMessage(body.at); + } + else if (body.after) { + this.ui.backInPresent(body); + } + + if (!this.isChannel(this.conversation)) { + let otherUser = this.otherUserFromPM(this.conversation); + let queuedMessage = this.queuedMessage(otherUser.domain); + if (queuedMessage) { + this.queued = this.queued.filter(q => { + return q.domain !== queuedMessage.domain; + }); + this.sendMessage(this.conversation, queuedMessage.message); + } + } + }); + break; + + case "MESSAGE": + case "NOTICE": + delete this.typers[body.user]; + + let c; + if (this.isChannel(body.conversation)) { + c = this.channelForID(body.conversation); + } + else { + c = this.pmForID(body.conversation); + } + c.activity = body.time; + + this.ui.updateConversations(); + this.ui.moveConversationToTop(body.conversation); + + await this.decryptMessageIfNeeded(body.conversation, body).then(decrypted => { + body.message = decrypted[0]; + if (body.p_message) { + body.p_message = decrypted[1]; + } + + if (typeof body.message == "object") { + if (body.message.message) { + body.message.message = body.message.message.toString(); + } + body.message = JSON.stringify(body.message); + } + if (typeof body.p_message == "object") { + if (body.p_message.message) { + body.p_message.message = body.p_message.message.toString(); + } + body.p_message = JSON.stringify(body.p_message); + } + + body.message = body.message.toString(); + if (body.p_message) { + body.p_message = body.p_message.toString(); + } + + if (!this.ui.inThePast && body.conversation == this.conversation) { + let data = { + messages: [body] + } + this.ui.insertMessages(data); + this.seen[this.conversation] = this.time(); + + if (!this.isActive) { + if (this.isChannel(body.conversation)) { + if (this.mentionsMe(body.message)) { + push = "mention"; + } + else if (this.replyingToMe(body)) { + push = "reply"; + } + } + else { + push = "pm"; + } + } + } + else { + if (this.isChannel(body.conversation)) { + if (this.mentionsMe(body.message)) { + this.ui.markMention(body.conversation, true); + push = "mention"; + } + else if (this.replyingToMe(body)) { + push = "reply"; + } + } + else { + push = "pm"; + } + } + + if (push) { + if (body.user !== this.domain) { + let name; + + switch (push) { + case "pm": + name = this.ui.toUnicode(this.userForID(body.user).domain); + break; + + case "mention": + case "reply": + name = `${this.ui.toUnicode(this.userForID(body.user).domain)} - #${this.ui.toUnicode(c.name)}`; + break; + } + + let subtitle = this.ui.messageSummary(decrypted[0]); + subtitle = this.ui.stripHTML(this.ui.replaceIds(subtitle)); + this.ui.sendNotification(name, subtitle, body.conversation); + } + } + }); + break; + + case "DELETEMESSAGE": + this.ui.deleteMessage(body.id); + break; + + case "REACT": + if (body.conversation == this.conversation) { + let message = this.messages.filter(m => { + return m.id == body.message; + })[0]; + + try { + let json = JSON.parse(message.reactions); + + if (!Object.keys(json).includes(body.reaction)) { + json[body.reaction] = []; + } + + if (json[body.reaction].includes(body.user)) { + let x = json[body.reaction].indexOf(body.user); + delete json[body.reaction].splice(x, 1); + + if (!Object.keys(json[body.reaction]).length) { + delete json[body.reaction]; + } + } + else { + json[body.reaction].push(body.user); + } + + message.reactions = JSON.stringify(json); + this.ui.updateReactions(body.message); + this.seen[this.conversation] = this.time(); + } + catch {} + } + break; + + case "TYPING": + this.typers[body.from] = { + to: body.to, + time: this.time() + } + break; + + case "MENTIONS": + this.ui.updateMentions(body); + this.gotMentions = true; + this.ready(true); + break; + + case "PONG": + this.updateActiveUsers(body.active); + //this.ui.checkVersion(body.version); + break; + + case "PINMESSAGE": + this.channelForID(body.conversation).pinned = body.id; + if (this.conversation == body.conversation) { + this.ui.setPinnedMessage(); + } + break; + + case "STARTVIDEO": + this.ui.muteAll(); + this.channelForID(body.conversation).video = true; + this.channelForID(body.conversation).videoUsers = body.users; + this.ui.showVideoIfNeeded(); + break; + + case "INVITEVIDEO": + this.channelForID(body.conversation).videoSpeakers = body.speakers; + this.ui.showVideoIfNeeded(); + break; + + case "JOINVIDEO": + if (body.users) { + this.channelForID(body.conversation).videoUsers = body.users; + } + if (body.watchers) { + this.channelForID(body.conversation).videoWatchers = body.watchers; + } + if (body.speakers) { + this.channelForID(body.conversation).videoSpeakers = body.speakers; + } + this.ui.showVideoIfNeeded(); + break; + + case "VIEWVIDEO": + if (body.users) { + this.channelForID(body.conversation).videoUsers = body.users; + } + if (body.watchers) { + this.channelForID(body.conversation).videoWatchers = body.watchers; + if (body.watchers.includes(this.domain)) { + this.channelForID(body.conversation).watching = true; + } + } + this.ui.showVideoIfNeeded(); + break; + + case "LEAVEVIDEO": + if (body.users) { + this.channelForID(body.conversation).videoUsers = body.users; + } + if (body.watchers) { + this.channelForID(body.conversation).videoWatchers = body.watchers; + } + if (body.speakers) { + this.channelForID(body.conversation).videoSpeakers = body.speakers; + } + this.ui.showVideoIfNeeded(); + break; + + case "ENDVIDEO": + this.endVideo(body.conversation); + break; + + case "MUTEVIDEO": + case "MUTEAUDIO": + let toggle; + let user = this.channelForID(body.conversation).videoUsers[body.user]; + switch (command) { + case "MUTEVIDEO": + toggle = "toggleVideo"; + user.video = !user.video; + break; + + case "MUTEAUDIO": + toggle = "toggleAudio"; + user.audio = !user.audio; + break; + } + this.ui.updateVideoUsers(); + if (body.user == this.domain) { + this.ui.setMute(toggle, -1); + } + break; + + case "CONNECTED": + if (this.userForID(body)) { + this.userForID(body).active = true; + this.ui.updateUserList(); + this.ui.updateConversations(); + } + break; + + case "DISCONNECTED": + if (this.userForID(body)) { + this.userForID(body).active = false; + this.ui.updateUserList(); + this.ui.updateConversations(); + } + break; + } + } + + endAllVideo() { + try { + this.stream.close(); + $.each(this.channels, (k, c) => { + this.endVideo(c.id); + }); + } + catch {}; + } + + endVideo(conversation) { + this.channelForID(conversation).videoUsers = {}; + this.channelForID(conversation).videoWatchers = []; + this.channelForID(conversation).videoSpeakers = []; + this.channelForID(conversation).video = false; + this.channelForID(conversation).watching = false; + this.ui.showVideoIfNeeded(); + } + + currentVideoUsers() { + return this.channelForID(this.conversation).videoUsers; + } + + updateActiveUsers(active) { + if (this.users) { + let current = this.active; + this.active = active; + + current.forEach(u => { + if (!active.includes(u)) { + let user = this.userForID(u); + user.active = false; + } + }); + + active.forEach(u => { + let user = this.userForID(u); + user.active = true; + }); + + this.ui.updateUserList(); + this.ui.updateConversations(); + } + } + + otherUserFromPM(id) { + let pm = this.pmForID(id); + let otherUserID = this.otherUser(pm.users); + let otherUser = this.userForID(otherUserID); + return otherUser; + } + + queuedMessage(domain) { + return this.queued.filter(q => { + return q.domain == domain; + })[0]; + } + + ready(bool) { + if (bool) { + if (this.gotChannels && this.gotPms && this.gotMentions) { + this.ui.changeMe(this.domain); + this.ui.setLoading(false); + this.ui.handleHash(); + this.changeConversation(this.conversation); + this.changedConversation(); + } + } + else { + this.gotChannels = false; + this.gotPms = false; + this.gotMentions = false; + this.ui.setLoading(true); + } + } + + isChannel(name) { + if (name) { + if (name.toString().length == 8) { + return true; + } + } + return false; + } + + channelForID(id) { + return this.channels.filter(c => { + return c.id == id; + })[0]; + } + + channelForName(name) { + return this.channels.filter(c => { + return c.name == name; + })[0]; + } + + stakedForName(name) { + return this.staked.filter(c => { + return c.name == name; + })[0]; + } + + pmForID(id) { + return this.pms.filter(c => { + return c.id == id; + })[0]; + } + + pmWithUser(id) { + return this.pms.filter(c => { + return c.users.includes(id); + })[0]; + } + + otherUser(users) { + return users.filter(u => { + return u !== this.domain; + })[0]; + } + + userForID(id) { + if (this.users) { + return this.users.filter(u => { + return u.id == id; + })[0]; + } + return false; + } + + userForName(name, active=false) { + return this.users.filter(u => { + return (u.domain == name || this.ui.toUnicode(u.domain) == name) && !u.locked && !u.deleted; + })[0]; + } + + usersForConversation(id) { + if (this.channels) { + let conversation = this.channels.filter(c => { + return c.id == id; + })[0]; + + let users = this.users.filter(u => { + return !u.locked; + }); + if (!conversation.public) { + users = this.users.filter(u => { + return !u.locked && u.tld == conversation.name || u.id == "n2sTWh5EZGI8xMQr"; + }); + } + + return users; + } + return []; + } + + changeConversation(id) { + let current = this.conversation; + let change = id; + + if (!this.pmForID(id) && !this.channelForID(id)) { + id = false; + } + + if (!id) { + change = this.channels[0].id; + } + + if (current !== change) { + this.conversation = change; + localStorage.setItem("conversation", this.conversation); + this.changedConversation(); + } + } + + changedConversation() { + this.ui.closeMenusIfNeeded(); + + this.messages = []; + this.ui.clear("input"); + this.ui.clear("messages"); + this.ui.setInThePast(false); + this.ui.messagesLoading(true); + this.ui.emptyUserList(); + this.ui.searchUsers(false); + this.ui.clearSelection(); + this.ui.updateTypingView(); + this.getMessages(); + + if (this.isChannel(this.conversation)) { + this.tab = "channels"; + } + else { + this.tab = "pms"; + } + + this.ui.setConversationTab(); + + this.ui.setActiveConversation(); + this.ui.markUnread(this.conversation, false); + this.ui.markMention(this.conversation, false); + this.ui.updateInputBar(); + + this.ui.showVideoIfNeeded(); + + this.seen[this.conversation] = this.time(); + this.ws.send(`CHANGEDCONVERSATION ${this.conversation}`); + } + + getMessage(id) { + let data = { + action: "getMessage", + domain: this.domain, + id: id + }; + + return this.api(data); + } + + getMessages(options={}) { + if (this.loadingMessages) { + return; + } + + this.loadingMessages = true; + + let data = { + conversation: this.conversation, + }; + let merged = {...data,...options}; + + this.ws.send(`MESSAGES ${JSON.stringify(merged)}`); + } + + async makeSecret(pm) { + let output = new Promise(resolve => { + let otherUser = this.otherUserFromPM(pm.id); + let otherKey = otherUser.pubkey; + + this.e2ee.deriveKey(otherKey, this.keys.privateKeyJwk).then(key => { + otherUser.sharedkey = key; + resolve(key); + }); + }); + + return await output; + } + + async decryptedBody(conversation, message) { + let output = new Promise(resolve => { + let pm = this.pmForID(conversation); + let user = this.userForID(this.otherUser(pm.users)); + + this.e2ee.decryptMessage(message, user.sharedkey, conversation).then(decrypted => { + resolve(decrypted.trim()); + }); + }); + + return await output; + } + + async decryptMessageIfNeeded(conversation, message) { + let body = new Promise(resolve => { + if (this.isChannel(conversation)) { + resolve(message.message); + } + else { + this.decryptedBody(conversation, message.message).then(decrypted => { + resolve(decrypted); + }); + } + }); + + let replyBody = new Promise(resolve => { + if (message.p_message) { + if (this.isChannel(conversation)) { + resolve(message.p_message); + } + else { + this.decryptedBody(conversation, message.p_message).then(decrypted => { + resolve(decrypted); + }); + } + } + else { + resolve(); + } + }); + + let prepared = await Promise.all([body, replyBody]); + return prepared; + } + + async encryptedBody(conversation, message) { + let output = new Promise(resolve => { + let pm = this.pmForID(conversation); + let user = this.userForID(this.otherUser(pm.users)); + + this.e2ee.encryptMessage(message, user.sharedkey, conversation).then(encrypted => { + resolve(encrypted.trim()); + }); + }); + + return await output; + } + + async encryptMessageIfNeeded(conversation, message) { + let output = new Promise(resolve => { + if (this.isChannel(conversation)) { + resolve(message); + } + else { + this.encryptedBody(conversation, message).then(encrypted => { + resolve(encrypted); + }); + } + }); + + return await output; + } + + changeDomain(domain) { + this.domain = domain; + localStorage.setItem("domain", domain); + + if (this.page == "chat") { + this.ready(false); + this.ws.send(`DOMAIN ${domain}`); + } + } + + usersInMessage(message) { + let matches = this.regex(/\@(?[^ \x00]+?)\//gm, message); + return matches; + } + + channelsInMessage(message) { + let matches = this.regex(/\#(?[^ \x00]+?)(?:\s|$)/gm, message); + return matches; + } + + replaceCompletions(text) { + let output = text; + + while (this.usersInMessage(output).length) { + let users = this.usersInMessage(output); + let result = users[0]; + + let name = result.groups.name; + let start = result.index; + let end = (start + name.length + 1 + 1); + + let match = this.users.filter(u => { + return this.ui.toUnicode(u.domain) == name && !u.locked; + }); + + let replace; + if (match.length) { + let id = match[0].id; + replace = `@${id}`; + } + else { + replace = `@\x00${name}/`; + } + output = this.replaceRange(output, start, end, replace); + } + + while (this.channelsInMessage(output).length) { + let channels = this.channelsInMessage(output); + let result = channels[0]; + + let name = result.groups.name; + let start = result.index; + let end = (start + name.length + 1); + + let match = this.channels.filter(c => { + return this.ui.toUnicode(c.name) == name; + }); + + let replace; + if (match.length) { + let id = match[0].id; + replace = `@${id}`; + } + else { + replace = `#\x00${name}`; + } + output = this.replaceRange(output, start, end, replace); + } + + return output; + } + + sendTyping() { + let input = $("textarea#message").val(); + + if (!this.typing || !input || (input && input[0] == "/")) { + return; + } + + let send = true; + if (this.typingSent) { + let diff = this.time() - this.typingSent; + + if (diff < this.typingSendDelay) { + send = false; + } + } + + if (send) { + this.typingSent = this.time(); + + let data = { + from: this.domain, + to: this.conversation + } + + this.ws.send(`TYPING ${JSON.stringify(data)}`); + } + } + + updateTypingStatus() { + if (this.lastTyped) { + if ((this.time() - this.lastTyped) > this.typingDelay) { + this.typing = false; + this.lastTyped = false; + } + else if ($("textarea#message").is(":focus") && $("textarea#message").val() !== "") { + this.typing = true; + } + } + } + + sendMessage(conversation, message) { + if (!message.trim().length) { + return; + } + + this.encryptMessageIfNeeded(conversation, message).then(encrypted => { + let data = { + conversation: conversation, + message: encrypted + } + + if (this.replying) { + data.replying = this.replying.message; + } + + this.typing = false; + this.ws.send(`MESSAGE ${JSON.stringify(data)}`); + + this.replying = null; + this.ui.updateReplying(); + }); + } + + async sendPayment(address, amount) { + const wallet = await bob3.connect(); + + if (!amount) { + return { message: "Please enter an amount." }; + } + + try { + const send = await wallet.send(address, amount); + return send; + } + catch (error) { + return error; + } + } + + async upload(data, attachment) { + let output = new Promise(resolve => { + $.ajax({ + url: "https://hns.chat/upload", + type: "POST", + data: data, + cache: false, + contentType: false, + processData: false, + beforeSend: (e) => {}, + xhr: () => { + let p = $.ajaxSettings.xhr(); + p.upload.onprogress = () => {} + return p; + }, + success: (response) => { + let json = JSON.parse(response); + + resolve(json); + } + }); + }); + + return await output; + } + + deleteAttachment(id) { + let data = { + action: "deleteAttachment", + id: id + }; + + return this.api(data); + } + + mentionsMe(message) { + if (message.includes(`@${this.domain}`)) { + return true; + } + return false; + } + + replyingToMe(message) { + if (message.p_user && message.p_user == this.domain) { + return true; + } + return false; + } +} + +new HNSChat(); \ No newline at end of file diff --git a/assets/js/stream.js b/assets/js/stream.js new file mode 100755 index 0000000..954b07a --- /dev/null +++ b/assets/js/stream.js @@ -0,0 +1,492 @@ +export class stream { + constructor(parent) { + this.parent = parent; + + this.janus; + this.sfu; + + this.janus2; + this.sfu2; + + this.dish = new Dish($("#videoContainer")[0]); + this.dish.append(); + this.dish.resize(); + + this.myid; + this.pvtid; + this.pvtid2; + + window.addEventListener("resize", () => { + this.dish.resize(); + }); + + Janus.init({debug: "none"}); + } + + async init(type=false) { + let done = new Promise(resolve => { + let instance = "main"; + let j = this; + let janus = j.janus; + if (type == "screen") { + janus = j.janus2; + instance = "screen"; + } + + if (janus) { + resolve(); + } + else { + if (type == "screen") { + j.janus2 = new Janus({ + server: j.parent.streamURL, + success: () => { + j.janus2.attach({ + plugin: "janus.plugin.videoroom", + success: (pluginHandle) => { + this.handle(instance, "success", pluginHandle).then(() => { + resolve(); + }); + }, + error: (error) => { + this.handle(instance, "error", error).then(() => { + resolve(); + }); + }, + onmessage: (msg, jsep) => { + if (["joined", "event"].includes(msg["videoroom"])) { + if (msg["videoroom"] == "joined") { + this.pvtid2 = msg["private_id"]; + } + this.handle(instance, "message", msg, jsep); + } + if (jsep) { + this.sfu2.handleRemoteJsep({ jsep: jsep }); + } + }, + onlocalstream: (stream) => { + this.handle(instance, "local", stream); + j.parent.ui.setMute("toggleScreen", 0); + }, + oncleanup: () => { + this.handle(instance, "cleanup", { display: j.parent.domain }); + j.parent.ui.setMute("toggleScreen", 1); + } + }); + } + }); + } + else { + j.janus = new Janus({ + server: j.parent.streamURL, + success: () => { + j.janus.attach({ + plugin: "janus.plugin.videoroom", + success: (pluginHandle) => { + this.handle(instance, "success", pluginHandle).then(() => { + resolve(); + }); + }, + error: (error) => { + this.handle(instance, "error", error).then(() => { + resolve(); + }); + }, + onmessage: (msg, jsep) => { + if (["joined", "event", "talking", "stopped-talking"].includes(msg["videoroom"])) { + if (msg["videoroom"] == "joined") { + this.myid = msg["id"]; + this.pvtid = msg["private_id"]; + } + this.handle(instance, "message", msg, jsep); + } + + if (jsep) { + this.sfu.handleRemoteJsep({ jsep: jsep }); + } + }, + onlocalstream: (stream) => { + this.handle(instance, "local", stream); + }, + oncleanup: () => { + this.handle(instance, "cleanup", { display: j.parent.domain }); + } + }); + } + }); + } + } + }); + return await done; + } + + subscribe(publisher) { + let j = this; + let feed; + j.janus.attach({ + plugin: "janus.plugin.videoroom", + opaqueId: j.parent.domain, + success: (pluginHandle) => { + feed = pluginHandle; + let message = { + request: "join", + room: j.parent.conversation, + ptype: "subscriber", + feed: publisher.id, + private_id: j.pvtid + }; + feed.send({ message: message }); + }, + onmessage: function(msg, jsep) { + if (jsep) { + Janus.debug("Handling SDP as well...", jsep); + feed.createAnswer({ + jsep: jsep, + media: { audioSend: false, videoSend: false }, + success: function(jsep) { + Janus.debug("Got SDP!", jsep); + let message = { request: "start", room: j.parent.conversation }; + feed.send({ message: message, jsep: jsep }); + }, + error: function(error) { + Janus.error("WebRTC error:", error); + } + }); + } + }, + onremotestream: (stream) => { + publisher.stream = stream; + j.handle("video", "remote", publisher); + }, + oncleanup: () => { + j.handle("video", "cleanup", publisher); + } + }); + } + + async handle(instance, type, data=false, jsep=false) { + let done = new Promise(resolve => { + switch (type) { + case "success": + if (instance == "screen") { + this.sfu2 = data; + this.register(this.sfu2); + } + else { + this.sfu = data; + if (Object.keys(this.parent.currentVideoUsers()).includes(this.parent.domain)) { + this.register(this.sfu); + } + else { + this.publishers(this.sfu); + } + } + resolve(); + break; + + case "error": + resolve(); + break; + + case "message": + switch (data.videoroom) { + case "talking": + this.talking(data.id, true); + break; + + case "stopped-talking": + this.talking(data.id, false); + break; + + default: + $.each(data["publishers"], (k, p) => { + if (Object.keys(this.parent.currentVideoUsers()).includes(p.display)) { + this.subscribe(p); + } + }); + break; + } + resolve(); + break; + + case "local": + if (instance == "screen") { + this.attachScreen(this.parent.domain, data); + } + else { + this.addCam(this.parent.domain, this.myid); + this.attachVideo(this.parent.domain, data); + } + resolve(); + break; + + case "remote": + if (data.audio_codec || "talking" in data) { + this.addCam(data.display, data.id); + this.attachVideo(data.display, data.stream); + } + else { + this.attachScreen(data.display, data.stream); + } + resolve(); + break; + + case "cleanup": + if ((data.audio_codec || !data.id) && instance !== "screen") { + this.removeCam(data.display); + } + else { + this.removeScreen(); + } + resolve(); + break; + } + }); + return await done; + } + + getRandomNumber(digit) { + return Math.random().toFixed(digit).split('.')[1]; + } + + register(sfu) { + let message = { + request: "join", + room: this.parent.conversation, + ptype: "publisher", + id: this.getRandomNumber(16), + display: this.parent.domain + }; + sfu.send({ message: message }); + } + + publishers(sfu) { + let message = { + request: "listparticipants", + room: this.parent.conversation + }; + sfu.send({ + "message" : message, + success: (result) => { + $.each(result.participants, (k, p) => { + if (Object.keys(this.parent.currentVideoUsers()).includes(p.display)) { + this.subscribe(p); + } + }); + } + }); + } + + leave(sfu) { + let message = { + request: "leave" + }; + sfu.send({ message: message }); + } + + async publish(type=false) { + let sfu = this.sfu; + let published = "main"; + let media = { video: "video", audioRecv: false, videoRecv: false, audioSend: true, videoSend: true }; + let message = { request: "configure", audio: true, video: true }; + + let done = new Promise(resolve => { + if (type == "screen") { + this.init("screen").then(() => { + sfu = this.sfu2; + published = "screen"; + media = { video: "screen", audioRecv: false, videoRecv: false, audioSend: false, videoSend: true }; + message = { request: "configure", audio: false, video: true }; + resolve(); + }); + } + else { + resolve(); + } + }); + await done; + + sfu.createOffer({ + media: media, + success: (jsep) => { + sfu.send({ message: message, jsep: jsep }); + if (type !== "screen") { + sfu.muteVideo(); + sfu.muteAudio(); + } + } + }); + } + + unpublish(type=false) { + let message = { + request: "unpublish" + }; + if (type) { + switch (type) { + case "video": + if (this.sfu) { + this.sfu.send({ message: message }); + } + break; + + case "screen": + if (this.sfu2) { + this.sfu2.send({ message: message }); + } + break; + } + } + else { + if (this.sfu) { + this.sfu.send({ message: message }); + } + if (this.sfu2) { + this.sfu2.send({ message: message }); + } + + $(".controls > .button").addClass("muted"); + } + } + + toggleScreen() { + let muted = $(".controls .button[data-action=toggleScreen]").hasClass("muted"); + if (muted) { + if (!$(".screen").hasClass("shown")) { + this.publish("screen"); + } + } + else { + this.unpublish("screen"); + } + this.dish.resize(); + } + + addCam(id, jid) { + if (!$(`.cam[data-id=${id}]`).length) { + let html = $(` +
+
+ +
+
+
+
+ `); + let row = $(`#users .users tr[data-id="${id}"]`).clone(); + row.append($(` + +
+ + `)); + html.find("table").append(row); + + let row2 = $(`#users .users tr[data-id="${id}"]`).clone(); + html.find(".background").append(row2); + + if (id == this.parent.domain) { + html.find("video")[0].muted = true; + html.addClass("me"); + } + + $(".videoHolder .cams").append(html); + } + if (id && jid) { + this.parent.ui.setData($(`.cam[data-id=${id}]`), "jid", jid); + } + this.dish.resize(); + } + + attachVideo(id, video) { + Janus.attachMediaStream($(`.cam[data-id=${id}] video`).get(0), video); + this.dish.resize(); + this.dish.resize(); + } + + attachScreen(id, video) { + let html = $(`.videoHolder .screen`); + let table = html.find("table"); + + let row = $(`#users .users tr[data-id="${id}"]`).clone(); + table.empty(); + table.append(row); + + let screen = html.find("video").get(0); + screen.muted = true; + Janus.attachMediaStream(screen, video); + $(".screen").addClass("shown"); + this.dish.resize(); + this.dish.resize(); + } + + removeCam(id) { + $(`.cam[data-id=${id}]`).remove(); + this.dish.resize(); + } + + removeScreen() { + $(".screen").removeClass("shown"); + this.dish.resize(); + } + + mute(type, bool) { + switch (type) { + case "audio": + if (bool) { + this.sfu.muteAudio(); + } + else { + this.sfu.unmuteAudio(); + } + break; + + case "video": + if (bool) { + this.sfu.muteVideo(); + } + else { + this.sfu.unmuteVideo(); + } + break; + } + } + + talking(id, bool) { + if (bool) { + $(`.cam[data-jid=${id}]`).addClass("talking"); + } + else { + $(`.cam[data-jid=${id}]`).removeClass("talking"); + } + } + + close() { + $(".cam").remove(); + + if (this.janus2) { + this.leave(this.sfu2); + this.sfu2 = null; + this.janus2 = null; + } + + if (this.janus) { + this.leave(this.sfu); + this.sfu = null; + this.janus = null; + } + } +} + + + + + + + + + + + + + + diff --git a/assets/js/ui.js b/assets/js/ui.js new file mode 100755 index 0000000..113dcc2 --- /dev/null +++ b/assets/js/ui.js @@ -0,0 +1,3156 @@ +let { punycode } = await import(`./punycode.js?r=${revision}`); + +export class ui { + constructor(parent) { + this.parent = parent; + + this.inThePast = false; + + this.browser = this.getBrowser(); + this.root = document.querySelector(':root'); + this.css = getComputedStyle($("html")[0]); + this.version = $("body").data("version"); + this.updateAvailable = false; + + this.emojiCategories = { + "Search": [], + "People": ["Smileys & Emotion", "People & Body"], + "Nature": ["Animals & Nature"], + "Food": ["Food & Drink"], + "Activities": ["Activities"], + "Travel": ["Travel & Places"], + "Objects": ["Objects"], + "Symbols": ["Symbols"], + "Flags": ["Flags"] + } + + if (!/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) { + $("body").addClass("desktop"); + } + + this.preloadIcons(); + } + + async gotoMessage(message) { + let messageExists = $(`.messageRow[data-id=${message}]`).length; + if (messageExists) { + this.scrollToMessage(message); + } + else { + let msg = await this.parent.getMessage(message); + if (msg.message) { + this.setInThePast(true); + this.clear("messages"); + this.messagesLoading(true); + + let options = { + at: message + } + this.parent.getMessages(options); + } + else { + return; + } + } + + setTimeout(() => { + this.highlightMessage(message); + }, 250); + } + + setInThePast(bool) { + if (bool) { + this.inThePast = true; + $("#jumpToPresent").removeClass("hidden"); + } + else { + this.inThePast = false; + $("#jumpToPresent").addClass("hidden"); + } + } + + backInPresent(body) { + let lastMessage = $("#messages > .messageRow[data-id]").last(); + let lastMessageID = lastMessage.data("id"); + + if (body.after && lastMessageID == body.latestMessage) { + this.setInThePast(false); + } + } + + fetchNewMessages() { + let lastMessage = $("#messages > .messageRow[data-id]").last(); + let lastMessageID = lastMessage.data("id"); + let lastMessageTime = lastMessage.data("time"); + + if (lastMessageID) { + let options = { + after: lastMessageID + } + this.parent.getMessages(options); + } + } + + getVariables() { + const variables = Array.from(document.styleSheets) + .filter(styleSheet => { + try { return styleSheet.cssRules; } + catch(e) { console.warn(e); } + }) + .map(styleSheet => Array.from(styleSheet.cssRules)) + .flat() + .filter(cssRule => cssRule.selectorText === ':root') + .map(cssRule => cssRule.cssText.split('{')[1].split('}')[0].trim().split(';')) + .flat() + .filter(text => text !== "") + .map(text => text.split(':')) + .map(parts => ({key: parts[0].trim(), value: parts[1].trim() })) + ; + return variables; + } + + preloadIcons() { + let variables = this.getVariables(); + + $.each(variables, (k, data) => { + let {key,value} = data; + + if (key.substring(key.length - 4) == "Icon") { + let match = value.match(/url\((?.+)\)/); + let asset = match.groups.asset.replaceAll("\\", ""); + let link = `https://${this.parent.host}${asset}`; + new Image().src = link; + } + }); + } + + setData(e, attr, val) { + $(e).data(attr, val); + $(e).attr(`data-${attr}`, val); + } + + setupSync() { + let link = this.parent.syncLink(); + let popover = $(".popover[data-name=syncSession]"); + let qr = popover.find("#qrcode"); + let input = popover.find("input[name=syncLink]"); + qr.empty(); + qr.html(''); + input.val(link); + if (!qr.find("canvas").length) { + let qrcode = new QRCode(qr[0], { + text: link, + width: 250, + height: 250, + colorLight: this.css.getPropertyValue("--tertiaryBackground"), + colorDark: this.css.getPropertyValue("--primaryForeground"), + correctLevel: QRCode.CorrectLevel.L + }); + } + qr.find("img").attr("draggable", "false"); + } + + copyToClipboard(button) { + let field = button.parent().find("input")[0]; + field.select(); + field.setSelectionRange(0, 99999); + navigator.clipboard.writeText(field.value); + field.setSelectionRange(0, 0); + + button.addClass("copied"); + setTimeout(() => { + button.removeClass("copied"); + }, 1000); + } + + sizeInput() { + let input = $("textarea#message"); + input.css("height", "1px"); + + let height = input[0].scrollHeight; + + if (height > 200) { + height = 200; + } + + input.css("height", height+"px"); + } + + wordForPosition(text, position) { + let index = text.indexOf(position); + let preText = text.substr(0, position); + + if (preText.indexOf(" ") > 0) { + let words = preText.split(" "); + return (words.length - 1) + } + else { + return 0; + } + } + + updateCompletions() { + let options = []; + + let closeIfNeeded = false; + + let input = $("textarea#message"); + let text = input.val(); + let words = text.split(" "); + let position = input[0].selectionStart; + + let word = words[this.wordForPosition(text, position)]; + if (word.length > 1) { + $("#completions .body .list").empty(); + + switch (word[0]) { + case "@": + $("#completions .title").html("Users"); + + let users = this.parent.usersForConversation(this.parent.conversation); + options = users.filter(user => { + let match = Array.from(this.toUnicode(user.domain)).slice(0, Array.from(word).length - 1).join("").toLowerCase(); + let search = word.toLowerCase(); + + return !user.locked && "@"+match === search; + }).slice(0, 10); + + $.each(options, (k, option) => { + let row = $(`#users .users tr[data-id="${option.id}"]`).clone(); + $("#completions .body .list").append(row); + }); + + closeIfNeeded = true; + break; + + case "#": + $("#completions .title").html("Channels"); + + let channels = this.parent.channels; + options = channels.filter(channel => { + let match = Array.from(this.toUnicode(channel.name)).slice(0, Array.from(word).length - 1).join("").toLowerCase(); + let search = word.toLowerCase(); + + return "#"+match === search; + }).slice(0, 10); + + $.each(options, (k, option) => { + let row = $(`#conversations .channels tr[data-id="${option.id}"]`).clone(); + $("#completions .body .list").append(row); + }); + + closeIfNeeded = true; + break; + } + } + else { + closeIfNeeded = true; + } + + if (options.length) { + $("#completions .list tr").first().addClass("active"); + this.popover("completions"); + } + else { + closeIfNeeded = true; + } + + if (closeIfNeeded) { + this.close(); + } + } + + updateSelectedCompletion(key) { + if (!$("#completions.shown").length) { + return; + } + + let selected = $("#completions tr.active"); + selected.removeClass("active"); + + let select; + let current = selected[0]; + + switch (key) { + case 38: + if (current.previousSibling) { + select = current.previousSibling; + } + else { + select = $("#completions .list").children().last(); + } + break; + + case 40: + if (current.nextSibling) { + select = current.nextSibling; + } + else { + select = $("#completions .list").children().first(); + } + break; + } + + $(select).addClass("active"); + } + + domains(array) { + let domains = this.parent.sorted(array, "domain"); + + switch (this.parent.page) { + case "chat": + $(".header .domains select").empty(); + + $.each(domains, (k, i) => { + let verify = ""; + if (i.locked) { + verify = " (Unverified)"; + } + $(".header .domains select").append(``); + }); + + $(".header .domains select").append(``); + $(".header .domains select").append(``); + + $(".header .domains select").val(this.parent.domain); + break; + + case "id": + case "invite": + if (!this.parent.varoLoaded() || this.parent.mobile) { + $(".varo").addClass("hidden"); + } + $(".section#manageDomains .domains").empty(); + $.each(domains, (k, i) => { + let html = $(` +
+
${this.toUnicode(i.domain)}
+
+
+
+
+ `); + + if (i.locked) { + html.find(".actions").prepend(``); + } + + $(".section#manageDomains .domains").append(html); + }); + + if (domains.length) { + $(".section#manageDomains #startChatting").removeClass("hidden"); + } + + if (this.parent.page !== "invite") { + this.showSection("manageDomains"); + } + break; + } + } + + removeDomain(id) { + $(`.section#manageDomains .domains .domain[data-id=${id}]`).remove(); + } + + stakedDomains(domains) { + $(".section#addDomain select[name=tld]").empty(); + + if (this.parent.page == "invite") { + $(".section[id=addDomain]").find(".button[data-action=addDomain]").addClass("hidden"); + $(".section[id=addDomain]").find(".or").addClass("hidden"); + + let info = this.parent.stakedForName(this.parent.data); + if (info) { + $(".section#addDomain select[name=tld]").append(``); + } + else { + $(".section#addDomain").empty(); + $(".section#addDomain").append(`
This invite code isn't valid.
`); + } + this.showSection("addDomain"); + } + else { + $.each(domains, (k, i) => { + $(".section#addDomain select[name=tld]").append(``); + }); + } + } + + showSection(section) { + $(".section").find("input").val(''); + $(".section").removeClass("shown"); + $(`.section#${section}`).addClass("shown"); + } + + updateDomainSelect() { + $(".header .domains select").val(this.parent.domain); + } + + avatarFallback(string) { + let fallback; + + if (!this.parent.regex(/[a-zA-Z0-9]/g, string[0]).length) { + $.each(sortedEmojis, (k, e) => { + if (string.substring(0, e.emoji.length) == e.emoji) { + fallback = e.emoji; + return false; + } + }); + } + + if (!fallback) { + fallback = String.fromCodePoint(string.codePointAt(0)).toUpperCase(); + } + return fallback; + } + + toUnicode(name) { + let puny = punycode.ToUnicode(name); + let zwj = nameToUnicode(puny); + return zwj; + } + + conversation(tab, data) { + let name = data.name; + let fallback = "#"; + + let user,domain; + if (tab == "pms") { + user = this.parent.otherUser(data.users); + domain = this.parent.userForID(user); + name = domain.domain; + } + + name = this.toUnicode(name); + + if (tab == "pms") { + fallback = this.avatarFallback(name); + } + + let html = $(` + + +
+
+
+
${fallback.toUpperCase()}
+ + ${name} + + `); + + if (tab == "pms") { + let active = ""; + if (domain.active) { + active = " active"; + } + + let avatar = $(` +
+
+ `); + html.find(".avatar").prepend(avatar); + } + + $(`#conversations .${tab} table`).append(html); + + this.updateAvatars(); + } + + updateConversations() { + let domain = this.parent.userForID(this.parent.domain); + + $.each($("#conversations .sections tr"), (k, c) => { + let id = $(c).data("id"); + + let data; + if (this.parent.isChannel(id)) { + data = this.parent.channelForID(id); + + if (!data.public && data.name !== domain.tld) { + $(c).addClass("locked"); + } + } + else { + data = this.parent.pmForID(id); + + if (data.activity) { + $(c).removeClass("hidden"); + } + else { + $(c).addClass("hidden"); + } + + let otherUser = this.parent.otherUser(data.users); + let otherUserData = this.parent.userForID(otherUser); + + if (otherUserData.active) { + $(c).find(".avatar .status").addClass("active"); + } + else { + $(c).find(".avatar .status").removeClass("active"); + } + + if (otherUserData.locked || otherUserData.deleted) { + $(c).addClass("locked"); + } + else if ($(c).hasClass("locked")) { + $(c).removeClass("locked"); + + if (this.parent.conversation == id) { + this.parent.changeConversation(id); + } + } + } + + if (data.activity >= this.parent.firstLaunch) { + if (data.id !== this.parent.conversation) { + this.markUnread(data.id, true); + } + } + + if (this.parent.seen[data.id]) { + if (this.parent.seen[data.id] >= data.activity) { + this.markUnread(data.id, false); + } + } + }); + } + + conversationStatus() { + let domain = this.parent.userForID(this.parent.domain); + + if (domain.locked) { + return "verify"; + } + else if ($(`#conversations tr[data-id=${this.parent.conversation}]`).hasClass("locked")) { + if (this.parent.isChannel(this.parent.conversation)) { + return "permissions"; + } + else { + let data = this.parent.pmForID(this.parent.conversation); + let otherUser = this.parent.otherUser(data.users); + let otherUserData = this.parent.userForID(otherUser); + + if (otherUserData.locked || otherUserData.deleted) { + return "user"; + } + } + } + + return true; + } + + updateInputBar() { + $("body").removeClass("unverified"); + + let status = this.conversationStatus(); + + switch (status) { + case "user": + case "verify": + case "permissions": + $(".inputHolder").addClass("locked"); + break; + + default: + $(".inputHolder").removeClass("locked"); + break; + } + + switch (status) { + case "user": + $(".inputHolder .locked").html("This user isn't available."); + break; + + case "verify": + $("body").addClass("unverified"); + $(".inputHolder .locked").html("Re-verify your name to chat."); + break; + + case "permissions": + $(".inputHolder .locked").html("You don't have permissions to chat here."); + break; + } + } + + setConversationTab() { + $("#conversations .tabs .tab").removeClass("active"); + $(`#conversations .tabs .tab[data-tab=${this.parent.tab}]`).addClass("active"); + + $(`#conversations .sections .section`).removeClass("shown"); + $(`#conversations .sections .section.${this.parent.tab}`).addClass("shown"); + } + + setActiveConversation() { + this.setData($("#holder"), "type", this.parent.tab); + + $("#conversations tr").removeClass("active"); + $(`#conversations tr[data-id=${this.parent.conversation}]`).addClass("active"); + + $(".messageHeader table").empty(); + $(".messageHeader table").append($(`#conversations tr.active`).clone()); + $(".messageHeader table tr").removeClass("hidden"); + + this.setPinnedMessage(); + this.updateAvatars(); + } + + async setPinnedMessage() { + $(".pinnedMessage .delete").addClass("hidden"); + $(".pinnedMessage").removeClass("shown"); + + let output = new Promise(resolve => { + if (!this.parent.isChannel(this.parent.conversation)) { + resolve(); + } + + let channelData = this.parent.channelForID(this.parent.conversation); + if (channelData.pinned) { + this.parent.getMessage(channelData.pinned).then(r => { + if (r.message) { + let message; + + let decoded = he.decode(he.decode(r.message)); + try { + let msg = JSON.parse(decoded); + message = msg.message; + } + catch { + message = decoded; + } + resolve(message); + } + else { + resolve(); + } + }); + } + else { + resolve(); + } + }); + + let message = await output; + if (message && message.length) { + $(".pinnedMessage .message").html(message); + + if (this.parent.isChannel(this.parent.conversation)) { + let me = this.parent.userForID(this.parent.domain); + let channel = this.parent.channelForID(this.parent.conversation); + + if (this.isAdmin(channel, me)) { + $(".pinnedMessage .delete").removeClass("hidden"); + } + } + + this.linkify($(".pinnedMessage .message")); + $(".pinnedMessage").addClass("shown"); + } + } + + isAdmin(channel, user) { + if ((channel.tldadmin && channel.name == user.domain) || user.admin || channel.admins.includes(user.id)) { + return true; + } + return false; + } + + markUnread(conversation, bool) { + if (bool) { + if (!$(`#conversations tr[data-id=${conversation}]`).hasClass("locked") && conversation !== this.parent.conversation) { + $(`#conversations tr[data-id=${conversation}]`).addClass("unread"); + } + } + else { + $(`#conversations tr[data-id=${conversation}]`).removeClass("unread"); + } + + this.updateNotifications(); + } + + markMention(conversation, bool) { + if (bool) { + if (!$(`#conversations tr[data-id=${conversation}]`).hasClass("locked") && conversation !== this.parent.conversation) { + $(`#conversations tr[data-id=${conversation}]`).addClass("mentions"); + } + } + else { + $(`#conversations tr[data-id=${conversation}]`).removeClass("mentions"); + } + + this.updateNotifications(); + } + + updateNotifications() { + if ($("#conversations .pms tr.unread").length) { + $("#conversations .tab[data-tab=pms]").addClass("notification"); + } + else { + $("#conversations .tab[data-tab=pms]").removeClass("notification"); + } + + if ($("#conversations .channels tr.mentions").length) { + $("#conversations .tab[data-tab=channels]").addClass("notification"); + } + else { + $("#conversations .tab[data-tab=channels]").removeClass("notification"); + } + + if ($("#conversations .tab.notification").length) { + $(".header .left").addClass("notification"); + } + else { + $(".header .left").removeClass("notification"); + } + } + + setLoading(bool) { + if (bool) { + $(".connecting").removeClass("hidden"); + } + else { + $(".connecting").addClass("hidden"); + } + } + + clear(type) { + switch (type) { + case "channels": + case "pms": + $(`#conversations .${type} table`).empty(); + break; + + case "messages": + $("#messages").empty(); + $(".needSLD").remove(); + break; + + case "input": + $("textarea#message").val(''); + break; + } + } + + setGatedView(data) { + let channel = this.parent.channelForID(this.parent.conversation); + let message = `#${this.toUnicode(channel.name)} is a private community for owners of a .${this.toUnicode(channel.name)} only.`; + + let names = this.parent.domains.filter(d => { + return d.tld == channel.name; + }); + + let html = $(` +
+ ${message} +
+ `); + switch (data.resolution) { + case "purchase": + html.append($(` +
Purchase a .${this.toUnicode(channel.name)}
+ `)); + break; + + case "create": + html.append($(` +
Create a free .${this.toUnicode(channel.name)}
+ `)); + break; + + default: + break; + } + + names.forEach(name => { + html.append($(` +
Switch to ${this.toUnicode(name.domain)}
+ `)); + }); + + $("#messageHolder").append(html); + } + + emptyUserList() { + $("#users #count").html(''); + $("#users .users table").empty(); + } + + setUserList() { + if (!this.parent.isChannel(this.parent.conversation)) { + return; + } + + if ($("#users .group.searching.shown").length) { + return; + } + + $("#users .users table").empty(); + + let users = this.parent.usersForConversation(this.parent.conversation); + let sorted = this.parent.sorted(users, "domain"); + + let active = sorted.filter(u => { + return u.active; + }); + + let inactive = sorted.filter(u => { + return !u.active; + }); + + $.each(active, (k, user) => { + this.addUserToUserlist(user); + }); + + $.each(inactive, (k, user) => { + this.addUserToUserlist(user); + }); + + this.updateAvatars(); + + $("#users #count").html(users.length.toLocaleString("en-US")); + } + + updateUserList() { + if (!this.parent.isChannel(this.parent.conversation)) { + return; + } + + let users = this.parent.usersForConversation(this.parent.conversation); + let sorted = this.parent.sorted(users, "domain"); + + let active = sorted.filter(u => { + return u.active; + }); + + let inactive = sorted.filter(u => { + return !u.active; + }); + + $.each(users, (k, user) => { + let userEl = $(`#users .user[data-id=${user.id}]`); + let isActive = !userEl.hasClass("inactive"); + if (user.active) { + if (!isActive) { + let position = active.indexOf(user) - 1; + let before = $($("#users .user").get(position)); + userEl.remove(); + userEl.removeClass("inactive"); + userEl.find(".avatar .status").addClass("active"); + if (position < 0) { + $("#users table").prepend(userEl); + } + else { + userEl.insertAfter(before); + } + } + } + else { + if (isActive) { + let position = inactive.indexOf(user) + active.length; + let before = $($("#users .user").get(position)); + userEl.remove(); + userEl.addClass("inactive"); + userEl.find(".avatar .status").removeClass("active"); + if (position < 0) { + $("#users table").prepend(userEl); + } + else { + userEl.insertAfter(before); + } + } + } + }); + } + + addUserToUserlist(user) { + let name = this.toUnicode(user.domain); + + let html = $(` + + ${this.avatar("td", user.id, user.domain, true)} + ${name} + + `); + + if (!user.active) { + html.addClass("inactive"); + } + + $("#users .users table").append(html); + } + + replaceSpecialMessage(message) { + if (message.substring(0, 12) == "ACTION ") { + return message.substring(12); + } + return message; + } + + messageSummary(message) { + let decoded = message; + try { + decoded = JSON.parse(message); + } + catch {} + + if (decoded.payment) { + return "sent a payment"; + } + else if (decoded.attachment) { + return "sent an attachment"; + } + else if (decoded.action) { + return decoded.action; + } + else if (decoded.message) { + return decoded.message; + } + return decoded; + } + + async insertMessages(data, decrypt=false) { + let messages = data.messages; + + for (let i in messages) { + let message = messages[i]; + + if ($(`.messageRow[data-id=${message.id}]`).length) { + return; + } + + if (decrypt) { + await this.parent.decryptMessageIfNeeded(this.parent.conversation, message).then(decrypted => { + message.message = decrypted[0]; + if (message.p_message) { + message.p_message = decrypted[1]; + } + }); + } + + if (message.p_message) { + message.p_message = this.messageSummary(message.p_message); + } + + let user = this.parent.userForID(message.user).domain; + let messageBody = he.decode(he.decode(message.message)); + messageBody = he.encode(messageBody); + + let isAction = false; + if (messageBody.substring(0, 12) == "ACTION ") { + messageBody = messageBody.substring(12); + isAction = true; + } + + let isNotice = false; + let hasEffect = false; + let hasStyle = false; + + let html = $(` +
+
+
+ ${this.avatar("div", message.user, user)} +
${this.toUnicode(user)}
+
+
+
+
+
+
+
+
+
+
+
+
+ `); + + let decoded = he.decode(messageBody); + try { + let json = JSON.parse(he.decode(decoded)); + + if (json.hnschat) { + if (json.attachment) { + let link; + try { + let url = new URL(json.attachment); + switch (url.host) { + case "media.tenor.com": + case "api.zora.co": + link = json.attachment; + break; + } + } + catch { + link = `https://${window.location.host}/uploads/${json.attachment}`; + } + + let image = $(` + + + + `); + html.find(".message").addClass("image"); + html.find(".message .body").empty(); + html.find(".message .body").append(image); + } + else if (json.payment) { + let link = `https://niami.io/tx/${json.payment}`; + let image = $(` + +
+ +
${this.parent.rtrim(json.amount.toLocaleString("en-US", { minimumFractionDigits: 6 }), "0")}
+
+
+
+ `); + html.find(".message").addClass("image payment"); + html.find(".message .body").empty(); + html.find(".message .body").append(image); + } + else if (json.action) { + messageBody = he.encode(json.action); + html.find(".message .body").html(messageBody); + isAction = true; + } + else if (json.message) { + messageBody = json.message.toString(); + messageBody = he.encode(messageBody); + html.find(".message .body").html(messageBody); + } + + if (json.effect) { + hasEffect = json.effect; + } + if (json.style) { + hasStyle = json.style; + } + } + } + catch (e) { + html.find(".message .body").html(messageBody); + } + + if (isAction) { + html.addClass("action"); + } + + let firstThree = Array.from(messageBody.toString()).slice(0, 3); + let isEmojis = true; + $.each(firstThree, (k, char) => { + if (!this.isCharEmoji(char)) { + isEmojis = false; + return false; + } + }); + if (isEmojis) { + html.addClass("emojis"); + } + + let isDice = true; + let chars = Array.from(messageBody.toString()); + $.each(chars, (k, char) => { + if (!["โš€","โš","โš‚","โšƒ","โš„","โš…"].includes(char)) { + isDice = false; + return false; + } + }); + if (isDice) { + html.addClass("emojis dice"); + } + + if (hasStyle) { + this.setData(html, "style", hasStyle); + } + + let messageTime = new Date(message.time * 1000).format(this.parent.timeFormat); + let actions = $(` +
+
${messageTime}
+
+
+
+
+
+ `) + + if (message.user == this.parent.domain) { + html.addClass("self"); + + html.find(".holder.msg").prepend(actions); + } + else { + html.find(".holder.msg").append(actions); + } + + if (this.parent.mentionsMe(message.message)) { + html.addClass("mention"); + } + + if (message.notice) { + html.addClass("notice"); + } + + if (message.replying) { + let reply = $(` +
+
+
+
+
+
+
+ `); + + if (message.p_user && message.p_message) { + let messageReplyBody = ""; + if (message.p_message.length) { + messageReplyBody = he.encode(message.p_message); + messageReplyBody = this.replaceSpecialMessage(messageReplyBody); + } + + let p_user = this.parent.userForID(message.p_user).domain; + + this.setData(reply.find(".user"), "id", message.p_user); + reply.find(".user").html(this.toUnicode(p_user)); + reply.find(".body").html(messageReplyBody); + + if (message.p_user == this.parent.domain) { + html.addClass("mention"); + } + } + else { + reply.find(".user").remove(); + reply.find(".body").html("Original message was deleted."); + } + + html.addClass("replying"); + html.prepend(reply); + } + + if (hasEffect) { + let effect = $(``); + html.find("> .contents").append(effect); + } + + if (!message.reactions) { + message.reactions = JSON.stringify({}); + } + + if (data.before || data.at) { + this.parent.messages.unshift(message); + $("#messages").prepend(html); + } + else { + this.parent.messages.push(message); + $("#messages").append(html); + this.fixScroll(); + } + + if (!decrypt && hasEffect) { + this.handleEffect(hasEffect); + } + + this.updateReactions(message.id); + this.stylizeMessage(html); + this.updateAvatars(); + } + + this.parent.loadingMessages = false; + + this.markEmptyIfNeeded(); + } + + async handleEffect(effect) { + let done = new Promise(resolve => { + switch (effect) { + case "confetti": + startConfetti(); + setTimeout(() => { + stopConfetti(); + resolve(); + }, 3000); + break; + } + }); + return await done; + } + + markEmptyIfNeeded() { + if (!$(".messageRow").length && !$(".needSLD").length) { + $("#messages").addClass("empty"); + } + else { + $("#messages").removeClass("empty"); + } + } + + deleteMessage(id) { + let message = $(`.messageRow[data-id=${id}]`); + + if (message.length) { + let previous = message.prev(); + let next = message.next(); + + message.remove(); + if (previous.length) { + this.stylizeMessage(previous); + } + if (next.length) { + this.stylizeMessage(next); + } + + if (this.parent.isChannel(this.parent.conversation)) { + let channel = this.parent.channelForID(this.parent.conversation); + if (id == channel.pinned) { + channel.pinned = null; + this.setPinnedMessage(); + } + } + } + } + + updateReactions(id) { + let message = $(`.messageRow[data-id=${id}]`); + message.find(".reactions").empty(); + + let reactions = this.parent.messages.filter(m => { + return m.id == id; + })[0].reactions; + + if (reactions) { + let json = JSON.parse(reactions); + if (Object.keys(json).length) { + $.each(json, (r, u) => { + let users = this.userString(u); + let reaction = $(` +
+
${r}
+
${u.length}
+
+ `); + + if (u.includes(this.parent.domain)) { + reaction.addClass("self"); + } + + message.find(".reactions").append(reaction); + }); + } + } + } + + moveConversationToTop(conversation) { + let div = $(`#conversations tr[data-id=${conversation}]`); + let parent = div.parent(); + div.remove(); + parent.prepend(div); + } + + userString(array) { + let output; + + let users = [...array]; + $.each(users, (k, u) => { + let name = this.parent.userForID(u).domain; + users[k] = name; + }); + + if (users.length == 1) { + output = users[0]; + } + else { + let last = users.pop(); + let others = users.join(", "); + output = `${others} and ${last}`; + } + + return output; + } + + isCharEmoji(char) { + if (char == "\u200d") { + return true; + } + + let match = emojis.filter(emoji => { + return emoji.emoji == char || emoji.emoji.replace("\ufe0f", "") == char; + }); + + if (match.length) { + return true; + } + + return false; + } + + stylizeMessage(message) { + let messageHolder = $("#messages"); + + let firstMessage = $("#messages > .messageRow[data-id]").first(); + let firstMessageID = firstMessage.data("id"); + + let lastMessage = $("#messages > .messageRow[data-id]").last(); + let lastMessageID = lastMessage.data("id"); + + let messageID = message.data("id"); + let messageTime = message.data("time"); + let messageDate = new Date(messageTime * 1000).format(this.parent.dateFormat); + let contents = message.find(".contents"); + let messageSender = message.data("sender"); + let messageUser; + + let previousMessage = message.prev(); + let previousMessageTime = previousMessage.data("time"); + let previousMessageDate = new Date(previousMessageTime * 1000).format(this.parent.dateFormat); + let previousMessageSender = previousMessage.data("sender"); + + let nextMessage = message.next(); + let nextMessageTime = nextMessage.data("time"); + let nextMessageDate = new Date(nextMessageTime * 1000).format(this.parent.dateFormat); + let nextMessageSender = nextMessage.data("sender"); + let nextMessageUser; + + let isFirst = false; + let isLast = false; + + let isReply = false; + + let isInformational = false; + let isAction = false; + let isDate = false; + + let before = false; + + let addUser = false; + let addNextUser = false; + let removeUser = false; + let removeNextUser = false; + + let prependDate = false; + let appendDate = false; + + if (firstMessageID == messageID) { + isFirst = true; + } + + if (lastMessageID == messageID) { + isLast = true; + } + + if (message.hasClass("replying")) { + isReply = true; + } + + if (message.hasClass("informational")) { + isInformational = true; + } + + if (message.hasClass("date")) { + isDate = true; + } + + if (message.hasClass("action")) { + isAction = true; + } + + if (nextMessage.length) { + before = true; + } + + if (isFirst || isReply) { + addUser = true; + } + + if (!before) { + if (!isDate && previousMessage.length && messageDate !== previousMessageDate && !previousMessage.hasClass("date")) { + prependDate = true; + } + } + else { + if (!isDate && nextMessage.length && messageDate !== nextMessageDate && !nextMessage.hasClass("date")) { + appendDate = true; + } + } + + if (isDate) { + previousMessage.addClass("last"); + message.addClass("first last"); + + if (nextMessage.length) { + addNextUser = true; + } + } + else { + let timeDifference; + + messageUser = this.parent.userForID(messageSender).domain; + + if (before) { + message.addClass("first"); + } + else { + message.addClass("last"); + } + + if (isFirst || isReply) { + message.addClass("first"); + } + + if (isLast) { + message.addClass("last"); + } + + if (previousMessage.length) { + timeDifference = messageTime - previousMessageTime; + + if (timeDifference >= 60 || previousMessageSender !== messageSender) { + previousMessage.addClass("last"); + message.addClass("first"); + addUser = true; + } + else if (!isReply) { + removeUser = true; + } + } + + if (timeDifference < 60 && previousMessageSender == messageSender && !message.hasClass("replying")) { + previousMessage.removeClass("last"); + } + + if (previousMessageSender !== messageSender) { + previousMessage.addClass("last"); + } + + if (nextMessage.length) { + timeDifference = nextMessageTime - messageTime; + + if (timeDifference > 60) { + nextMessage.addClass("first"); + addNextUser = true; + } + + if (nextMessage.hasClass("first")) { + message.addClass("last"); + } + } + + if (timeDifference < 60 && nextMessageSender == messageSender && !nextMessage.hasClass("replying")) { + removeNextUser = true; + } + + if (addUser) { + if (!contents.find(".user").length) { + //let user = $('
'); + //user.html(messageUser); + //contents.prepend(user); + //contents.prepend(messageAvatar(messageSender, messageUser)); + } + } + if (removeUser) { + message.removeClass("first"); + //message.find(".contents .user").remove(); + //message.find(".contents .avatar").remove(); + } + if (removeNextUser) { + message.removeClass("last"); + nextMessage.removeClass("first"); + //nextMessage.find(".contents .user").remove(); + //nextMessage.find(".contents .avatar").remove(); + } + if (prependDate) { + let infoRow = $('
'); + infoRow.html(messageDate); + infoRow.insertBefore(message); + this.stylizeMessage(infoRow); + } + if (appendDate) { + let infoRow = $('
'); + infoRow.html(nextMessageDate); + infoRow.insertAfter(message); + this.stylizeMessage(infoRow); + } + } + + if (addNextUser) { + if (!nextMessage.find(".contents .user").length) { + //nextMessageUser = this.parent.userForID(nextMessageSender).domain; + //let user = $('
'); + //user.html(nextMessageUser); + //nextMessage.addClass("first"); + //nextMessage.find(".contents").prepend(user); + //nextMessage.find(".contents").prepend(messageAvatar(nextMessageSender, nextMessageUser)); + } + } + + let newLastMessage = $(".messageRow").last(); + if (newLastMessage.hasClass("informational date")) { + newLastMessage.remove(); + } + + //this.codify(message.find(".contents .body")); + this.linkify(message.find(".contents .body")); + + this.updateAvatars(); + } + + codify(elements) { + $.each(elements, (k, e) => { + e = $(e); + + let output = e.html(); + + while (this.parent.regex(/\`{3}(?[.\s\S]+?)\`{3}/gm, output).length) { + let matches = this.parent.regex(/\`{3}(?[.\s\S]+?)\`{3}/gm, output); + + if (matches.length) { + let result = matches[0]; + let full = result[0]; + let code = result.groups.code; + let start = result.index; + let end = (start + full.length); + let replace = `
${code}
`; + output = this.parent.replaceRange(output, start, end, replace); + } + } + + while (this.parent.regex(/\`(?[.\s\S]+?)\`/gm, output).length) { + let matches = this.parent.regex(/\`(?[.\s\S]+?)\`/gm, output); + + if (matches.length) { + let result = matches[0]; + let full = result[0]; + let code = result.groups.code; + let start = result.index; + let end = (start + full.length); + let replace = `${code}`; + output = this.parent.replaceRange(output, start, end, replace); + } + } + + e.html(output); + }); + } + + linkify(elements) { + $.each(elements, (k, e) => { + e = $(e); + + let output = e.html(); + let links = anchorme.list(output).reverse(); + + $.each(links, (k, link) => { + let href = link.string; + + if (link.isEmail) { + href = `mailto:${href}`; + } + else if (link.isURL && href.substring(0, 8) !== "https://" && href.substring(0, 7) !== "http://") { + href = `http://${href}`; + } + + let replace = `${link.string}` + output = this.parent.replaceRange(output, link.start, link.end, replace); + }); + + let mentions = this.usersInMessage(output); + $.each(mentions, (k, mention) => { + let id = mention.groups.name; + if (id == this.parent.domain) { + e.closest(".messageRow").addClass("mention"); + } + }); + + output = this.replaceIds(output); + e.html(output); + + this.expandLinks(e); + }); + } + + expandLinks(message) { + if (message.hasClass("expanded")) { + return; + } + + message.addClass("expanded"); + + let links = message.find("a.inline"); + + if (links.length) { + if (!message.parent().hasClass("message")) { + return; + } + + let link = links[0].href; + let embed = this.shouldInlineLink(link); + if (embed) { + let div; + switch (embed) { + case "image": + div = $(` + +
+
+ +
+
+
+ `); + break; + + case "video": + div = $(` +
+
+ +
+
+ `); + break; + } + + if (div) { + message.closest(".messageRow").find(".linkHolder").append(div); + this.fixScroll(); + } + } + else { + let data = { + action: "getMetaTags", + url: link + } + if (link.substring(0, 7) == "mailto:") { + return; + } + this.parent.api(data).then(r => { + let div = $(` + +
+
+
+ `); + + if (r.tags) { + let t = r.tags; + if (t.title) { + div.find(".info").append(`
${t.title}
`); + + if (t.description) { + div.find(".info").append(`
${t.description}
`); + } + + /* + if (t.video) { + div.find(".preview").prepend(` +
+