From 77c541a0151841d1f4ceb0a84ca391e1b526d58d Mon Sep 17 00:00:00 2001
From: nilsteampassnet Add some more replacements e.g. "£" with " pound ". Add some more replacements e.g. "£" with " pound ". An array of replacements. Language of the source string e.g.: en, de_at, or de-ch.
+ * (default is 'en') | ASCII::*_LANGUAGE_CODE Add some more replacements e.g. "£" with " pound ". TRUE === return {orig: string[], replace: string[]}
+ * array An array of replacements. Add some more replacements e.g. "£" with " pound ". TRUE === return {orig: string[], replace: string[]}
+ * array An array of replacements. The string to be sanitized. Set to true, if you need to normalize the
+ * whitespace. Set to true, if you need to normalize MS Word chars
+ * e.g.: "…"
+ * => "..." Set to true, to keep non-breaking-spaces, in
+ * combination with
+ * $normalize_whitespace Set to false, if you not want to remove invisible
+ * characters e.g.: "\0" A clean UTF-8 string. The string to check.
+ * true if it is ASCII The string to be normalized. A string with normalized characters for commonly used chars in Word documents. The string to be normalized. Set to true, to keep non-breaking-spaces. Set to true, to keep non-printable (for the web)
+ * bidirectional text chars. Set to true, to convert e.g. LINE-, PARAGRAPH-SEPARATOR with "\n" and LINE TABULATION with "\t". A string with normalized whitespace. The input string. Language of the source string.
+ * (default is 'en') | ASCII::*_LANGUAGE_CODE Whether or not to remove the
+ * unsupported characters. Add some more replacements e.g. "£" with " pound
+ * ". Use ASCII::to_transliterate() for unknown chars. Single char replacement is better for the
+ * performance, but some languages need to replace more then one char
+ * at the same time. | NULL === auto-setting, depended on the
+ * language A string that contains only ASCII characters. ASCII::to_transliterate() is used by default - unsafe characters are
+ * simply replaced with hyphen otherwise. A string that contains only safe characters for a filename. The string used to replace whitespace. Language of the source string.
+ * (default is 'en') | ASCII::*_LANGUAGE_CODE A map of replaceable strings. Add some more replacements e.g. "£" with "
+ * pound ". Use "string to lower" for the input. Use ASCII::to_transliterate() for unknown
+ * chars. A string that has been converted to an URL slug. The input string. Character use if character unknown. (default is '?')
+ * But you can also use NULL to keep the unknown chars. Use "transliterator_transliterate()" from PHP-Intl
+ *
+ * @psalm-pure
+ *
+ * @return string
+ * A String that contains only ASCII characters. UTF-8 string to be converted to extended ASCII. Internal-Map of code points to ASCII characters. Mapped borken string. A UTF-8 string. The position of character to return. Set the charset for e.g. "mb_" function Single multi-byte character. The input string. The output string that contains BOM. The array to work on Either CASE_UPPER Set the charset for e.g. "mb_" function An array with its keys lower- or uppercased. Delimiter marking the start of the substring. Delimiter marking the end of the substring. Index from which to begin the search. Default: 0 Set the charset for e.g. "mb_" function UTF-8 Byte Order Mark. The input string. Position of the character. Default is UTF-8 The character at $index. The input string. An array of chars. You don't need to run it manually, it will be triggered if it's needed. The code point for which to generate a character. Default is UTF-8 Multi-byte character, returns null on failure or empty input. The callback function. UTF-8 string to run callback on. The outcome of the callback, as array. The original unicode string. An array of byte lengths of each character. The input character. The input character The code point encoded as U+xxxx. The original string to be split. The maximum character length of a chunk. The character(s) to be inserted at the end of each chunk. The chunked string. The string to be sanitized. Set to true, if you need to remove
+ * UTF-BOM. Set to true, if you need to normalize the
+ * whitespace. Set to true, if you need to normalize MS
+ * Word chars e.g.: "…"
+ * => "..." Set to true, to keep non-breaking-spaces,
+ * in
+ * combination with
+ * $normalize_whitespace Set to true, if you need to remove diamond
+ * question mark e.g.: "�" Set to false, if you not want to remove
+ * invisible characters e.g.: "\0" Set to true, if you not want to remove
+ * invisible url encoded characters e.g.: "%0B" An clean UTF-8 encoded string. The input string. A UTF-8 encoded string or an array of such chars. If True, will return code points in U+xxxx format,
+ * default, code points will be returned as integers.
+ * The array of code points: The input string. A string with trimmed $str and condensed whitespace. The input string. Remove non UTF-8 chars from the string. Set to false, if you don't want to use
+ *
+ * @psalm-pure
+ *
+ * @return int[]
+ * An associative array of Character as keys and
+ * their count as values. INFO: if no identifier is given e.g. " " or "", we will create a unique string automatically true if available, false otherwise Please do not use it anymore, we will make is private in next major version. Set the charset for e.g. "mb_" function A decoded MIME field on success,
+ * or false if an error occurs during the decoding. e.g. DE Emoji or empty string on error. The input string.
+ * When TRUE, we se a reversible string mapping
+ * between "emoji_encode" and "emoji_decode". The input string
+ * when TRUE, we use a reversible string mapping
+ * between "emoji_encode" and "emoji_decode" e.g. 'UTF-16', 'UTF-8', 'ISO-8859-1', etc. The input string Force the new encoding (we try to fix broken / double
+ * encoding for UTF-8) e.g. 'UTF-16', 'UTF-8', 'ISO-8859-1', etc. Set the input charset. Set the output charset. Set the transfer encoding. Set the used linefeed. Set the max length indent. An encoded MIME field on success,
+ * or false if an error occurs during the encoding. The input string. The searched string. Default: null === text->length / 2 Default: … Set the charset for e.g. "mb_" function
+ * Name of the file to read.
+ *
+ * Prior to PHP 5, this parameter is called
+ * use_include_path and is a bool.
+ * As of PHP 5 the FILE_USE_INCLUDE_PATH can be used
+ * to trigger include path
+ * search.
+ *
+ * A valid context resource created with
+ * stream_context_create. If you don't need to use a
+ * custom context, you can skip this parameter by &null;.
+ *
+ * The offset where the reading starts.
+ *
+ * Maximum length of data read. The default is to read until end
+ * of file is reached.
+ * The time in seconds for the timeout. Maybe you can't use this option for
+ * some files, because they used non default utf-8 chars. Binary files
+ * like images or pdf will not be converted. e.g. 'UTF-16', 'UTF-8', 'ISO-8859-1', etc. The function returns the read data as string or false on failure. Path to a valid file. true if the file has BOM at the start, false otherwise
+ * One of INPUT_GET, INPUT_POST,
+ * INPUT_COOKIE, INPUT_SERVER, or
+ * INPUT_ENV.
+ *
+ * Name of a variable to get.
+ *
+ * The ID of the filter to apply. The
+ * manual page lists the available filters.
+ *
+ * Associative array of options or bitwise disjunction of flags. If filter
+ * accepts options, flags can be provided in "flags" field of array.
+ *
+ * Value of the requested variable on success, FALSE if the filter fails, or NULL if the
+ * variable_name variable is not set. If the flag FILTER_NULL_ON_FAILURE is used, it
+ * returns FALSE if the variable is not set and NULL if the filter fails.
+ *
+ * One of INPUT_GET, INPUT_POST,
+ * INPUT_COOKIE, INPUT_SERVER, or
+ * INPUT_ENV.
+ *
+ * An array defining the arguments. A valid key is a string
+ * containing a variable name and a valid value is either a filter type, or an array
+ * optionally specifying the filter, flags and options. If the value is an
+ * array, valid keys are filter which specifies the
+ * filter type,
+ * flags which specifies any flags that apply to the
+ * filter, and options which specifies any options that
+ * apply to the filter. See the example below for a better understanding.
+ *
+ * This parameter can be also an integer holding a filter constant. Then all values in the
+ * input array are filtered by this filter.
+ *
+ * Add missing keys as NULL to the return value.
+ *
+ * An array containing the values of the requested variables on success, or FALSE on failure.
+ * An array value will be FALSE if the filter fails, or NULL if the variable is not
+ * set. Or if the flag FILTER_NULL_ON_FAILURE is used, it returns FALSE if the variable
+ * is not set and NULL if the filter fails.
+ *
+ * Value to filter.
+ *
+ * The ID of the filter to apply. The
+ * manual page lists the available filters.
+ *
+ * Associative array of options or bitwise disjunction of flags. If filter
+ * accepts options, flags can be provided in "flags" field of array. For
+ * the "callback" filter, callable type should be passed. The
+ * callback must accept one argument, the value to be filtered, and return
+ * the value after filtering/sanitizing it.
+ *
+ * The filtered data, or FALSE if the filter fails.
+ * An array with string keys containing the data to filter.
+ *
+ * An array defining the arguments. A valid key is a string
+ * containing a variable name and a valid value is either a
+ * filter type, or an
+ * array optionally specifying the filter, flags and options.
+ * If the value is an array, valid keys are filter
+ * which specifies the filter type,
+ * flags which specifies any flags that apply to the
+ * filter, and options which specifies any options that
+ * apply to the filter. See the example below for a better understanding.
+ *
+ * This parameter can be also an integer holding a filter constant. Then all values
+ * in the input array are filtered by this filter.
+ *
+ * Add missing keys as NULL to the return value.
+ *
+ * An array containing the values of the requested variables on success, or FALSE on failure.
+ * An array value will be FALSE if the filter fails, or NULL if the variable is not
+ * set.
+ * true if available, false otherwise Please do not use it anymore, we will make is private in next major version. The input string. Number of characters to retrieve from the start. Set the charset for e.g. "mb_" function TRUE if string is less than or equal to $box_size, FALSE otherwise. The input string Will return the fixed input-"array" or
+ * the fixed input-"string". 'RTL' or 'LTR'. Length of the random string. Characters string for the random selection. Set the charset for e.g. "mb_" function Extra entropy via a string or int value. Return the unique identifier as md5-hash? Default: true The input string. Whether or not the string contains a lower case character. The input string. Whether or not the string contains whitespace. The input string. Whether or not the string contains an upper case character. The hexadecimal value. One single UTF-8 character. The hexadecimal code point representation. The code point, or false on failure. The Unicode string to be encoded as numbered entities. Keep ASCII chars. Set the charset for e.g. "mb_" function HTML numbered entities.
+ * The input string.
+ *
+ * A bitmask of one or more of the following flags, which specify how to handle quotes
+ * and which document type to use. The default is ENT_COMPAT | ENT_HTML401.
+ *
+ * $array = ASCII::charsArray();
+ * var_dump($array['ru']['б']); // 'b'
+ *
+ *
+ * @psalm-suppress InvalidNullableReturnType - we use the prepare* methods here, so we don't get NULL here
+ *
+ * @param bool $replace_extra_symbols [optional]
+ * $array = ASCII::charsArrayWithMultiLanguageValues();
+ * var_dump($array['b']); // ['β', 'б', 'ဗ', 'ბ', 'ب']
+ *
+ *
+ * @param bool $replace_extra_symbols [optional]
+ * $array = ASCII::charsArrayWithOneLanguage('ru');
+ * $tmpKey = \array_search('yo', $array['replace']);
+ * echo $array['orig'][$tmpKey]; // 'ё'
+ *
+ *
+ * @psalm-suppress InvalidNullableReturnType - we use the prepare* methods here, so we don't get NULL here
+ *
+ * @param string $language [optional]
+ * $array = ASCII::charsArrayWithSingleLanguageValues();
+ * $tmpKey = \array_search('hnaik', $array['replace']);
+ * echo $array['orig'][$tmpKey]; // '၌'
+ *
+ *
+ * @param bool $replace_extra_symbols [optional]
+ * ASCII::is_ascii('白'); // false
+ *
+ *
+ * @param string $str
+ * false otherwise
+ *
+ * ASCII::normalize_msword('„Abcdef…”'); // '"Abcdef..."'
+ *
+ *
+ * @param string $str
+ * ASCII::normalize_whitespace("abc-\xc2\xa0-öäü-\xe2\x80\xaf-\xE2\x80\xAC", true); // "abc-\xc2\xa0-öäü- -"
+ *
+ *
+ * @param string $str
+ * ASCII::to_ascii('�Düsseldorf�', 'en'); // Dusseldorf
+ *
+ *
+ * @param string $str
+ * ASCII::to_filename('שדגשדג.png', true)); // 'shdgshdg.png'
+ *
+ *
+ * @param string $str
+ * @param bool $use_transliterate
+ * ASCII::to_transliterate('déjà σσς iıii'); // 'deja sss iiii'
+ *
+ *
+ * @param string $str UTF8::access('fòô', 1); // 'ò'
+ *
+ * @param string $str UTF8::add_bom_to_string('fòô'); // "\xEF\xBB\xBF" . 'fòô'
+ *
+ * @param string $str
+ * or CASE_LOWER (default)UTF8::binary_to_str('11110000100111111001100010000011'); // '😃'
+ *
+ * @param string $bin 1|0
+ *
+ * @psalm-pure
+ *
+ * @return string
+ */
+ public static function binary_to_str($bin): string
+ {
+ if (!isset($bin[0])) {
+ return '';
+ }
+
+ $convert = \base_convert($bin, 2, 16);
+ if ($convert === '0') {
+ return '';
+ }
+
+ return \pack('H*', $convert);
+ }
+
+ /**
+ * Returns the UTF-8 Byte Order Mark Character.
+ *
+ * INFO: take a look at UTF8::$bom for e.g. UTF-16 and UTF-32 BOM values
+ *
+ * EXAMPLE: UTF8::bom(); // "\xEF\xBB\xBF"
+ *
+ * @psalm-pure
+ *
+ * @return non-empty-string
+ * UTF8::chr(0x2603); // '☃'
+ *
+ * @param int $code_point UTF8::chr_map([UTF8::class, 'strtolower'], 'Κόσμε'); // ['κ','ό', 'σ', 'μ', 'ε']
+ *
+ * @param callable(string): string $callback UTF8::chr_size_list('中文空白-test'); // [3, 3, 3, 3, 1, 1, 1, 1, 1]
+ *
+ * @param string $str UTF8::chr_to_decimal('§'); // 0xa7
+ *
+ * @param string $char UTF8::chr_to_hex('§'); // U+00a7
+ *
+ * @param int|string $char UTF8::chunk_split('ABC-ÖÄÜ-中文空白-κόσμε', 3); // "ABC\r\n-ÖÄ\r\nÜ-中\r\n文空白\r\n-κό\r\nσμε"
+ *
+ * @param string $str UTF8::clean("\xEF\xBB\xBF„Abcdef\xc2\xa0\x20…” — 😃 - Düsseldorf", true, true); // '„Abcdef …” — 😃 - Düsseldorf'
+ *
+ * @param string $str
WARNING:
+ * maybe contains false-positives e.g. aa%0Baa -> aaaa.
+ * UTF8::cleanup("\xEF\xBB\xBF„Abcdef\xc2\xa0\x20…” — 😃 - Düsseldorf", true, true); // '„Abcdef …” — 😃 - Düsseldorf'
+ *
+ * @param string $str
+ * UTF8::codepoints('κöñ'); // array(954, 246, 241)
+ * // ... OR ...
+ * UTF8::codepoints('κöñ', true); // array('U+03ba', 'U+00f6', 'U+00f1')
+ *
+ *
+ * @param string|string[] $arg
+ * int[] for $u_style === false
+ * string[] for $u_style === true
+ * UTF8::count_chars('κaκbκc'); // array('κ' => 3, 'a' => 1, 'b' => 1, 'c' => 1)
+ *
+ * @param string $str UTF8::css_identifier('123foo/bar!!!'); // _23foo-bar
+ *
+ * copy&past from https://github.com/drupal/core/blob/8.8.x/lib/Drupal/Component/Utility/Html.php#L95
+ *
+ * @param string $str UTF8::decimal_to_chr(931); // 'Σ'
+ *
+ * @param int|string $int
+ *
+ * @phpstan-param int|numeric-string $int
+ *
+ * @psalm-pure
+ *
+ * @return string
+ */
+ public static function decimal_to_chr($int): string
+ {
+ // We cannot use html_entity_decode() here, as it will not return
+ // characters for many values < 160.
+ return \mb_convert_encoding('' . $int . ';', 'UTF-8', 'HTML-ENTITIES');
+ }
+
+ /**
+ * Decodes a MIME header field
+ *
+ * @param string $str
+ * @param string $encoding [optional]
+ * UTF8::emoji_decode('foo CHARACTER_OGRE', false); // 'foo 👹'
+ * //
+ * UTF8::emoji_decode('foo _-_PORTABLE_UTF8_-_308095726_-_627590803_-_8FTU_ELBATROP_-_', true); // 'foo 👹'
+ *
+ *
+ * @param string $str
+ * UTF8::emoji_encode('foo 👹', false)); // 'foo CHARACTER_OGRE'
+ * //
+ * UTF8::emoji_encode('foo 👹', true)); // 'foo _-_PORTABLE_UTF8_-_308095726_-_627590803_-_8FTU_ELBATROP_-_'
+ *
+ *
+ * @param string $str
+ * UTF8::encode('ISO-8859-1', '-ABC-中文空白-'); // '-ABC-????-'
+ * //
+ * UTF8::encode('UTF-8', '-ABC-中文空白-'); // '-ABC-中文空白-'
+ * //
+ * UTF8::encode('HTML', '-ABC-中文空白-'); // '-ABC-中文空白-'
+ * //
+ * UTF8::encode('BASE64', '-ABC-中文空白-'); // 'LUFCQy3kuK3mlofnqbrnmb0t'
+ *
+ *
+ * @param string $to_encoding
otherwise we auto-detect the current
+ * string-encoding
+ * A empty string will trigger the autodetect anyway.UTF8::file_get_contents('utf16le.txt'); // ...
+ *
+ * WARNING: Do not use UTF-8 Option ($convert_to_utf8) for binary files (e.g.: images) !!!
+ *
+ * @see http://php.net/manual/en/function.file-get-contents.php
+ *
+ * @param string $filename
+ * A empty string will trigger the autodetect anyway.UTF8::file_has_bom('utf8_with_bom.txt'); // true
+ *
+ * @param string $file_path UTF8::filter(array("\xE9", 'à', 'a')); // array('é', 'à', 'a')
+ *
+ * @param array|object|string $var
+ * @param int $normalization_form
+ * @param string $leading_combining
+ *
+ * @psalm-pure
+ *
+ * @return mixed
+ *
+ * @template TFilter
+ * @phpstan-param TFilter $var
+ * @phpstan-return TFilter
+ */
+ public static function filter(
+ $var,
+ int $normalization_form = \Normalizer::NFC,
+ string $leading_combining = '◌'
+ ) {
+ switch (\gettype($var)) {
+ case 'object':
+ case 'array':
+ /* @phpstan-ignore-next-line | object & array are both iterable */
+ foreach ($var as &$v) {
+ $v = self::filter($v, $normalization_form, $leading_combining);
+ }
+ unset($v);
+
+ break;
+ case 'string':
+
+ if (\strpos($var, "\r") !== false) {
+ $var = self::normalize_line_ending($var);
+ }
+
+ if (!ASCII::is_ascii($var)) {
+ if (\Normalizer::isNormalized($var, $normalization_form)) {
+ $n = '-';
+ } else {
+ $n = \Normalizer::normalize($var, $normalization_form);
+
+ if ($n && isset($n[0])) {
+ $var = $n;
+ } else {
+ $var = self::encode('UTF-8', $var);
+ }
+ }
+
+ \assert(\is_string($var));
+ if (
+ $n
+ &&
+ $var[0] >= "\x80"
+ &&
+ isset($n[0], $leading_combining[0])
+ &&
+ \preg_match('/^\\p{Mn}/u', $var)
+ ) {
+ // Prevent leading combining chars
+ // for NFC-safe concatenations.
+ $var = $leading_combining . $var;
+ }
+ }
+
+ break;
+ default:
+ // nothing
+ }
+
+ /** @noinspection PhpSillyAssignmentInspection */
+ /** @phpstan-var TFilter $var */
+ $var = $var;
+
+ return $var;
+ }
+
+ /**
+ * "filter_input()"-wrapper with normalizes to UTF-8 NFC, converting from WINDOWS-1252 when needed.
+ *
+ * Gets a specific external variable by name and optionally filters it.
+ *
+ * EXAMPLE:
+ * // _GET['foo'] = 'bar';
+ * UTF8::filter_input(INPUT_GET, 'foo', FILTER_UNSAFE_RAW)); // 'bar'
+ *
+ *
+ * @see http://php.net/manual/en/function.filter-input.php
+ *
+ * @param int $type
+ * // _GET['foo'] = 'bar';
+ * UTF8::filter_input_array(INPUT_GET, array('foo' => 'FILTER_UNSAFE_RAW')); // array('bar')
+ *
+ *
+ * @see http://php.net/manual/en/function.filter-input-array.php
+ *
+ * @param int $type UTF8::filter_var('-ABC-中文空白-', FILTER_VALIDATE_URL); // false
+ *
+ * @see http://php.net/manual/en/function.filter-var.php
+ *
+ * @param float|int|string|null $variable
+ * // for filters that accept options, use this format
+ * $options = array(
+ * 'options' => array(
+ * 'default' => 3, // value to return if the filter fails
+ * // other options here
+ * 'min_range' => 0
+ * ),
+ * 'flags' => FILTER_FLAG_ALLOW_OCTAL,
+ * );
+ * $var = filter_var('0755', FILTER_VALIDATE_INT, $options);
+ * // for filter that only accept flags, you can pass them directly
+ * $var = filter_var('oops', FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
+ * // for filter that only accept flags, you can also pass as an array
+ * $var = filter_var('oops', FILTER_VALIDATE_BOOLEAN,
+ * array('flags' => FILTER_NULL_ON_FAILURE));
+ * // callback validate filter
+ * function foo($value)
+ * {
+ * // Expected format: Surname, GivenNames
+ * if (strpos($value, ", ") === false) return false;
+ * list($surname, $givennames) = explode(", ", $value, 2);
+ * $empty = (empty($surname) || empty($givennames));
+ * $notstrings = (!is_string($surname) || !is_string($givennames));
+ * if ($empty || $notstrings) {
+ * return false;
+ * } else {
+ * return $value;
+ * }
+ * }
+ * $var = filter_var('Doe, Jane Sue', FILTER_CALLBACK, array('options' => 'foo'));
+ *
+ *
+ * $filters = [
+ * 'name' => ['filter' => FILTER_CALLBACK, 'options' => [UTF8::class, 'ucwords']],
+ * 'age' => ['filter' => FILTER_VALIDATE_INT, 'options' => ['min_range' => 1, 'max_range' => 120]],
+ * 'email' => FILTER_VALIDATE_EMAIL,
+ * ];
+ *
+ * $data = [
+ * 'name' => 'κόσμε',
+ * 'age' => '18',
+ * 'email' => 'foo@bar.de'
+ * ];
+ *
+ * UTF8::filter_var_array($data, $filters, true); // ['name' => 'Κόσμε', 'age' => 18, 'email' => 'foo@bar.de']
+ *
+ *
+ * @see http://php.net/manual/en/function.filter-var-array.php
+ *
+ * @param arrayUTF8::fits_inside('κόσμε', 6); // false
+ *
+ * @param string $str the original string to be checked
+ * @param int $box_size the size in number of chars to be checked against string
+ *
+ * @psalm-pure
+ *
+ * @return bool
+ * UTF8::fix_simple_utf8('Düsseldorf'); // 'Düsseldorf'
+ *
+ * If you received an UTF-8 string that was converted from Windows-1252 as it was ISO-8859-1
+ * (ignoring Windows-1252 chars from 80 to 9F) use this function to fix it.
+ * See: http://en.wikipedia.org/wiki/Windows-1252
+ *
+ * @param string $str UTF8::fix_utf8('Fédération'); // 'Fédération'
+ *
+ * @param string|string[] $str you can use a string or an array of strings
+ *
+ * @psalm-pure
+ *
+ * @return string|string[]
+ * UTF8::getCharDirection('ا'); // 'RTL'
+ *
+ * @param string $char
+ *
+ * @psalm-pure
+ *
+ * @return string
+ *
+ * return bool-value, if $key is used and available
+ * otherwise return null
+ */
+ public static function getSupportInfo(string $key = null)
+ {
+ if ($key === null) {
+ return self::$SUPPORT;
+ }
+
+ if (self::$INTL_TRANSLITERATOR_LIST === null) {
+ self::$INTL_TRANSLITERATOR_LIST = self::getData('transliterator_list');
+ }
+ // compatibility fix for old versions
+ self::$SUPPORT['intl__transliterator_list_ids'] = self::$INTL_TRANSLITERATOR_LIST;
+
+ return self::$SUPPORT[$key] ?? null;
+ }
+
+ /**
+ * Warning: this method only works for some file-types (png, jpg)
+ * if you need more supported types, please use e.g. "finfo"
+ *
+ * @param string $str
+ * @param array{ext: null|string, mime: null|string, type: null|string} $fallback
+ *
+ * @return array{ext: null|string, mime: null|string, type: null|string}
+ *
+ * @psalm-pure
+ */
+ public static function get_file_type(
+ string $str,
+ array $fallback = [
+ 'ext' => null,
+ 'mime' => 'application/octet-stream',
+ 'type' => null,
+ ]
+ ): array {
+ if ($str === '') {
+ return $fallback;
+ }
+
+ /** @var false|string $str_info - needed for PhpStan (stubs error) */
+ $str_info = \substr($str, 0, 2);
+ if ($str_info === false || \strlen($str_info) !== 2) {
+ return $fallback;
+ }
+
+ // DEBUG
+ //var_dump($str_info);
+
+ $str_info = \unpack('C2chars', $str_info);
+
+ if ($str_info === false) {
+ return $fallback;
+ }
+ $type_code = (int) ($str_info['chars1'] . $str_info['chars2']);
+
+ // DEBUG
+ //var_dump($type_code);
+
+ //
+ // info: https://en.wikipedia.org/wiki/Magic_number_%28programming%29#Format_indicator
+ //
+ switch ($type_code) {
+ // WARNING: do not add too simple comparisons, because of false-positive results:
+ //
+ // 3780 => 'pdf', 7790 => 'exe', 7784 => 'midi', 8075 => 'zip',
+ // 8297 => 'rar', 7173 => 'gif', 7373 => 'tiff' 6677 => 'bmp', ...
+ //
+ case 255216:
+ $ext = 'jpg';
+ $mime = 'image/jpeg';
+ $type = 'binary';
+
+ break;
+ case 13780:
+ $ext = 'png';
+ $mime = 'image/png';
+ $type = 'binary';
+
+ break;
+ default:
+ return $fallback;
+ }
+
+ return [
+ 'ext' => $ext,
+ 'mime' => $mime,
+ 'type' => $type,
+ ];
+ }
+
+ /**
+ * @param int<1, max> $length UTF8::hex_to_chr('U+00a7'); // '§'
+ *
+ * @param string $hexdec UTF8::hex_to_int('U+00f1'); // 241
+ *
+ * @param string $hexdec UTF8::html_encode('中文空白'); // '中文空白'
+ *
+ * @param string $str UTF8::html_entity_decode('中文空白'); // '中文空白'
+ *
+ * @see http://php.net/manual/en/function.html-entity-decode.php
+ *
+ * @param string $str
+ * Available flags constants
+ *
+ *
+ *
+ * Constant Name
+ * Description
+ *
+ *
+ * ENT_COMPAT
+ * Will convert double-quotes and leave single-quotes alone.
+ *
+ *
+ * ENT_QUOTES
+ * Will convert both double and single quotes.
+ *
+ *
+ * ENT_NOQUOTES
+ * Will leave both double and single quotes unconverted.
+ *
+ *
+ * ENT_HTML401
+ *
+ * Handle code as HTML 4.01.
+ *
+ *
+ *
+ * ENT_XML1
+ *
+ * Handle code as XML 1.
+ *
+ *
+ *
+ * ENT_XHTML
+ *
+ * Handle code as XHTML.
+ *
+ *
+ *
+ * ENT_HTML5
+ *
+ * Handle code as HTML 5.
+ *
+ *
Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return string + *The decoded string.
+ * + * @template T as string + * @phpstan-param T $str + * @phpstan-return (T is non-empty-string ? non-empty-string : string) + */ + public static function html_entity_decode( + string $str, + int $flags = null, + string $encoding = 'UTF-8' + ): string { + if ( + !isset($str[3]) // examples: &; || &x; + || + \strpos($str, '&') === false // no "&" + ) { + return $str; + } + + if ($encoding !== 'UTF-8' && $encoding !== 'CP850') { + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + } + + if ($flags === null) { + $flags = \ENT_QUOTES | \ENT_HTML5; + } + + if ( + $encoding !== 'UTF-8' + && + $encoding !== 'ISO-8859-1' + && + $encoding !== 'WINDOWS-1252' + && + self::$SUPPORT['mbstring'] === false + ) { + /** + * @psalm-suppress ImpureFunctionCall - this is only a warning + */ + \trigger_error('UTF8::html_entity_decode() without mbstring cannot handle "' . $encoding . '" encoding', \E_USER_WARNING); + } + + do { + $str_compare = $str; + + if (\strpos($str, '&') !== false) { + if (\strpos($str, '') !== false) { + // decode also numeric & UTF16 two byte entities + $str = (string) \preg_replace( + '/((?:x0*[0-9a-fA-F]{2,6}(?![0-9a-fA-F;])|(?:0*\d{2,6}(?![0-9;]))))/S', + '$1;', + $str + ); + } + + $str = \html_entity_decode( + $str, + $flags, + $encoding + ); + } + } while ($str_compare !== $str); + + return $str; + } + + /** + * Create a escape html version of the string via "UTF8::htmlspecialchars()". + * + * @param string $str + * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return string + */ + public static function html_escape(string $str, string $encoding = 'UTF-8'): string + { + return self::htmlspecialchars( + $str, + \ENT_QUOTES | \ENT_SUBSTITUTE, + $encoding + ); + } + + /** + * Remove empty html-tag. + * + * e.g.:+ * + * @param string $str + * + * @psalm-pure + * + * @return string + */ + public static function html_stripe_empty_tags(string $str): string + { + return (string) \preg_replace( + '/<[^\\/>]*?>\\s*?<\\/[^>]*?>/u', + '', + $str + ); + } + + /** + * Convert all applicable characters to HTML entities: UTF-8 version of htmlentities(). + * + * EXAMPLE:
UTF8::htmlentities('<白-öäü>'); // '<白-öäü>'
+ *
+ * @see http://php.net/manual/en/function.htmlentities.php
+ *
+ * @param string $str + * The input string. + *
+ * @param int $flags [optional]+ * A bitmask of one or more of the following flags, which specify how to handle + * quotes, invalid code unit sequences and the used document type. The default is + * ENT_COMPAT | ENT_HTML401. + *
Constant Name | + *Description | + *
ENT_COMPAT | + *Will convert double-quotes and leave single-quotes alone. | + *
ENT_QUOTES | + *Will convert both double and single quotes. | + *
ENT_NOQUOTES | + *Will leave both double and single quotes unconverted. | + *
ENT_IGNORE | + *+ * Silently discard invalid code unit sequences instead of returning + * an empty string. Using this flag is discouraged as it + * may have security implications. + * | + *
ENT_SUBSTITUTE | + *+ * Replace invalid code unit sequences with a Unicode Replacement Character + * U+FFFD (UTF-8) or &#FFFD; (otherwise) instead of returning an empty + * string. + * | + *
ENT_DISALLOWED | + *+ * Replace invalid code points for the given document type with a + * Unicode Replacement Character U+FFFD (UTF-8) or &#FFFD; + * (otherwise) instead of leaving them as is. This may be useful, for + * instance, to ensure the well-formedness of XML documents with + * embedded external content. + * | + *
ENT_HTML401 | + *+ * Handle code as HTML 4.01. + * | + *
ENT_XML1 | + *+ * Handle code as XML 1. + * | + *
ENT_XHTML | + *+ * Handle code as XHTML. + * | + *
ENT_HTML5 | + *+ * Handle code as HTML 5. + * | + *
+ * Like htmlspecialchars, + * htmlentities takes an optional third argument + * encoding which defines encoding used in + * conversion. + * Although this argument is technically optional, you are highly + * encouraged to specify the correct value for your code. + *
+ * @param bool $double_encode [optional]+ * When double_encode is turned off PHP will not + * encode existing html entities. The default is to convert everything. + *
+ * + * @psalm-pure + * + * @return string + *
+ * The encoded string.
+ *
+ * If the input string contains an invalid code unit
+ * sequence within the given encoding an empty string
+ * will be returned, unless either the ENT_IGNORE or
+ * ENT_SUBSTITUTE flags are set.
+ *
UTF8::htmlspecialchars('<白-öäü>'); // '<白-öäü>'
+ *
+ * @see http://php.net/manual/en/function.htmlspecialchars.php
+ *
+ * @param string $str + * The string being converted. + *
+ * @param int $flags [optional]+ * A bitmask of one or more of the following flags, which specify how to handle + * quotes, invalid code unit sequences and the used document type. The default is + * ENT_COMPAT | ENT_HTML401. + *
Constant Name | + *Description | + *
ENT_COMPAT | + *Will convert double-quotes and leave single-quotes alone. | + *
ENT_QUOTES | + *Will convert both double and single quotes. | + *
ENT_NOQUOTES | + *Will leave both double and single quotes unconverted. | + *
ENT_IGNORE | + *+ * Silently discard invalid code unit sequences instead of returning + * an empty string. Using this flag is discouraged as it + * may have security implications. + * | + *
ENT_SUBSTITUTE | + *+ * Replace invalid code unit sequences with a Unicode Replacement Character + * U+FFFD (UTF-8) or &#FFFD; (otherwise) instead of returning an empty + * string. + * | + *
ENT_DISALLOWED | + *+ * Replace invalid code points for the given document type with a + * Unicode Replacement Character U+FFFD (UTF-8) or &#FFFD; + * (otherwise) instead of leaving them as is. This may be useful, for + * instance, to ensure the well-formedness of XML documents with + * embedded external content. + * | + *
ENT_HTML401 | + *+ * Handle code as HTML 4.01. + * | + *
ENT_XML1 | + *+ * Handle code as XML 1. + * | + *
ENT_XHTML | + *+ * Handle code as XHTML. + * | + *
ENT_HTML5 | + *+ * Handle code as HTML 5. + * | + *
+ * Defines encoding used in conversion. + *
+ *+ * For the purposes of this function, the encodings + * ISO-8859-1, ISO-8859-15, + * UTF-8, cp866, + * cp1251, cp1252, and + * KOI8-R are effectively equivalent, provided the + * string itself is valid for the encoding, as + * the characters affected by htmlspecialchars occupy + * the same positions in all of these encodings. + *
+ * @param bool $double_encode [optional]+ * When double_encode is turned off PHP will not + * encode existing html entities, the default is to convert everything. + *
+ * + * @psalm-pure + * + * @return string + *The converted string.
+ *+ * If the input string contains an invalid code unit + * sequence within the given encoding an empty string + * will be returned, unless either the ENT_IGNORE or + * ENT_SUBSTITUTE flags are set.
+ * + * @template T as string + * @phpstan-param T $str + * @phpstan-return (T is non-empty-string ? non-empty-string : string) + */ + public static function htmlspecialchars( + string $str, + int $flags = \ENT_COMPAT, + string $encoding = 'UTF-8', + bool $double_encode = true + ): string { + if ($encoding !== 'UTF-8' && $encoding !== 'CP850') { + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + } + + return \htmlspecialchars( + $str, + $flags, + $encoding, + $double_encode + ); + } + + /** + * Checks whether iconv is available on the server. + * + * @psalm-pure + * + * @return bool + *true if available, false otherwise
+ * + * @internalPlease do not use it anymore, we will make is private in next major version.
+ */ + public static function iconv_loaded(): bool + { + return \extension_loaded('iconv'); + } + + /** + * Converts Integer to hexadecimal U+xxxx code point representation. + * + * INFO: opposite to UTF8::hex_to_int() + * + * EXAMPLE:UTF8::int_to_hex(241); // 'U+00f1'
+ *
+ * @param int $int The integer to be converted to hexadecimal code point.
+ * @param string $prefix [optional] + * + * @psalm-pure + * + * @return string the code point, or empty string on failure + */ + public static function int_to_hex(int $int, string $prefix = 'U+'): string + { + $hex = \dechex($int); + + $hex = (\strlen($hex) < 4 ? \substr('0000' . $hex, -4) : $hex); + + return $prefix . $hex . ''; + } + + /** + * Checks whether intl-char is available on the server. + * + * @psalm-pure + * + * @return bool + *true if available, false otherwise
+ * + * @internalPlease do not use it anymore, we will make is private in next major version.
+ */ + public static function intlChar_loaded(): bool + { + return \class_exists('IntlChar'); + } + + /** + * Checks whether intl is available on the server. + * + * @psalm-pure + * + * @return bool + *true if available, false otherwise
+ * + * @internalPlease do not use it anymore, we will make is private in next major version.
+ */ + public static function intl_loaded(): bool + { + return \extension_loaded('intl'); + } + + /** + * Returns true if the string contains only alphabetic chars, false otherwise. + * + * @param string $strThe input string.
+ * + * @psalm-pure + * + * @return bool + *Whether or not $str contains only alphabetic chars.
+ */ + public static function is_alpha(string $str): bool + { + if (self::$SUPPORT['mbstring'] === true) { + return \mb_ereg_match('^[[:alpha:]]*$', $str); + } + + return self::str_matches_pattern($str, '^[[:alpha:]]*$'); + } + + /** + * Returns true if the string contains only alphabetic and numeric chars, false otherwise. + * + * @param string $strThe input string.
+ * + * @psalm-pure + * + * @return bool + *Whether or not $str contains only alphanumeric chars.
+ */ + public static function is_alphanumeric(string $str): bool + { + if (self::$SUPPORT['mbstring'] === true) { + return \mb_ereg_match('^[[:alnum:]]*$', $str); + } + + return self::str_matches_pattern($str, '^[[:alnum:]]*$'); + } + + /** + * Returns true if the string contains only punctuation chars, false otherwise. + * + * @param string $strThe input string.
+ * + * @psalm-pure + * + * @return bool + *Whether or not $str contains only punctuation chars.
+ */ + public static function is_punctuation(string $str): bool + { + return self::str_matches_pattern($str, '^[[:punct:]]*$'); + } + + /** + * Returns true if the string contains only printable (non-invisible) chars, false otherwise. + * + * @param string $strThe input string.
+ * @param bool $ignore_control_characters [optional]Ignore control characters like [LRM] or [LSEP].
+ * + * @psalm-pure + * + * @return bool + *Whether or not $str contains only printable (non-invisible) chars.
+ */ + public static function is_printable(string $str, bool $ignore_control_characters = false): bool + { + return self::remove_invisible_characters($str, false, '', $ignore_control_characters) === $str; + } + + /** + * Checks if a string is 7 bit ASCII. + * + * EXAMPLE:UTF8::is_ascii('白'); // false
+ *
+ * @param string $str The string to check.
+ * + * @psalm-pure + * + * @return bool + *
+ * true if it is ASCII
+ * false otherwise
+ *
UTF8::is_base64('4KSu4KWL4KSo4KS/4KSa'); // true
+ *
+ * @param string|null $str The input string.
+ * @param bool $empty_string_is_valid [optional]Is an empty string valid base64 or not?
+ * + * @psalm-pure + * + * @return bool + *Whether or not $str is base64 encoded.
+ */ + public static function is_base64($str, bool $empty_string_is_valid = false): bool + { + if ( + !$empty_string_is_valid + && + $str === '' + ) { + return false; + } + + if (!\is_string($str)) { + return false; + } + + $base64String = \base64_decode($str, true); + + return $base64String !== false && \base64_encode($base64String) === $str; + } + + /** + * Check if the input is binary... (is look like a hack). + * + * EXAMPLE:UTF8::is_binary(01); // true
+ *
+ * @param int|string $input
+ * @param bool $strict
+ *
+ * @psalm-pure
+ *
+ * @return bool
+ */
+ public static function is_binary($input, bool $strict = false): bool
+ {
+ $input = (string) $input;
+ if ($input === '') {
+ return false;
+ }
+
+ if (\preg_match('~^[01]+$~', $input)) {
+ return true;
+ }
+
+ $ext = self::get_file_type($input);
+ if ($ext['type'] === 'binary') {
+ return true;
+ }
+
+ if (!$strict) {
+ $test_length = \strlen($input);
+ $test_null_counting = \substr_count($input, "\x0", 0, $test_length);
+ if (($test_null_counting / $test_length) > 0.25) {
+ return true;
+ }
+ }
+
+ if ($strict) {
+ if (self::$SUPPORT['finfo'] === false) {
+ throw new \RuntimeException('ext-fileinfo: is not installed');
+ }
+
+ /**
+ * @psalm-suppress ImpureMethodCall - it will return the same result for the same file ...
+ */
+ $finfo_encoding = (new \finfo(\FILEINFO_MIME_ENCODING))->buffer($input);
+ if ($finfo_encoding && $finfo_encoding === 'binary') {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Check if the file is binary.
+ *
+ * EXAMPLE: UTF8::is_binary('./utf32.txt'); // true
+ *
+ * @param string $file
+ *
+ * @return bool
+ */
+ public static function is_binary_file($file): bool
+ {
+ // init
+ $block = '';
+
+ $fp = \fopen($file, 'rb');
+ if (\is_resource($fp)) {
+ $block = \fread($fp, 512);
+ \fclose($fp);
+ }
+
+ if ($block === '' || $block === false) {
+ return false;
+ }
+
+ return self::is_binary($block, true);
+ }
+
+ /**
+ * Returns true if the string contains only whitespace chars, false otherwise.
+ *
+ * @param string $str The input string.
+ * + * @psalm-pure + * + * @return bool + *Whether or not $str contains only whitespace characters.
+ */ + public static function is_blank(string $str): bool + { + if (self::$SUPPORT['mbstring'] === true) { + return \mb_ereg_match('^[[:space:]]*$', $str); + } + + return self::str_matches_pattern($str, '^[[:space:]]*$'); + } + + /** + * Checks if the given string is equal to any "Byte Order Mark". + * + * WARNING: Use "UTF8::string_has_bom()" if you will check BOM in a string. + * + * EXAMPLE:UTF8::is_bom("\xef\xbb\xbf"); // true
+ *
+ * @param string $str The input string.
+ * + * @psalm-pure + * + * @return bool + *true if the $utf8_chr is Byte Order Mark, false otherwise.
+ */ + public static function is_bom($str): bool + { + /** @noinspection PhpUnusedLocalVariableInspection */ + foreach (self::$BOM as $bom_string => &$bom_byte_length) { + if ($str === $bom_string) { + return true; + } + } + + return false; + } + + /** + * Determine whether the string is considered to be empty. + * + * A variable is considered empty if it does not exist or if its value equals FALSE. + * empty() does not generate a warning if the variable does not exist. + * + * @param arrayWhether or not $str is empty().
+ */ + public static function is_empty($str): bool + { + return empty($str); + } + + /** + * Returns true if the string contains only hexadecimal chars, false otherwise. + * + * @param string $strThe input string.
+ * + * @psalm-pure + * + * @return bool + *Whether or not $str contains only hexadecimal chars.
+ */ + public static function is_hexadecimal(string $str): bool + { + if (self::$SUPPORT['mbstring'] === true) { + return \mb_ereg_match('^[[:xdigit:]]*$', $str); + } + + return self::str_matches_pattern($str, '^[[:xdigit:]]*$'); + } + + /** + * Check if the string contains any HTML tags. + * + * EXAMPLE:UTF8::is_html('lall'); // true
+ *
+ * @param string $str The input string.
+ * + * @psalm-pure + * + * @return bool + *Whether or not $str contains html elements.
+ */ + public static function is_html(string $str): bool + { + if ($str === '') { + return false; + } + + // init + $matches = []; + + $str = self::emoji_encode($str); // hack for emoji support :/ + + \preg_match("/<\\/?\\w+(?:(?:\\s+\\w+(?:\\s*=\\s*(?:\".*?\"|'.*?'|[^'\">\\s]+))?)*\\s*|\\s*)\\/?>/u", $str, $matches); + + return $matches !== []; + } + + /** + * Check if $url is an correct url. + * + * @param string $url + * @param bool $disallow_localhost + * + * @psalm-pure + * + * @return bool + */ + public static function is_url(string $url, bool $disallow_localhost = false): bool + { + if ($url === '') { + return false; + } + + // WARNING: keep this as hack protection + if (!self::str_istarts_with_any($url, ['http://', 'https://'])) { + return false; + } + + // e.g. -> the server itself connect to "https://foo.localhost/phpmyadmin/... + if ($disallow_localhost) { + if (self::str_istarts_with_any( + $url, + [ + 'http://localhost', + 'https://localhost', + 'http://127.0.0.1', + 'https://127.0.0.1', + 'http://::1', + 'https://::1', + ] + )) { + return false; + } + + $regex = '/^(?:http(?:s)?:\/\/).*?(?:\.localhost)/iu'; + if (\preg_match($regex, $url)) { + return false; + } + } + + // INFO: this is needed for e.g. "http://müller.de/" (internationalized domain names) and non ASCII-parameters + $regex = '/^(?:http(?:s)?:\\/\\/)(?:[\p{L}0-9][\p{L}0-9_-]*(?:\\.[\p{L}0-9][\p{L}0-9_-]*))(?:\\d+)?(?:\\/\\.*)?/iu'; + if (\preg_match($regex, $url)) { + return true; + } + + return \filter_var($url, \FILTER_VALIDATE_URL) !== false; + } + + /** + * Try to check if "$str" is a JSON-string. + * + * EXAMPLE:UTF8::is_json('{"array":[1,"¥","ä"]}'); // true
+ *
+ * @param string $str The input string.
+ * @param bool $only_array_or_object_results_are_valid [optional]Only array and objects are valid json + * results.
+ * + * @return bool + *Whether or not the $str is in JSON format.
+ */ + public static function is_json(string $str, bool $only_array_or_object_results_are_valid = true): bool + { + if ($str === '') { + return false; + } + + if (self::$SUPPORT['json'] === false) { + throw new \RuntimeException('ext-json: is not installed'); + } + + $jsonOrNull = self::json_decode($str); + if ($jsonOrNull === null && \strtoupper($str) !== 'NULL') { + return false; + } + + if ( + $only_array_or_object_results_are_valid + && + !\is_object($jsonOrNull) + && + !\is_array($jsonOrNull) + ) { + return false; + } + + return \json_last_error() === \JSON_ERROR_NONE; + } + + /** + * @param string $strThe input string.
+ * + * @psalm-pure + * + * @return bool + *Whether or not $str contains only lowercase chars.
+ */ + public static function is_lowercase(string $str): bool + { + if (self::$SUPPORT['mbstring'] === true) { + return \mb_ereg_match('^[[:lower:]]*$', $str); + } + + return self::str_matches_pattern($str, '^[[:lower:]]*$'); + } + + /** + * Returns true if the string is serialized, false otherwise. + * + * @param string $strThe input string.
+ * + * @psalm-pure + * + * @return bool + *Whether or not $str is serialized.
+ */ + public static function is_serialized(string $str): bool + { + if ($str === '') { + return false; + } + + /** @noinspection PhpUsageOfSilenceOperatorInspection */ + /** @noinspection UnserializeExploitsInspection */ + return $str === 'b:0;' + || + @\unserialize($str, []) !== false; + } + + /** + * Returns true if the string contains only lower case chars, false + * otherwise. + * + * @param string $strThe input string.
+ * + * @psalm-pure + * + * @return bool + *Whether or not $str contains only lower case characters.
+ */ + public static function is_uppercase(string $str): bool + { + if (self::$SUPPORT['mbstring'] === true) { + return \mb_ereg_match('^[[:upper:]]*$', $str); + } + + return self::str_matches_pattern($str, '^[[:upper:]]*$'); + } + + /** + * Check if the string is UTF-16. + * + * EXAMPLE:
+ * UTF8::is_utf16(file_get_contents('utf-16-le.txt')); // 1
+ * //
+ * UTF8::is_utf16(file_get_contents('utf-16-be.txt')); // 2
+ * //
+ * UTF8::is_utf16(file_get_contents('utf-8.txt')); // false
+ *
+ *
+ * @param string $str The input string.
+ * @param bool $check_if_string_is_binary + * + * @psalm-pure + * + * @return false|int + * false if is't not UTF-16,
+ * UTF8::is_utf32(file_get_contents('utf-32-le.txt')); // 1
+ * //
+ * UTF8::is_utf32(file_get_contents('utf-32-be.txt')); // 2
+ * //
+ * UTF8::is_utf32(file_get_contents('utf-8.txt')); // false
+ *
+ *
+ * @param string $str The input string.
+ * @param bool $check_if_string_is_binary + * + * @psalm-pure + * + * @return false|int + * false if is't not UTF-32,
+ * UTF8::is_utf8(['Iñtërnâtiônàlizætiøn', 'foo']); // true
+ * //
+ * UTF8::is_utf8(["Iñtërnâtiônàlizætiøn\xA0\xA1", 'bar']); // false
+ *
+ *
+ * @param int|string|string[]|null $str The input to be checked.
+ * @param bool $strictCheck also if the string is not UTF-16 or UTF-32.
+ * + * @psalm-pure + * + * @return bool + */ + public static function is_utf8($str, bool $strict = false): bool + { + if (\is_array($str)) { + foreach ($str as &$v) { + if (!self::is_utf8($v, $strict)) { + return false; + } + } + + return true; + } + + return self::is_utf8_string((string) $str, $strict); + } + + /** + * (PHP 5 >= 5.2.0, PECL json >= 1.2.0)UTF8::json_decode('[1,"\u00a5","\u00e4"]'); // array(1, '¥', 'ä')
+ *
+ * @see http://php.net/manual/en/function.json-decode.php
+ *
+ * @param string $json + * The json string being decoded. + *
+ *+ * This function only works with UTF-8 encoded strings. + *
+ *PHP implements a superset of + * JSON - it will also encode and decode scalar types and NULL. The JSON standard + * only supports these values when they are nested inside an array or an object. + *
+ * @param bool $assoc [optional]+ * When TRUE, returned objects will be converted into + * associative arrays. + *
+ * @param int $depth [optional]+ * User specified recursion depth. + *
+ * @param int $options [optional]+ * Bitmask of JSON decode options. Currently only + * JSON_BIGINT_AS_STRING + * is supported (default is to cast large integers as floats) + *
+ * + * @psalm-pure + * + * @return mixed + *The value encoded in json in appropriate PHP type. Values true, false and + * null (case-insensitive) are returned as TRUE, FALSE and NULL respectively. + * NULL is returned if the json cannot be decoded or if the encoded data + * is deeper than the recursion limit.
+ */ + public static function json_decode( + string $json, + bool $assoc = false, + int $depth = 512, + int $options = 0 + ) { + $json = self::filter($json); + + if (self::$SUPPORT['json'] === false) { + throw new \RuntimeException('ext-json: is not installed'); + } + + if ($depth < 1) { + $depth = 1; + } + + return \json_decode($json, $assoc, $depth, $options); + } + + /** + * (PHP 5 >= 5.2.0, PECL json >= 1.2.0)UTF8::json_encode(array(1, '¥', 'ä')); // '[1,"\u00a5","\u00e4"]'
+ *
+ * @see http://php.net/manual/en/function.json-encode.php
+ *
+ * @param mixed $value + * The value being encoded. Can be any type except + * a resource. + *
+ *+ * All string data must be UTF-8 encoded. + *
+ *PHP implements a superset of + * JSON - it will also encode and decode scalar types and NULL. The JSON standard + * only supports these values when they are nested inside an array or an object. + *
+ * @param int $options [optional]+ * Bitmask consisting of JSON_HEX_QUOT, + * JSON_HEX_TAG, + * JSON_HEX_AMP, + * JSON_HEX_APOS, + * JSON_NUMERIC_CHECK, + * JSON_PRETTY_PRINT, + * JSON_UNESCAPED_SLASHES, + * JSON_FORCE_OBJECT, + * JSON_UNESCAPED_UNICODE. The behaviour of these + * constants is described on + * the JSON constants page. + *
+ * @param int $depth [optional]+ * Set the maximum depth. Must be greater than zero. + *
+ * + * @psalm-pure + * + * @return false|string + *A JSON encoded string on success or
+ * FALSE on failure.
true if available, false otherwise
+ * + * @internalPlease do not use it anymore, we will make is private in next major version.
+ */ + public static function json_loaded(): bool + { + return \function_exists('json_decode'); + } + + /** + * Makes string's first char lowercase. + * + * EXAMPLE:UTF8::lcfirst('ÑTËRNÂTIÔNÀLIZÆTIØN'); // ñTËRNÂTIÔNÀLIZÆTIØN
+ *
+ * @param string $str The input string
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * @param string|null $lang [optional]Set the language for special cases: az, el, lt, + * tr
+ * @param bool $try_to_keep_the_string_length [optional]true === try to keep the string length: e.g. ẞ + * -> ß
+ * + * @psalm-pure + * + * @return string + *The resulting string.
+ */ + public static function lcfirst( + string $str, + string $encoding = 'UTF-8', + bool $clean_utf8 = false, + string $lang = null, + bool $try_to_keep_the_string_length = false + ): string { + if ($clean_utf8) { + $str = self::clean($str); + } + + $use_mb_functions = ($lang === null && !$try_to_keep_the_string_length); + + if ($encoding === 'UTF-8') { + $str_part_two = (string) \mb_substr($str, 1); + + if ($use_mb_functions) { + $str_part_one = \mb_strtolower( + (string) \mb_substr($str, 0, 1) + ); + } else { + $str_part_one = self::strtolower( + (string) \mb_substr($str, 0, 1), + $encoding, + false, + $lang, + $try_to_keep_the_string_length + ); + } + } else { + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + + $str_part_two = (string) self::substr($str, 1, null, $encoding); + + $str_part_one = self::strtolower( + (string) self::substr($str, 0, 1, $encoding), + $encoding, + false, + $lang, + $try_to_keep_the_string_length + ); + } + + return $str_part_one . $str_part_two; + } + + /** + * Lowercase for all words in the string. + * + * @param string $strThe input string.
+ * @param string[] $exceptions [optional]Exclusion for some words.
+ * @param string $char_list [optional]Additional chars that contains to words and do + * not start a new word.
+ * @param string $encoding [optional]Set the charset.
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * @param string|null $lang [optional]Set the language for special cases: az, el, lt, + * tr
+ * @param bool $try_to_keep_the_string_length [optional]true === try to keep the string length: e.g. ẞ + * -> ß
+ * + * @psalm-pure + * + * @return string + */ + public static function lcwords( + string $str, + array $exceptions = [], + string $char_list = '', + string $encoding = 'UTF-8', + bool $clean_utf8 = false, + string $lang = null, + bool $try_to_keep_the_string_length = false + ): string { + if (!$str) { + return ''; + } + + $words = self::str_to_words($str, $char_list); + $use_exceptions = $exceptions !== []; + + $words_str = ''; + foreach ($words as &$word) { + if (!$word) { + continue; + } + + if ( + !$use_exceptions + || + !\in_array($word, $exceptions, true) + ) { + $words_str .= self::lcfirst($word, $encoding, $clean_utf8, $lang, $try_to_keep_the_string_length); + } else { + $words_str .= $word; + } + } + + return $words_str; + } + + /** + * Calculate Levenshtein distance between two strings. + * + * For better performance, in a real application with a single input string + * matched against many strings from a database, you will probably want to pre- + * encode the input only once and use \levenshtein(). + * + * Source: https://github.com/KEINOS/mb_levenshtein + * + * @see https://www.php.net/manual/en/function.levenshtein + * + * @param string $str1One of the strings being evaluated for Levenshtein distance.
+ * @param string $str2One of the strings being evaluated for Levenshtein distance.
+ * @param int $insertionCost [optional]Defines the cost of insertion.
+ * @param int $replacementCost [optional]Defines the cost of replacement.
+ * @param int $deletionCost [optional]Defines the cost of deletion.
+ * + * @return int + */ + public static function levenshtein( + string $str1, + string $str2, + int $insertionCost = 1, + int $replacementCost = 1, + int $deletionCost = 1 + ): int { + $result = ASCII::to_ascii_remap($str1, $str2); + + return \levenshtein($result[0], $result[1], $insertionCost, $replacementCost, $deletionCost); + } + + /** + * Strip whitespace or other characters from the beginning of a UTF-8 string. + * + * EXAMPLE:UTF8::ltrim(' 中文空白 '); // '中文空白 '
+ *
+ * @param string $str The string to be trimmed
+ * @param string|null $charsOptional characters to be stripped
+ * + * @psalm-pure + * + * @return string the string with unwanted characters stripped from the left + */ + public static function ltrim(string $str = '', string $chars = null): string + { + if ($str === '') { + return ''; + } + + if (self::$SUPPORT['mbstring'] === true) { + if ($chars !== null) { + /** @noinspection PregQuoteUsageInspection */ + $chars = \preg_quote($chars); + $pattern = "^[{$chars}]+"; + } else { + $pattern = '^[\\s]+'; + } + + return (string) \mb_ereg_replace($pattern, '', $str); + } + + if ($chars !== null) { + $chars = \preg_quote($chars, '/'); + $pattern = "^[{$chars}]+"; + } else { + $pattern = '^[\\s]+'; + } + + return self::regex_replace($str, $pattern, ''); + } + + /** + * Returns the UTF-8 character with the maximum code point in the given data. + * + * EXAMPLE:UTF8::max('abc-äöü-中文空白'); // 'ø'
+ *
+ * @param string|string[] $arg A UTF-8 encoded string or an array of such strings.
+ * + * @psalm-pure + * + * @return string|null the character with the highest code point than others, returns null on failure or empty input + */ + public static function max($arg) + { + if (\is_array($arg)) { + $arg = \implode('', $arg); + } + + $codepoints = self::codepoints($arg); + if ($codepoints === []) { + return null; + } + + $codepoint_max = \max($codepoints); + + return self::chr((int) $codepoint_max); + } + + /** + * Calculates and returns the maximum number of bytes taken by any + * UTF-8 encoded character in the given string. + * + * EXAMPLE:UTF8::max_chr_width('Intërnâtiônàlizætiøn'); // 2
+ *
+ * @param string $str The original Unicode string.
+ * + * @psalm-pure + * + * @return int + *Max byte lengths of the given chars.
+ * + * @phpstan-return 0|1|2|3|4 + */ + public static function max_chr_width(string $str): int + { + $bytes = self::chr_size_list($str); + if ($bytes !== []) { + return (int) \max($bytes); + } + + return 0; + } + + /** + * Checks whether mbstring is available on the server. + * + * @psalm-pure + * + * @return bool + *true if available, false otherwise
+ * + * @internalPlease do not use it anymore, we will make is private in next major version.
+ */ + public static function mbstring_loaded(): bool + { + return \extension_loaded('mbstring'); + } + + /** + * Returns the UTF-8 character with the minimum code point in the given data. + * + * EXAMPLE:UTF8::min('abc-äöü-中文空白'); // '-'
+ *
+ * @param string|string[] $arg A UTF-8 encoded string or an array of such strings.
+ *
+ * @psalm-pure
+ *
+ * @return string|null
+ * The character with the lowest code point than others, returns null on failure or empty input.
+ */ + public static function min($arg) + { + if (\is_array($arg)) { + $arg = \implode('', $arg); + } + + $codepoints = self::codepoints($arg); + if ($codepoints === []) { + return null; + } + + $codepoint_min = \min($codepoints); + + return self::chr((int) $codepoint_min); + } + + /** + * Normalize the encoding-"name" input. + * + * EXAMPLE:UTF8::normalize_encoding('UTF8'); // 'UTF-8'
+ *
+ * @param mixed $encoding e.g.: ISO, UTF8, WINDOWS-1251 etc.
+ * @param mixed $fallbacke.g.: UTF-8
+ * + * @psalm-pure + * + * @return mixed|string + *e.g.: ISO-8859-1, UTF-8, WINDOWS-1251 etc.
Will return a empty string as fallback (by default)
The input string.
+ * @param string|string[] $replacerThe replacer char e.g. "\n" (Linux) or "\r\n" (Windows). You can also use \PHP_EOL + * here.
+ * + * @psalm-pure + * + * @return string + *A string with normalized line ending.
+ */ + public static function normalize_line_ending(string $str, $replacer = "\n"): string + { + return \str_replace(["\r\n", "\r", "\n"], $replacer, $str); + } + + /** + * Normalize some MS Word special characters. + * + * EXAMPLE:UTF8::normalize_msword('„Abcdef…”'); // '"Abcdef..."'
+ *
+ * @param string $str The string to be normalized.
+ * + * @psalm-pure + * + * @return string + *A string with normalized characters for commonly used chars in Word documents.
+ */ + public static function normalize_msword(string $str): string + { + return ASCII::normalize_msword($str); + } + + /** + * Normalize the whitespace. + * + * EXAMPLE:UTF8::normalize_whitespace("abc-\xc2\xa0-öäü-\xe2\x80\xaf-\xE2\x80\xAC", true); // "abc-\xc2\xa0-öäü- -"
+ *
+ * @param string $str The string to be normalized.
+ * @param bool $keep_non_breaking_space [optional]Set to true, to keep non-breaking-spaces.
+ * @param bool $keep_bidi_unicode_controls [optional]Set to true, to keep non-printable (for the web) + * bidirectional text chars.
+ * @param bool $normalize_control_characters [optional]Set to true, to convert e.g. LINE-, PARAGRAPH-SEPARATOR with "\n" and LINE TABULATION with "\t".
+ * + * @psalm-pure + * + * @return string + *A string with normalized whitespace.
+ */ + public static function normalize_whitespace( + string $str, + bool $keep_non_breaking_space = false, + bool $keep_bidi_unicode_controls = false, + bool $normalize_control_characters = false + ): string { + return ASCII::normalize_whitespace( + $str, + $keep_non_breaking_space, + $keep_bidi_unicode_controls, + $normalize_control_characters + ); + } + + /** + * Calculates Unicode code point of the given UTF-8 encoded character. + * + * INFO: opposite to UTF8::chr() + * + * EXAMPLE:UTF8::ord('☃'); // 0x2603
+ *
+ * @param string $chr The character of which to calculate code point.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return int + *Unicode code point of the given character,
+ * 0 on invalid UTF-8 byte sequence
+ * UTF8::parse_str('Iñtërnâtiônéàlizætiøn=測試&arr[]=foo+測試&arr[]=ການທົດສອບ', $array);
+ * echo $array['Iñtërnâtiônéàlizætiøn']; // '測試'
+ *
+ *
+ * @see http://php.net/manual/en/function.parse-str.php
+ *
+ * @param string $str The input string.
+ * @param arrayThe result will be returned into this reference parameter.
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * + * @psalm-pure + * + * @return bool + *Will return false if php can't parse the string and we haven't any $result.
+ */ + public static function parse_str(string $str, &$result, bool $clean_utf8 = false): bool + { + if ($clean_utf8) { + $str = self::clean($str); + } + + if (self::$SUPPORT['mbstring'] === true) { + $return = \mb_parse_str($str, $result); + + return $return !== false && $result !== []; + } + + /** + * @psalm-suppress ImpureFunctionCall - we use the second parameter, so we don't change variables by magic + */ + \parse_str($str, $result); + + return $result !== []; + } + + /** + * Checks if \u modifier is available that enables Unicode support in PCRE. + * + * @psalm-pure + * + * @return bool + *
+ * true if support is available,
+ * false otherwise
+ *
UTF8::range('κ', 'ζ'); // array('κ', 'ι', 'θ', 'η', 'ζ',)
+ *
+ * @param int|string $var1 Numeric or hexadecimal code points, or a UTF-8 character to start from.
+ * @param int|string $var2Numeric or hexadecimal code points, or a UTF-8 character to end at.
+ * @param bool $use_ctypeuse ctype to detect numeric and hexadecimal, otherwise we will use a simple + * "is_numeric"
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * @param float|int $step [optional]+ * If a step value is given, it will be used as the + * increment between elements in the sequence. step + * should be given as a positive number. If not specified, + * step will default to 1. + *
+ * + * @psalm-pure + * + * @return list$array['foo'][123] = 'lall'; UTF8::getUrlParamFromArray('foo[123]', $array); // 'lall'
+ *
+ * @param arrayUTF8::rawurldecode('tes%20öäü%20\u00edtest+test'); // 'tes öäü ítest+test'
+ *
+ * e.g:
+ * 'test+test' => 'test+test'
+ * 'Düsseldorf' => 'Düsseldorf'
+ * 'D%FCsseldorf' => 'Düsseldorf'
+ * 'Düsseldorf' => 'Düsseldorf'
+ * 'D%26%23xFC%3Bsseldorf' => 'Düsseldorf'
+ * 'Düsseldorf' => 'Düsseldorf'
+ * 'D%C3%BCsseldorf' => 'Düsseldorf'
+ * 'D%C3%83%C2%BCsseldorf' => 'Düsseldorf'
+ * 'D%25C3%2583%25C2%25BCsseldorf' => 'Düsseldorf'
+ *
+ * @param string $str The input string.
+ * @param bool $multi_decodeDecode as often as possible.
+ * + * @psalm-pure + * + * @return string + *The decoded URL, as a string.
+ * + * @template T as string + * @phpstan-param T $str + * @phpstan-return (T is non-empty-string ? non-empty-string : string) + */ + public static function rawurldecode(string $str, bool $multi_decode = true): string + { + if ($str === '') { + return ''; + } + + $str = self::urldecode_unicode_helper($str); + + if ($multi_decode) { + do { + $str_compare = $str; + + /** + * @psalm-suppress PossiblyInvalidArgument + */ + $str = \rawurldecode( + self::html_entity_decode( + self::to_utf8($str), + \ENT_QUOTES | \ENT_HTML5 + ) + ); + } while ($str_compare !== $str); + } else { + /** + * @psalm-suppress PossiblyInvalidArgument + */ + $str = \rawurldecode( + self::html_entity_decode( + self::to_utf8($str), + \ENT_QUOTES | \ENT_HTML5 + ) + ); + } + + return self::fix_simple_utf8($str); + } + + /** + * Replaces all occurrences of $pattern in $str by $replacement. + * + * @param string $strThe input string.
+ * @param string $patternThe regular expression pattern.
+ * @param string $replacementThe string to replace with.
+ * @param string $options [optional]Matching conditions to be used.
+ * @param string $delimiter [optional]Delimiter the the regex. Default: '/'
+ * + * @psalm-pure + * + * @return string + */ + public static function regex_replace( + string $str, + string $pattern, + string $replacement, + string $options = '', + string $delimiter = '/' + ): string { + if ($options === 'msr') { + $options = 'ms'; + } + + // fallback + if (!$delimiter) { + $delimiter = '/'; + } + + return (string) \preg_replace( + $delimiter . $pattern . $delimiter . 'u' . $options, + $replacement, + $str + ); + } + + /** + * Remove the BOM from UTF-8 / UTF-16 / UTF-32 strings. + * + * EXAMPLE:UTF8::remove_bom("\xEF\xBB\xBFΜπορώ να"); // 'Μπορώ να'
+ *
+ * @param string $str The input string.
+ * + * @psalm-pure + * + * @return string + *A string without UTF-BOM.
+ */ + public static function remove_bom(string $str): string + { + if ($str === '') { + return ''; + } + + $str_length = \strlen($str); + foreach (self::$BOM as $bom_string => $bom_byte_length) { + if (\strncmp($str, $bom_string, $bom_byte_length) === 0) { + /** @var false|string $str_tmp - needed for PhpStan (stubs error) */ + $str_tmp = \substr($str, $bom_byte_length, $str_length); + if ($str_tmp === false) { + return ''; + } + + $str_length -= $bom_byte_length; + + $str = (string) $str_tmp; + } + } + + return $str; + } + + /** + * Removes duplicate occurrences of a string in another string. + * + * EXAMPLE:UTF8::remove_duplicates('öäü-κόσμεκόσμε-äöü', 'κόσμε'); // 'öäü-κόσμε-äöü'
+ *
+ * @param string $str The base string.
+ * @param string|string[] $whatString to search for in the base string.
+ * + * @psalm-pure + * + * @return string + *A string with removed duplicates.
+ */ + public static function remove_duplicates(string $str, $what = ' '): string + { + if (\is_string($what)) { + $what = [$what]; + } + + /** + * @psalm-suppress RedundantConditionGivenDocblockType + * @phpstan-ignore-next-line | ignore wrong inputs + */ + if (\is_array($what)) { + foreach ($what as $item) { + $str = (string) \preg_replace('/(' . \preg_quote($item, '/') . ')+/u', $item, $str); + } + } + + return $str; + } + + /** + * Remove html via "strip_tags()" from the string. + * + * @param string $strThe input string.
+ * @param string $allowable_tags [optional]You can use the optional second parameter to specify tags which + * should not be stripped. Default: null + *
+ * + * @psalm-pure + * + * @return string + *A string with without html tags.
+ */ + public static function remove_html(string $str, string $allowable_tags = ''): string + { + return \strip_tags($str, $allowable_tags); + } + + /** + * Remove all breaks [The input string.
+ * @param string $replacement [optional]Default is a empty string.
+ * + * @psalm-pure + * + * @return string + *A string without breaks.
+ */ + public static function remove_html_breaks(string $str, string $replacement = ''): string + { + return (string) \preg_replace("#/\r\n|\r|\n|UTF8::remove_invisible_characters("κόσ\0με"); // 'κόσμε'
+ *
+ * copy&past from https://github.com/bcit-ci/CodeIgniter/blob/develop/system/core/Common.php
+ *
+ * @param string $str The input string.
+ * @param bool $url_encoded [optional]
+ * Try to remove url encoded control character.
+ * WARNING: maybe contains false-positives e.g. aa%0Baa -> aaaa.
+ *
+ * Default: false
+ *
The replacement character.
+ * @param bool $keep_basic_control_characters [optional]Keep control characters like [LRM] or [LSEP].
+ * + * @psalm-pure + * + * @return string + *A string without invisible chars.
+ */ + public static function remove_invisible_characters( + string $str, + bool $url_encoded = false, + string $replacement = '', + bool $keep_basic_control_characters = true + ): string { + return ASCII::remove_invisible_characters( + $str, + $url_encoded, + $replacement, + $keep_basic_control_characters + ); + } + + /** + * Returns a new string with the prefix $substring removed, if present. + * + * @param string $strThe input string.
+ * @param string $substringThe prefix to remove.
+ * @param string $encoding [optional]Default: 'UTF-8'
+ * + * @psalm-pure + * + * @return string + *A string without the prefix $substring.
+ */ + public static function remove_left( + string $str, + string $substring, + string $encoding = 'UTF-8' + ): string { + if ( + $substring + && + \strpos($str, $substring) === 0 + ) { + if ($encoding === 'UTF-8') { + return (string) \mb_substr( + $str, + (int) \mb_strlen($substring) + ); + } + + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + + return (string) self::substr( + $str, + (int) self::strlen($substring, $encoding), + null, + $encoding + ); + } + + return $str; + } + + /** + * Returns a new string with the suffix $substring removed, if present. + * + * @param string $str + * @param string $substringThe suffix to remove.
+ * @param string $encoding [optional]Default: 'UTF-8'
+ * + * @psalm-pure + * + * @return string + *A string having a $str without the suffix $substring.
+ */ + public static function remove_right( + string $str, + string $substring, + string $encoding = 'UTF-8' + ): string { + if ($substring && \substr($str, -\strlen($substring)) === $substring) { + if ($encoding === 'UTF-8') { + return (string) \mb_substr( + $str, + 0, + (int) \mb_strlen($str) - (int) \mb_strlen($substring) + ); + } + + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + + return (string) self::substr( + $str, + 0, + (int) self::strlen($str, $encoding) - (int) self::strlen($substring, $encoding), + $encoding + ); + } + + return $str; + } + + /** + * Returns a new string with the suffix $substring removed, if present and case-insensitive. + * + * @param string $str + * @param string $substringThe suffix to remove.
+ * @param string $encoding [optional]Default: 'UTF-8'
+ * + * @psalm-pure + * + * @return string + *A string having a $str without the suffix $substring.
+ */ + public static function remove_iright( + string $str, + string $substring, + string $encoding = 'UTF-8' + ): string { + if ($substring && self::strtoupper(\substr($str, -\strlen($substring)), $encoding) === self::strtoupper($substring, $encoding)) { + if ($encoding === 'UTF-8') { + return (string) \mb_substr( + $str, + 0, + (int) \mb_strlen($str) - (int) \mb_strlen($substring) + ); + } + + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + + return (string) self::substr( + $str, + 0, + (int) self::strlen($str, $encoding) - (int) self::strlen($substring, $encoding), + $encoding + ); + } + + return $str; + } + + /** + * Returns a new string with the prefix $substring removed, if present and case-insensitive. + * + * @param string $strThe input string.
+ * @param string $substringThe prefix to remove.
+ * @param string $encoding [optional]Default: 'UTF-8'
+ * + * @psalm-pure + * + * @return string + *A string without the prefix $substring.
+ */ + public static function remove_ileft( + string $str, + string $substring, + string $encoding = 'UTF-8' + ): string { + if ( + $substring + && + \strpos(self::strtoupper($str, $encoding), self::strtoupper($substring, $encoding)) === 0 + ) { + if ($encoding === 'UTF-8') { + return (string) \mb_substr( + $str, + (int) \mb_strlen($substring) + ); + } + + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + + return (string) self::substr( + $str, + (int) self::strlen($substring, $encoding), + null, + $encoding + ); + } + + return $str; + } + + /** + * Replaces all occurrences of $search in $str by $replacement. + * + * @param string $strThe input string.
+ * @param string $searchThe needle to search for.
+ * @param string $replacementThe string to replace with.
+ * @param bool $case_sensitive [optional]Whether or not to enforce case-sensitivity. Default: true
+ * + * @psalm-pure + * + * @return string + *A string with replaced parts.
+ */ + public static function replace( + string $str, + string $search, + string $replacement, + bool $case_sensitive = true + ): string { + if ($case_sensitive) { + return \str_replace($search, $replacement, $str); + } + + return self::str_ireplace($search, $replacement, $str); + } + + /** + * Replaces all occurrences of $search in $str by $replacement. + * + * @param string $strThe input string.
+ * @param string[] $searchThe elements to search for.
+ * @param string|string[] $replacementThe string to replace with.
+ * @param bool $case_sensitive [optional]Whether or not to enforce case-sensitivity. Default: true
+ * + * @psalm-pure + * + * @return string + *A string with replaced parts.
+ */ + public static function replace_all( + string $str, + array $search, + $replacement, + bool $case_sensitive = true + ): string { + if ($case_sensitive) { + return \str_replace($search, $replacement, $str); + } + + return self::str_ireplace($search, $replacement, $str); + } + + /** + * Replace the diamond question mark (�) and invalid-UTF8 chars with the replacement. + * + * EXAMPLE:UTF8::replace_diamond_question_mark('中文空白�', ''); // '中文空白'
+ *
+ * @param string $str The input string
+ * @param string $replacement_charThe replacement character.
+ * @param bool $process_invalid_utf8_charsConvert invalid UTF-8 chars
+ * + * @psalm-pure + * + * @return string + *A string without diamond question marks (�).
+ */ + public static function replace_diamond_question_mark( + string $str, + string $replacement_char = '', + bool $process_invalid_utf8_chars = true + ): string { + if ($str === '') { + return ''; + } + + if ($process_invalid_utf8_chars) { + if ($replacement_char === '') { + $replacement_char_helper = 'none'; + } else { + $replacement_char_helper = \ord($replacement_char); + } + + if (self::$SUPPORT['mbstring'] === false) { + // if there is no native support for "mbstring", + // then we need to clean the string before ... + $str = self::clean($str); + } + + /** + * @psalm-suppress ImpureFunctionCall - we will reset the value in the next step + */ + $save = \mb_substitute_character(); + /** @noinspection PhpUsageOfSilenceOperatorInspection - ignore "Unknown character" warnings, it's working anyway */ + @\mb_substitute_character($replacement_char_helper); + // the polyfill maybe return false, so cast to string + $str = (string) \mb_convert_encoding($str, 'UTF-8', 'UTF-8'); + \mb_substitute_character($save); + } + + return \str_replace( + [ + "\xEF\xBF\xBD", + '�', + ], + [ + $replacement_char, + $replacement_char, + ], + $str + ); + } + + /** + * Strip whitespace or other characters from the end of a UTF-8 string. + * + * EXAMPLE:UTF8::rtrim('-ABC-中文空白- '); // '-ABC-中文空白-'
+ *
+ * @param string $str The string to be trimmed.
+ * @param string|null $charsOptional characters to be stripped.
+ * + * @psalm-pure + * + * @return string + *A string with unwanted characters stripped from the right.
+ */ + public static function rtrim(string $str = '', string $chars = null): string + { + if ($str === '') { + return ''; + } + + if (self::$SUPPORT['mbstring'] === true) { + if ($chars !== null) { + /** @noinspection PregQuoteUsageInspection */ + $chars = \preg_quote($chars); + $pattern = "[{$chars}]+$"; + } else { + $pattern = '[\\s]+$'; + } + + return (string) \mb_ereg_replace($pattern, '', $str); + } + + if ($chars !== null) { + $chars = \preg_quote($chars, '/'); + $pattern = "[{$chars}]+$"; + } else { + $pattern = '[\\s]+$'; + } + + return self::regex_replace($str, $pattern, ''); + } + + /** + * WARNING: Print native UTF-8 support (libs) by default, e.g. for debugging. + * + * @param bool $useEcho + * + * @psalm-pure + * + * @return string|void + * + * @phpstan-return ($useEcho is true ? void : string) + */ + public static function showSupport(bool $useEcho = true) + { + // init + $html = ''; + + $html .= ''; + foreach (self::$SUPPORT as $key => &$value) { + $html .= $key . ' - ' . \print_r($value, true) . "\n'; + + if ($useEcho) { + echo $html; + } + + return $html; + } + + /** + * Converts a UTF-8 character to HTML Numbered Entity like "{". + * + * EXAMPLE:
"; + } + $html .= '
UTF8::single_chr_html_encode('κ'); // 'κ'
+ *
+ * @param string $char The Unicode character to be encoded as numbered entity.
+ * @param bool $keep_ascii_charsSet to true to keep ASCII chars.> + * @param string $encoding [optional]
Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return string + *The HTML numbered entity for the given character.
+ * + * @template T as string + * @phpstan-param T $char + * @phpstan-return (T is non-empty-string ? non-empty-string : string) + */ + public static function single_chr_html_encode( + string $char, + bool $keep_ascii_chars = false, + string $encoding = 'UTF-8' + ): string { + if ($char === '') { + return ''; + } + + if ( + $keep_ascii_chars + && + ASCII::is_ascii($char) + ) { + return $char; + } + + return '' . self::ord($char, $encoding) . ';'; + } + + /** + * @param string $str + * @param int<1, max> $tab_length + * + * @psalm-pure + * + * @return string + * + * @template T as string + * @phpstan-param T $str + * @phpstan-return (T is non-empty-string ? non-empty-string : string) + */ + public static function spaces_to_tabs(string $str, int $tab_length = 4): string + { + if ($tab_length === 4) { + $tab = ' '; + } elseif ($tab_length === 2) { + $tab = ' '; + } else { + $tab = \str_repeat(' ', $tab_length); + } + + return \str_replace($tab, "\t", $str); + } + + /** + * Returns a camelCase version of the string. Trims surrounding spaces, + * capitalizes letters following digits, spaces, dashes and underscores, + * and removes spaces, dashes, as well as underscores. + * + * @param string $strThe input string.
+ * @param string $encoding [optional]Default: 'UTF-8'
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * @param string|null $lang [optional]Set the language for special cases: az, el, lt, + * tr
+ * @param bool $try_to_keep_the_string_length [optional]true === try to keep the string length: e.g. ẞ + * -> ß
+ * + * @psalm-pure + * + * @return string + */ + public static function str_camelize( + string $str, + string $encoding = 'UTF-8', + bool $clean_utf8 = false, + string $lang = null, + bool $try_to_keep_the_string_length = false + ): string { + if ($clean_utf8) { + $str = self::clean($str); + } + + if ($encoding !== 'UTF-8' && $encoding !== 'CP850') { + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + } + + $str = self::lcfirst( + \trim($str), + $encoding, + false, + $lang, + $try_to_keep_the_string_length + ); + $str = (string) \preg_replace('/^[-_]+/', '', $str); + + $use_mb_functions = $lang === null && !$try_to_keep_the_string_length; + + $str = (string) \preg_replace_callback( + '/[-_\\s]+(.)?/u', + /** + * @param array $match + * + * @psalm-pure + * + * @return string + */ + static function (array $match) use ($use_mb_functions, $encoding, $lang, $try_to_keep_the_string_length): string { + if (isset($match[1])) { + if ($use_mb_functions) { + if ($encoding === 'UTF-8') { + return \mb_strtoupper($match[1]); + } + + return \mb_strtoupper($match[1], $encoding); + } + + return self::strtoupper($match[1], $encoding, false, $lang, $try_to_keep_the_string_length); + } + + return ''; + }, + $str + ); + + return (string) \preg_replace_callback( + '/[\\p{N}]+(.)?/u', + /** + * @param array $match + * + * @psalm-pure + * + * @return string + */ + static function (array $match) use ($use_mb_functions, $encoding, $clean_utf8, $lang, $try_to_keep_the_string_length): string { + if ($use_mb_functions) { + if ($encoding === 'UTF-8') { + return \mb_strtoupper($match[0]); + } + + return \mb_strtoupper($match[0], $encoding); + } + + return self::strtoupper($match[0], $encoding, $clean_utf8, $lang, $try_to_keep_the_string_length); + }, + $str + ); + } + + /** + * Returns the string with the first letter of each word capitalized, + * except for when the word is a name which shouldn't be capitalized. + * + * @param string $str + * + * @psalm-pure + * + * @return string + *A string with $str capitalized.
+ */ + public static function str_capitalize_name(string $str): string + { + return self::str_capitalize_name_helper( + self::str_capitalize_name_helper( + self::collapse_whitespace($str), + ' ' + ), + '-' + ); + } + + /** + * Returns true if the string contains $needle, false otherwise. By default + * the comparison is case-sensitive, but can be made insensitive by setting + * $case_sensitive to false. + * + * @param string $haystackThe input string.
+ * @param string $needleSubstring to look for.
+ * @param bool $case_sensitive [optional]Whether or not to enforce case-sensitivity. Default: true
+ * + * @psalm-pure + * + * @return bool + *Whether or not $haystack contains $needle.
+ */ + public static function str_contains( + string $haystack, + string $needle, + bool $case_sensitive = true + ): bool { + if ($case_sensitive) { + if (\PHP_VERSION_ID >= 80000) { + /** @phpstan-ignore-next-line - only for PHP8 */ + return \str_contains($haystack, $needle); + } + + return \strpos($haystack, $needle) !== false; + } + + return \mb_stripos($haystack, $needle) !== false; + } + + /** + * Returns true if the string contains all $needles, false otherwise. By + * default, the comparison is case-sensitive, but can be made insensitive by + * setting $case_sensitive to false. + * + * @param string $haystackThe input string.
+ * @param scalar[] $needlesSubStrings to look for.
+ * @param bool $case_sensitive [optional]Whether or not to enforce case-sensitivity. Default: true
+ * + * @psalm-pure + * + * @return bool + *Whether or not $haystack contains $needle.
+ */ + public static function str_contains_all( + string $haystack, + array $needles, + bool $case_sensitive = true + ): bool { + if ($haystack === '' || $needles === []) { + return false; + } + + foreach ($needles as &$needle) { + if ( + $case_sensitive + && + (!$needle || \strpos($haystack, (string)$needle) === false) + ) { + return false; + } + + if (!$needle || \mb_stripos($haystack, (string) $needle) === false) { + return false; + } + } + + return true; + } + + /** + * Returns true if the string contains any $needles, false otherwise. By + * default the comparison is case-sensitive, but can be made insensitive by + * setting $case_sensitive to false. + * + * @param string $haystackThe input string.
+ * @param scalar[] $needlesSubStrings to look for.
+ * @param bool $case_sensitive [optional]Whether or not to enforce case-sensitivity. Default: true
+ * + * @psalm-pure + * + * @return bool + *Whether or not $str contains $needle.
+ */ + public static function str_contains_any( + string $haystack, + array $needles, + bool $case_sensitive = true + ): bool { + if ($haystack === '' || $needles === []) { + return false; + } + + foreach ($needles as &$needle) { + if (!$needle) { + continue; + } + + if ($case_sensitive) { + if (\strpos($haystack, (string) $needle) !== false) { + return true; + } + + continue; + } + + if (\mb_stripos($haystack, (string) $needle) !== false) { + return true; + } + } + + return false; + } + + /** + * Returns a lowercase and trimmed string separated by dashes. Dashes are + * inserted before uppercase characters (with the exception of the first + * character of the string), and in place of spaces as well as underscores. + * + * @param string $strThe input string.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return string + */ + public static function str_dasherize(string $str, string $encoding = 'UTF-8'): string + { + return self::str_delimit($str, '-', $encoding); + } + + /** + * Returns a lowercase and trimmed string separated by the given delimiter. + * + * Delimiters are inserted before uppercase characters (with the exception + * of the first character of the string), and in place of spaces, dashes, + * and underscores. Alpha delimiters are not converted to lowercase. + * + * EXAMPLE:
+ * UTF8::str_delimit('test case, '#'); // 'test#case'
+ * UTF8::str_delimit('test -case', '**'); // 'test**case'
+ *
+ *
+ * @param string $str The input string.
+ * @param string $delimiterSequence used to separate parts of the string.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * @param string|null $lang [optional]Set the language for special cases: az, el, lt, + * tr
+ * @param bool $try_to_keep_the_string_length [optional]true === try to keep the string length: e.g. ẞ -> + * ß
+ * + * @psalm-pure + * + * @return string + * + * @template T as string + * @phpstan-param T $str + * @phpstan-return (T is non-empty-string ? non-empty-string : string) + */ + public static function str_delimit( + string $str, + string $delimiter, + string $encoding = 'UTF-8', + bool $clean_utf8 = false, + string $lang = null, + bool $try_to_keep_the_string_length = false + ): string { + if (self::$SUPPORT['mbstring'] === true) { + $str = (string) \mb_ereg_replace('\\B(\\p{Lu})', '-\1', \trim($str)); + + $use_mb_functions = $lang === null && !$try_to_keep_the_string_length; + if ($use_mb_functions && $encoding === 'UTF-8') { + $str = \mb_strtolower($str); + } else { + $str = self::strtolower($str, $encoding, $clean_utf8, $lang, $try_to_keep_the_string_length); + } + + return (string) \mb_ereg_replace('[\\-_\\s]+', $delimiter, $str); + } + + $str = (string) \preg_replace('/\\B(\\p{Lu})/u', '-\1', \trim($str)); + + $use_mb_functions = $lang === null && !$try_to_keep_the_string_length; + if ($use_mb_functions && $encoding === 'UTF-8') { + $str = \mb_strtolower($str); + } else { + $str = self::strtolower($str, $encoding, $clean_utf8, $lang, $try_to_keep_the_string_length); + } + + return (string) \preg_replace('/[\\-_\\s]+/u', $delimiter, $str); + } + + /** + * Optimized "mb_detect_encoding()"-function -> with support for UTF-16 and UTF-32. + * + * EXAMPLE:
+ * UTF8::str_detect_encoding('中文空白'); // 'UTF-8'
+ * UTF8::str_detect_encoding('Abc'); // 'ASCII'
+ *
+ *
+ * @param string $str The input string.
+ * + * @psalm-pure + * + * @return false|string + *
+ * The detected string-encoding e.g. UTF-8 or UTF-16BE,
+ * otherwise it will return false e.g. for BINARY or not detected encoding.
+ *
+ * UTF8::str_ends_with('BeginMiddleΚόσμε', 'Κόσμε'); // true
+ * UTF8::str_ends_with('BeginMiddleΚόσμε', 'κόσμε'); // false
+ *
+ *
+ * @param string $haystack The string to search in.
+ * @param string $needleThe substring to search for.
+ * + * @psalm-pure + * + * @return bool + */ + public static function str_ends_with(string $haystack, string $needle): bool + { + if ($needle === '') { + return true; + } + + if ($haystack === '') { + return false; + } + + if (\PHP_VERSION_ID >= 80000) { + /** @phpstan-ignore-next-line - only for PHP8 */ + return \str_ends_with($haystack, $needle); + } + + return \substr($haystack, -\strlen($needle)) === $needle; + } + + /** + * Returns true if the string ends with any of $substrings, false otherwise. + * + * - case-sensitive + * + * @param string $strThe input string.
+ * @param string[] $substringsSubstrings to look for.
+ * + * @psalm-pure + * + * @return bool + *Whether or not $str ends with $substring.
+ */ + public static function str_ends_with_any(string $str, array $substrings): bool + { + if ($substrings === []) { + return false; + } + + foreach ($substrings as &$substring) { + if (\substr($str, -\strlen($substring)) === $substring) { + return true; + } + } + + return false; + } + + /** + * Ensures that the string begins with $substring. If it doesn't, it's + * prepended. + * + * @param string $strThe input string.
+ * @param string $substringThe substring to add if not present.
+ * + * @psalm-pure + * + * @template T as string + * @template TSub as string + * @phpstan-param T $str + * @phpstan-param TSub $substring + * @phpstan-return (TSub is non-empty-string ? non-empty-string : (T is non-empty-string ? non-empty-string : string)) + */ + public static function str_ensure_left(string $str, string $substring): string + { + if ( + $substring !== '' + && + \strpos($str, $substring) === 0 + ) { + return $str; + } + + return $substring . $str; + } + + /** + * Ensures that the string ends with $substring. If it doesn't, it's appended. + * + * @param string $strThe input string.
+ * @param string $substringThe substring to add if not present.
+ * + * @psalm-pure + * + * @return string + * + * @template T as string + * @template TSub as string + * @phpstan-param T $str + * @phpstan-param TSub $substring + * @phpstan-return (TSub is non-empty-string ? non-empty-string : (T is non-empty-string ? non-empty-string : string)) + */ + public static function str_ensure_right(string $str, string $substring): string + { + if ( + $str === '' + || + $substring === '' + || + \substr($str, -\strlen($substring)) !== $substring + ) { + $str .= $substring; + } + + return $str; + } + + /** + * Capitalizes the first word of the string, replaces underscores with + * spaces, and strips '_id'. + * + * @param string $str + * + * @psalm-pure + * + * @return string + */ + public static function str_humanize($str): string + { + $str = \str_replace( + [ + '_id', + '_', + ], + [ + '', + ' ', + ], + $str + ); + + return self::ucfirst(\trim($str)); + } + + /** + * Check if the string ends with the given substring, case-insensitive. + * + * EXAMPLE:
+ * UTF8::str_iends_with('BeginMiddleΚόσμε', 'Κόσμε'); // true
+ * UTF8::str_iends_with('BeginMiddleΚόσμε', 'κόσμε'); // true
+ *
+ *
+ * @param string $haystack The string to search in.
+ * @param string $needleThe substring to search for.
+ * + * @psalm-pure + * + * @return bool + */ + public static function str_iends_with(string $haystack, string $needle): bool + { + if ($needle === '') { + return true; + } + + if ($haystack === '') { + return false; + } + + return self::strcasecmp(\substr($haystack, -\strlen($needle)), $needle) === 0; + } + + /** + * Returns true if the string ends with any of $substrings, false otherwise. + * + * - case-insensitive + * + * @param string $strThe input string.
+ * @param string[] $substringsSubstrings to look for.
+ * + * @psalm-pure + * + * @return bool + *Whether or not $str ends with $substring.
+ */ + public static function str_iends_with_any(string $str, array $substrings): bool + { + if ($substrings === []) { + return false; + } + + foreach ($substrings as &$substring) { + if (self::str_iends_with($str, $substring)) { + return true; + } + } + + return false; + } + + /** + * Inserts $substring into the string at the $index provided. + * + * @param string $strThe input string.
+ * @param string $substringString to be inserted.
+ * @param int $indexThe index at which to insert the substring.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return string + */ + public static function str_insert( + string $str, + string $substring, + int $index, + string $encoding = 'UTF-8' + ): string { + if ($encoding === 'UTF-8') { + $len = (int) \mb_strlen($str); + if ($index > $len) { + return $str; + } + + /** @noinspection UnnecessaryCastingInspection */ + return (string) \mb_substr($str, 0, $index) . + $substring . + (string) \mb_substr($str, $index, $len); + } + + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + + $len = (int) self::strlen($str, $encoding); + if ($index > $len) { + return $str; + } + + return ((string) self::substr($str, 0, $index, $encoding)) . + $substring . + ((string) self::substr($str, $index, $len, $encoding)); + } + + /** + * Case-insensitive and UTF-8 safe version of
+ * UTF8::str_ireplace('lIzÆ', 'lise', 'Iñtërnâtiônàlizætiøn'); // 'Iñtërnâtiônàlisetiøn'
+ *
+ *
+ * @see http://php.net/manual/en/function.str-ireplace.php
+ *
+ * @param string|string[] $search + * Every replacement with search array is + * performed on the result of previous replacement. + *
+ * @param string|string[] $replacementThe replacement.
+ * @param string|string[] $subject+ * If subject is an array, then the search and + * replace is performed with every entry of + * subject, and the return value is an array as + * well. + *
+ * @param int $count [optional]+ * The number of matched and replaced needles will + * be returned in count which is passed by + * reference. + *
+ * + * @psalm-pure + * + * @return string|string[] + *A string or an array of replacements.
+ * + * @template TStrIReplaceSubject + * @phpstan-param TStrIReplaceSubject $subject + * @phpstan-return TStrIReplaceSubject + */ + public static function str_ireplace($search, $replacement, $subject, &$count = null) + { + $search = (array) $search; + + /** @noinspection AlterInForeachInspection */ + foreach ($search as &$s) { + $s = (string) $s; + if ($s === '') { + $s = '/^(?<=.)$/'; + } else { + $s = '/' . \preg_quote($s, '/') . '/ui'; + } + } + + // fallback + /** @phpstan-ignore-next-line - only a fallback for PHP8 */ + if ($replacement === null) { + $replacement = ''; + } + /** @phpstan-ignore-next-line - only a fallback for PHP8 */ + if ($subject === null) { + $subject = ''; + } + + /** + * @psalm-suppress PossiblyNullArgument + * @phpstan-var TStrIReplaceSubject $subject + */ + $subject = \preg_replace($search, $replacement, $subject, -1, $count); + + return $subject; + } + + /** + * Replaces $search from the beginning of string with $replacement. + * + * @param string $strThe input string.
+ * @param string $searchThe string to search for.
+ * @param string $replacementThe replacement.
+ * + * @psalm-pure + * + * @return string + *The string after the replacement.
+ */ + public static function str_ireplace_beginning(string $str, string $search, string $replacement): string + { + if ($str === '') { + if ($replacement === '') { + return ''; + } + + if ($search === '') { + return $replacement; + } + } + + if ($search === '') { + return $str . $replacement; + } + + $searchLength = \strlen($search); + if (\strncasecmp($str, $search, $searchLength) === 0) { + return $replacement . \substr($str, $searchLength); + } + + return $str; + } + + /** + * Replaces $search from the ending of string with $replacement. + * + * @param string $strThe input string.
+ * @param string $searchThe string to search for.
+ * @param string $replacementThe replacement.
+ * + * @psalm-pure + * + * @return string + *The string after the replacement.
+ */ + public static function str_ireplace_ending(string $str, string $search, string $replacement): string + { + if ($str === '') { + if ($replacement === '') { + return ''; + } + + if ($search === '') { + return $replacement; + } + } + + if ($search === '') { + return $str . $replacement; + } + + if (\stripos($str, $search, \strlen($str) - \strlen($search)) !== false) { + $str = \substr($str, 0, -\strlen($search)) . $replacement; + } + + return $str; + } + + /** + * Check if the string starts with the given substring, case-insensitive. + * + * EXAMPLE:
+ * UTF8::str_istarts_with('ΚόσμεMiddleEnd', 'Κόσμε'); // true
+ * UTF8::str_istarts_with('ΚόσμεMiddleEnd', 'κόσμε'); // true
+ *
+ *
+ * @param string $haystack The string to search in.
+ * @param string $needleThe substring to search for.
+ * + * @psalm-pure + * + * @return bool + */ + public static function str_istarts_with(string $haystack, string $needle): bool + { + if ($needle === '') { + return true; + } + + if ($haystack === '') { + return false; + } + + return self::stripos($haystack, $needle) === 0; + } + + /** + * Returns true if the string begins with any of $substrings, false otherwise. + * + * - case-insensitive + * + * @param string $strThe input string.
+ * @param scalar[] $substringsSubstrings to look for.
+ * + * @psalm-pure + * + * @return bool + *Whether or not $str starts with $substring.
+ */ + public static function str_istarts_with_any(string $str, array $substrings): bool + { + if ($str === '') { + return false; + } + + if ($substrings === []) { + return false; + } + + foreach ($substrings as &$substring) { + if (self::str_istarts_with($str, (string) $substring)) { + return true; + } + } + + return false; + } + + /** + * Gets the substring after the first occurrence of a separator. + * + * @param string $strThe input string.
+ * @param string $separatorThe string separator.
+ * @param string $encoding [optional]Default: 'UTF-8'
+ * + * @psalm-pure + * + * @return string + */ + public static function str_isubstr_after_first_separator( + string $str, + string $separator, + string $encoding = 'UTF-8' + ): string { + if ($separator === '' || $str === '') { + return ''; + } + + $offset = self::stripos($str, $separator); + if ($offset === false) { + return ''; + } + + if ($encoding === 'UTF-8') { + return (string) \mb_substr( + $str, + $offset + (int) \mb_strlen($separator) + ); + } + + return (string) self::substr( + $str, + $offset + (int) self::strlen($separator, $encoding), + null, + $encoding + ); + } + + /** + * Gets the substring after the last occurrence of a separator. + * + * @param string $strThe input string.
+ * @param string $separatorThe string separator.
+ * @param string $encoding [optional]Default: 'UTF-8'
+ * + * @psalm-pure + * + * @return string + */ + public static function str_isubstr_after_last_separator( + string $str, + string $separator, + string $encoding = 'UTF-8' + ): string { + if ($separator === '' || $str === '') { + return ''; + } + + $offset = self::strripos($str, $separator); + if ($offset === false) { + return ''; + } + + if ($encoding === 'UTF-8') { + return (string) \mb_substr( + $str, + $offset + (int) self::strlen($separator) + ); + } + + return (string) self::substr( + $str, + $offset + (int) self::strlen($separator, $encoding), + null, + $encoding + ); + } + + /** + * Gets the substring before the first occurrence of a separator. + * + * @param string $strThe input string.
+ * @param string $separatorThe string separator.
+ * @param string $encoding [optional]Default: 'UTF-8'
+ * + * @psalm-pure + * + * @return string + */ + public static function str_isubstr_before_first_separator( + string $str, + string $separator, + string $encoding = 'UTF-8' + ): string { + if ($separator === '' || $str === '') { + return ''; + } + + $offset = self::stripos($str, $separator); + if ($offset === false) { + return ''; + } + + if ($encoding === 'UTF-8') { + return (string) \mb_substr($str, 0, $offset); + } + + return (string) self::substr($str, 0, $offset, $encoding); + } + + /** + * Gets the substring before the last occurrence of a separator. + * + * @param string $strThe input string.
+ * @param string $separatorThe string separator.
+ * @param string $encoding [optional]Default: 'UTF-8'
+ * + * @psalm-pure + * + * @return string + */ + public static function str_isubstr_before_last_separator( + string $str, + string $separator, + string $encoding = 'UTF-8' + ): string { + if ($separator === '' || $str === '') { + return ''; + } + + if ($encoding === 'UTF-8') { + $offset = \mb_strripos($str, $separator); + if ($offset === false) { + return ''; + } + + return (string) \mb_substr($str, 0, $offset); + } + + $offset = self::strripos($str, $separator, 0, $encoding); + if ($offset === false) { + return ''; + } + + return (string) self::substr($str, 0, $offset, $encoding); + } + + /** + * Gets the substring after (or before via "$before_needle") the first occurrence of the "$needle". + * + * @param string $strThe input string.
+ * @param string $needleThe string to look for.
+ * @param bool $before_needle [optional]Default: false
+ * @param string $encoding [optional]Default: 'UTF-8'
+ * + * @psalm-pure + * + * @return string + */ + public static function str_isubstr_first( + string $str, + string $needle, + bool $before_needle = false, + string $encoding = 'UTF-8' + ): string { + if ( + $needle === '' + || + $str === '' + ) { + return ''; + } + + $part = self::stristr( + $str, + $needle, + $before_needle, + $encoding + ); + if ($part === false) { + return ''; + } + + return $part; + } + + /** + * Gets the substring after (or before via "$before_needle") the last occurrence of the "$needle". + * + * @param string $strThe input string.
+ * @param string $needleThe string to look for.
+ * @param bool $before_needle [optional]Default: false
+ * @param string $encoding [optional]Default: 'UTF-8'
+ * + * @psalm-pure + * + * @return string + */ + public static function str_isubstr_last( + string $str, + string $needle, + bool $before_needle = false, + string $encoding = 'UTF-8' + ): string { + if ( + $needle === '' + || + $str === '' + ) { + return ''; + } + + $part = self::strrichr( + $str, + $needle, + $before_needle, + $encoding + ); + if ($part === false) { + return ''; + } + + return $part; + } + + /** + * Returns the last $n characters of the string. + * + * @param string $strThe input string.
+ * @param int $nNumber of characters to retrieve from the end.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return string + */ + public static function str_last_char( + string $str, + int $n = 1, + string $encoding = 'UTF-8' + ): string { + if ($str === '' || $n <= 0) { + return ''; + } + + if ($encoding === 'UTF-8') { + return (string) \mb_substr($str, -$n); + } + + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + + return (string) self::substr($str, -$n, null, $encoding); + } + + /** + * Limit the number of characters in a string. + * + * @param string $strThe input string.
+ * @param int<1, max> $length [optional]Default: 100
+ * @param string $str_add_on [optional]Default: …
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return string + * + * @template T as string + * @phpstan-param T $str + * @phpstan-return (T is non-empty-string ? non-empty-string : string) + */ + public static function str_limit( + string $str, + int $length = 100, + string $str_add_on = '…', + string $encoding = 'UTF-8' + ): string { + if ( + $str === '' + || + /* @phpstan-ignore-next-line | we do not trust the phpdoc check */ + $length <= 0 + ) { + return ''; + } + + if ($encoding === 'UTF-8') { + if ((int) \mb_strlen($str) <= $length) { + return $str; + } + + /** @noinspection UnnecessaryCastingInspection */ + return (string) \mb_substr($str, 0, $length - (int) self::strlen($str_add_on)) . $str_add_on; + } + + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + + if ((int) self::strlen($str, $encoding) <= $length) { + return $str; + } + + return ((string) self::substr($str, 0, $length - (int) self::strlen($str_add_on), $encoding)) . $str_add_on; + } + + /** + * Limit the number of characters in a string in bytes. + * + * @param string $strThe input string.
+ * @param int<1, max> $length [optional]Default: 100
+ * @param string $str_add_on [optional]Default: ...
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return string + * + * @template T as string + * @phpstan-param T $str + * @phpstan-return (T is non-empty-string ? non-empty-string : string) + */ + public static function str_limit_in_byte( + string $str, + int $length = 100, + string $str_add_on = '...', + string $encoding = 'UTF-8' + ): string { + if ( + $str === '' + || + /* @phpstan-ignore-next-line | we do not trust the phpdoc check */ + $length <= 0 + ) { + return ''; + } + + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + + if ((int) self::strlen_in_byte($str, $encoding) <= $length) { + return $str; + } + + return ((string) self::substr_in_byte($str, 0, $length - (int) self::strlen_in_byte($str_add_on), $encoding)) . $str_add_on; + } + + /** + * Limit the number of characters in a string, but also after the next word. + * + * EXAMPLE:UTF8::str_limit_after_word('fòô bàř fòô', 8, ''); // 'fòô bàř'
+ *
+ * @param string $str The input string.
+ * @param int<1, max> $length [optional]Default: 100
+ * @param string $str_add_on [optional]Default: …
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return string + * + * @template T as string + * @phpstan-param T $str + * @phpstan-return (T is non-empty-string ? non-empty-string : string) + */ + public static function str_limit_after_word( + string $str, + int $length = 100, + string $str_add_on = '…', + string $encoding = 'UTF-8' + ): string { + if ( + $str === '' + || + /* @phpstan-ignore-next-line | we do not trust the phpdoc check */ + $length <= 0 + ) { + return ''; + } + + if ($encoding === 'UTF-8') { + if ((int) \mb_strlen($str) <= $length) { + return $str; + } + + if (\mb_substr($str, $length - 1, 1) === ' ') { + return ((string) \mb_substr($str, 0, $length - 1)) . $str_add_on; + } + + $str = \mb_substr($str, 0, $length); + + $array = \explode(' ', $str, -1); + $new_str = \implode(' ', $array); + + if ($new_str === '') { + return ((string) \mb_substr($str, 0, $length - 1)) . $str_add_on; + } + } else { + if ((int) self::strlen($str, $encoding) <= $length) { + return $str; + } + + if (self::substr($str, $length - 1, 1, $encoding) === ' ') { + return ((string) self::substr($str, 0, $length - 1, $encoding)) . $str_add_on; + } + + /** @noinspection CallableParameterUseCaseInTypeContextInspection - FP */ + $str = self::substr($str, 0, $length, $encoding); + if ($str === false) { + return '' . $str_add_on; + } + + $array = \explode(' ', $str, -1); + $new_str = \implode(' ', $array); + + if ($new_str === '') { + return ((string) self::substr($str, 0, $length - 1, $encoding)) . $str_add_on; + } + } + + return $new_str . $str_add_on; + } + + /** + * Returns the longest common prefix between the $str1 and $str2. + * + * @param string $str1The input sting.
+ * @param string $str2Second string for comparison.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return string + */ + public static function str_longest_common_prefix( + string $str1, + string $str2, + string $encoding = 'UTF-8' + ): string { + // init + $longest_common_prefix = ''; + + if ($encoding === 'UTF-8') { + $max_length = (int) \min( + \mb_strlen($str1), + \mb_strlen($str2) + ); + + for ($i = 0; $i < $max_length; ++$i) { + $char = \mb_substr($str1, $i, 1); + + if ( + $char !== false /* @phpstan-ignore-line | old polyfill will return false, or? */ + && + $char === \mb_substr($str2, $i, 1) + ) { + $longest_common_prefix .= $char; + } else { + break; + } + } + } else { + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + + $max_length = (int) \min( + self::strlen($str1, $encoding), + self::strlen($str2, $encoding) + ); + + for ($i = 0; $i < $max_length; ++$i) { + $char = self::substr($str1, $i, 1, $encoding); + + if ( + $char !== false + && + $char === self::substr($str2, $i, 1, $encoding) + ) { + $longest_common_prefix .= $char; + } else { + break; + } + } + } + + return $longest_common_prefix; + } + + /** + * Returns the longest common substring between the $str1 and $str2. + * In the case of ties, it returns that which occurs first. + * + * @param string $str1 + * @param string $str2Second string for comparison.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return string + *A string with its $str being the longest common substring.
+ */ + public static function str_longest_common_substring( + string $str1, + string $str2, + string $encoding = 'UTF-8' + ): string { + if ($str1 === '' || $str2 === '') { + return ''; + } + + // Uses dynamic programming to solve + // http://en.wikipedia.org/wiki/Longest_common_substring_problem + + if ($encoding === 'UTF-8') { + $str_length = (int) \mb_strlen($str1); + $other_length = (int) \mb_strlen($str2); + } else { + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + + $str_length = (int) self::strlen($str1, $encoding); + $other_length = (int) self::strlen($str2, $encoding); + } + + // Return if either string is empty + if ($str_length === 0 || $other_length === 0) { + return ''; + } + + $len = 0; + $end = 0; + $table = \array_fill( + 0, + $str_length + 1, + \array_fill(0, $other_length + 1, 0) + ); + + if ($encoding === 'UTF-8') { + for ($i = 1; $i <= $str_length; ++$i) { + for ($j = 1; $j <= $other_length; ++$j) { + $str_char = \mb_substr($str1, $i - 1, 1); + $other_char = \mb_substr($str2, $j - 1, 1); + + if ($str_char === $other_char) { + $table[$i][$j] = $table[$i - 1][$j - 1] + 1; + if ($table[$i][$j] > $len) { + $len = $table[$i][$j]; + $end = $i; + } + } else { + $table[$i][$j] = 0; + } + } + } + } else { + for ($i = 1; $i <= $str_length; ++$i) { + for ($j = 1; $j <= $other_length; ++$j) { + $str_char = self::substr($str1, $i - 1, 1, $encoding); + $other_char = self::substr($str2, $j - 1, 1, $encoding); + + if ($str_char === $other_char) { + $table[$i][$j] = $table[$i - 1][$j - 1] + 1; + if ($table[$i][$j] > $len) { + $len = $table[$i][$j]; + $end = $i; + } + } else { + $table[$i][$j] = 0; + } + } + } + } + + if ($encoding === 'UTF-8') { + return (string) \mb_substr($str1, $end - $len, $len); + } + + return (string) self::substr($str1, $end - $len, $len, $encoding); + } + + /** + * Returns the longest common suffix between the $str1 and $str2. + * + * @param string $str1 + * @param string $str2Second string for comparison.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return string + */ + public static function str_longest_common_suffix( + string $str1, + string $str2, + string $encoding = 'UTF-8' + ): string { + if ($str1 === '' || $str2 === '') { + return ''; + } + + if ($encoding === 'UTF-8') { + $max_length = (int) \min( + \mb_strlen($str1, $encoding), + \mb_strlen($str2, $encoding) + ); + + $longest_common_suffix = ''; + for ($i = 1; $i <= $max_length; ++$i) { + $char = \mb_substr($str1, -$i, 1); + + if ( + $char !== false /* @phpstan-ignore-line | old polyfill will return false, or? */ + && + $char === \mb_substr($str2, -$i, 1) + ) { + $longest_common_suffix = $char . $longest_common_suffix; + } else { + break; + } + } + } else { + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + + $max_length = (int) \min( + self::strlen($str1, $encoding), + self::strlen($str2, $encoding) + ); + + $longest_common_suffix = ''; + for ($i = 1; $i <= $max_length; ++$i) { + $char = self::substr($str1, -$i, 1, $encoding); + + if ( + $char !== false + && + $char === self::substr($str2, -$i, 1, $encoding) + ) { + $longest_common_suffix = $char . $longest_common_suffix; + } else { + break; + } + } + } + + return $longest_common_suffix; + } + + /** + * Returns true if $str matches the supplied pattern, false otherwise. + * + * @param string $strThe input string.
+ * @param string $patternRegex pattern to match against.
+ * + * @psalm-pure + * + * @return bool + *Whether or not $str matches the pattern.
+ */ + public static function str_matches_pattern(string $str, string $pattern): bool + { + return (bool) \preg_match('/' . $pattern . '/u', $str); + } + + /** + * Returns whether or not a character exists at an index. Offsets may be + * negative to count from the last character in the string. Implements + * part of the ArrayAccess interface. + * + * @param string $strThe input string.
+ * @param int $offsetThe index to check.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return bool + *Whether or not the index exists.
+ */ + public static function str_offset_exists(string $str, int $offset, string $encoding = 'UTF-8'): bool + { + // init + $length = (int) self::strlen($str, $encoding); + + if ($offset >= 0) { + return $length > $offset; + } + + return $length >= \abs($offset); + } + + /** + * Returns the character at the given index. Offsets may be negative to + * count from the last character in the string. Implements part of the + * ArrayAccess interface, and throws an OutOfBoundsException if the index + * does not exist. + * + * @param string $strThe input string.
+ * @param int<1, max> $indexThe index from which to retrieve the char.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @throws \OutOfBoundsException if the positive or negative offset does not exist + * + * @return string + *The character at the specified index.
+ * + * @psalm-pure + */ + public static function str_offset_get(string $str, int $index, string $encoding = 'UTF-8'): string + { + // init + $length = (int) self::strlen($str); + + if ( + /* @phpstan-ignore-next-line | we do not trust the phpdoc check */ + ($index >= 0 && $length <= $index) + || + $length < \abs($index) + ) { + throw new \OutOfBoundsException('No character exists at the index'); + } + + return self::char_at($str, $index, $encoding); + } + + /** + * Pad a UTF-8 string to a given length with another string. + * + * EXAMPLE:UTF8::str_pad('中文空白', 10, '_', STR_PAD_BOTH); // '___中文空白___'
+ *
+ * @param string $str The input string.
+ * @param int $pad_lengthThe length of return string.
+ * @param string $pad_string [optional]String to use for padding the input string.
+ * @param int|string $pad_type [optional]
+ * Can be STR_PAD_RIGHT (default), [or string "right"]
+ * STR_PAD_LEFT [or string "left"] or
+ * STR_PAD_BOTH [or string "both"]
+ *
Default: 'UTF-8'
+ * + * @psalm-pure + * + * @return string + *Returns the padded string.
+ */ + public static function str_pad( + string $str, + int $pad_length, + string $pad_string = ' ', + $pad_type = \STR_PAD_RIGHT, + string $encoding = 'UTF-8' + ): string { + if ($pad_length === 0 || $pad_string === '') { + return $str; + } + + if ($pad_type !== (int) $pad_type) { + if ($pad_type === 'left') { + $pad_type = \STR_PAD_LEFT; + } elseif ($pad_type === 'right') { + $pad_type = \STR_PAD_RIGHT; + } elseif ($pad_type === 'both') { + $pad_type = \STR_PAD_BOTH; + } else { + throw new \InvalidArgumentException( + 'Pad expects $pad_type to be "STR_PAD_*" or ' . "to be one of 'left', 'right' or 'both'" + ); + } + } + + if ($encoding === 'UTF-8') { + $str_length = (int) \mb_strlen($str); + + if ($pad_length >= $str_length) { + switch ($pad_type) { + case \STR_PAD_LEFT: + $ps_length = (int) \mb_strlen($pad_string); + + $diff = ($pad_length - $str_length); + + $pre = (string) \mb_substr( + \str_repeat($pad_string, (int) \ceil($diff / $ps_length)), + 0, + $diff + ); + $post = ''; + + break; + + case \STR_PAD_BOTH: + $diff = ($pad_length - $str_length); + + $ps_length_left = (int) \floor($diff / 2); + + $ps_length_right = (int) \ceil($diff / 2); + + $pre = (string) \mb_substr( + \str_repeat($pad_string, $ps_length_left), + 0, + $ps_length_left + ); + $post = (string) \mb_substr( + \str_repeat($pad_string, $ps_length_right), + 0, + $ps_length_right + ); + + break; + + case \STR_PAD_RIGHT: + default: + $ps_length = (int) \mb_strlen($pad_string); + + $diff = ($pad_length - $str_length); + + $post = (string) \mb_substr( + \str_repeat($pad_string, (int) \ceil($diff / $ps_length)), + 0, + $diff + ); + $pre = ''; + } + + return $pre . $str . $post; + } + + return $str; + } + + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + + $str_length = (int) self::strlen($str, $encoding); + + if ($pad_length >= $str_length) { + switch ($pad_type) { + case \STR_PAD_LEFT: + $ps_length = (int) self::strlen($pad_string, $encoding); + + $diff = ($pad_length - $str_length); + + $pre = (string) self::substr( + \str_repeat($pad_string, (int) \ceil($diff / $ps_length)), + 0, + $diff, + $encoding + ); + $post = ''; + + break; + + case \STR_PAD_BOTH: + $diff = ($pad_length - $str_length); + + $ps_length_left = (int) \floor($diff / 2); + + $ps_length_right = (int) \ceil($diff / 2); + + $pre = (string) self::substr( + \str_repeat($pad_string, $ps_length_left), + 0, + $ps_length_left, + $encoding + ); + $post = (string) self::substr( + \str_repeat($pad_string, $ps_length_right), + 0, + $ps_length_right, + $encoding + ); + + break; + + case \STR_PAD_RIGHT: + default: + $ps_length = (int) self::strlen($pad_string, $encoding); + + $diff = ($pad_length - $str_length); + + $post = (string) self::substr( + \str_repeat($pad_string, (int) \ceil($diff / $ps_length)), + 0, + $diff, + $encoding + ); + $pre = ''; + } + + return $pre . $str . $post; + } + + return $str; + } + + /** + * Returns a new string of a given length such that both sides of the + * string are padded. Alias for "UTF8::str_pad()" with a $pad_type of 'both'. + * + * @param string $str + * @param int $lengthDesired string length after padding.
+ * @param string $pad_str [optional]String used to pad, defaults to space. Default: ' '
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return string + *The string with padding applied.
+ */ + public static function str_pad_both( + string $str, + int $length, + string $pad_str = ' ', + string $encoding = 'UTF-8' + ): string { + return self::str_pad( + $str, + $length, + $pad_str, + \STR_PAD_BOTH, + $encoding + ); + } + + /** + * Returns a new string of a given length such that the beginning of the + * string is padded. Alias for "UTF8::str_pad()" with a $pad_type of 'left'. + * + * @param string $str + * @param int $lengthDesired string length after padding.
+ * @param string $pad_str [optional]String used to pad, defaults to space. Default: ' '
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return string + *The string with left padding.
+ */ + public static function str_pad_left( + string $str, + int $length, + string $pad_str = ' ', + string $encoding = 'UTF-8' + ): string { + return self::str_pad( + $str, + $length, + $pad_str, + \STR_PAD_LEFT, + $encoding + ); + } + + /** + * Returns a new string of a given length such that the end of the string + * is padded. Alias for "UTF8::str_pad()" with a $pad_type of 'right'. + * + * @param string $str + * @param int $lengthDesired string length after padding.
+ * @param string $pad_str [optional]String used to pad, defaults to space. Default: ' '
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return string + *The string with right padding.
+ */ + public static function str_pad_right( + string $str, + int $length, + string $pad_str = ' ', + string $encoding = 'UTF-8' + ): string { + return self::str_pad( + $str, + $length, + $pad_str, + \STR_PAD_RIGHT, + $encoding + ); + } + + /** + * Repeat a string. + * + * EXAMPLE:UTF8::str_repeat("°~\xf0\x90\x28\xbc", 2); // '°~ð(¼°~ð(¼'
+ *
+ * @param string $str + * The string to be repeated. + *
+ * @param int<1, max> $multiplier+ * Number of time the input string should be + * repeated. + *
+ *+ * multiplier has to be greater than or equal to 0. + * If the multiplier is set to 0, the function + * will return an empty string. + *
+ * + * @psalm-pure + * + * @return string + *The repeated string.
+ * + * @template T as string + * @phpstan-param T $str + * @phpstan-return (T is non-empty-string ? non-empty-string : string) + */ + public static function str_repeat(string $str, int $multiplier): string + { + $str = self::filter($str); + + return \str_repeat($str, $multiplier); + } + + /** + * INFO: This is only a wrapper for "str_replace()" -> the original functions is already UTF-8 safe. + * + * Replace all occurrences of the search string with the replacement string + * + * @see http://php.net/manual/en/function.str-replace.php + * + * @param string|string[] $search+ * The value being searched for, otherwise known as the needle. + * An array may be used to designate multiple needles. + *
+ * @param string|string[] $replace+ * The replacement value that replaces found search + * values. An array may be used to designate multiple replacements. + *
+ * @param string|string[] $subject+ * The string or array of strings being searched and replaced on, + * otherwise known as the haystack. + *
+ *+ * If subject is an array, then the search and + * replace is performed with every entry of + * subject, and the return value is an array as + * well. + *
+ * @param int|null $count [optional]+ * If passed, this will hold the number of matched and replaced needles. + *
+ * + * @psalm-pure + * + * @return string|string[] + *This function returns a string or an array with the replaced values.
+ * + * @template TStrReplaceSubject + * @phpstan-param TStrReplaceSubject $subject + * @phpstan-return TStrReplaceSubject + * + * @deprecated please use \str_replace() instead + */ + public static function str_replace( + $search, + $replace, + $subject, + int &$count = null + ) { + /** + * @psalm-suppress PossiblyNullArgument + * @phpstan-var TStrReplaceSubject $return; + */ + $return = \str_replace( + $search, + $replace, + $subject, + $count + ); + + return $return; + } + + /** + * Replaces $search from the beginning of string with $replacement. + * + * @param string $strThe input string.
+ * @param string $searchThe string to search for.
+ * @param string $replacementThe replacement.
+ * + * @psalm-pure + * + * @return string + *A string after the replacements.
+ */ + public static function str_replace_beginning( + string $str, + string $search, + string $replacement + ): string { + if ($str === '') { + if ($replacement === '') { + return ''; + } + + if ($search === '') { + return $replacement; + } + } + + if ($search === '') { + return $str . $replacement; + } + + $searchLength = \strlen($search); + if (\strncmp($str, $search, $searchLength) === 0) { + return $replacement . \substr($str, $searchLength); + } + + return $str; + } + + /** + * Replaces $search from the ending of string with $replacement. + * + * @param string $strThe input string.
+ * @param string $searchThe string to search for.
+ * @param string $replacementThe replacement.
+ * + * @psalm-pure + * + * @return string + *A string after the replacements.
+ */ + public static function str_replace_ending( + string $str, + string $search, + string $replacement + ): string { + if ($str === '') { + if ($replacement === '') { + return ''; + } + + if ($search === '') { + return $replacement; + } + } + + if ($search === '') { + return $str . $replacement; + } + + if (\strpos($str, $search, \strlen($str) - \strlen($search)) !== false) { + $str = \substr($str, 0, -\strlen($search)) . $replacement; + } + + return $str; + } + + /** + * Replace the first "$search"-term with the "$replace"-term. + * + * @param string $search + * @param string $replace + * @param string $subject + * + * @psalm-pure + * + * @return string + * + * @psalm-suppress InvalidReturnType + */ + public static function str_replace_first( + string $search, + string $replace, + string $subject + ): string { + $pos = self::strpos($subject, $search); + + if ($pos !== false) { + /** + * @psalm-suppress InvalidReturnStatement + */ + return self::substr_replace( + $subject, + $replace, + $pos, + (int) self::strlen($search) + ); + } + + return $subject; + } + + /** + * Replace the last "$search"-term with the "$replace"-term. + * + * @param string $search + * @param string $replace + * @param string $subject + * + * @psalm-pure + * + * @return string + * + * @psalm-suppress InvalidReturnType + */ + public static function str_replace_last( + string $search, + string $replace, + string $subject + ): string { + $pos = self::strrpos($subject, $search); + if ($pos !== false) { + /** + * @psalm-suppress InvalidReturnStatement + */ + return self::substr_replace( + $subject, + $replace, + $pos, + (int) self::strlen($search) + ); + } + + return $subject; + } + + /** + * Shuffles all the characters in the string. + * + * INFO: uses random algorithm which is weak for cryptography purposes + * + * EXAMPLE:UTF8::str_shuffle('fòô bàř fòô'); // 'àòôřb ffòô '
+ *
+ * @param string $str The input string
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @return string + *The shuffled string.
+ * + * @template T as string + * @phpstan-param T $str + * @phpstan-return (T is non-empty-string ? non-empty-string : string) + */ + public static function str_shuffle(string $str, string $encoding = 'UTF-8'): string + { + if ($encoding === 'UTF-8') { + $indexes = \range(0, (int) \mb_strlen($str) - 1); + \shuffle($indexes); + + // init + $shuffled_str = ''; + + foreach ($indexes as &$i) { + $tmp_sub_str = \mb_substr($str, $i, 1); + if ($tmp_sub_str !== false) { /* @phpstan-ignore-line | old polyfill will return false, or? */ + $shuffled_str .= $tmp_sub_str; + } + } + } else { + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + + $indexes = \range(0, (int) self::strlen($str, $encoding) - 1); + \shuffle($indexes); + + // init + $shuffled_str = ''; + + foreach ($indexes as &$i) { + $tmp_sub_str = self::substr($str, $i, 1, $encoding); + if ($tmp_sub_str !== false) { + $shuffled_str .= $tmp_sub_str; + } + } + } + + return $shuffled_str; + } + + /** + * Returns the substring beginning at $start, and up to, but not including + * the index specified by $end. If $end is omitted, the function extracts + * the remaining string. If $end is negative, it is computed from the end + * of the string. + * + * @param string $str + * @param int $startInitial index from which to begin extraction.
+ * @param int|null $end [optional]Index at which to end extraction. Default: null
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return false|string + *The extracted substring.
If str is shorter than start + * characters long, FALSE will be returned. + */ + public static function str_slice( + string $str, + int $start, + int $end = null, + string $encoding = 'UTF-8' + ) { + if ($encoding === 'UTF-8') { + if ($end === null) { + $length = (int) \mb_strlen($str); + } elseif ($end >= 0 && $end <= $start) { + return ''; + } elseif ($end < 0) { + $length = (int) \mb_strlen($str) + $end - $start; + } else { + $length = $end - $start; + } + + return \mb_substr($str, $start, $length); + } + + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + + if ($end === null) { + $length = (int) self::strlen($str, $encoding); + } elseif ($end >= 0 && $end <= $start) { + return ''; + } elseif ($end < 0) { + $length = (int) self::strlen($str, $encoding) + $end - $start; + } else { + $length = $end - $start; + } + + return self::substr($str, $start, $length, $encoding); + } + + /** + * Convert a string to e.g.: "snake_case" + * + * @param string $str + * @param string $encoding [optional]
Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return string + *A string in snake_case.
+ */ + public static function str_snakeize(string $str, string $encoding = 'UTF-8'): string + { + if ($str === '') { + return ''; + } + + $str = \str_replace( + '-', + '_', + self::normalize_whitespace($str) + ); + + if ($encoding !== 'UTF-8' && $encoding !== 'CP850') { + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + } + + $str = (string) \preg_replace_callback( + '/([\\p{N}|\\p{Lu}])/u', + /** + * @param string[] $matches + * + * @psalm-pure + * + * @return string + */ + static function (array $matches) use ($encoding): string { + $match = $matches[1]; + $match_int = (int) $match; + + if ((string) $match_int === $match) { + return '_' . $match . '_'; + } + + if ($encoding === 'UTF-8') { + return '_' . \mb_strtolower($match); + } + + return '_' . self::strtolower($match, $encoding); + }, + $str + ); + + $str = (string) \preg_replace( + [ + '/\\s+/u', // convert spaces to "_" + '/^\\s+|\\s+$/u', // trim leading & trailing spaces + '/_+/', // remove double "_" + ], + [ + '_', + '', + '_', + ], + $str + ); + + return \trim(\trim($str, '_')); // trim leading & trailing "_" + whitespace + } + + /** + * Sort all characters according to code points. + * + * EXAMPLE:UTF8::str_sort(' -ABC-中文空白- '); // ' ---ABC中文白空'
+ *
+ * @param string $str A UTF-8 string.
+ * @param bool $uniqueSort unique. If true, repeated characters are ignored.
+ * @param bool $descIf true, will sort characters in reverse code point order.
+ * + * @psalm-pure + * + * @return string + *A string of sorted characters.
+ */ + public static function str_sort(string $str, bool $unique = false, bool $desc = false): string + { + /** @var int[] $array */ + $array = self::codepoints($str); + + if ($unique) { + $array = \array_flip(\array_flip($array)); + } + + if ($desc) { + \arsort($array); + } else { + \asort($array); + } + + return self::string($array); + } + + /** + * Convert a string to an array of Unicode characters. + * + * EXAMPLE:
+ * UTF8::str_split_array(['中文空白', 'test'], 2); // [['中文', '空白'], ['te', 'st']]
+ *
+ *
+ * @param int[]|string[] $input The string[] or int[] to split into array.
+ * @param int<1, max> $length [optional]Max character length of each array + * element.
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the + * string.
+ * @param bool $try_to_use_mb_functions [optional]Set to false, if you don't want to use + * "mb_substr"
+ * + * @psalm-pure + * + * @return listAn array containing chunks of the input.
+ */ + public static function str_split_array( + array $input, + int $length = 1, + bool $clean_utf8 = false, + bool $try_to_use_mb_functions = true + ): array { + foreach ($input as &$v) { + $v = self::str_split( + $v, + $length, + $clean_utf8, + $try_to_use_mb_functions + ); + } + + /** @var listUTF8::str_split('中文空白'); // array('中', '文', '空', '白')
+ *
+ * @param int|string $str The string or int to split into array.
+ * @param int<1, max> $length [optional]Max character length of each array + * element.
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the + * string.
+ * @param bool $try_to_use_mb_functions [optional]Set to false, if you don't want to use + * "mb_substr"
+ * + * @psalm-pure + * + * @return listAn array containing chunks of chars from the input.
+ */ + public static function str_split( + $str, + int $length = 1, + bool $clean_utf8 = false, + bool $try_to_use_mb_functions = true + ): array { + /* @phpstan-ignore-next-line | we do not trust the phpdoc check */ + if ($length <= 0) { + return []; + } + + // this is only an old fallback + /** @noinspection PhpSillyAssignmentInspection - hack for phpstan */ + /** @var int|int[]|string|string[] $str */ + $str = $str; + if (\is_array($str)) { + /** @psalm-suppress InvalidReturnStatement */ + /** @phpstan-ignore-next-line - old code :/ */ + return self::str_split_array( + $str, + $length, + $clean_utf8, + $try_to_use_mb_functions + ); + } + + // init + $str = (string) $str; + + if ($str === '') { + return []; + } + + if ($clean_utf8) { + $str = self::clean($str); + } + + if ( + $try_to_use_mb_functions + && + self::$SUPPORT['mbstring'] === true + ) { + if (\function_exists('mb_str_split')) { + try { + /** + * @psalm-suppress ImpureFunctionCall - why? + */ + $return = \mb_str_split($str, $length); + } catch (\Error $e) { + // PHP >= 8.0 : mb_str_split() will now throw ValueError on error. Previously, mb_str_split() returned false instead. + $return = false; + } + if ($return !== false) { + return $return; + } + } + + $i_max = \mb_strlen($str); + if ($i_max <= 127) { + $ret = []; + for ($i = 0; $i < $i_max; ++$i) { + $ret[] = \mb_substr($str, $i, 1); + } + } else { + $return_array = []; + \preg_match_all('/./us', $str, $return_array); + $ret = $return_array[0] ?? []; + } + } elseif (self::$SUPPORT['pcre_utf8'] === true) { + $return_array = []; + \preg_match_all('/./us', $str, $return_array); + $ret = $return_array[0] ?? []; + } else { + + // fallback + + $ret = []; + $len = \strlen($str); + + for ($i = 0; $i < $len; ++$i) { + if (($str[$i] & "\x80") === "\x00") { + $ret[] = $str[$i]; + } elseif ( + isset($str[$i + 1]) + && + ($str[$i] & "\xE0") === "\xC0" + ) { + if (($str[$i + 1] & "\xC0") === "\x80") { + $ret[] = $str[$i] . $str[$i + 1]; + + ++$i; + } + } elseif ( + isset($str[$i + 2]) + && + ($str[$i] & "\xF0") === "\xE0" + ) { + if ( + ($str[$i + 1] & "\xC0") === "\x80" + && + ($str[$i + 2] & "\xC0") === "\x80" + ) { + $ret[] = $str[$i] . $str[$i + 1] . $str[$i + 2]; + + $i += 2; + } + } elseif ( + isset($str[$i + 3]) + && + ($str[$i] & "\xF8") === "\xF0" + ) { + if ( + ($str[$i + 1] & "\xC0") === "\x80" + && + ($str[$i + 2] & "\xC0") === "\x80" + && + ($str[$i + 3] & "\xC0") === "\x80" + ) { + $ret[] = $str[$i] . $str[$i + 1] . $str[$i + 2] . $str[$i + 3]; + + $i += 3; + } + } + } + } + + if ($length > 1) { + return \array_map( + static function (array $item): string { + /* @phpstan-ignore-next-line | "array_map + array_chunk" is not supported by phpstan?! */ + return \implode('', $item); + }, + \array_chunk($ret, $length) + ); + } + + if (isset($ret[0]) && $ret[0] === '') { + return []; + } + + return $ret; + } + + /** + * Splits the string with the provided regular expression, returning an + * array of strings. An optional integer $limit will truncate the + * results. + * + * @param string $str + * @param string $patternThe regex with which to split the string.
+ * @param int $limit [optional]Maximum number of results to return. Default: -1 === no limit
+ * + * @psalm-pure + * + * @return string[] + *An array of strings.
+ */ + public static function str_split_pattern(string $str, string $pattern, int $limit = -1): array + { + if ($limit === 0) { + return []; + } + + if ($pattern === '') { + return [$str]; + } + + if (self::$SUPPORT['mbstring'] === true) { + if ($limit >= 0) { + $result_tmp = \mb_split($pattern, $str); + if ($result_tmp === false) { + return []; + } + + $result = []; + foreach ($result_tmp as $item_tmp) { + if ($limit === 0) { + break; + } + --$limit; + + $result[] = $item_tmp; + } + + return $result; + } + + $result = \mb_split($pattern, $str); + if ($result === false) { + return []; + } + + return $result; + } + + if ($limit > 0) { + ++$limit; + } else { + $limit = -1; + } + + $array = \preg_split('/' . \preg_quote($pattern, '/') . '/u', $str, $limit); + if ($array === false) { + return []; + } + + if ($limit > 0 && \count($array) === $limit) { + \array_pop($array); + } + + return $array; + } + + /** + * Check if the string starts with the given substring. + * + * EXAMPLE:
+ * UTF8::str_starts_with('ΚόσμεMiddleEnd', 'Κόσμε'); // true
+ * UTF8::str_starts_with('ΚόσμεMiddleEnd', 'κόσμε'); // false
+ *
+ *
+ * @param string $haystack The string to search in.
+ * @param string $needleThe substring to search for.
+ * + * @psalm-pure + * + * @return bool + */ + public static function str_starts_with(string $haystack, string $needle): bool + { + if ($needle === '') { + return true; + } + + if ($haystack === '') { + return false; + } + + if (\PHP_VERSION_ID >= 80000) { + /** @phpstan-ignore-next-line - only for PHP8 */ + return \str_starts_with($haystack, $needle); + } + + return \strncmp($haystack, $needle, \strlen($needle)) === 0; + } + + /** + * Returns true if the string begins with any of $substrings, false otherwise. + * + * - case-sensitive + * + * @param string $strThe input string.
+ * @param scalar[] $substringsSubstrings to look for.
+ * + * @psalm-pure + * + * @return bool + *Whether or not $str starts with $substring.
+ */ + public static function str_starts_with_any(string $str, array $substrings): bool + { + if ($str === '') { + return false; + } + + if ($substrings === []) { + return false; + } + + foreach ($substrings as &$substring) { + if (self::str_starts_with($str, (string) $substring)) { + return true; + } + } + + return false; + } + + /** + * Gets the substring after the first occurrence of a separator. + * + * @param string $strThe input string.
+ * @param string $separatorThe string separator.
+ * @param string $encoding [optional]Default: 'UTF-8'
+ * + * @psalm-pure + * + * @return string + */ + public static function str_substr_after_first_separator(string $str, string $separator, string $encoding = 'UTF-8'): string + { + if ($separator === '' || $str === '') { + return ''; + } + + if ($encoding === 'UTF-8') { + $offset = \mb_strpos($str, $separator); + if ($offset === false) { + return ''; + } + + return (string) \mb_substr( + $str, + $offset + (int) \mb_strlen($separator) + ); + } + + $offset = self::strpos($str, $separator, 0, $encoding); + if ($offset === false) { + return ''; + } + + return (string) \mb_substr( + $str, + $offset + (int) self::strlen($separator, $encoding), + null, + $encoding + ); + } + + /** + * Gets the substring after the last occurrence of a separator. + * + * @param string $strThe input string.
+ * @param string $separatorThe string separator.
+ * @param string $encoding [optional]Default: 'UTF-8'
+ * + * @psalm-pure + * + * @return string + */ + public static function str_substr_after_last_separator( + string $str, + string $separator, + string $encoding = 'UTF-8' + ): string { + if ($separator === '' || $str === '') { + return ''; + } + + if ($encoding === 'UTF-8') { + $offset = \mb_strrpos($str, $separator); + if ($offset === false) { + return ''; + } + + return (string) \mb_substr( + $str, + $offset + (int) \mb_strlen($separator) + ); + } + + $offset = self::strrpos($str, $separator, 0, $encoding); + if ($offset === false) { + return ''; + } + + return (string) self::substr( + $str, + $offset + (int) self::strlen($separator, $encoding), + null, + $encoding + ); + } + + /** + * Gets the substring before the first occurrence of a separator. + * + * @param string $strThe input string.
+ * @param string $separatorThe string separator.
+ * @param string $encoding [optional]Default: 'UTF-8'
+ * + * @psalm-pure + * + * @return string + */ + public static function str_substr_before_first_separator( + string $str, + string $separator, + string $encoding = 'UTF-8' + ): string { + if ($separator === '' || $str === '') { + return ''; + } + + if ($encoding === 'UTF-8') { + $offset = \mb_strpos($str, $separator); + if ($offset === false) { + return ''; + } + + return (string) \mb_substr( + $str, + 0, + $offset + ); + } + + $offset = self::strpos($str, $separator, 0, $encoding); + if ($offset === false) { + return ''; + } + + return (string) self::substr( + $str, + 0, + $offset, + $encoding + ); + } + + /** + * Gets the substring before the last occurrence of a separator. + * + * @param string $strThe input string.
+ * @param string $separatorThe string separator.
+ * @param string $encoding [optional]Default: 'UTF-8'
+ * + * @psalm-pure + * + * @return string + */ + public static function str_substr_before_last_separator(string $str, string $separator, string $encoding = 'UTF-8'): string + { + if ($separator === '' || $str === '') { + return ''; + } + + if ($encoding === 'UTF-8') { + $offset = \mb_strrpos($str, $separator); + if ($offset === false) { + return ''; + } + + return (string) \mb_substr( + $str, + 0, + $offset + ); + } + + $offset = self::strrpos($str, $separator, 0, $encoding); + if ($offset === false) { + return ''; + } + + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + + return (string) self::substr( + $str, + 0, + $offset, + $encoding + ); + } + + /** + * Gets the substring after (or before via "$before_needle") the first occurrence of the "$needle". + * + * @param string $strThe input string.
+ * @param string $needleThe string to look for.
+ * @param bool $before_needle [optional]Default: false
+ * @param string $encoding [optional]Default: 'UTF-8'
+ * + * @psalm-pure + * + * @return string + */ + public static function str_substr_first( + string $str, + string $needle, + bool $before_needle = false, + string $encoding = 'UTF-8' + ): string { + if ($str === '' || $needle === '') { + return ''; + } + + if ($encoding === 'UTF-8') { + if ($before_needle) { + $part = \mb_strstr( + $str, + $needle, + $before_needle + ); + } else { + $part = \mb_strstr( + $str, + $needle + ); + } + } else { + $part = self::strstr( + $str, + $needle, + $before_needle, + $encoding + ); + } + + return $part === false ? '' : $part; + } + + /** + * Gets the substring after (or before via "$before_needle") the last occurrence of the "$needle". + * + * @param string $strThe input string.
+ * @param string $needleThe string to look for.
+ * @param bool $before_needle [optional]Default: false
+ * @param string $encoding [optional]Default: 'UTF-8'
+ * + * @psalm-pure + * + * @return string + */ + public static function str_substr_last( + string $str, + string $needle, + bool $before_needle = false, + string $encoding = 'UTF-8' + ): string { + if ($str === '' || $needle === '') { + return ''; + } + + if ($encoding === 'UTF-8') { + if ($before_needle) { + $part = \mb_strrchr( + $str, + $needle, + $before_needle + ); + } else { + $part = \mb_strrchr( + $str, + $needle + ); + } + } else { + $part = self::strrchr( + $str, + $needle, + $before_needle, + $encoding + ); + } + + return $part === false ? '' : $part; + } + + /** + * Surrounds $str with the given substring. + * + * @param string $str + * @param string $substringThe substring to add to both sides.
+ * + * @psalm-pure + * + * @return string + *A string with the substring both prepended and appended.
+ * + * @template T as string + * @template TSub as string + * @phpstan-param T $str + * @phpstan-param TSub $substring + * @phpstan-return (T is non-empty-string ? non-empty-string : (TSub is non-empty-string ? non-empty-string : string)) + */ + public static function str_surround(string $str, string $substring): string + { + return $substring . $str . $substring; + } + + /** + * Returns a trimmed string with the first letter of each word capitalized. + * Also accepts an array, $ignore, allowing you to list words not to be + * capitalized. + * + * @param string $str + * @param string[]|null $ignore [optional]An array of words not to capitalize or + * null. Default: null
+ * @param string $encoding [optional]Default: 'UTF-8'
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the + * string.
+ * @param string|null $lang [optional]Set the language for special cases: az, + * el, lt, tr
+ * @param bool $try_to_keep_the_string_length [optional]true === try to keep the string length: + * e.g. ẞ -> ß
+ * @param bool $use_trim_first [optional]true === trim the input string, + * first
+ * @param string|null $word_define_chars [optional]An string of chars that will be used as + * whitespace separator === words.
+ * + * @psalm-pure + * + * @return string + *The titleized string.
+ */ + public static function str_titleize( + string $str, + array $ignore = null, + string $encoding = 'UTF-8', + bool $clean_utf8 = false, + string $lang = null, + bool $try_to_keep_the_string_length = false, + bool $use_trim_first = true, + string $word_define_chars = null + ): string { + if ($str === '') { + return ''; + } + + if ($encoding !== 'UTF-8' && $encoding !== 'CP850') { + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + } + + if ($use_trim_first) { + $str = \trim($str); + } + + if ($clean_utf8) { + $str = self::clean($str); + } + + $use_mb_functions = $lang === null && !$try_to_keep_the_string_length; + + if ($word_define_chars) { + $word_define_chars = \preg_quote($word_define_chars, '/'); + } else { + $word_define_chars = ''; + } + + $str = (string) \preg_replace_callback( + '/([^\\s' . $word_define_chars . ']+)/u', + static function (array $match) use ($try_to_keep_the_string_length, $lang, $ignore, $use_mb_functions, $encoding): string { + if ($ignore !== null && \in_array($match[0], $ignore, true)) { + return $match[0]; + } + + if ($use_mb_functions) { + if ($encoding === 'UTF-8') { + return \mb_strtoupper(\mb_substr($match[0], 0, 1)) + . \mb_strtolower(\mb_substr($match[0], 1)); + } + + return \mb_strtoupper(\mb_substr($match[0], 0, 1, $encoding), $encoding) + . \mb_strtolower(\mb_substr($match[0], 1, null, $encoding), $encoding); + } + + return self::ucfirst( + self::strtolower( + $match[0], + $encoding, + false, + $lang, + $try_to_keep_the_string_length + ), + $encoding, + false, + $lang, + $try_to_keep_the_string_length + ); + }, + $str + ); + + return $str; + } + + /** + * Convert a string into a obfuscate string. + * + * EXAMPLE:
+ *
+ * UTF8::str_obfuscate('lars@moelleken.org', 0.5, '*', ['@', '.']); // e.g. "l***@m**lleke*.*r*"
+ *
+ *
+ * @param string $str
+ * @param float $percent
+ * @param string $obfuscateChar
+ * @param string[] $keepChars
+ *
+ * @psalm-pure
+ *
+ * @return string
+ * The obfuscate string.
+ */ + public static function str_obfuscate( + string $str, + float $percent = 0.5, + string $obfuscateChar = '*', + array $keepChars = [] + ): string { + $obfuscateCharHelper = "\u{2603}"; + $str = \str_replace($obfuscateChar, $obfuscateCharHelper, $str); + + $chars = self::chars($str); + $charsMax = \count($chars); + $charsMaxChange = \round($charsMax * $percent); + $charsCounter = 0; + $charKeyDone = []; + + while ($charsCounter < $charsMaxChange) { + foreach ($chars as $charKey => $char) { + if (isset($charKeyDone[$charKey])) { + continue; + } + + if (\random_int(0, 100) > 50) { + continue; + } + + if ($char === $obfuscateChar) { + continue; + } + + ++$charsCounter; + $charKeyDone[$charKey] = true; + + if ($charsCounter > $charsMaxChange) { + break; + } + + if (\in_array($char, $keepChars, true)) { + continue; + } + + $chars[$charKey] = $obfuscateChar; + } + } + + $str = \implode('', $chars); + + return \str_replace($obfuscateCharHelper, $obfuscateChar, $str); + } + + /** + * Returns a trimmed string in proper title case. + * + * Also accepts an array, $ignore, allowing you to list words not to be + * capitalized. + * + * Adapted from John Gruber's script. + * + * @see https://gist.github.com/gruber/9f9e8650d68b13ce4d78 + * + * @param string $str + * @param string[] $ignoreAn array of words not to capitalize.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return string + *The titleized string.
+ */ + public static function str_titleize_for_humans( + string $str, + array $ignore = [], + string $encoding = 'UTF-8' + ): string { + if ($str === '') { + return ''; + } + + $small_words = [ + '(? In-Flight + $str = (string) \preg_replace_callback( + '~\\b + (? "Stand-In" (Stand is already capped at this point) + $str = (string) \preg_replace_callback( + '~\\b + (?UTF8::str_to_binary('😃'); // '11110000100111111001100010000011' + * + * @param string $strThe input string.
+ * + * @psalm-pure + * + * @return false|string + *false on error
+ */ + public static function str_to_binary(string $str) + { + $value = \unpack('H*', $str); + if ($value === false) { + return false; + } + + return \base_convert($value[1], 16, 2); + } + + /** + * @param string $str + * @param bool $remove_empty_valuesRemove empty values.
+ * @param int|null $remove_short_valuesThe min. string length or null to disable
+ * + * @psalm-pure + * + * @return string[] + */ + public static function str_to_lines(string $str, bool $remove_empty_values = false, int $remove_short_values = null): array + { + if ($str === '') { + return $remove_empty_values ? [] : ['']; + } + + if (self::$SUPPORT['mbstring'] === true) { + $return = \mb_split("[\r\n]{1,2}", $str); + } else { + $return = \preg_split("/[\r\n]{1,2}/u", $str); + } + + if ($return === false) { + return $remove_empty_values ? [] : ['']; + } + + if ( + $remove_short_values === null + && + !$remove_empty_values + ) { + return $return; + } + + return self::reduce_string_array( + $return, + $remove_empty_values, + $remove_short_values + ); + } + + /** + * Convert a string into an array of words. + * + * EXAMPLE:UTF8::str_to_words('中文空白 oöäü#s', '#') // array('', '中文空白', ' ', 'oöäü#s', '')
+ *
+ * @param string $str
+ * @param string $char_list Additional chars for the definition of "words".
+ * @param bool $remove_empty_valuesRemove empty values.
+ * @param int|null $remove_short_valuesThe min. string length or null to disable
+ * + * @psalm-pure + * + * @return listDesired length of the truncated string.
+ * @param string $substring [optional]The substring to append if it can fit. Default: ''
+ * @param string $encoding [optional]Default: 'UTF-8'
+ * + * @psalm-pure + * + * @return string + *A string after truncating.
+ */ + public static function str_truncate( + string $str, + int $length, + string $substring = '', + string $encoding = 'UTF-8' + ): string { + if ($str === '') { + return ''; + } + + if ($encoding === 'UTF-8') { + if ($length >= (int) \mb_strlen($str)) { + return $str; + } + + if ($substring !== '') { + $length -= (int) \mb_strlen($substring); + + /** @noinspection UnnecessaryCastingInspection */ + return (string) \mb_substr($str, 0, $length) . $substring; + } + + return (string) \mb_substr($str, 0, $length); + } + + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + + if ($length >= (int) self::strlen($str, $encoding)) { + return $str; + } + + if ($substring !== '') { + $length -= (int) self::strlen($substring, $encoding); + } + + return ( + (string) self::substr( + $str, + 0, + $length, + $encoding + ) + ) . $substring; + } + + /** + * Truncates the string to a given length, while ensuring that it does not + * split words. If $substring is provided, and truncating occurs, the + * string is further truncated so that the substring may be appended without + * exceeding the desired length. + * + * @param string $str + * @param int $lengthDesired length of the truncated string.
+ * @param string $substring [optional]The substring to append if it can fit. + * Default: + * ''
+ * @param string $encoding [optional]Default: 'UTF-8'
+ * @param bool $ignore_do_not_split_words_for_one_word [optional]Default: false
+ * + * @psalm-pure + * + * @return string + *A string after truncating.
+ */ + public static function str_truncate_safe( + string $str, + int $length, + string $substring = '', + string $encoding = 'UTF-8', + bool $ignore_do_not_split_words_for_one_word = false + ): string { + if ($str === '' || $length <= 0) { + return $substring; + } + + if ($encoding === 'UTF-8') { + if ($length >= (int) \mb_strlen($str)) { + return $str; + } + + // need to further trim the string so we can append the substring + $length -= (int) \mb_strlen($substring); + if ($length <= 0) { + return $substring; + } + + /** @var false|string $truncated - needed for PhpStan (stubs error) */ + $truncated = \mb_substr($str, 0, $length); + if ($truncated === false) { + return ''; + } + + // if the last word was truncated + $space_position = \mb_strpos($str, ' ', $length - 1); + if ($space_position !== $length) { + // find pos of the last occurrence of a space, get up to that + $last_position = \mb_strrpos($truncated, ' ', 0); + + if ( + $last_position !== false + || + ( + $space_position !== false + && + !$ignore_do_not_split_words_for_one_word + ) + ) { + $truncated = (string) \mb_substr($truncated, 0, (int) $last_position); + } + } + } else { + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + + if ($length >= (int) self::strlen($str, $encoding)) { + return $str; + } + + // need to further trim the string so we can append the substring + $length -= (int) self::strlen($substring, $encoding); + if ($length <= 0) { + return $substring; + } + + $truncated = self::substr($str, 0, $length, $encoding); + + if ($truncated === false) { + return ''; + } + + // if the last word was truncated + $space_position = self::strpos($str, ' ', $length - 1, $encoding); + if ($space_position !== $length) { + // find pos of the last occurrence of a space, get up to that + $last_position = self::strrpos($truncated, ' ', 0, $encoding); + + if ( + $last_position !== false + || + ( + $space_position !== false + && + !$ignore_do_not_split_words_for_one_word + ) + ) { + $truncated = (string) self::substr($truncated, 0, (int) $last_position, $encoding); + } + } + } + + return $truncated . $substring; + } + + /** + * Returns a lowercase and trimmed string separated by underscores. + * Underscores are inserted before uppercase characters (with the exception + * of the first character of the string), and in place of spaces as well as + * dashes. + * + * @param string $str + * + * @psalm-pure + * + * @return string + *The underscored string.
+ */ + public static function str_underscored(string $str): string + { + return self::str_delimit($str, '_'); + } + + /** + * Returns an UpperCamelCase version of the supplied string. It trims + * surrounding spaces, capitalizes letters following digits, spaces, dashes + * and underscores, and removes spaces, dashes, underscores. + * + * @param string $strThe input string.
+ * @param string $encoding [optional]Default: 'UTF-8'
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * @param string|null $lang [optional]Set the language for special cases: az, el, lt, + * tr
+ * @param bool $try_to_keep_the_string_length [optional]true === try to keep the string length: e.g. ẞ + * -> ß
+ * + * @psalm-pure + * + * @return string + *A string in UpperCamelCase.
+ */ + public static function str_upper_camelize( + string $str, + string $encoding = 'UTF-8', + bool $clean_utf8 = false, + string $lang = null, + bool $try_to_keep_the_string_length = false + ): string { + return self::ucfirst(self::str_camelize($str, $encoding), $encoding, $clean_utf8, $lang, $try_to_keep_the_string_length); + } + + /** + * Get the number of words in a specific string. + * + * EXAMPLES:
+ * // format: 0 -> return only word count (int)
+ * //
+ * UTF8::str_word_count('中文空白 öäü abc#c'); // 4
+ * UTF8::str_word_count('中文空白 öäü abc#c', 0, '#'); // 3
+ *
+ * // format: 1 -> return words (array)
+ * //
+ * UTF8::str_word_count('中文空白 öäü abc#c', 1); // array('中文空白', 'öäü', 'abc', 'c')
+ * UTF8::str_word_count('中文空白 öäü abc#c', 1, '#'); // array('中文空白', 'öäü', 'abc#c')
+ *
+ * // format: 2 -> return words with offset (array)
+ * //
+ * UTF8::str_word_count('中文空白 öäü ab#c', 2); // array(0 => '中文空白', 5 => 'öäü', 9 => 'abc', 13 => 'c')
+ * UTF8::str_word_count('中文空白 öäü ab#c', 2, '#'); // array(0 => '中文空白', 5 => 'öäü', 9 => 'abc#c')
+ *
+ *
+ * @param string $str The input string.
+ * @param int $format [optional]
+ * 0 => return a number of words (default)
+ * 1 => return an array of words
+ * 2 => return an array of words with word-offset as key
+ *
Additional chars that contains to words and do not start a new word.
+ * + * @psalm-pure + * + * @return int|string[] + *The number of words in the string.
+ * + * @phpstan-param 0|1|2 $format + * @phpstan-return ($format is 2 ? arrayUTF8::strcasecmp("iñtërnâtiôn\nàlizætiøn", "Iñtërnâtiôn\nàlizætiøn"); // 0
+ *
+ * @param string $str1 The first string.
+ * @param string $str2The second string.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return int + * < 0 if str1 is less than str2;UTF8::strcmp("iñtërnâtiôn\nàlizætiøn", "iñtërnâtiôn\nàlizætiøn"); // 0
+ *
+ * @param string $str1 The first string.
+ * @param string $str2The second string.
+ * + * @psalm-pure + * + * @return int + * < 0 if str1 is less than str2Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return int + * + * @phpstan-return 0|positive-int + */ + public static function strcspn( + string $str, + string $char_list, + int $offset = 0, + int $length = null, + string $encoding = 'UTF-8' + ): int { + if ($encoding !== 'UTF-8' && $encoding !== 'CP850') { + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + } + + if ($char_list === '') { + return (int) self::strlen($str, $encoding); + } + + if ($offset || $length !== null) { + if ($encoding === 'UTF-8') { + if ($length === null) { + $str_tmp = \mb_substr($str, $offset); + } else { + $str_tmp = \mb_substr($str, $offset, $length); + } + } else { + $str_tmp = self::substr($str, $offset, $length, $encoding); + } + + if ($str_tmp === false) { + return 0; + } + + $str = $str_tmp; + } + + if ($str === '') { + return 0; + } + + $matches = []; + if (\preg_match('/^(.*?)' . self::rxClass($char_list) . '/us', $str, $matches)) { + $return = self::strlen($matches[1], $encoding); + if ($return === false) { + return 0; + } + + return $return; + } + + return (int) self::strlen($str, $encoding); + } + + /** + * Create a UTF-8 string from code points. + * + * INFO: opposite to UTF8::codepoints() + * + * EXAMPLE:UTF8::string(array(246, 228, 252)); // 'öäü'
+ *
+ * @param int|int[]|string|string[] $intOrHex Integer or Hexadecimal codepoints.
+ * + * @phpstan-param int[]|numeric-string[]|int|numeric-string $intOrHex + * + * @psalm-pure + * + * @return string + *A UTF-8 encoded string.
+ */ + public static function string($intOrHex): string + { + if ($intOrHex === []) { + return ''; + } + + if (!\is_array($intOrHex)) { + $intOrHex = [$intOrHex]; + } + + $str = ''; + foreach ($intOrHex as $strPart) { + $str .= '' . (int) $strPart . ';'; + } + + // We cannot use html_entity_decode() here, as it will not return + // characters for many values < 160. + return mb_convert_encoding($str, 'UTF-8', 'HTML-ENTITIES'); + } + + /** + * Checks if string starts with "BOM" (Byte Order Mark Character) character. + * + * EXAMPLE:UTF8::string_has_bom("\xef\xbb\xbf foobar"); // true
+ *
+ * @param string $str The input string.
+ * + * @psalm-pure + * + * @return bool + *
+ * true if the string has BOM at the start,
+ * false otherwise
+ *
UTF8::strip_tags("κόσμε\xa0\xa1"); // 'κόσμε'
+ *
+ * @see http://php.net/manual/en/function.strip-tags.php
+ *
+ * @param string $str + * The input string. + *
+ * @param string|null $allowable_tags [optional]+ * You can use the optional second parameter to specify tags which should + * not be stripped. + *
+ *+ * HTML comments and PHP tags are also stripped. This is hardcoded and + * can not be changed with allowable_tags. + *
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * + * @psalm-pure + * + * @return string + *The stripped string.
+ */ + public static function strip_tags( + string $str, + string $allowable_tags = null, + bool $clean_utf8 = false + ): string { + if ($str === '') { + return ''; + } + + if ($clean_utf8) { + $str = self::clean($str); + } + + if ($allowable_tags === null) { + return \strip_tags($str); + } + + return \strip_tags($str, $allowable_tags); + } + + /** + * Strip all whitespace characters. This includes tabs and newline + * characters, as well as multibyte whitespace such as the thin space + * and ideographic space. + * + * EXAMPLE:UTF8::strip_whitespace(' Ο συγγραφέας '); // 'Οσυγγραφέας'
+ *
+ * @param string $str
+ *
+ * @psalm-pure
+ *
+ * @return string
+ */
+ public static function strip_whitespace(string $str): string
+ {
+ if ($str === '') {
+ return '';
+ }
+
+ return (string) \preg_replace('/[[:space:]]+/u', '', $str);
+ }
+
+ /**
+ * Find the position of the first occurrence of a substring in a string, case-insensitive.
+ *
+ * INFO: use UTF8::stripos_in_byte() for the byte-length
+ *
+ * EXAMPLE: UTF8::stripos('aσσb', 'ΣΣ'); // 1
(σσ == ΣΣ)
+ *
+ * @see http://php.net/manual/en/function.mb-stripos.php
+ *
+ * @param string $haystack The string from which to get the position of the first occurrence of needle.
+ * @param string $needleThe string to find in haystack.
+ * @param int $offset [optional]The position in haystack to start searching.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * + * @psalm-pure + * + * @return false|int + * Return the (int) numeric position of the first occurrence of needle in the + * haystack string,
+ * $str = 'iñtërnâtiônàlizætiøn';
+ * $search = 'NÂT';
+ *
+ * UTF8::stristr($str, $search)); // 'nâtiônàlizætiøn'
+ * UTF8::stristr($str, $search, true)); // 'iñtër'
+ *
+ *
+ * @param string $haystack The input string. Must be valid UTF-8.
+ * @param string $needleThe string to look for. Must be valid UTF-8.
+ * @param bool $before_needle [optional]+ * If TRUE, it returns the part of the + * haystack before the first occurrence of the needle (excluding the needle). + *
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * + * @psalm-pure + * + * @return false|string + *A sub-string,
or false if needle is not found.
UTF8::strlen("Iñtërnâtiôn\xE9àlizætiøn")); // 20
+ *
+ * @see http://php.net/manual/en/function.mb-strlen.php
+ *
+ * @param string $str The string being checked for length.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * + * @psalm-pure + * + * @return false|int + *
+ * The number (int) of characters in the string $str having character encoding
+ * $encoding.
+ * (One multi-byte character counted as +1).
+ *
+ * Can return false, if e.g. mbstring is not installed and we process invalid
+ * chars.
+ *
+ * UTF8::strnatcasecmp('2', '10Hello WORLD 中文空白!'); // -1
+ * UTF8::strcasecmp('2Hello world 中文空白!', '10Hello WORLD 中文空白!'); // 1
+ *
+ * UTF8::strnatcasecmp('10Hello world 中文空白!', '2Hello WORLD 中文空白!'); // 1
+ * UTF8::strcasecmp('10Hello world 中文空白!', '2Hello WORLD 中文空白!'); // -1
+ *
+ *
+ * @param string $str1 The first string.
+ * @param string $str2The second string.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return int + * < 0 if str1 is less than str2
+ * UTF8::strnatcmp('2Hello world 中文空白!', '10Hello WORLD 中文空白!'); // -1
+ * UTF8::strcmp('2Hello world 中文空白!', '10Hello WORLD 中文空白!'); // 1
+ *
+ * UTF8::strnatcmp('10Hello world 中文空白!', '2Hello WORLD 中文空白!'); // 1
+ * UTF8::strcmp('10Hello world 中文空白!', '2Hello WORLD 中文空白!'); // -1
+ *
+ *
+ * @see http://php.net/manual/en/function.strnatcmp.php
+ *
+ * @param string $str1 The first string.
+ * @param string $str2The second string.
+ * + * @psalm-pure + * + * @return int + * < 0 if str1 is less than str2;
+ * UTF8::strcasecmp("iñtërnâtiôn\nàlizætiøn321", "iñtërnâtiôn\nàlizætiøn123", 5); // 0
+ *
+ *
+ * @see http://php.net/manual/en/function.strncasecmp.php
+ *
+ * @param string $str1 The first string.
+ * @param string $str2The second string.
+ * @param int $lenThe length of strings to be used in the comparison.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return int + * < 0 if str1 is less than str2;
+ * UTF8::strncmp("Iñtërnâtiôn\nàlizætiøn321", "Iñtërnâtiôn\nàlizætiøn123", 5); // 0
+ *
+ *
+ * @see http://php.net/manual/en/function.strncmp.php
+ *
+ * @param string $str1 The first string.
+ * @param string $str2The second string.
+ * @param int $lenNumber of characters to use in the comparison.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return int + * < 0 if str1 is less than str2;UTF8::strpbrk('-中文空白-', '白'); // '白-'
+ *
+ * @see http://php.net/manual/en/function.strpbrk.php
+ *
+ * @param string $haystack The string where char_list is looked for.
+ * @param string $char_listThis parameter is case-sensitive.
+ * + * @psalm-pure + * + * @return false|string + *The string starting from the character found, or false if it is not found.
+ */ + public static function strpbrk(string $haystack, string $char_list) + { + if ($haystack === '' || $char_list === '') { + return false; + } + + if (\preg_match('/' . self::rxClass($char_list) . '/us', $haystack, $m)) { + return \substr($haystack, (int) \strpos($haystack, $m[0])); + } + + return false; + } + + /** + * Find the position of the first occurrence of a substring in a string. + * + * INFO: use UTF8::strpos_in_byte() for the byte-length + * + * EXAMPLE:UTF8::strpos('ABC-ÖÄÜ-中文空白-中文空白', '中'); // 8
+ *
+ * @see http://php.net/manual/en/function.mb-strpos.php
+ *
+ * @param string $haystack The string from which to get the position of the first occurrence of needle.
+ * @param int|string $needleThe string to find in haystack.
Or a code point as int.
The search offset. If it is not specified, 0 is used.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * + * @psalm-pure + * + * @return false|int + * The (int) numeric position of the first occurrence of needle in the haystack + * string.+ * The string being checked. + *
+ * @param string $needle+ * The position counted from the beginning of haystack. + *
+ * @param int $offset [optional]+ * The search offset. If it is not specified, 0 is used. + *
+ * + * @psalm-pure + * + * @return false|int + *The numeric position of the first occurrence of needle in the + * haystack string. If needle is not found, it returns false.
+ * + * @phpstan-return false|0|positive-int + */ + public static function strpos_in_byte(string $haystack, string $needle, int $offset = 0) + { + if ($haystack === '' || $needle === '') { + return false; + } + + if (self::$SUPPORT['mbstring_func_overload'] === true) { + // "mb_" is available if overload is used, so use it ... + return \mb_strpos($haystack, $needle, $offset, 'CP850'); // 8-BIT + } + + return \strpos($haystack, $needle, $offset); + } + + /** + * Find the position of the first occurrence of a substring in a string, case-insensitive. + * + * @param string $haystack+ * The string being checked. + *
+ * @param string $needle+ * The position counted from the beginning of haystack. + *
+ * @param int $offset [optional]+ * The search offset. If it is not specified, 0 is used. + *
+ * + * @psalm-pure + * + * @return false|int + *The numeric position of the first occurrence of needle in the + * haystack string. If needle is not found, it returns false.
+ * + * @phpstan-return false|0|positive-int + */ + public static function stripos_in_byte(string $haystack, string $needle, int $offset = 0) + { + if ($haystack === '' || $needle === '') { + return false; + } + + if (self::$SUPPORT['mbstring_func_overload'] === true) { + // "mb_" is available if overload is used, so use it ... + return \mb_stripos($haystack, $needle, $offset, 'CP850'); // 8-BIT + } + + return \stripos($haystack, $needle, $offset); + } + + /** + * Find the last occurrence of a character in a string within another. + * + * EXAMPLE:UTF8::strrchr('κόσμεκόσμε-äöü', 'κόσμε'); // 'κόσμε-äöü'
+ *
+ * @see http://php.net/manual/en/function.mb-strrchr.php
+ *
+ * @param string $haystack The string from which to get the last occurrence of needle.
+ * @param string $needleThe string to find in haystack
+ * @param bool $before_needle [optional]+ * Determines which portion of haystack + * this function returns. + * If set to true, it returns all of haystack + * from the beginning to the last occurrence of needle. + * If set to false, it returns all of haystack + * from the last occurrence of needle to the end, + *
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * + * @psalm-pure + * + * @return false|string + *The portion of haystack or false if needle is not found.
+ */ + public static function strrchr( + string $haystack, + string $needle, + bool $before_needle = false, + string $encoding = 'UTF-8', + bool $clean_utf8 = false + ) { + if ($haystack === '' || $needle === '') { + return false; + } + + if ($encoding !== 'UTF-8' && $encoding !== 'CP850') { + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + } + + if ($clean_utf8) { + // "mb_strpos()" and "iconv_strpos()" returns wrong position, + // if invalid characters are found in $haystack before $needle + $needle = self::clean($needle); + $haystack = self::clean($haystack); + } + + // + // fallback via mbstring + // + + if (self::$SUPPORT['mbstring'] === true) { + if ($encoding === 'UTF-8') { + return \mb_strrchr($haystack, $needle, $before_needle); + } + + return \mb_strrchr($haystack, $needle, $before_needle, $encoding); + } + + // + // fallback for binary || ascii only + // + + if ( + !$before_needle + && + ( + $encoding === 'CP850' + || + $encoding === 'ASCII' + ) + ) { + return \strrchr($haystack, $needle); + } + + if ( + $encoding !== 'UTF-8' + && + self::$SUPPORT['mbstring'] === false + ) { + /** + * @psalm-suppress ImpureFunctionCall - this is only a warning + */ + \trigger_error('UTF8::strrchr() without mbstring cannot handle "' . $encoding . '" encoding', \E_USER_WARNING); + } + + // + // fallback via iconv + // + + if (self::$SUPPORT['iconv'] === true) { + $needle_tmp = self::substr($needle, 0, 1, $encoding); + if ($needle_tmp === false) { + return false; + } + $needle = $needle_tmp; + + $pos = \iconv_strrpos($haystack, $needle, $encoding); + if ($pos === false) { + return false; + } + + if ($before_needle) { + return self::substr($haystack, 0, $pos, $encoding); + } + + return self::substr($haystack, $pos, null, $encoding); + } + + // + // fallback via vanilla php + // + + $needle_tmp = self::substr($needle, 0, 1, $encoding); + if ($needle_tmp === false) { + return false; + } + $needle = $needle_tmp; + + $pos = self::strrpos($haystack, $needle, 0, $encoding); + if ($pos === false) { + return false; + } + + if ($before_needle) { + return self::substr($haystack, 0, $pos, $encoding); + } + + return self::substr($haystack, $pos, null, $encoding); + } + + /** + * Reverses characters order in the string. + * + * EXAMPLE:UTF8::strrev('κ-öäü'); // 'üäö-κ'
+ *
+ * @param string $str The input string.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return string + *The string with characters in the reverse sequence.
+ */ + public static function strrev(string $str, string $encoding = 'UTF-8'): string + { + if ($str === '') { + return ''; + } + + // init + $reversed = ''; + + $str = self::emoji_encode($str, true); + + if ($encoding === 'UTF-8') { + if (self::$SUPPORT['intl'] === true) { + // try "grapheme" first: https://stackoverflow.com/questions/17496493/strrev-dosent-support-utf-8 + $i = (int) \grapheme_strlen($str); + while ($i--) { + $reversed_tmp = \grapheme_substr($str, $i, 1); + if ($reversed_tmp !== false) { + $reversed .= $reversed_tmp; + } + } + } else { + $i = (int) \mb_strlen($str); + while ($i--) { + $reversed_tmp = \mb_substr($str, $i, 1); + if ($reversed_tmp !== false) { /* @phpstan-ignore-line | old polyfill will return false, or? */ + $reversed .= $reversed_tmp; + } + } + } + } else { + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + + $i = (int) self::strlen($str, $encoding); + while ($i--) { + $reversed_tmp = self::substr($str, $i, 1, $encoding); + if ($reversed_tmp !== false) { + $reversed .= $reversed_tmp; + } + } + } + + return self::emoji_decode($reversed, true); + } + + /** + * Find the last occurrence of a character in a string within another, case-insensitive. + * + * EXAMPLE:UTF8::strrichr('Aκόσμεκόσμε-äöü', 'aκόσμε'); // 'Aκόσμεκόσμε-äöü'
+ *
+ * @see http://php.net/manual/en/function.mb-strrichr.php
+ *
+ * @param string $haystack The string from which to get the last occurrence of needle.
+ * @param string $needleThe string to find in haystack.
+ * @param bool $before_needle [optional]+ * Determines which portion of haystack + * this function returns. + * If set to true, it returns all of haystack + * from the beginning to the last occurrence of needle. + * If set to false, it returns all of haystack + * from the last occurrence of needle to the end, + *
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * + * @psalm-pure + * + * @return false|string + *The portion of haystack or
false if needle is not found.
UTF8::strripos('ABC-ÖÄÜ-中文空白-中文空白', '中'); // 13
+ *
+ * @param string $haystack The string to look in.
+ * @param int|string $needleThe string to look for.
+ * @param int $offset [optional]Number of characters to ignore in the beginning or end.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * + * @psalm-pure + * + * @return false|int + *The (int) numeric position of the last occurrence of needle in the haystack
+ * string.
If needle is not found, it returns false.
+ * The string from which to get the position of the last occurrence + * of needle. + *
+ * @param string $needle+ * The string to find in haystack. + *
+ * @param int $offset [optional]+ * The position in haystack + * to start searching. + *
+ * + * @psalm-pure + * + * @return false|int + *eturn the numeric position of the last occurrence of needle in the + * haystack string, or false if needle is not found.
+ */ + public static function strripos_in_byte(string $haystack, string $needle, int $offset = 0) + { + if ($haystack === '' || $needle === '') { + return false; + } + + if (self::$SUPPORT['mbstring_func_overload'] === true) { + // "mb_" is available if overload is used, so use it ... + return \mb_strripos($haystack, $needle, $offset, 'CP850'); // 8-BIT + } + + return \strripos($haystack, $needle, $offset); + } + + /** + * Find the position of the last occurrence of a substring in a string. + * + * EXAMPLE:UTF8::strrpos('ABC-ÖÄÜ-中文空白-中文空白', '中'); // 13
+ *
+ * @see http://php.net/manual/en/function.mb-strrpos.php
+ *
+ * @param string $haystack The string being checked, for the last occurrence of needle
+ * @param int|string $needleThe string to find in haystack.
Or a code point as int.
May be specified to begin searching an arbitrary number of characters + * into the string. Negative values will stop searching at an arbitrary point prior to + * the end of the string. + *
+ * @param string $encoding [optional]Set the charset.
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * + * @psalm-pure + * + * @return false|int + *The (int) numeric position of the last occurrence of needle in the haystack
+ * string.
If needle is not found, it returns false.
+ * The string being checked, for the last occurrence + * of needle. + *
+ * @param string $needle+ * The string to find in haystack. + *
+ * @param int $offset [optional]May be specified to begin searching an arbitrary number of characters into + * the string. Negative values will stop searching at an arbitrary point + * prior to the end of the string. + *
+ * + * @psalm-pure + * + * @return false|int + *The numeric position of the last occurrence of needle in the + * haystack string. If needle is not found, it returns false.
+ */ + public static function strrpos_in_byte(string $haystack, string $needle, int $offset = 0) + { + if ($haystack === '' || $needle === '') { + return false; + } + + if (self::$SUPPORT['mbstring_func_overload'] === true) { + // "mb_" is available if overload is used, so use it ... + return \mb_strrpos($haystack, $needle, $offset, 'CP850'); // 8-BIT + } + + return \strrpos($haystack, $needle, $offset); + } + + /** + * Finds the length of the initial segment of a string consisting entirely of characters contained within a given + * mask. + * + * EXAMPLE:UTF8::strspn('iñtërnâtiônàlizætiøn', 'itñ'); // '3'
+ *
+ * @param string $str The input string.
+ * @param string $maskThe mask of chars
+ * @param int $offset [optional] + * @param int|null $length [optional] + * @param string $encoding [optional]Set the charset.
+ * + * @psalm-pure + * + * @return false|int + */ + public static function strspn( + string $str, + string $mask, + int $offset = 0, + int $length = null, + string $encoding = 'UTF-8' + ) { + if ($encoding !== 'UTF-8' && $encoding !== 'CP850') { + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + } + + if ($offset || $length !== null) { + if ($encoding === 'UTF-8') { + if ($length === null) { + $str = (string) \mb_substr($str, $offset); + } else { + $str = (string) \mb_substr($str, $offset, $length); + } + } else { + $str = (string) self::substr($str, $offset, $length, $encoding); + } + } + + if ($str === '' || $mask === '') { + return 0; + } + + $matches = []; + + return \preg_match('/^' . self::rxClass($mask) . '+/u', $str, $matches) ? (int) self::strlen($matches[0], $encoding) : 0; + } + + /** + * Returns part of haystack string from the first occurrence of needle to the end of haystack. + * + * EXAMPLE:
+ * $str = 'iñtërnâtiônàlizætiøn';
+ * $search = 'nât';
+ *
+ * UTF8::strstr($str, $search)); // 'nâtiônàlizætiøn'
+ * UTF8::strstr($str, $search, true)); // 'iñtër'
+ *
+ *
+ * @param string $haystack The input string. Must be valid UTF-8.
+ * @param string $needleThe string to look for. Must be valid UTF-8.
+ * @param bool $before_needle [optional]+ * If TRUE, strstr() returns the part of the + * haystack before the first occurrence of the needle (excluding the needle). + *
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * + * @psalm-pure + * + * @return false|string + *A sub-string,
or false if needle is not found.
+ * The string from which to get the first occurrence + * of needle. + *
+ * @param string $needle+ * The string to find in haystack. + *
+ * @param bool $before_needle [optional]+ * Determines which portion of haystack + * this function returns. + * If set to true, it returns all of haystack + * from the beginning to the first occurrence of needle. + * If set to false, it returns all of haystack + * from the first occurrence of needle to the end, + *
+ * + * @psalm-pure + * + * @return false|string + *The portion of haystack, + * or false if needle is not found.
+ */ + public static function strstr_in_byte( + string $haystack, + string $needle, + bool $before_needle = false + ) { + if ($haystack === '' || $needle === '') { + return false; + } + + if (self::$SUPPORT['mbstring_func_overload'] === true) { + // "mb_" is available if overload is used, so use it ... + return \mb_strstr($haystack, $needle, $before_needle, 'CP850'); // 8-BIT + } + + return \strstr($haystack, $needle, $before_needle); + } + + /** + * Unicode transformation for case-less matching. + * + * EXAMPLE:UTF8::strtocasefold('ǰ◌̱'); // 'ǰ◌̱'
+ *
+ * @see http://unicode.org/reports/tr21/tr21-5.html
+ *
+ * @param string $str The input string.
+ * @param bool $full [optional]
+ * true, replace full case folding chars (default)
+ * false, use only limited static array [UTF8::$COMMON_CASE_FOLD]
+ *
Remove non UTF-8 chars from the string.
+ * @param string $encoding [optional]Set the charset.
+ * @param string|null $lang [optional]Set the language for special cases: az, el, lt, tr
+ * @param bool $lower [optional]Use lowercase string, otherwise use uppercase string. PS: uppercase + * is for some languages better ...
+ * + * @psalm-pure + * + * @return string + */ + public static function strtocasefold( + string $str, + bool $full = true, + bool $clean_utf8 = false, + string $encoding = 'UTF-8', + string $lang = null, + bool $lower = true + ): string { + if ($str === '') { + return ''; + } + + if ($clean_utf8) { + // "mb_strpos()" and "iconv_strpos()" returns wrong position, + // if invalid characters are found in $haystack before $needle + $str = self::clean($str); + } + + $str = self::fixStrCaseHelper($str, $lower, $full); + + if ($lang === null && $encoding === 'UTF-8') { + if ($lower) { + return \mb_strtolower($str); + } + + return \mb_strtoupper($str); + } + + if ($lower) { + return self::strtolower($str, $encoding, false, $lang); + } + + return self::strtoupper($str, $encoding, false, $lang); + } + + /** + * Make a string lowercase. + * + * EXAMPLE:UTF8::strtolower('DÉJÀ Σσς Iıİi'); // 'déjà σσς iıii'
+ *
+ * @see http://php.net/manual/en/function.mb-strtolower.php
+ *
+ * @param string $str The string being lowercased.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * @param string|null $lang [optional]Set the language for special cases: az, el, lt, + * tr
+ * @param bool $try_to_keep_the_string_length [optional]true === try to keep the string length: e.g. ẞ + * -> ß
+ * + * @psalm-pure + * + * @return string + *String with all alphabetic characters converted to lowercase.
+ */ + public static function strtolower( + $str, + string $encoding = 'UTF-8', + bool $clean_utf8 = false, + string $lang = null, + bool $try_to_keep_the_string_length = false + ): string { + // init + $str = (string) $str; + + if ($str === '') { + return ''; + } + + if ($clean_utf8) { + // "mb_strpos()" and "iconv_strpos()" returns wrong position, + // if invalid characters are found in $haystack before $needle + $str = self::clean($str); + } + + // hack for old php version or for the polyfill ... + if ($try_to_keep_the_string_length) { + $str = self::fixStrCaseHelper($str, true); + } + + if ($lang === null && $encoding === 'UTF-8') { + return \mb_strtolower($str); + } + + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + + if ($lang !== null) { + if (self::$SUPPORT['intl'] === true) { + if (self::$INTL_TRANSLITERATOR_LIST === null) { + self::$INTL_TRANSLITERATOR_LIST = self::getData('transliterator_list'); + } + + $language_code = $lang . '-Lower'; + if (!\in_array($language_code, self::$INTL_TRANSLITERATOR_LIST, true)) { + /** + * @psalm-suppress ImpureFunctionCall - this is only a warning + */ + \trigger_error('UTF8::strtolower() cannot handle special language: ' . $lang . ' | supported: ' . \print_r(self::$INTL_TRANSLITERATOR_LIST, true), \E_USER_WARNING); + + $language_code = 'Any-Lower'; + } + + return (string) \transliterator_transliterate($language_code, $str); + } + + /** + * @psalm-suppress ImpureFunctionCall - this is only a warning + */ + \trigger_error('UTF8::strtolower() without intl cannot handle the "lang" parameter: ' . $lang, \E_USER_WARNING); + } + + // always fallback via symfony polyfill + return \mb_strtolower($str, $encoding); + } + + /** + * Make a string uppercase. + * + * EXAMPLE:UTF8::strtoupper('Déjà Σσς Iıİi'); // 'DÉJÀ ΣΣΣ IIİI'
+ *
+ * @see http://php.net/manual/en/function.mb-strtoupper.php
+ *
+ * @param string $str The string being uppercased.
+ * @param string $encoding [optional]Set the charset.
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * @param string|null $lang [optional]Set the language for special cases: az, el, lt, + * tr
+ * @param bool $try_to_keep_the_string_length [optional]true === try to keep the string length: e.g. ẞ + * -> ß
+ * + * @psalm-pure + * + * @return string + *String with all alphabetic characters converted to uppercase.
+ */ + public static function strtoupper( + $str, + string $encoding = 'UTF-8', + bool $clean_utf8 = false, + string $lang = null, + bool $try_to_keep_the_string_length = false + ): string { + // init + $str = (string) $str; + + if ($str === '') { + return ''; + } + + if ($clean_utf8) { + // "mb_strpos()" and "iconv_strpos()" returns wrong position, + // if invalid characters are found in $haystack before $needle + $str = self::clean($str); + } + + // hack for old php version or for the polyfill ... + if ($try_to_keep_the_string_length) { + $str = self::fixStrCaseHelper($str); + } + + if ($lang === null && $encoding === 'UTF-8') { + return \mb_strtoupper($str); + } + + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + + if ($lang !== null) { + if (self::$SUPPORT['intl'] === true) { + if (self::$INTL_TRANSLITERATOR_LIST === null) { + self::$INTL_TRANSLITERATOR_LIST = self::getData('transliterator_list'); + } + + $language_code = $lang . '-Upper'; + if (!\in_array($language_code, self::$INTL_TRANSLITERATOR_LIST, true)) { + /** + * @psalm-suppress ImpureFunctionCall - this is only a warning + */ + \trigger_error('UTF8::strtoupper() without intl for special language: ' . $lang, \E_USER_WARNING); + + $language_code = 'Any-Upper'; + } + + return (string) \transliterator_transliterate($language_code, $str); + } + + /** + * @psalm-suppress ImpureFunctionCall - this is only a warning + */ + \trigger_error('UTF8::strtolower() without intl cannot handle the "lang"-parameter: ' . $lang, \E_USER_WARNING); + } + + // always fallback via symfony polyfill + return \mb_strtoupper($str, $encoding); + } + + /** + * Translate characters or replace sub-strings. + * + * EXAMPLE: + *
+ * $array = [
+ * 'Hello' => '○●◎',
+ * '中文空白' => 'earth',
+ * ];
+ * UTF8::strtr('Hello 中文空白', $array); // '○●◎ earth'
+ *
+ *
+ * @see http://php.net/manual/en/function.strtr.php
+ *
+ * @param string $str The string being translated.
+ * @param string|string[] $fromThe string replacing from.
+ * @param string|string[] $to [optional]The string being translated to to.
+ * + * @psalm-pure + * + * @return string + *This function returns a copy of str, translating all occurrences of each character in "from" + * to the corresponding character in "to".
+ */ + public static function strtr(string $str, $from, $to = ''): string + { + if ($str === '') { + return ''; + } + + if ($from === $to) { + return $str; + } + + if ($to !== '') { + if (!\is_array($from)) { + $from = self::str_split($from); + } + + if (!\is_array($to)) { + $to = self::str_split($to); + } + + $count_from = \count($from); + $count_to = \count($to); + + if ($count_from !== $count_to) { + if ($count_from > $count_to) { + $from = \array_slice($from, 0, $count_to); + } elseif ($count_from < $count_to) { + $to = \array_slice($to, 0, $count_from); + } + } + + try { + $from = \array_combine($from, $to); + } catch (\Error $e) { + // PHP >= 8.0 : array_combine() will now throw a ValueError if the number of elements for each array is not equal; previously this function returned false instead. + $from = false; + } + if ($from === false) { + throw new \InvalidArgumentException('The number of elements for each array isn\'t equal or the arrays are empty: (from: ' . \print_r($from, true) . ' | to: ' . \print_r($to, true) . ')'); + } + } + + if (\is_string($from)) { + return \str_replace($from, $to, $str); + } + + return \strtr($str, $from); + } + + /** + * Return the width of a string. + * + * INFO: use UTF8::strlen() for the byte-length + * + * EXAMPLE:UTF8::strwidth("Iñtërnâtiôn\xE9àlizætiøn")); // 21
+ *
+ * @param string $str The input string.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * + * @psalm-pure + * + * @return int + * + * @phpstan-return 0|positive-int + */ + public static function strwidth( + string $str, + string $encoding = 'UTF-8', + bool $clean_utf8 = false + ): int { + if ($str === '') { + return 0; + } + + if ($encoding !== 'UTF-8' && $encoding !== 'CP850') { + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + } + + if ($clean_utf8) { + // iconv and mbstring are not tolerant to invalid encoding + // further, their behaviour is inconsistent with that of PHP's substr + $str = self::clean($str); + } + + // + // fallback via mbstring + // + + if (self::$SUPPORT['mbstring'] === true) { + if ($encoding === 'UTF-8') { + return \mb_strwidth($str); + } + + return \mb_strwidth($str, $encoding); + } + + // + // fallback via vanilla php + // + + if ($encoding !== 'UTF-8') { + $str = self::encode('UTF-8', $str, false, $encoding); + } + + $wide = 0; + $str = (string) \preg_replace('/[\x{1100}-\x{115F}\x{2329}\x{232A}\x{2E80}-\x{303E}\x{3040}-\x{A4CF}\x{AC00}-\x{D7A3}\x{F900}-\x{FAFF}\x{FE10}-\x{FE19}\x{FE30}-\x{FE6F}\x{FF00}-\x{FF60}\x{FFE0}-\x{FFE6}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}]/u', '', $str, -1, $wide); + + /* @phpstan-ignore-next-line | should return 0|positive-int */ + return ($wide << 1) + (int) self::strlen($str); + } + + /** + * Get part of a string. + * + * EXAMPLE:UTF8::substr('中文空白', 1, 2); // '文空'
+ *
+ * @see http://php.net/manual/en/function.mb-substr.php
+ *
+ * @param string $str The string being checked.
+ * @param int $offsetThe first position used in str.
+ * @param int|null $length [optional]The maximum length of the returned string.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * + * @psalm-pure + * + * @return false|string + * The portion of str specified by the offset and + * length parameters.If str is shorter than offset
+ * characters long, FALSE will be returned.
+ */
+ public static function substr(
+ string $str,
+ int $offset = 0,
+ int $length = null,
+ string $encoding = 'UTF-8',
+ bool $clean_utf8 = false
+ ) {
+ // empty string
+ if ($str === '' || $length === 0) {
+ return '';
+ }
+
+ if ($clean_utf8) {
+ // iconv and mbstring are not tolerant to invalid encoding
+ // further, their behaviour is inconsistent with that of PHP's substr
+ $str = self::clean($str);
+ }
+
+ // whole string
+ if (!$offset && $length === null) {
+ return $str;
+ }
+
+ if ($encoding !== 'UTF-8' && $encoding !== 'CP850') {
+ $encoding = self::normalize_encoding($encoding, 'UTF-8');
+ }
+
+ //
+ // fallback via mbstring
+ //
+
+ if (self::$SUPPORT['mbstring'] === true && $encoding === 'UTF-8') {
+ if ($length === null) {
+ return \mb_substr($str, $offset);
+ }
+
+ return \mb_substr($str, $offset, $length);
+ }
+
+ //
+ // fallback for binary || ascii only
+ //
+
+ if (
+ $encoding === 'CP850'
+ ||
+ $encoding === 'ASCII'
+ ) {
+ if ($length === null) {
+ return \substr($str, $offset);
+ }
+
+ return \substr($str, $offset, $length);
+ }
+
+ // otherwise we need the string-length
+ $str_length = 0;
+ if (
+ $offset
+ ||
+ $length === null /* @phpstan-ignore-line | can be NULL here?! */
+ ) {
+ $str_length = self::strlen($str, $encoding);
+ }
+
+ // e.g.: invalid chars + mbstring not installed
+ if ($str_length === false) {
+ return false;
+ }
+
+ // empty string
+ if ($offset === $str_length && !$length) {
+ return '';
+ }
+
+ // impossible
+ if ($offset && $offset > $str_length) {
+ return '';
+ }
+
+ $length = $length ?? $str_length;
+
+ if (
+ $encoding !== 'UTF-8'
+ &&
+ self::$SUPPORT['mbstring'] === false
+ ) {
+ /**
+ * @psalm-suppress ImpureFunctionCall - this is only a warning
+ */
+ \trigger_error('UTF8::substr() without mbstring cannot handle "' . $encoding . '" encoding', \E_USER_WARNING);
+ }
+
+ //
+ // fallback via intl
+ //
+
+ if (
+ $encoding === 'UTF-8' // INFO: "grapheme_substr()" can't handle other encodings
+ &&
+ $offset >= 0 // grapheme_substr() can't handle negative offset
+ &&
+ self::$SUPPORT['intl'] === true
+ ) {
+ $return_tmp = \grapheme_substr($str, $offset, $length);
+ if ($return_tmp !== false) {
+ return $return_tmp;
+ }
+ }
+
+ //
+ // fallback via iconv
+ //
+
+ if (
+ $length >= 0 // "iconv_substr()" can't handle negative length
+ &&
+ self::$SUPPORT['iconv'] === true
+ ) {
+ $return_tmp = \iconv_substr($str, $offset, $length);
+ if ($return_tmp !== false) {
+ return $return_tmp;
+ }
+ }
+
+ //
+ // fallback for ascii only
+ //
+
+ if (ASCII::is_ascii($str)) {
+ return \substr($str, $offset, $length);
+ }
+
+ //
+ // fallback via vanilla php
+ //
+
+ // split to array, and remove invalid characters
+ // &&
+ // extract relevant part, and join to make sting again
+ return \implode('', \array_slice(self::str_split($str), $offset, $length));
+ }
+
+ /**
+ * Binary-safe comparison of two strings from an offset, up to a length of characters.
+ *
+ * EXAMPLE:
+ * UTF8::substr_compare("○●◎\r", '●◎', 0, 2); // -1
+ * UTF8::substr_compare("○●◎\r", '◎●', 1, 2); // 1
+ * UTF8::substr_compare("○●◎\r", '●◎', 1, 2); // 0
+ *
+ *
+ * @param string $str1
The main string being compared.
+ * @param string $str2The secondary string being compared.
+ * @param int $offset [optional]The start position for the comparison. If negative, it starts + * counting from the end of the string.
+ * @param int|null $length [optional]The length of the comparison. The default value is the largest + * of the length of the str compared to the length of main_str less the + * offset.
+ * @param bool $case_insensitivity [optional]If case_insensitivity is TRUE, comparison is case + * insensitive.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return int + * < 0 if str1 is less than str2;UTF8::substr_count('中文空白', '文空', 1, 2); // 1
+ *
+ * @see http://php.net/manual/en/function.substr-count.php
+ *
+ * @param string $haystack The string to search in.
+ * @param string $needleThe substring to search for.
+ * @param int $offset [optional]The offset where to start counting.
+ * @param int|null $length [optional]+ * The maximum length after the specified offset to search for the + * substring. It outputs a warning if the offset plus the length is + * greater than the haystack length. + *
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * + * @psalm-pure + * + * @return false|int + *This functions returns an integer or false if there isn't a string.
+ */ + public static function substr_count( + string $haystack, + string $needle, + int $offset = 0, + int $length = null, + string $encoding = 'UTF-8', + bool $clean_utf8 = false + ) { + if ($needle === '') { + return false; + } + + if ($haystack === '' || $length === 0) { + return 0; + } + + if ($encoding !== 'UTF-8' && $encoding !== 'CP850') { + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + } + + if ($clean_utf8) { + // "mb_strpos()" and "iconv_strpos()" returns wrong position, + // if invalid characters are found in $haystack before $needle + $needle = self::clean($needle); + $haystack = self::clean($haystack); + } + + if ($offset || $length > 0) { + if ($length === null) { + $length_tmp = self::strlen($haystack, $encoding); + if ($length_tmp === false) { + return false; + } + $length = $length_tmp; + } + + if ($encoding === 'UTF-8') { + $haystack = (string) \mb_substr($haystack, $offset, $length); + } else { + $haystack = (string) \mb_substr($haystack, $offset, $length, $encoding); + } + } + + if ( + $encoding !== 'UTF-8' + && + self::$SUPPORT['mbstring'] === false + ) { + /** + * @psalm-suppress ImpureFunctionCall - this is only a warning + */ + \trigger_error('UTF8::substr_count() without mbstring cannot handle "' . $encoding . '" encoding', \E_USER_WARNING); + } + + if (self::$SUPPORT['mbstring'] === true) { + if ($encoding === 'UTF-8') { + return \mb_substr_count($haystack, $needle); + } + + return \mb_substr_count($haystack, $needle, $encoding); + } + + \preg_match_all('/' . \preg_quote($needle, '/') . '/us', $haystack, $matches, \PREG_SET_ORDER); + + return \count($matches); + } + + /** + * Count the number of substring occurrences. + * + * @param string $haystack+ * The string being checked. + *
+ * @param string $needle+ * The string being found. + *
+ * @param int $offset [optional]+ * The offset where to start counting + *
+ * @param int|null $length [optional]+ * The maximum length after the specified offset to search for the + * substring. It outputs a warning if the offset plus the length is + * greater than the haystack length. + *
+ * + * @psalm-pure + * + * @return false|int + *The number of times the + * needle substring occurs in the + * haystack string.
+ */ + public static function substr_count_in_byte( + string $haystack, + string $needle, + int $offset = 0, + int $length = null + ) { + if ($haystack === '' || $needle === '') { + return 0; + } + + if ( + ($offset || $length !== null) + && + self::$SUPPORT['mbstring_func_overload'] === true + ) { + if ($length === null) { + $length_tmp = self::strlen($haystack); + if ($length_tmp === false) { + return false; + } + $length = $length_tmp; + } + + if ( + ( + $length !== 0 + && + $offset !== 0 + ) + && + ($length + $offset) <= 0 + && + \PHP_VERSION_ID < 71000 // output from "substr_count()" have changed in PHP 7.1 + ) { + return false; + } + + /** @var false|string $haystack_tmp - needed for PhpStan (stubs error) */ + $haystack_tmp = \substr($haystack, $offset, $length); + if ($haystack_tmp === false) { + $haystack_tmp = ''; + } + $haystack = (string) $haystack_tmp; + } + + if (self::$SUPPORT['mbstring_func_overload'] === true) { + // "mb_" is available if overload is used, so use it ... + return \mb_substr_count($haystack, $needle, 'CP850'); // 8-BIT + } + + if ($length === null) { + return \substr_count($haystack, $needle, $offset); + } + + return \substr_count($haystack, $needle, $offset, $length); + } + + /** + * Returns the number of occurrences of $substring in the given string. + * By default, the comparison is case-sensitive, but can be made insensitive + * by setting $case_sensitive to false. + * + * @param string $strThe input string.
+ * @param string $substringThe substring to search for.
+ * @param bool $case_sensitive [optional]Whether or not to enforce case-sensitivity. Default: true
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return int + * + * @phpstan-return 0|positive-int + */ + public static function substr_count_simple( + string $str, + string $substring, + bool $case_sensitive = true, + string $encoding = 'UTF-8' + ): int { + if ($str === '' || $substring === '') { + return 0; + } + + if ($encoding === 'UTF-8') { + if ($case_sensitive) { + return (int) \mb_substr_count($str, $substring); + } + + return (int) \mb_substr_count( + \mb_strtoupper($str), + \mb_strtoupper($substring) + ); + } + + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + + if ($case_sensitive) { + return (int) \mb_substr_count($str, $substring, $encoding); + } + + return (int) \mb_substr_count( + self::strtocasefold($str, true, false, $encoding, null, false), + self::strtocasefold($substring, true, false, $encoding, null, false), + $encoding + ); + } + + /** + * Removes a prefix ($needle) from the beginning of the string ($haystack), case-insensitive. + * + * EXMAPLE:
+ * UTF8::substr_ileft('ΚόσμεMiddleEnd', 'Κόσμε'); // 'MiddleEnd'
+ * UTF8::substr_ileft('ΚόσμεMiddleEnd', 'κόσμε'); // 'MiddleEnd'
+ *
+ *
+ * @param string $haystack The string to search in.
+ * @param string $needleThe substring to search for.
+ * + * @psalm-pure + * + * @return string + *Return the sub-string.
+ */ + public static function substr_ileft(string $haystack, string $needle): string + { + if ($haystack === '') { + return ''; + } + + if ($needle === '') { + return $haystack; + } + + if (self::str_istarts_with($haystack, $needle)) { + $haystack = (string) \mb_substr($haystack, (int) self::strlen($needle)); + } + + return $haystack; + } + + /** + * Get part of a string process in bytes. + * + * @param string $strThe string being checked.
+ * @param int $offsetThe first position used in str.
+ * @param int|null $length [optional]The maximum length of the returned string.
+ * + * @psalm-pure + * + * @return false|string + *The portion of str specified by the offset and + * length parameters.
If str is shorter than offset + * characters long, FALSE will be returned.
+ */ + public static function substr_in_byte(string $str, int $offset = 0, int $length = null) + { + // empty string + if ($str === '' || $length === 0) { + return ''; + } + + // whole string + if (!$offset && $length === null) { + return $str; + } + + if (self::$SUPPORT['mbstring_func_overload'] === true) { + // "mb_" is available if overload is used, so use it ... + return \mb_substr($str, $offset, $length, 'CP850'); // 8-BIT + } + + return \substr($str, $offset, $length ?? 2147483647); + } + + /** + * Removes a suffix ($needle) from the end of the string ($haystack), case-insensitive. + * + * EXAMPLE:
+ * UTF8::substr_iright('BeginMiddleΚόσμε', 'Κόσμε'); // 'BeginMiddle'
+ * UTF8::substr_iright('BeginMiddleΚόσμε', 'κόσμε'); // 'BeginMiddle'
+ *
+ *
+ * @param string $haystack The string to search in.
+ * @param string $needleThe substring to search for.
+ * + * @psalm-pure + * + * @return string + *Return the sub-string.
+ */
+ public static function substr_iright(string $haystack, string $needle): string
+ {
+ if ($haystack === '') {
+ return '';
+ }
+
+ if ($needle === '') {
+ return $haystack;
+ }
+
+ if (self::str_iends_with($haystack, $needle)) {
+ $haystack = (string) \mb_substr($haystack, 0, (int) self::strlen($haystack) - (int) self::strlen($needle));
+ }
+
+ return $haystack;
+ }
+
+ /**
+ * Removes a prefix ($needle) from the beginning of the string ($haystack).
+ *
+ * EXAMPLE:
+ * UTF8::substr_left('ΚόσμεMiddleEnd', 'Κόσμε'); // 'MiddleEnd'
+ * UTF8::substr_left('ΚόσμεMiddleEnd', 'κόσμε'); // 'ΚόσμεMiddleEnd'
+ *
+ *
+ * @param string $haystack
The string to search in.
+ * @param string $needleThe substring to search for.
+ * + * @psalm-pure + * + * @return string + *Return the sub-string.
+ */ + public static function substr_left(string $haystack, string $needle): string + { + if ($haystack === '') { + return ''; + } + + if ($needle === '') { + return $haystack; + } + + if (self::str_starts_with($haystack, $needle)) { + $haystack = (string) \mb_substr($haystack, (int) self::strlen($needle)); + } + + return $haystack; + } + + /** + * Replace text within a portion of a string. + * + * EXAMPLE:UTF8::substr_replace(array('Iñtërnâtiônàlizætiøn', 'foo'), 'æ', 1); // array('Iæñtërnâtiônàlizætiøn', 'fæoo')
+ *
+ * source: https://gist.github.com/stemar/8287074
+ *
+ * @param string|string[] $str The input string or an array of stings.
+ * @param string|string[] $replacementThe replacement string or an array of stings.
+ * @param int|int[] $offset
+ * If start is positive, the replacing will begin at the start'th offset
+ * into string.
+ *
+ * If start is negative, the replacing will begin at the start'th character
+ * from the end of string.
+ *
If given and is positive, it represents the length of the + * portion of string which is to be replaced. If it is negative, it + * represents the number of characters from the end of string at which to + * stop replacing. If it is not given, then it will default to strlen( + * string ); i.e. end the replacing at the end of string. Of course, if + * length is zero then this function will have the effect of inserting + * replacement into string at the given start offset.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return string|string[] + *The result string is returned. If string is an array then array is returned.
+ * + * @template TSubstrReplace string|string[] + * @phpstan-param TSubstrReplace $str + * @phpstan-return TSubstrReplace + */ + public static function substr_replace( + $str, + $replacement, + $offset, + $length = null, + string $encoding = 'UTF-8' + ) { + if (\is_array($str)) { + $num = \count($str); + + // the replacement + if (\is_array($replacement)) { + $replacement = \array_slice($replacement, 0, $num); + } else { + $replacement = \array_pad([$replacement], $num, $replacement); + } + + // the offset + if (\is_array($offset)) { + $offset = \array_slice($offset, 0, $num); + foreach ($offset as &$value_tmp) { + $value_tmp = (int) $value_tmp === $value_tmp ? $value_tmp : 0; + } + unset($value_tmp); + } else { + $offset = \array_pad([$offset], $num, $offset); + } + + // the length + if ($length === null) { + $length = \array_fill(0, $num, 0); + } elseif (\is_array($length)) { + $length = \array_slice($length, 0, $num); + foreach ($length as &$value_tmp_V2) { + $value_tmp_V2 = (int) $value_tmp_V2 === $value_tmp_V2 ? $value_tmp_V2 : $num; + } + unset($value_tmp_V2); + } else { + $length = \array_pad([$length], $num, $length); + } + + // recursive call + /** @phpstan-ignore-next-line - phpstan currently can't handle recursive calls */ + return \array_map([self::class, 'substr_replace'], $str, $replacement, $offset, $length); + } + + if (\is_array($replacement)) { + if ($replacement !== []) { + $replacement = $replacement[0]; + } else { + $replacement = ''; + } + } + + // init + $str = (string) $str; + $replacement = (string) $replacement; + + if (\is_array($length)) { + throw new \InvalidArgumentException('Parameter "$length" can only be an array, if "$str" is also an array.'); + } + + if (\is_array($offset)) { + throw new \InvalidArgumentException('Parameter "$offset" can only be an array, if "$str" is also an array.'); + } + + if ($str === '') { + return $replacement; + } + + if (self::$SUPPORT['mbstring'] === true) { + $string_length = (int) self::strlen($str, $encoding); + + if ($offset < 0) { + $offset = (int) \max(0, $string_length + $offset); + } elseif ($offset > $string_length) { + $offset = $string_length; + } + + if ($length !== null && $length < 0) { + $length = (int) \max(0, $string_length - $offset + $length); + } elseif ($length === null || $length > $string_length) { + $length = $string_length; + } + + if (($offset + $length) > $string_length) { + $length = $string_length - $offset; + } + + return ((string) \mb_substr($str, 0, $offset, $encoding)) . + $replacement . + ((string) \mb_substr($str, $offset + $length, $string_length - $offset - $length, $encoding)); + } + + // + // fallback for ascii only + // + + if (ASCII::is_ascii($str)) { + return ($length === null) ? + \substr_replace($str, $replacement, $offset) : + \substr_replace($str, $replacement, $offset, $length); + } + + // + // fallback via vanilla php + // + + \preg_match_all('/./us', $str, $str_matches); + \preg_match_all('/./us', $replacement, $replacement_matches); + + if ($length === null) { + $length_tmp = self::strlen($str, $encoding); + if ($length_tmp === false) { + // e.g.: non mbstring support + invalid chars + return ''; + } + $length = $length_tmp; + } + + \array_splice($str_matches[0], $offset, $length, $replacement_matches[0]); + + return \implode('', $str_matches[0]); + } + + /** + * Removes a suffix ($needle) from the end of the string ($haystack). + * + * EXAMPLE:
+ * UTF8::substr_right('BeginMiddleΚόσμε', 'Κόσμε'); // 'BeginMiddle'
+ * UTF8::substr_right('BeginMiddleΚόσμε', 'κόσμε'); // 'BeginMiddleΚόσμε'
+ *
+ *
+ * @param string $haystack The string to search in.
+ * @param string $needleThe substring to search for.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * + * @psalm-pure + * + * @return string + *Return the sub-string.
+ */ + public static function substr_right( + string $haystack, + string $needle, + string $encoding = 'UTF-8' + ): string { + if ($haystack === '') { + return ''; + } + + if ($needle === '') { + return $haystack; + } + + if ( + $encoding === 'UTF-8' + && + \substr($haystack, -\strlen($needle)) === $needle + ) { + return (string) \mb_substr($haystack, 0, (int) \mb_strlen($haystack) - (int) \mb_strlen($needle)); + } + + if (\substr($haystack, -\strlen($needle)) === $needle) { + return (string) self::substr( + $haystack, + 0, + (int) self::strlen($haystack, $encoding) - (int) self::strlen($needle, $encoding), + $encoding + ); + } + + return $haystack; + } + + /** + * Returns a case swapped version of the string. + * + * EXAMPLE:UTF8::swapCase('déJÀ σσς iıII'); // 'DÉjà ΣΣΣ IIii'
+ *
+ * @param string $str The input string.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * + * @psalm-pure + * + * @return string + *Each character's case swapped.
+ */ + public static function swapCase(string $str, string $encoding = 'UTF-8', bool $clean_utf8 = false): string + { + if ($str === '') { + return ''; + } + + if ($clean_utf8) { + // "mb_strpos()" and "iconv_strpos()" returns wrong position, + // if invalid characters are found in $haystack before $needle + $str = self::clean($str); + } + + if ($encoding === 'UTF-8') { + return (string) (\mb_strtolower($str) ^ \mb_strtoupper($str) ^ $str); + } + + return (string) (self::strtolower($str, $encoding) ^ self::strtoupper($str, $encoding) ^ $str); + } + + /** + * Checks whether symfony-polyfills are used. + * + * @psalm-pure + * + * @return bool + *true if in use, false otherwise
+ * + * @internalPlease do not use it anymore, we will make is private in next major version.
+ */ + public static function symfony_polyfill_used(): bool + { + // init + $return = false; + + $return_tmp = \extension_loaded('mbstring'); + if (!$return_tmp && \function_exists('mb_strlen')) { + $return = true; + } + + $return_tmp = \extension_loaded('iconv'); + if (!$return_tmp && \function_exists('iconv')) { + $return = true; + } + + return $return; + } + + /** + * @param string $str + * @param int $tab_length + * + * @psalm-pure + * + * @return string + */ + public static function tabs_to_spaces(string $str, int $tab_length = 4): string + { + if ($tab_length === 4) { + $spaces = ' '; + } elseif ($tab_length === 2) { + $spaces = ' '; + } else { + $spaces = \str_repeat(' ', $tab_length); + } + + return \str_replace("\t", $spaces, $str); + } + + /** + * Converts the first character of each word in the string to uppercase + * and all other chars to lowercase. + * + * @param string $strThe input string.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * @param string|null $lang [optional]Set the language for special cases: az, el, lt, + * tr
+ * @param bool $try_to_keep_the_string_length [optional]true === try to keep the string length: e.g. ẞ + * -> ß
+ * + * @psalm-pure + * + * @return string + *A string with all characters of $str being title-cased.
+ */ + public static function titlecase( + string $str, + string $encoding = 'UTF-8', + bool $clean_utf8 = false, + string $lang = null, + bool $try_to_keep_the_string_length = false + ): string { + if ($clean_utf8) { + // "mb_strpos()" and "iconv_strpos()" returns wrong position, + // if invalid characters are found in $haystack before $needle + $str = self::clean($str); + } + + if ( + $lang === null + && + !$try_to_keep_the_string_length + ) { + if ($encoding === 'UTF-8') { + return \mb_convert_case($str, \MB_CASE_TITLE); + } + + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + + return \mb_convert_case($str, \MB_CASE_TITLE, $encoding); + } + + return self::str_titleize( + $str, + null, + $encoding, + false, + $lang, + $try_to_keep_the_string_length, + false + ); + } + + /** + * Convert a string into ASCII. + * + * EXAMPLE:UTF8::to_ascii('déjà σσς iıii'); // 'deja sss iiii'
+ *
+ * @param string $str The input string.
+ * @param string $unknown [optional]Character use if character unknown. (default is ?)
+ * @param bool $strict [optional]Use "transliterator_transliterate()" from PHP-Intl | WARNING: bad + * performance
+ * + * @psalm-pure + * + * @return string + */ + public static function to_ascii( + string $str, + string $unknown = '?', + bool $strict = false + ): string { + return ASCII::to_transliterate($str, $unknown, $strict); + } + + /** + * @param bool|float|int|string $str + * + * @psalm-pure + * + * @return bool + */ + public static function to_boolean($str): bool + { + // init + $str = (string) $str; + + if ($str === '') { + return false; + } + + // Info: http://php.net/manual/en/filter.filters.validate.php + $map = [ + 'true' => true, + '1' => true, + 'on' => true, + 'yes' => true, + 'false' => false, + '0' => false, + 'off' => false, + 'no' => false, + ]; + + if (isset($map[$str])) { + return $map[$str]; + } + + $key = \strtolower($str); + if (isset($map[$key])) { + return $map[$key]; + } + + if (\is_numeric($str)) { + return ((float) $str) > 0; + } + + return (bool) \trim($str); + } + + /** + * Convert given string to safe filename (and keep string case). + * + * @param string $str + * @param bool $use_transliterate No transliteration, conversion etc. is done by default - unsafe characters are + * simply replaced with hyphen. + * @param string $fallback_char + * + * @psalm-pure + * + * @return string + */ + public static function to_filename( + string $str, + bool $use_transliterate = false, + string $fallback_char = '-' + ): string { + return ASCII::to_filename( + $str, + $use_transliterate, + $fallback_char + ); + } + + /** + * Convert a string into "ISO-8859"-encoding (Latin-1). + * + * EXAMPLE:UTF8::to_utf8(UTF8::to_iso8859(' -ABC-中文空白- ')); // ' -ABC-????- '
+ *
+ * @param string|string[] $str
+ *
+ * @psalm-pure
+ *
+ * @return string|string[]
+ *
+ * @template TToIso8859 as string|string[]
+ * @phpstan-param TToIso8859 $str
+ * @phpstan-return (TToIso8859 is string ? string : string[])
+ */
+ public static function to_iso8859($str)
+ {
+ if (\is_array($str)) {
+ foreach ($str as &$v) {
+ $v = self::to_iso8859($v);
+ }
+
+ return $str;
+ }
+
+ /* @phpstan-ignore-next-line | FP? -> "Cannot cast TToIso8859 of arrayUTF8::to_utf8(["\u0063\u0061\u0074"]); // array('cat')
+ *
+ * @param string|string[] $str Any string or array of strings.
+ * @param bool $decode_html_entity_to_utf8Set to true, if you need to decode html-entities.
+ * + * @psalm-pure + * + * @return string|string[] + *The UTF-8 encoded string
+ * + * @template TToUtf8 as string|string[] + * @phpstan-param TToUtf8 $str + * @phpstan-return (TToUtf8 is string ? string : string[]) + */ + public static function to_utf8($str, bool $decode_html_entity_to_utf8 = false) + { + if (\is_array($str)) { + foreach ($str as &$v) { + $v = self::to_utf8_string($v, $decode_html_entity_to_utf8); + } + + /** @phpstan-var TToUtf8 $str */ + return $str; + } + + \assert(\is_string($str)); + + $str = self::to_utf8_string($str, $decode_html_entity_to_utf8); + + /** @phpstan-var TToUtf8 $str */ + return $str; + } + + /** + * This function leaves UTF-8 characters alone, while converting almost all non-UTF8 to UTF8. + * + *UTF8::to_utf8_string("\u0063\u0061\u0074"); // 'cat'
+ *
+ * @param string $str Any string.
+ * @param bool $decode_html_entity_to_utf8Set to true, if you need to decode html-entities.
+ * + * @psalm-pure + * + * @return string + *The UTF-8 encoded string
+ * + * @template T as string + * @phpstan-param T $str + * @phpstan-return (T is non-empty-string ? non-empty-string : string) + */ + public static function to_utf8_string(string $str, bool $decode_html_entity_to_utf8 = false): string + { + if ($str === '') { + return $str; + } + + $max = \strlen($str); + $buf = ''; + + for ($i = 0; $i < $max; ++$i) { + $c1 = $str[$i]; + + if ($c1 >= "\xC0") { // should be converted to UTF8, if it's not UTF8 already + + if ($c1 <= "\xDF") { // looks like 2 bytes UTF8 + + $c2 = $i + 1 >= $max ? "\x00" : $str[$i + 1]; + + if ($c2 >= "\x80" && $c2 <= "\xBF") { // yeah, almost sure it's UTF8 already + $buf .= $c1 . $c2; + ++$i; + } else { // not valid UTF8 - convert it + $buf .= self::to_utf8_convert_helper($c1); + } + } elseif ($c1 >= "\xE0" && $c1 <= "\xEF") { // looks like 3 bytes UTF8 + + $c2 = $i + 1 >= $max ? "\x00" : $str[$i + 1]; + $c3 = $i + 2 >= $max ? "\x00" : $str[$i + 2]; + + if ($c2 >= "\x80" && $c2 <= "\xBF" && $c3 >= "\x80" && $c3 <= "\xBF") { // yeah, almost sure it's UTF8 already + $buf .= $c1 . $c2 . $c3; + $i += 2; + } else { // not valid UTF8 - convert it + $buf .= self::to_utf8_convert_helper($c1); + } + } elseif ($c1 >= "\xF0" && $c1 <= "\xF7") { // looks like 4 bytes UTF8 + + $c2 = $i + 1 >= $max ? "\x00" : $str[$i + 1]; + $c3 = $i + 2 >= $max ? "\x00" : $str[$i + 2]; + $c4 = $i + 3 >= $max ? "\x00" : $str[$i + 3]; + + if ($c2 >= "\x80" && $c2 <= "\xBF" && $c3 >= "\x80" && $c3 <= "\xBF" && $c4 >= "\x80" && $c4 <= "\xBF") { // yeah, almost sure it's UTF8 already + $buf .= $c1 . $c2 . $c3 . $c4; + $i += 3; + } else { // not valid UTF8 - convert it + $buf .= self::to_utf8_convert_helper($c1); + } + } else { // doesn't look like UTF8, but should be converted + + $buf .= self::to_utf8_convert_helper($c1); + } + } elseif (($c1 & "\xC0") === "\x80") { // needs conversion + + $buf .= self::to_utf8_convert_helper($c1); + } else { // it doesn't need conversion + + $buf .= $c1; + } + } + + // decode unicode escape sequences + unicode surrogate pairs + $buf = \preg_replace_callback( + '/\\\\u([dD][89abAB][0-9a-fA-F]{2})\\\\u([dD][cdefCDEF][\da-fA-F]{2})|\\\\u([0-9a-fA-F]{4})/', + /** + * @param array $matches + * + * @psalm-pure + * + * @return string + */ + static function (array $matches): string { + if (isset($matches[3])) { + $cp = (int) \hexdec($matches[3]); + } else { + // http://unicode.org/faq/utf_bom.html#utf16-4 + $cp = ((int) \hexdec($matches[1]) << 10) + + (int) \hexdec($matches[2]) + + 0x10000 + - (0xD800 << 10) + - 0xDC00; + } + + // https://github.com/php/php-src/blob/php-7.3.2/ext/standard/html.c#L471 + // + // php_utf32_utf8(unsigned char *buf, unsigned k) + + if ($cp < 0x80) { + return (string) self::chr($cp); + } + + if ($cp < 0xA0) { + /** @noinspection UnnecessaryCastingInspection */ + return (string) self::chr(0xC0 | $cp >> 6) . (string) self::chr(0x80 | $cp & 0x3F); + } + + return self::decimal_to_chr($cp); + }, + $buf + ); + + if ($buf === null) { + return ''; + } + + // decode UTF-8 codepoints + if ($decode_html_entity_to_utf8) { + $buf = self::html_entity_decode($buf); + } + + return $buf; + } + + /** + * Returns the given string as an integer, or null if the string isn't numeric. + * + * @param string $str + * + * @psalm-pure + * + * @return int|null + *null if the string isn't numeric
+ */ + public static function to_int(string $str) + { + if (\is_numeric($str)) { + return (int) $str; + } + + return null; + } + + /** + * Returns the given input as string, or null if the input isn't int|float|string + * and do not implement the "__toString()" method. + * + * @param float|int|object|string|null $input + * + * @psalm-pure + * + * @return string|null + *null if the input isn't int|float|string and has no "__toString()" method
+ */ + public static function to_string($input) + { + if ($input === null) { + return null; + } + + $input_type = \gettype($input); + + if ( + $input_type === 'string' + || + $input_type === 'integer' + || + $input_type === 'float' + || + $input_type === 'double' + ) { + /* @phpstan-ignore-next-line | "gettype" is not supported by phpstan?! */ + return (string) $input; + } + + /** @phpstan-ignore-next-line - "gettype": FP? */ + if ($input_type === 'object' && \method_exists($input, '__toString')) { + return (string) $input; + } + + return null; + } + + /** + * Strip whitespace or other characters from the beginning and end of a UTF-8 string. + * + * INFO: This is slower then "trim()" + * + * We can only use the original-function, if we use <= 7-Bit in the string / chars + * but the check for ASCII (7-Bit) cost more time, then we can safe here. + * + * EXAMPLE:UTF8::trim(' -ABC-中文空白- '); // '-ABC-中文空白-'
+ *
+ * @param string $str The string to be trimmed
+ * @param string|null $chars [optional]Optional characters to be stripped
+ * + * @psalm-pure + * + * @return string + *The trimmed string.
+ */ + public static function trim(string $str = '', string $chars = null): string + { + if ($str === '') { + return ''; + } + + if (self::$SUPPORT['mbstring'] === true) { + if ($chars !== null) { + /** @noinspection PregQuoteUsageInspection */ + $chars = \preg_quote($chars); + $pattern = "^[{$chars}]+|[{$chars}]+\$"; + } else { + $pattern = '^[\\s]+|[\\s]+$'; + } + + return (string) \mb_ereg_replace($pattern, '', $str); + } + + if ($chars !== null) { + $chars = \preg_quote($chars, '/'); + $pattern = "^[{$chars}]+|[{$chars}]+\$"; + } else { + $pattern = '^[\\s]+|[\\s]+$'; + } + + return self::regex_replace($str, $pattern, ''); + } + + /** + * Makes string's first char uppercase. + * + * EXAMPLE:UTF8::ucfirst('ñtërnâtiônàlizætiøn foo'); // 'Ñtërnâtiônàlizætiøn foo'
+ *
+ * @param string $str The input string.
+ * @param string $encoding [optional]Set the charset for e.g. "mb_" function
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * @param string|null $lang [optional]Set the language for special cases: az, el, lt, + * tr
+ * @param bool $try_to_keep_the_string_length [optional]true === try to keep the string length: e.g. ẞ + * -> ß
+ * + * @psalm-pure + * + * @return string + *The resulting string with with char uppercase.
+ */ + public static function ucfirst( + string $str, + string $encoding = 'UTF-8', + bool $clean_utf8 = false, + string $lang = null, + bool $try_to_keep_the_string_length = false + ): string { + if ($str === '') { + return ''; + } + + if ($clean_utf8) { + // "mb_strpos()" and "iconv_strpos()" returns wrong position, + // if invalid characters are found in $haystack before $needle + $str = self::clean($str); + } + + $use_mb_functions = $lang === null && !$try_to_keep_the_string_length; + + if ($encoding === 'UTF-8') { + $str_part_two = (string) \mb_substr($str, 1); + + if ($use_mb_functions) { + $str_part_one = \mb_strtoupper( + (string) \mb_substr($str, 0, 1) + ); + } else { + $str_part_one = self::strtoupper( + (string) \mb_substr($str, 0, 1), + $encoding, + false, + $lang, + $try_to_keep_the_string_length + ); + } + } else { + $encoding = self::normalize_encoding($encoding, 'UTF-8'); + + $str_part_two = (string) self::substr($str, 1, null, $encoding); + + if ($use_mb_functions) { + $str_part_one = \mb_strtoupper( + (string) \mb_substr($str, 0, 1, $encoding), + $encoding + ); + } else { + $str_part_one = self::strtoupper( + (string) self::substr($str, 0, 1, $encoding), + $encoding, + false, + $lang, + $try_to_keep_the_string_length + ); + } + } + + return $str_part_one . $str_part_two; + } + + /** + * Uppercase for all words in the string. + * + * EXAMPLE:UTF8::ucwords('iñt ërn âTi ônà liz æti øn'); // 'Iñt Ërn ÂTi Ônà Liz Æti Øn'
+ *
+ * @param string $str The input string.
+ * @param string[] $exceptions [optional]Exclusion for some words.
+ * @param string $char_list [optional]Additional chars that contains to words and do not start a new + * word.
+ * @param string $encoding [optional]Set the charset.
+ * @param bool $clean_utf8 [optional]Remove non UTF-8 chars from the string.
+ * + * @psalm-pure + * + * @return string + */ + public static function ucwords( + string $str, + array $exceptions = [], + string $char_list = '', + string $encoding = 'UTF-8', + bool $clean_utf8 = false + ): string { + if (!$str) { + return ''; + } + + // INFO: mb_convert_case($str, MB_CASE_TITLE); + // -> MB_CASE_TITLE didn't only uppercase the first letter, it also lowercase all other letters + + if ($clean_utf8) { + // "mb_strpos()" and "iconv_strpos()" returns wrong position, + // if invalid characters are found in $haystack before $needle + $str = self::clean($str); + } + + $use_php_default_functions = !(bool) ($char_list . \implode('', $exceptions)); + + if ( + $use_php_default_functions + && + ASCII::is_ascii($str) + ) { + return \ucwords($str); + } + + $words = self::str_to_words($str, $char_list); + $use_exceptions = $exceptions !== []; + + $words_str = ''; + foreach ($words as &$word) { + if (!$word) { + continue; + } + + if ( + !$use_exceptions + || + !\in_array($word, $exceptions, true) + ) { + $words_str .= self::ucfirst($word, $encoding); + } else { + $words_str .= $word; + } + } + + return $words_str; + } + + /** + * Multi decode HTML entity + fix urlencoded-win1252-chars. + * + * EXAMPLE:UTF8::urldecode('tes%20öäü%20\u00edtest+test'); // 'tes öäü ítest test'
+ *
+ * e.g:
+ * 'test+test' => 'test test'
+ * 'Düsseldorf' => 'Düsseldorf'
+ * 'D%FCsseldorf' => 'Düsseldorf'
+ * 'Düsseldorf' => 'Düsseldorf'
+ * 'D%26%23xFC%3Bsseldorf' => 'Düsseldorf'
+ * 'Düsseldorf' => 'Düsseldorf'
+ * 'D%C3%BCsseldorf' => 'Düsseldorf'
+ * 'D%C3%83%C2%BCsseldorf' => 'Düsseldorf'
+ * 'D%25C3%2583%25C2%25BCsseldorf' => 'Düsseldorf'
+ *
+ * @param string $str The input string.
+ * @param bool $multi_decodeDecode as often as possible.
+ * + * @psalm-pure + * + * @return string + * + * @template T as string + * @phpstan-param T $str + * @phpstan-return (T is non-empty-string ? non-empty-string : string) + */ + public static function urldecode(string $str, bool $multi_decode = true): string + { + if ($str === '') { + return ''; + } + + $str = self::urldecode_unicode_helper($str); + + if ($multi_decode) { + do { + $str_compare = $str; + + /** + * @psalm-suppress PossiblyInvalidArgument + */ + $str = \urldecode( + self::html_entity_decode( + self::to_utf8($str), + \ENT_QUOTES | \ENT_HTML5 + ) + ); + } while ($str_compare !== $str); + } else { + /** + * @psalm-suppress PossiblyInvalidArgument + */ + $str = \urldecode( + self::html_entity_decode( + self::to_utf8($str), + \ENT_QUOTES | \ENT_HTML5 + ) + ); + } + + return self::fix_simple_utf8($str); + } + + /** + * Decodes a UTF-8 string to ISO-8859-1. + * + * EXAMPLE:UTF8::encode('UTF-8', UTF8::utf8_decode('-ABC-中文空白-')); // '-ABC-????-'
+ *
+ * @param string $str The input string.
+ * @param bool $keep_utf8_chars + * + * @psalm-pure + * + * @return string + */ + public static function utf8_decode(string $str, bool $keep_utf8_chars = false): string + { + if ($str === '') { + return ''; + } + + // save for later comparision + $str_backup = $str; + $len = \strlen($str); + + if (self::$ORD === null) { + self::$ORD = self::getData('ord'); + } + + if (self::$CHR === null) { + self::$CHR = self::getData('chr'); + } + + $no_char_found = '?'; + for ($i = 0, $j = 0; $i < $len; ++$i, ++$j) { + switch ($str[$i] & "\xF0") { + case "\xC0": + case "\xD0": + $c = (self::$ORD[$str[$i] & "\x1F"] << 6) | self::$ORD[$str[++$i] & "\x3F"]; + $str[$j] = $c < 256 ? self::$CHR[$c] : $no_char_found; + + break; + + case "\xF0": + ++$i; + + // no break + + case "\xE0": + $str[$j] = $no_char_found; + $i += 2; + + break; + + default: + $str[$j] = $str[$i]; + } + } + + /** @var false|string $return - needed for PhpStan (stubs error) */ + $return = \substr($str, 0, $j); + if ($return === false) { + $return = ''; + } + + if ( + $keep_utf8_chars + && + (int) self::strlen($return) >= (int) self::strlen($str_backup) + ) { + return $str_backup; + } + + return $return; + } + + /** + * Encodes an ISO-8859-1 string to UTF-8. + * + * EXAMPLE:UTF8::utf8_decode(UTF8::utf8_encode('-ABC-中文空白-')); // '-ABC-中文空白-'
+ *
+ * @param string $str The input string.
+ * + * @psalm-pure + * + * @return string + */ + public static function utf8_encode(string $str): string + { + if ($str === '') { + return ''; + } + + /** @noinspection PhpUsageOfSilenceOperatorInspection | TODO for PHP > 8.2: find a replacement for this */ + /** @var false|string $str - the polyfill maybe return false */ + $str = @\utf8_encode($str); + + if ($str === false) { + return ''; + } + + return $str; + } + + /** + * Returns an array with all utf8 whitespace characters. + * + * @see http://www.bogofilter.org/pipermail/bogofilter/2003-March/001889.html + * + * @psalm-pure + * + * @return string[] + * An array with all known whitespace characters as values and the type of whitespace as keys + * as defined in above URL + */ + public static function whitespace_table(): array + { + return self::$WHITESPACE_TABLE; + } + + /** + * Limit the number of words in a string. + * + * EXAMPLE:UTF8::words_limit('fòô bàř fòô', 2, ''); // 'fòô bàř'
+ *
+ * @param string $str The input string.
+ * @param int<1, max> $limitThe limit of words as integer.
+ * @param string $str_add_onReplacement for the striped string.
+ * + * @psalm-pure + * + * @return string + */ + public static function words_limit( + string $str, + int $limit = 100, + string $str_add_on = '…' + ): string { + if ( + $str === '' + || + /* @phpstan-ignore-next-line | we do not trust the phpdoc check */ + $limit <= 0 + ) { + return ''; + } + + \preg_match('/^\\s*+(?:[^\\s]++\\s*+){1,' . $limit . '}/u', $str, $matches); + + if ( + !isset($matches[0]) + || + \mb_strlen($str) === (int) \mb_strlen($matches[0]) + ) { + return $str; + } + + return \rtrim($matches[0]) . $str_add_on; + } + + /** + * Wraps a string to a given number of characters + * + * EXAMPLE:UTF8::wordwrap('Iñtërnâtiônàlizætiøn', 2, '
', true)); // 'Iñ
të
rn
ât
iô
nà
li
zæ
ti
øn'
+ *
+ * @see http://php.net/manual/en/function.wordwrap.php
+ *
+ * @param string $str The input string.
+ * @param int<1, max> $width [optional]The column width.
+ * @param string $break [optional]The line is broken using the optional break parameter.
+ * @param bool $cut [optional]+ * If the cut is set to true, the string is + * always wrapped at or before the specified width. So if you have + * a word that is larger than the given width, it is broken apart. + *
+ * + * @psalm-pure + * + * @return string + *The given string wrapped at the specified column.
+ */ + public static function wordwrap( + string $str, + int $width = 75, + string $break = "\n", + bool $cut = false + ): string { + if ($str === '' || $break === '') { + return ''; + } + + $str_split = \explode($break, $str); + + /** @var string[] $charsArray */ + $charsArray = []; + $word_split = ''; + foreach ($str_split as $i => $i_value) { + if ($i) { + $charsArray[] = $break; + $word_split .= '#'; + } + + foreach (self::str_split($i_value) as $c) { + $charsArray[] = $c; + if ($c === ' ') { + $word_split .= ' '; + } else { + $word_split .= '?'; + } + } + } + + $str_return = ''; + $j = 0; + $b = -1; + $i = -1; + $word_split = \wordwrap($word_split, $width, '#', $cut); + + $max = \mb_strlen($word_split); + /** @noinspection PhpAssignmentInConditionInspection - is ok here */ + while (($b = \mb_strpos($word_split, '#', $b + 1)) !== false) { + for (++$i; $i < $b; ++$i) { + if (isset($charsArray[$j])) { + $str_return .= $charsArray[$j]; + unset($charsArray[$j]); + } + ++$j; + + // prevent endless loop, e.g. if there is a error in the "mb_*" polyfill + if ($i > $max) { + break 2; + } + } + + if ( + $break === $charsArray[$j] + || + $charsArray[$j] === ' ' + ) { + unset($charsArray[$j++]); + } + + $str_return .= $break; + + // prevent endless loop, e.g. if there is a error in the "mb_*" polyfill + if ($b > $max) { + break; + } + } + + return $str_return . \implode('', $charsArray); + } + + /** + * Line-Wrap the string after $limit, but split the string by "$delimiter" before ... + * ... so that we wrap the per line. + * + * @param string $strThe input string.
+ * @param int<1, max> $width [optional]The column width.
+ * @param string $break [optional]The line is broken using the optional break parameter.
+ * @param bool $cut [optional]+ * If the cut is set to true, the string is + * always wrapped at or before the specified width. So if you have + * a word that is larger than the given width, it is broken apart. + *
+ * @param bool $add_final_break [optional]+ * If this flag is true, then the method will add a $break at the end + * of the result string. + *
+ * @param non-empty-string|null $delimiter [optional]+ * You can change the default behavior, where we split the string by newline. + *
+ * + * @psalm-pure + * + * @return string + */ + public static function wordwrap_per_line( + string $str, + int $width = 75, + string $break = "\n", + bool $cut = false, + bool $add_final_break = true, + string $delimiter = null + ): string { + if ($delimiter === null) { + $strings = \preg_split('/\\r\\n|\\r|\\n/', $str); + } else { + $strings = \explode($delimiter, $str); + } + + $string_helper_array = []; + if ($strings !== false) { + foreach ($strings as $value) { + $string_helper_array[] = self::wordwrap($value, $width, $break, $cut); + } + } + + if ($add_final_break) { + $final_break = $break; + } else { + $final_break = ''; + } + + return \implode($delimiter ?? "\n", $string_helper_array) . $final_break; + } + + /** + * Returns an array of Unicode White Space characters. + * + * @psalm-pure + * + * @return string[] + *An array with numeric code point as key and White Space Character as value.
+ */ + public static function ws(): array + { + return self::$WHITESPACE; + } + + /** + * Checks whether the passed string contains only byte sequences that are valid UTF-8 characters. + * + * EXAMPLE:
+ * UTF8::is_utf8_string('Iñtërnâtiônàlizætiøn']); // true
+ * //
+ * UTF8::is_utf8_string("Iñtërnâtiônàlizætiøn\xA0\xA1"); // false
+ *
+ *
+ * @see http://hsivonen.iki.fi/php-utf8/
+ *
+ * @param string $str The string to be checked.
+ * @param bool $strictCheck also if the string is not UTF-16 or UTF-32.
+ * + * @psalm-pure + * + * @return bool + */ + private static function is_utf8_string(string $str, bool $strict = false) + { + if ($str === '') { + return true; + } + + if ($strict) { + $is_binary = self::is_binary($str, true); + + if ($is_binary && self::is_utf16($str, false) !== false) { + return false; + } + + if ($is_binary && self::is_utf32($str, false) !== false) { + return false; + } + } + + if (self::$SUPPORT['pcre_utf8']) { + // If even just the first character can be matched, when the /u + // modifier is used, then it's valid UTF-8. If the UTF-8 is somehow + // invalid, nothing at all will match, even if the string contains + // some valid sequences + return \preg_match('/^./us', $str) === 1; + } + + $mState = 0; // cached expected number of octets after the current octet + // until the beginning of the next UTF8 character sequence + $mUcs4 = 0; // cached Unicode character + $mBytes = 1; // cached expected number of octets in the current sequence + + if (self::$ORD === null) { + self::$ORD = self::getData('ord'); + } + + $len = \strlen($str); + for ($i = 0; $i < $len; ++$i) { + $in = self::$ORD[$str[$i]]; + + if ($mState === 0) { + // When mState is zero we expect either a US-ASCII character or a + // multi-octet sequence. + if ((0x80 & $in) === 0) { + // US-ASCII, pass straight through. + $mBytes = 1; + } elseif ((0xE0 & $in) === 0xC0) { + // First octet of 2 octet sequence. + $mUcs4 = $in; + $mUcs4 = ($mUcs4 & 0x1F) << 6; + $mState = 1; + $mBytes = 2; + } elseif ((0xF0 & $in) === 0xE0) { + // First octet of 3 octet sequence. + $mUcs4 = $in; + $mUcs4 = ($mUcs4 & 0x0F) << 12; + $mState = 2; + $mBytes = 3; + } elseif ((0xF8 & $in) === 0xF0) { + // First octet of 4 octet sequence. + $mUcs4 = $in; + $mUcs4 = ($mUcs4 & 0x07) << 18; + $mState = 3; + $mBytes = 4; + } elseif ((0xFC & $in) === 0xF8) { + /* First octet of 5 octet sequence. + * + * This is illegal because the encoded codepoint must be either + * (a) not the shortest form or + * (b) outside the Unicode range of 0-0x10FFFF. + * Rather than trying to resynchronize, we will carry on until the end + * of the sequence and let the later error handling code catch it. + */ + $mUcs4 = $in; + $mUcs4 = ($mUcs4 & 0x03) << 24; + $mState = 4; + $mBytes = 5; + } elseif ((0xFE & $in) === 0xFC) { + // First octet of 6 octet sequence, see comments for 5 octet sequence. + $mUcs4 = $in; + $mUcs4 = ($mUcs4 & 1) << 30; + $mState = 5; + $mBytes = 6; + } else { + // Current octet is neither in the US-ASCII range nor a legal first + // octet of a multi-octet sequence. + return false; + } + } elseif ((0xC0 & $in) === 0x80) { + + // When mState is non-zero, we expect a continuation of the multi-octet + // sequence + + // Legal continuation. + $shift = ($mState - 1) * 6; + $tmp = $in; + $tmp = ($tmp & 0x0000003F) << $shift; + $mUcs4 |= $tmp; + // Prefix: End of the multi-octet sequence. mUcs4 now contains the final + // Unicode code point to be output. + if (--$mState === 0) { + // Check for illegal sequences and code points. + // + // From Unicode 3.1, non-shortest form is illegal + if ( + ($mBytes === 2 && $mUcs4 < 0x0080) + || + ($mBytes === 3 && $mUcs4 < 0x0800) + || + ($mBytes === 4 && $mUcs4 < 0x10000) + || + ($mBytes > 4) + || + // From Unicode 3.2, surrogate characters are illegal. + (($mUcs4 & 0xFFFFF800) === 0xD800) + || + // Code points outside the Unicode range are illegal. + ($mUcs4 > 0x10FFFF) + ) { + return false; + } + // initialize UTF8 cache + $mState = 0; + $mUcs4 = 0; + $mBytes = 1; + } + } else { + // ((0xC0 & (*in) != 0x80) && (mState != 0)) + // Incomplete multi-octet sequence. + return false; + } + } + + return $mState === 0; + } + + /** + * @param string $str + * @param bool $use_lowercaseUse uppercase by default, otherwise use lowercase.
+ * @param bool $use_full_case_foldConvert not only common cases.
+ * + * @psalm-pure + * + * @return string + */ + private static function fixStrCaseHelper( + string $str, + bool $use_lowercase = false, + bool $use_full_case_fold = false + ) { + $upper = self::$COMMON_CASE_FOLD['upper']; + $lower = self::$COMMON_CASE_FOLD['lower']; + + if ($use_lowercase) { + $str = \str_replace( + $upper, + $lower, + $str + ); + } else { + $str = \str_replace( + $lower, + $upper, + $str + ); + } + + if ($use_full_case_fold) { + /** + * @psalm-suppress ImpureStaticVariable + * + * @var arrayThe input string
+ * + * @psalm-pure + * + * @return string|null + */ + private static function strtonatfold(string $str) + { + $str = \Normalizer::normalize($str, \Normalizer::NFD); + if ($str === false) { + return ''; + } + + return \preg_replace( + '/\p{Mn}+/u', + '', + $str + ); + } + + /** + * @param int|string $input + * + * @psalm-pure + * + * @return string + */ + private static function to_utf8_convert_helper($input) + { + // init + $buf = ''; + + if (self::$ORD === null) { + self::$ORD = self::getData('ord'); + } + + if (self::$CHR === null) { + self::$CHR = self::getData('chr'); + } + + if (self::$WIN1252_TO_UTF8 === null) { + self::$WIN1252_TO_UTF8 = self::getData('win1252_to_utf8'); + } + + $ordC1 = self::$ORD[$input]; + if (isset(self::$WIN1252_TO_UTF8[$ordC1])) { // found in Windows-1252 special cases + $buf .= self::$WIN1252_TO_UTF8[$ordC1]; + } else { + $cc1 = self::$CHR[$ordC1 / 64] | "\xC0"; + $cc2 = ((string) $input & "\x3F") | "\x80"; + $buf .= $cc1 . $cc2; + } + + return $buf; + } + + /** + * @param string $str + * + * @psalm-pure + * + * @return string + */ + private static function urldecode_unicode_helper(string $str) + { + if (\strpos($str, '%u') === false) { + return $str; + } + + $pattern = '/%u([0-9a-fA-F]{3,4})/'; + if (\preg_match($pattern, $str)) { + $str = (string) \preg_replace($pattern, '\\1;', $str); + } + + return $str; + } +} \ No newline at end of file diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/ascii_by_languages.php b/includes/libraries/anti-xss-master/src/voku/helper/data/ascii_by_languages.php new file mode 100644 index 000000000..68c3f9d25 --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/ascii_by_languages.php @@ -0,0 +1,2950 @@ + [ + 'Á' => 'A', + 'á' => 'a', + 'Ä' => 'A', + 'ä' => 'a', + 'À' => 'A', + 'à' => 'a', + 'Â' => 'A', + 'â' => 'a', + 'É' => 'E', + 'é' => 'e', + 'Ë' => 'E', + 'ë' => 'e', + 'È' => 'E', + 'è' => 'e', + 'Ê' => 'E', + 'ê' => 'e', + 'Í' => 'I', + 'í' => 'i', + 'Ï' => 'I', + 'ï' => 'i', + 'Ì' => 'I', + 'ì' => 'i', + 'Î' => 'I', + 'î' => 'i', + 'Ó' => 'O', + 'ó' => 'o', + 'Ö' => 'O', + 'ö' => 'o', + 'Ò' => 'O', + 'ò' => 'o', + 'Ô' => 'O', + 'ô' => 'o', + 'Ú' => 'U', + 'ú' => 'u', + 'Ü' => 'U', + 'ü' => 'u', + 'Ù' => 'U', + 'ù' => 'u', + 'Û' => 'U', + 'û' => 'u', + 'Ý' => 'Y', + 'ý' => 'y', + 'Ÿ' => 'Y', + ], + // Italian + 'it' => [ + 'à' => 'a', + 'À' => 'A', + 'é' => 'e', + 'É' => 'E', + 'è' => 'e', + 'È' => 'E', + 'ì' => 'i', + 'Ì' => 'I', + 'Ò' => 'O', + 'ò' => 'o', + 'ù' => 'u', + 'Ù' => 'U', + ], + // Macedonian + 'mk' => [ + 'А' => 'A', + 'Б' => 'B', + 'В' => 'V', + 'Г' => 'G', + 'Д' => 'D', + 'Ѓ' => 'Gj', + 'Е' => 'E', + 'Ж' => 'Zh', + 'З' => 'Z', + 'Ѕ' => 'Dz', + 'И' => 'I', + 'Ј' => 'J', + 'К' => 'K', + 'Л' => 'L', + 'Љ' => 'Lj', + 'М' => 'M', + 'Н' => 'N', + 'Њ' => 'Nj', + 'О' => 'O', + 'П' => 'P', + 'Р' => 'R', + 'С' => 'S', + 'Т' => 'T', + 'Ќ' => 'Kj', + 'У' => 'U', + 'Ф' => 'F', + 'Х' => 'H', + 'Ц' => 'C', + 'Ч' => 'Ch', + 'Џ' => 'Dj', + 'Ш' => 'Sh', + 'а' => 'a', + 'б' => 'b', + 'в' => 'v', + 'г' => 'g', + 'д' => 'd', + 'ѓ' => 'gj', + 'е' => 'e', + 'ж' => 'zh', + 'з' => 'z', + 'ѕ' => 'dz', + 'и' => 'i', + 'ј' => 'j', + 'к' => 'k', + 'л' => 'l', + 'љ' => 'lj', + 'м' => 'm', + 'н' => 'n', + 'њ' => 'nj', + 'о' => 'o', + 'п' => 'p', + 'р' => 'r', + 'с' => 's', + 'т' => 't', + 'ќ' => 'kj', + 'у' => 'u', + 'ф' => 'f', + 'х' => 'h', + 'ц' => 'c', + 'ч' => 'ch', + 'џ' => 'dj', + 'ш' => 'sh', + ], + // Portuguese (Brazil) + 'pt' => [ + 'æ' => 'ae', + 'ǽ' => 'ae', + 'À' => 'A', + 'Á' => 'A', + 'Â' => 'A', + 'Ã' => 'A', + 'Å' => 'AA', + 'Ǻ' => 'A', + 'Ă' => 'A', + 'Ǎ' => 'A', + 'Æ' => 'AE', + 'Ǽ' => 'AE', + 'à' => 'a', + 'á' => 'a', + 'â' => 'a', + 'ã' => 'a', + 'å' => 'aa', + 'ǻ' => 'a', + 'ă' => 'a', + 'ǎ' => 'a', + 'ª' => 'a', + 'Ĉ' => 'C', + 'Ċ' => 'C', + 'Ç' => 'C', + 'ç' => 'c', + 'ĉ' => 'c', + 'ċ' => 'c', + 'Ð' => 'Dj', + 'Đ' => 'D', + 'ð' => 'dj', + 'đ' => 'd', + 'È' => 'E', + 'É' => 'E', + 'Ê' => 'E', + 'Ë' => 'E', + 'Ĕ' => 'E', + 'Ė' => 'E', + 'è' => 'e', + 'é' => 'e', + 'ê' => 'e', + 'ë' => 'e', + 'ĕ' => 'e', + 'ė' => 'e', + 'ƒ' => 'f', + 'Ĝ' => 'G', + 'Ġ' => 'G', + 'ĝ' => 'g', + 'ġ' => 'g', + 'Ĥ' => 'H', + 'Ħ' => 'H', + 'ĥ' => 'h', + 'ħ' => 'h', + 'Ì' => 'I', + 'Í' => 'I', + 'Î' => 'I', + 'Ï' => 'I', + 'Ĩ' => 'I', + 'Ĭ' => 'I', + 'Ǐ' => 'I', + 'Į' => 'I', + 'IJ' => 'IJ', + 'ì' => 'i', + 'í' => 'i', + 'î' => 'i', + 'ï' => 'i', + 'ĩ' => 'i', + 'ĭ' => 'i', + 'ǐ' => 'i', + 'į' => 'i', + 'ij' => 'ij', + 'Ĵ' => 'J', + 'ĵ' => 'j', + 'Ĺ' => 'L', + 'Ľ' => 'L', + 'Ŀ' => 'L', + 'ĺ' => 'l', + 'ľ' => 'l', + 'ŀ' => 'l', + 'Ñ' => 'N', + 'ñ' => 'n', + 'ʼn' => 'n', + 'Ò' => 'O', + 'Ó' => 'O', + 'Ô' => 'O', + 'Õ' => 'O', + 'Ō' => 'O', + 'Ŏ' => 'O', + 'Ǒ' => 'O', + 'Ő' => 'O', + 'Ơ' => 'O', + 'Ø' => 'OE', + 'Ǿ' => 'O', + 'Œ' => 'OE', + 'ò' => 'o', + 'ó' => 'o', + 'ô' => 'o', + 'õ' => 'o', + 'ō' => 'o', + 'ŏ' => 'o', + 'ǒ' => 'o', + 'ő' => 'o', + 'ơ' => 'o', + 'ø' => 'oe', + 'ǿ' => 'o', + 'º' => 'o', + 'œ' => 'oe', + 'Ŕ' => 'R', + 'Ŗ' => 'R', + 'ŕ' => 'r', + 'ŗ' => 'r', + 'Ŝ' => 'S', + 'Ș' => 'S', + 'ŝ' => 's', + 'ș' => 's', + 'ſ' => 's', + 'Ţ' => 'T', + 'Ț' => 'T', + 'Ŧ' => 'T', + 'Þ' => 'TH', + 'ţ' => 't', + 'ț' => 't', + 'ŧ' => 't', + 'þ' => 'th', + 'Ù' => 'U', + 'Ú' => 'U', + 'Û' => 'U', + 'Ü' => 'U', + 'Ũ' => 'U', + 'Ŭ' => 'U', + 'Ű' => 'U', + 'Ų' => 'U', + 'Ư' => 'U', + 'Ǔ' => 'U', + 'Ǖ' => 'U', + 'Ǘ' => 'U', + 'Ǚ' => 'U', + 'Ǜ' => 'U', + 'ù' => 'u', + 'ú' => 'u', + 'û' => 'u', + 'ü' => 'u', + 'ũ' => 'u', + 'ŭ' => 'u', + 'ű' => 'u', + 'ų' => 'u', + 'ư' => 'u', + 'ǔ' => 'u', + 'ǖ' => 'u', + 'ǘ' => 'u', + 'ǚ' => 'u', + 'ǜ' => 'u', + 'Ŵ' => 'W', + 'ŵ' => 'w', + 'Ý' => 'Y', + 'Ÿ' => 'Y', + 'Ŷ' => 'Y', + 'ý' => 'y', + 'ÿ' => 'y', + 'ŷ' => 'y', + ], + // Greek(lish) (Elláda) + 'el__greeklish' => [ + 'ΑΥ' => 'AU', + 'ΑΎ' => 'AU', + 'Αυ' => 'Au', + 'Αύ' => 'Au', + 'ΕΊ' => 'EI', + 'ΕΙ' => 'EI', + 'Ει' => 'EI', + 'ΕΥ' => 'EU', + 'ΕΎ' => 'EU', + 'Εί' => 'Ei', + 'Ευ' => 'Eu', + 'Εύ' => 'Eu', + 'ΟΙ' => 'OI', + 'ΟΊ' => 'OI', + 'ΟΥ' => 'OU', + 'ΟΎ' => 'OU', + 'Οι' => 'Oi', + 'Οί' => 'Oi', + 'Ου' => 'Ou', + 'Ού' => 'Ou', + 'ΥΙ' => 'YI', + 'ΎΙ' => 'YI', + 'Υι' => 'Yi', + 'Ύι' => 'Yi', + 'ΥΊ' => 'Yi', + 'Υί' => 'Yi', + 'αυ' => 'au', + 'αύ' => 'au', + 'εί' => 'ei', + 'ει' => 'ei', + 'ευ' => 'eu', + 'εύ' => 'eu', + 'οι' => 'oi', + 'οί' => 'oi', + 'ου' => 'ou', + 'ού' => 'ou', + 'υι' => 'yi', + 'ύι' => 'yi', + 'υί' => 'yi', + 'Α' => 'A', + 'Ά' => 'A', + 'Β' => 'B', + 'Δ' => 'D', + 'Ε' => 'E', + 'Έ' => 'E', + 'Φ' => 'F', + 'Γ' => 'G', + 'Η' => 'H', + 'Ή' => 'H', + 'Ι' => 'I', + 'Ί' => 'I', + 'Ϊ' => 'I', + 'Κ' => 'K', + 'Ξ' => 'Ks', + 'Λ' => 'L', + 'Μ' => 'M', + 'Ν' => 'N', + 'Π' => 'N', + 'Ο' => 'O', + 'Ό' => 'O', + 'Ψ' => 'Ps', + 'Ρ' => 'R', + 'Σ' => 'S', + 'Τ' => 'T', + 'Θ' => 'Th', + 'Ω' => 'W', + 'Ώ' => 'W', + 'Χ' => 'X', + 'ϒ' => 'Y', + 'Υ' => 'Y', + 'Ύ' => 'Y', + 'Ϋ' => 'Y', + 'Ζ' => 'Z', + 'α' => 'a', + 'ά' => 'a', + 'β' => 'b', + 'δ' => 'd', + 'ε' => 'e', + 'έ' => 'e', + 'φ' => 'f', + 'γ' => 'g', + 'η' => 'h', + 'ή' => 'h', + 'ι' => 'i', + 'ί' => 'i', + 'ϊ' => 'i', + 'ΐ' => 'i', + 'κ' => 'k', + 'ξ' => 'ks', + 'λ' => 'l', + 'μ' => 'm', + 'ν' => 'n', + 'ο' => 'o', + 'ό' => 'o', + 'π' => 'p', + 'ψ' => 'ps', + 'ρ' => 'r', + 'σ' => 's', + 'ς' => 's', + 'τ' => 't', + 'ϑ' => 'th', + 'θ' => 'th', + 'ϐ' => 'v', + 'ω' => 'w', + 'ώ' => 'w', + 'χ' => 'x', + 'υ' => 'y', + 'ύ' => 'y', + 'ΰ' => 'y', + 'ϋ' => 'y', + 'ζ' => 'z', + ], + // Greek (Elláda) + 'el' => [ + 'ΑΥ' => 'AU', + 'Αυ' => 'Au', + 'ΟΥ' => 'U', + 'Ου' => 'u', + 'ΕΥ' => 'EF', + 'Ευ' => 'Ef', + 'ΕΙ' => 'I', + 'Ει' => 'I', + 'ΟΙ' => 'I', + 'Οι' => 'I', + 'ΥΙ' => 'I', + 'Υι' => 'I', + 'ΑΎ' => 'AU', + 'Αύ' => 'Au', + 'ΟΎ' => 'OU', + 'Ού' => 'Ou', + 'ΕΎ' => 'EU', + 'Εύ' => 'Eu', + 'ΕΊ' => 'I', + 'Εί' => 'I', + 'ΟΊ' => 'I', + 'Οί' => 'I', + 'ΎΙ' => 'I', + 'Ύι' => 'I', + 'ΥΊ' => 'I', + 'Υί' => 'I', + 'αυ' => 'au', + 'ου' => 'u', + 'ευ' => 'ef', + 'ει' => 'i', + 'οι' => 'i', + 'υι' => 'i', + 'αύ' => 'au', + 'ού' => 'ou', + 'εύ' => 'eu', + 'εί' => 'i', + 'οί' => 'i', + 'ύι' => 'i', + 'υί' => 'i', + 'α' => 'a', + 'β' => 'v', + 'γ' => 'gh', + 'δ' => 'd', + 'ε' => 'e', + 'ζ' => 'z', + 'η' => 'i', + 'θ' => 'th', + 'ι' => 'i', + 'κ' => 'k', + 'λ' => 'l', + 'μ' => 'm', + 'ν' => 'n', + 'ξ' => 'ks', + 'ο' => 'o', + 'π' => 'p', + 'ρ' => 'r', + 'σ' => 's', + 'τ' => 't', + 'υ' => 'i', + 'φ' => 'f', + 'χ' => 'kh', + 'ψ' => 'ps', + 'ω' => 'o', + 'ά' => 'a', + 'έ' => 'e', + 'ί' => 'i', + 'ό' => 'o', + 'ϒ' => 'Y', + 'ύ' => 'y', + 'ή' => 'i', + 'ώ' => 'w', + 'ς' => 's', + 'ϊ' => 'i', + 'ΰ' => 'y', + 'ϋ' => 'y', + 'ΐ' => 'i', + 'Α' => 'A', + 'Β' => 'B', + 'Γ' => 'G', + 'Δ' => 'D', + 'Ε' => 'E', + 'Ζ' => 'Z', + 'Η' => 'H', + 'Θ' => 'Th', + 'Ι' => 'I', + 'Κ' => 'K', + 'Λ' => 'L', + 'Μ' => 'M', + 'Ν' => 'N', + 'Ξ' => 'Ks', + 'Ο' => 'O', + 'Π' => 'P', + 'Ρ' => 'R', + 'Σ' => 'S', + 'Τ' => 'T', + 'Υ' => 'Y', + 'Φ' => 'F', + 'Χ' => 'X', + 'Ψ' => 'Ps', + 'Ω' => 'O', + 'Ά' => 'A', + 'Έ' => 'E', + 'Ί' => 'I', + 'Ό' => 'O', + 'Ύ' => 'Y', + 'Ή' => 'I', + 'Ώ' => 'W', + 'Ϊ' => 'I', + 'Ϋ' => 'Y', + 'ϐ' => 'v', + 'ϑ' => 'th', + ], + // Hindi + 'hi' => [ + 'अ' => 'a', + 'आ' => 'aa', + 'ए' => 'e', + 'ई' => 'ii', + 'ऍ' => 'ei', + 'ऎ' => 'ae', + 'ऐ' => 'ai', + 'इ' => 'i', + 'ओ' => 'o', + 'ऑ' => 'oi', + 'ऒ' => 'oii', + 'ऊ' => 'uu', + 'औ' => 'ou', + 'उ' => 'u', + 'ब' => 'B', + 'भ' => 'Bha', + 'च' => 'Ca', + 'छ' => 'Chha', + 'ड' => 'Da', + 'ढ' => 'Dha', + 'फ' => 'Fa', + 'फ़' => 'Fi', + 'ग' => 'Ga', + 'घ' => 'Gha', + 'ग़' => 'Ghi', + 'ह' => 'Ha', + 'ज' => 'Ja', + 'झ' => 'Jha', + 'क' => 'Ka', + 'ख' => 'Kha', + 'ख़' => 'Khi', + 'ल' => 'L', + 'ळ' => 'Li', + 'ऌ' => 'Li', + 'ऴ' => 'Lii', + 'ॡ' => 'Lii', + 'म' => 'Ma', + 'न' => 'Na', + 'ङ' => 'Na', + 'ञ' => 'Nia', + 'ण' => 'Nae', + 'ऩ' => 'Ni', + 'ॐ' => 'oms', + 'प' => 'Pa', + 'क़' => 'Qi', + 'र' => 'Ra', + 'ऋ' => 'Ri', + 'ॠ' => 'Ri', + 'ऱ' => 'Ri', + 'स' => 'Sa', + 'श' => 'Sha', + 'ष' => 'Shha', + 'ट' => 'Ta', + 'त' => 'Ta', + 'ठ' => 'Tha', + 'द' => 'Tha', + 'थ' => 'Tha', + 'ध' => 'Thha', + 'ड़' => 'ugDha', + 'ढ़' => 'ugDhha', + 'व' => 'Va', + 'य' => 'Ya', + 'य़' => 'Yi', + 'ज़' => 'Za', + ], + // Armenian + 'hy' => [ + 'Ա' => 'A', + 'Բ' => 'B', + 'Գ' => 'G', + 'Դ' => 'D', + 'Ե' => 'E', + 'Զ' => 'Z', + 'Է' => 'E', + 'Ը' => 'Y', + 'Թ' => 'Th', + 'Ժ' => 'Zh', + 'Ի' => 'I', + 'Լ' => 'L', + 'Խ' => 'Kh', + 'Ծ' => 'Ts', + 'Կ' => 'K', + 'Հ' => 'H', + 'Ձ' => 'Dz', + 'Ղ' => 'Gh', + 'Ճ' => 'Tch', + 'Մ' => 'M', + 'Յ' => 'Y', + 'Ն' => 'N', + 'Շ' => 'Sh', + 'Ո' => 'Vo', + 'Չ' => 'Ch', + 'Պ' => 'P', + 'Ջ' => 'J', + 'Ռ' => 'R', + 'Ս' => 'S', + 'Վ' => 'V', + 'Տ' => 'T', + 'Ր' => 'R', + 'Ց' => 'C', + 'Ւ' => 'u', + 'Փ' => 'Ph', + 'Ք' => 'Q', + 'և' => 'ev', + 'Օ' => 'O', + 'Ֆ' => 'F', + 'ա' => 'a', + 'բ' => 'b', + 'գ' => 'g', + 'դ' => 'd', + 'ե' => 'e', + 'զ' => 'z', + 'է' => 'e', + 'ը' => 'y', + 'թ' => 'th', + 'ժ' => 'zh', + 'ի' => 'i', + 'լ' => 'l', + 'խ' => 'kh', + 'ծ' => 'ts', + 'կ' => 'k', + 'հ' => 'h', + 'ձ' => 'dz', + 'ղ' => 'gh', + 'ճ' => 'tch', + 'մ' => 'm', + 'յ' => 'y', + 'ն' => 'n', + 'շ' => 'sh', + 'ո' => 'vo', + 'չ' => 'ch', + 'պ' => 'p', + 'ջ' => 'j', + 'ռ' => 'r', + 'ս' => 's', + 'վ' => 'v', + 'տ' => 't', + 'ր' => 'r', + 'ց' => 'c', + 'ւ' => 'u', + 'փ' => 'ph', + 'ք' => 'q', + 'օ' => 'o', + 'ֆ' => 'f', + ], + // Swedish + 'sv' => [ + 'Ä' => 'A', + 'ä' => 'a', + 'Å' => 'A', + 'å' => 'a', + 'Ö' => 'O', + 'ö' => 'o', + ], + // Turkmen + 'tk' => [ + 'Ç' => 'C', + 'Ä' => 'A', + 'Ž' => 'Z', + 'Ň' => 'N', + 'Ö' => 'O', + 'Ş' => 'S', + 'Ü' => 'U', + 'Ý' => 'Y', + 'ç' => 'c', + 'ä' => 'a', + 'ž' => 'z', + 'ň' => 'n', + 'ö' => 'o', + 'ş' => 's', + 'ü' => 'u', + 'ý' => 'y', + ], + // Turkish + 'tr' => [ + 'ň' => 'n', + 'Ň' => 'N', + 'ş' => 's', + 'Ş' => 'S', + 'ı' => 'i', + 'İ' => 'I', + 'ç' => 'c', + 'Ç' => 'C', + 'ä' => 'a', + 'Ä' => 'A', + 'ü' => 'u', + 'Ü' => 'U', + 'ö' => 'o', + 'Ö' => 'O', + 'ğ' => 'g', + 'Ğ' => 'G', + 'ý' => 'y', + 'Ý' => 'Y', + 'ž' => 'z', + 'Ž' => 'Z', + ], + // Bulgarian + 'bg' => [ + 'ьо' => 'yo', + 'А' => 'A', + 'Б' => 'B', + 'В' => 'V', + 'Г' => 'G', + 'Д' => 'D', + 'Е' => 'E', + 'Ж' => 'Zh', + 'З' => 'Z', + 'И' => 'I', + 'Й' => 'Y', + 'К' => 'K', + 'Л' => 'L', + 'М' => 'M', + 'Н' => 'N', + 'О' => 'O', + 'П' => 'P', + 'Р' => 'R', + 'С' => 'S', + 'Т' => 'T', + 'У' => 'U', + 'Ф' => 'F', + 'Х' => 'H', + 'Ц' => 'C', + 'Ч' => 'Ch', + 'Ш' => 'Sh', + 'Щ' => 'Sht', + 'Ъ' => 'A', + 'Ь' => '', + 'Ю' => 'Yu', + 'Я' => 'Ya', + 'а' => 'a', + 'б' => 'b', + 'в' => 'v', + 'г' => 'g', + 'д' => 'd', + 'е' => 'e', + 'ж' => 'zh', + 'з' => 'z', + 'и' => 'i', + 'й' => 'y', + 'к' => 'k', + 'л' => 'l', + 'м' => 'm', + 'н' => 'n', + 'о' => 'o', + 'п' => 'p', + 'р' => 'r', + 'с' => 's', + 'т' => 't', + 'у' => 'u', + 'ф' => 'f', + 'х' => 'h', + 'ц' => 'c', + 'ч' => 'ch', + 'ш' => 'sh', + 'щ' => 'sht', + 'ъ' => 'a', + 'ь' => '', + 'ю' => 'yu', + 'я' => 'ya', + ], + // Hungarian + 'hu' => [ + 'Á' => 'A', + 'Ē' => 'E', + 'É' => 'E', + 'Í' => 'I', + 'Ó' => 'O', + 'Ö' => 'O', + 'Ő' => 'O', + 'Ú' => 'U', + 'Ü' => 'U', + 'Ű' => 'U', + 'á' => 'a', + 'ē' => 'e', + 'é' => 'e', + 'í' => 'i', + 'ó' => 'o', + 'ö' => 'o', + 'ő' => 'o', + 'ú' => 'u', + 'ü' => 'u', + 'ű' => 'u', + ], + // Myanmar (Burmese) + 'my' => [ + 'န်ုပ်' => 'nub', + 'ောင်' => 'aung', + 'ိုက်' => 'aik', + 'ိုဒ်' => 'ok', + 'ိုင်' => 'aing', + 'ိုလ်' => 'ol', + 'ေါင်' => 'aung', + 'သြော' => 'aw', + 'ောက်' => 'auk', + 'ိတ်' => 'eik', + 'ုတ်' => 'ok', + 'ုန်' => 'on', + 'ေတ်' => 'it', + 'ုဒ်' => 'ait', + 'ာန်' => 'an', + 'ိန်' => 'ein', + 'ွတ်' => 'ut', + 'ေါ်' => 'aw', + 'ွန်' => 'un', + 'ိပ်' => 'eik', + 'ုပ်' => 'ok', + 'ွပ်' => 'ut', + 'ိမ်' => 'ein', + 'ုမ်' => 'on', + 'ော်' => 'aw', + 'ွမ်' => 'un', + 'က်' => 'et', + 'ေါ' => 'aw', + 'ော' => 'aw', + 'ျွ' => 'ywa', + 'ြွ' => 'yw', + 'ို' => 'o', + 'ုံ' => 'on', + 'တ်' => 'at', + 'င်' => 'in', + 'ည်' => 'i', + 'ဒ်' => 'd', + 'န်' => 'an', + 'ပ်' => 'at', + 'မ်' => 'an', + 'စျ' => 'za', + 'ယ်' => 'e', + 'ဉ်' => 'in', + 'စ်' => 'it', + 'ိံ' => 'ein', + 'ဲ' => 'e', + 'း' => '', + 'ာ' => 'a', + 'ါ' => 'a', + 'ေ' => 'e', + 'ံ' => 'an', + 'ိ' => 'i', + 'ီ' => 'i', + 'ု' => 'u', + 'ူ' => 'u', + '်' => 'at', + '္' => '', + '့' => '', + 'က' => 'k', + '၉' => '9', + 'တ' => 't', + 'ရ' => 'ya', + 'ယ' => 'y', + 'မ' => 'm', + 'ဘ' => 'ba', + 'ဗ' => 'b', + 'ဖ' => 'pa', + 'ပ' => 'p', + 'န' => 'n', + 'ဓ' => 'da', + 'ဒ' => 'd', + 'ထ' => 'ta', + 'ဏ' => 'na', + 'ဝ' => 'w', + 'ဎ' => 'da', + 'ဍ' => 'd', + 'ဌ' => 'ta', + 'ဋ' => 't', + 'ည' => 'ny', + 'ဇ' => 'z', + 'ဆ' => 'sa', + 'စ' => 's', + 'င' => 'ng', + 'ဃ' => 'ga', + 'ဂ' => 'g', + 'လ' => 'l', + 'သ' => 'th', + '၈' => '8', + 'ဩ' => 'aw', + 'ခ' => 'kh', + '၆' => '6', + '၅' => '5', + '၄' => '4', + '၃' => '3', + '၂' => '2', + '၁' => '1', + '၀' => '0', + '၌' => 'hnaik', + '၍' => 'ywae', + 'ဪ' => 'aw', + 'ဦ' => '-u', + 'ဟ' => 'h', + 'ဉ' => 'u', + 'ဤ' => '-i', + 'ဣ' => 'i', + '၏' => '-e', + 'ဧ' => 'e', + 'ှ' => 'h', + 'ွ' => 'w', + 'ျ' => 'ya', + 'ြ' => 'y', + 'အ' => 'a', + 'ဠ' => 'la', + '၇' => '7', + ], + // Croatian (Hrvatska) + 'hr' => [ + 'DŽ' => 'DZ', + 'Dž' => 'Dz', + 'dž' => 'dz', + 'DZ' => 'DZ', + 'Dz' => 'Dz', + 'dz' => 'dz', + 'IJ' => 'IJ', + 'ij' => 'ij', + 'LJ' => 'LJ', + 'Lj' => 'Lj', + 'lj' => 'lj', + 'NJ' => 'NJ', + 'Nj' => 'Nj', + 'nj' => 'nj', + 'ž' => 'z', + 'Ž' => 'Z', + 'đ' => 'dj', + 'Đ' => 'Dj', + 'č' => 'c', + 'Č' => 'C', + 'ć' => 'c', + 'Ć' => 'C', + 'š' => 's', + 'Š' => 'S', + ], + // Finnish + 'fi' => [ + 'Ä' => 'A', + 'Ö' => 'O', + 'ä' => 'a', + 'ö' => 'o', + ], + // Georgian (Kartvelian) + 'ka' => [ + 'ა' => 'a', + 'ბ' => 'b', + 'გ' => 'g', + 'დ' => 'd', + 'ე' => 'e', + 'ვ' => 'v', + 'ზ' => 'z', + 'თ' => 't', + 'ი' => 'i', + 'კ' => 'k', + 'ლ' => 'l', + 'მ' => 'm', + 'ნ' => 'n', + 'ო' => 'o', + 'პ' => 'p', + 'ჟ' => 'zh', + 'რ' => 'r', + 'ს' => 's', + 'ტ' => 't', + 'უ' => 'u', + 'ფ' => 'f', + 'ქ' => 'q', + 'ღ' => 'gh', + 'ყ' => 'y', + 'შ' => 'sh', + 'ჩ' => 'ch', + 'ც' => 'ts', + 'ძ' => 'dz', + 'წ' => 'ts', + 'ჭ' => 'ch', + 'ხ' => 'kh', + 'ჯ' => 'j', + 'ჰ' => 'h', + ], + // Russian + 'ru' => [ + 'А' => 'A', + 'а' => 'a', + 'Б' => 'B', + 'б' => 'b', + 'В' => 'V', + 'в' => 'v', + 'Г' => 'G', + 'г' => 'g', + 'Д' => 'D', + 'д' => 'd', + 'Е' => 'E', + 'е' => 'e', + 'Ё' => 'Yo', + 'ё' => 'yo', + 'Ж' => 'Zh', + 'ж' => 'zh', + 'З' => 'Z', + 'з' => 'z', + 'И' => 'I', + 'и' => 'i', + 'Й' => 'Y', + 'й' => 'y', + 'К' => 'K', + 'к' => 'k', + 'Л' => 'L', + 'л' => 'l', + 'М' => 'M', + 'м' => 'm', + 'Н' => 'N', + 'н' => 'n', + 'О' => 'O', + 'о' => 'o', + 'П' => 'P', + 'п' => 'p', + 'Р' => 'R', + 'р' => 'r', + 'С' => 'S', + 'с' => 's', + 'Т' => 'T', + 'т' => 't', + 'У' => 'U', + 'у' => 'u', + 'Ф' => 'F', + 'ф' => 'f', + 'Х' => 'H', + 'х' => 'h', + 'Ц' => 'Ts', + 'ц' => 'ts', + 'Ч' => 'Ch', + 'ч' => 'ch', + 'ш' => 'sh', + 'Ш' => 'Sh', + 'Щ' => 'Sch', + 'щ' => 'sch', + 'Ъ' => '', + 'ъ' => '', + 'Ы' => 'Y', + 'ы' => 'y', + 'Ь' => '', + 'ь' => '', + 'Э' => 'E', + 'э' => 'e', + 'Ю' => 'Yu', + 'ю' => 'yu', + 'Я' => 'Ya', + 'я' => 'ya', + ], + // Russian - GOST 7.79-2000(B) + // -> https://en.m.wikipedia.org/wiki/Romanization_of_Russian#content-collapsible-block-1 + 'ru__gost_2000_b' => [ + 'А' => 'A', + 'а' => 'a', + 'Б' => 'B', + 'б' => 'b', + 'В' => 'V', + 'в' => 'v', + 'Г' => 'G', + 'г' => 'g', + 'Д' => 'D', + 'д' => 'd', + 'Е' => 'E', + 'е' => 'e', + 'Ё' => 'Yo', + 'ё' => 'yo', + 'Ж' => 'Zh', + 'ж' => 'zh', + 'З' => 'Z', + 'з' => 'z', + 'И' => 'i', + 'и' => 'i', + 'Й' => 'i', + 'й' => 'i', + 'К' => 'K', + 'к' => 'k', + 'Л' => 'L', + 'л' => 'l', + 'М' => 'M', + 'м' => 'm', + 'Н' => 'N', + 'н' => 'n', + 'О' => 'O', + 'о' => 'o', + 'П' => 'P', + 'п' => 'p', + 'Р' => 'R', + 'р' => 'r', + 'С' => 'S', + 'с' => 's', + 'Т' => 'T', + 'т' => 't', + 'У' => 'U', + 'у' => 'u', + 'Ф' => 'F', + 'ф' => 'f', + 'Х' => 'X', + 'х' => 'x', + 'Ц' => 'Cz', + 'ц' => 'cz', + 'Ч' => 'Ch', + 'ч' => 'ch', + 'ш' => 'sh', + 'Ш' => 'Sh', + 'Щ' => 'Shh', + 'щ' => 'shh', + 'Ъ' => '', + 'ъ' => '', + 'Ы' => 'Y\'', + 'ы' => 'y\'', + 'Ь' => '', + 'ь' => '', + 'Э' => 'E\'', + 'э' => 'e\'', + 'Ю' => 'Yu', + 'ю' => 'yu', + 'Я' => 'Ya', + 'я' => 'ya', + 'І' => 'I', + 'і' => 'i', + 'Ѳ' => 'Fh', + 'ѳ' => 'fh', + 'Ѣ' => 'Ye', + 'ѣ' => 'ye', + 'Ѵ' => 'Yh', + 'ѵ' => 'yh', + 'Є' => '', + 'є' => '', + 'Ѥ' => '', + 'ѥ' => '', + 'Ѕ' => 'Js', + 'ѕ' => 'js', + 'Ꙋ' => '', + 'ꙋ' => '', + 'Ѡ' => '', + 'ѡ' => '', + 'Ѿ' => '', + 'ѿ' => '', + 'Ѫ' => '', + 'ѫ' => '', + 'Ѧ' => '', + 'ѧ' => '', + 'Ѭ' => '', + 'ѭ' => '', + 'Ѩ' => '', + 'ѩ' => '', + 'Ѯ' => '', + 'ѯ' => '', + 'Ѱ' => '', + 'ѱ' => '', + ], + // Russian - Passport (2013), ICAO + // -> https://en.m.wikipedia.org/wiki/Romanization_of_Russian#content-collapsible-block-1 + 'ru__passport_2013' => [ + 'А' => 'A', + 'а' => 'a', + 'Б' => 'B', + 'б' => 'b', + 'В' => 'V', + 'в' => 'v', + 'Г' => 'G', + 'г' => 'g', + 'Д' => 'D', + 'д' => 'd', + 'Е' => 'E', + 'е' => 'e', + 'Ё' => 'E', + 'ё' => 'e', + 'Ж' => 'Zh', + 'ж' => 'zh', + 'З' => 'Z', + 'з' => 'z', + 'И' => 'i', + 'и' => 'i', + 'Й' => 'i', + 'й' => 'i', + 'К' => 'K', + 'к' => 'k', + 'Л' => 'L', + 'л' => 'l', + 'М' => 'M', + 'м' => 'm', + 'Н' => 'N', + 'н' => 'n', + 'О' => 'O', + 'о' => 'o', + 'П' => 'P', + 'п' => 'p', + 'Р' => 'R', + 'р' => 'r', + 'С' => 'S', + 'с' => 's', + 'Т' => 'T', + 'т' => 't', + 'У' => 'U', + 'у' => 'u', + 'Ф' => 'F', + 'ф' => 'f', + 'Х' => 'Kh', + 'х' => 'kh', + 'Ц' => 'Ts', + 'ц' => 'ts', + 'Ч' => 'Ch', + 'ч' => 'ch', + 'ш' => 'sh', + 'Ш' => 'Sh', + 'Щ' => 'Shch', + 'щ' => 'shch', + 'Ъ' => 'Ie', + 'ъ' => 'ie', + 'Ы' => 'Y', + 'ы' => 'y', + 'Ь' => '', + 'ь' => '', + 'Э' => 'E', + 'э' => 'e', + 'Ю' => 'Iu', + 'ю' => 'iu', + 'Я' => 'Ia', + 'я' => 'ia', + 'І' => '', + 'і' => '', + 'Ѳ' => '', + 'ѳ' => '', + 'Ѣ' => '', + 'ѣ' => '', + 'Ѵ' => '', + 'ѵ' => '', + 'Є' => '', + 'є' => '', + 'Ѥ' => '', + 'ѥ' => '', + 'Ѕ' => '', + 'ѕ' => '', + 'Ꙋ' => '', + 'ꙋ' => '', + 'Ѡ' => '', + 'ѡ' => '', + 'Ѿ' => '', + 'ѿ' => '', + 'Ѫ' => '', + 'ѫ' => '', + 'Ѧ' => '', + 'ѧ' => '', + 'Ѭ' => '', + 'ѭ' => '', + 'Ѩ' => '', + 'ѩ' => '', + 'Ѯ' => '', + 'ѯ' => '', + 'Ѱ' => '', + 'ѱ' => '', + ], + // Ukrainian + // -> https://zakon.rada.gov.ua/laws/show/55-2010-%D0%BF?lang=en + 'uk' => [ + 'Г' => 'H', + 'г' => 'h', + 'Ґ' => 'G', + 'ґ' => 'g', + 'Є' => 'Ye', + 'є' => 'ye', + 'И' => 'Y', + 'и' => 'y', + 'І' => 'I', + 'і' => 'i', + 'Ї' => 'Yi', + 'ї' => 'yi', + 'Й' => 'Y', + 'й' => 'y', + 'Х' => 'Kh', + 'х' => 'kh', + 'Ц' => 'Ts', + 'ц' => 'ts', + 'Ч' => 'Ch', + 'ч' => 'ch', + 'Ш' => 'Sh', + 'ш' => 'sh', + 'Щ' => 'Shch', + 'щ' => 'shch', + ], + // Kazakh + 'kk' => [ + 'Ә' => 'A', + 'Ғ' => 'G', + 'Қ' => 'Q', + 'Ң' => 'N', + 'Ө' => 'O', + 'Ұ' => 'U', + 'Ү' => 'U', + 'Һ' => 'H', + 'ә' => 'a', + 'ғ' => 'g', + 'қ' => 'q', + 'ң' => 'n', + 'ө' => 'o', + 'ұ' => 'u', + 'ү' => 'u', + 'һ' => 'h', + ], + // Czech + 'cs' => [ + 'á' => 'a', + 'Á' => 'A', + 'č' => 'c', + 'Č' => 'C', + 'ď' => 'd', + 'Ď' => 'D', + 'é' => 'e', + 'É' => 'E', + 'ě' => 'e', + 'Ě' => 'E', + 'í' => 'i', + 'Í' => 'I', + 'ň' => 'n', + 'Ň' => 'N', + 'ó' => 'o', + 'Ó' => 'O', + 'ř' => 'r', + 'Ř' => 'R', + 'š' => 's', + 'Š' => 'S', + 'ť' => 't', + 'Ť' => 'T', + 'ú' => 'u', + 'Ú' => 'U', + 'ů' => 'u', + 'Ů' => 'U', + 'ý' => 'y', + 'Ý' => 'Y', + 'ž' => 'z', + 'Ž' => 'Z', + ], + // Danish + 'da' => [ + 'Æ' => 'Ae', + 'æ' => 'ae', + 'Ø' => 'Oe', + 'ø' => 'oe', + 'Å' => 'Aa', + 'å' => 'aa', + 'É' => 'E', + 'é' => 'e', + ], + // Polish + 'pl' => [ + 'ą' => 'a', + 'ć' => 'c', + 'ę' => 'e', + 'ł' => 'l', + 'ń' => 'n', + 'ó' => 'o', + 'ś' => 's', + 'ź' => 'z', + 'ż' => 'z', + 'Ą' => 'A', + 'Ć' => 'C', + 'Ę' => 'E', + 'Ł' => 'L', + 'Ń' => 'N', + 'Ó' => 'O', + 'Ś' => 'S', + 'Ź' => 'Z', + 'Ż' => 'Z', + ], + // Romanian + 'ro' => [ + 'ă' => 'a', + 'â' => 'a', + 'Ă' => 'A', + 'Â' => 'A', + 'î' => 'i', + 'Î' => 'I', + 'ș' => 's', + 'ş' => 's', + 'Ş' => 'S', + 'Ș' => 'S', + 'ț' => 't', + 'ţ' => 't', + 'Ţ' => 'T', + 'Ț' => 'T', + ], + // Esperanto + 'eo' => [ + 'ĉ' => 'cx', + 'ĝ' => 'gx', + 'ĥ' => 'hx', + 'ĵ' => 'jx', + 'ŝ' => 'sx', + 'ŭ' => 'ux', + 'Ĉ' => 'CX', + 'Ĝ' => 'GX', + 'Ĥ' => 'HX', + 'Ĵ' => 'JX', + 'Ŝ' => 'SX', + 'Ŭ' => 'UX', + ], + // Estonian + 'et' => [ + 'Š' => 'S', + 'Ž' => 'Z', + 'Õ' => 'O', + 'Ä' => 'A', + 'Ö' => 'O', + 'Ü' => 'U', + 'š' => 's', + 'ž' => 'z', + 'õ' => 'o', + 'ä' => 'a', + 'ö' => 'o', + 'ü' => 'u', + ], + // Latvian + 'lv' => [ + 'ā' => 'a', + 'č' => 'c', + 'ē' => 'e', + 'ģ' => 'g', + 'ī' => 'i', + 'ķ' => 'k', + 'ļ' => 'l', + 'ņ' => 'n', + 'š' => 's', + 'ū' => 'u', + 'ž' => 'z', + 'Ā' => 'A', + 'Č' => 'C', + 'Ē' => 'E', + 'Ģ' => 'G', + 'Ī' => 'i', + 'Ķ' => 'k', + 'Ļ' => 'L', + 'Ņ' => 'N', + 'Š' => 'S', + 'Ū' => 'u', + 'Ž' => 'Z', + ], + // Lithuanian + 'lt' => [ + 'ą' => 'a', + 'č' => 'c', + 'ę' => 'e', + 'ė' => 'e', + 'į' => 'i', + 'š' => 's', + 'ų' => 'u', + 'ū' => 'u', + 'ž' => 'z', + 'Ą' => 'A', + 'Č' => 'C', + 'Ę' => 'E', + 'Ė' => 'E', + 'Į' => 'I', + 'Š' => 'S', + 'Ų' => 'U', + 'Ū' => 'U', + 'Ž' => 'Z', + ], + // Norwegian + 'no' => [ + 'Æ' => 'AE', + 'æ' => 'ae', + 'Ø' => 'OE', + 'ø' => 'oe', + 'Å' => 'AA', + 'å' => 'aa', + ], + // Vietnamese + 'vi' => [ + 'Á' => 'A', + 'À' => 'A', + 'Ả' => 'A', + 'Ã' => 'A', + 'Ạ' => 'A', + 'Ă' => 'A', + 'Ắ' => 'A', + 'Ằ' => 'A', + 'Ẳ' => 'A', + 'Ẵ' => 'A', + 'Ặ' => 'A', + 'Â' => 'A', + 'Ấ' => 'A', + 'Ầ' => 'A', + 'Ẩ' => 'A', + 'Ẫ' => 'A', + 'Ậ' => 'A', + 'á' => 'a', + 'à' => 'a', + 'ả' => 'a', + 'ã' => 'a', + 'ạ' => 'a', + 'ă' => 'a', + 'ắ' => 'a', + 'ằ' => 'a', + 'ẳ' => 'a', + 'ẵ' => 'a', + 'ặ' => 'a', + 'â' => 'a', + 'ấ' => 'a', + 'ầ' => 'a', + 'ẩ' => 'a', + 'ẫ' => 'a', + 'ậ' => 'a', + 'É' => 'E', + 'È' => 'E', + 'Ẻ' => 'E', + 'Ẽ' => 'E', + 'Ẹ' => 'E', + 'Ê' => 'E', + 'Ế' => 'E', + 'Ề' => 'E', + 'Ể' => 'E', + 'Ễ' => 'E', + 'Ệ' => 'E', + 'é' => 'e', + 'è' => 'e', + 'ẻ' => 'e', + 'ẽ' => 'e', + 'ẹ' => 'e', + 'ê' => 'e', + 'ế' => 'e', + 'ề' => 'e', + 'ể' => 'e', + 'ễ' => 'e', + 'ệ' => 'e', + 'Í' => 'I', + 'Ì' => 'I', + 'Ỉ' => 'I', + 'Ĩ' => 'I', + 'Ị' => 'I', + 'í' => 'i', + 'ì' => 'i', + 'ỉ' => 'i', + 'ĩ' => 'i', + 'ị' => 'i', + 'Ó' => 'O', + 'Ò' => 'O', + 'Ỏ' => 'O', + 'Õ' => 'O', + 'Ọ' => 'O', + 'Ô' => 'O', + 'Ố' => 'O', + 'Ồ' => 'O', + 'Ổ' => 'O', + 'Ỗ' => 'O', + 'Ộ' => 'O', + 'Ơ' => 'O', + 'Ớ' => 'O', + 'Ờ' => 'O', + 'Ở' => 'O', + 'Ỡ' => 'O', + 'Ợ' => 'O', + 'ó' => 'o', + 'ò' => 'o', + 'ỏ' => 'o', + 'õ' => 'o', + 'ọ' => 'o', + 'ô' => 'o', + 'ố' => 'o', + 'ồ' => 'o', + 'ổ' => 'o', + 'ỗ' => 'o', + 'ộ' => 'o', + 'ơ' => 'o', + 'ớ' => 'o', + 'ờ' => 'o', + 'ở' => 'o', + 'ỡ' => 'o', + 'ợ' => 'o', + 'Ú' => 'U', + 'Ù' => 'U', + 'Ủ' => 'U', + 'Ũ' => 'U', + 'Ụ' => 'U', + 'Ư' => 'U', + 'Ứ' => 'U', + 'Ừ' => 'U', + 'Ử' => 'U', + 'Ữ' => 'U', + 'Ự' => 'U', + 'ú' => 'u', + 'ù' => 'u', + 'ủ' => 'u', + 'ũ' => 'u', + 'ụ' => 'u', + 'ư' => 'u', + 'ứ' => 'u', + 'ừ' => 'u', + 'ử' => 'u', + 'ữ' => 'u', + 'ự' => 'u', + 'Ý' => 'Y', + 'Ỳ' => 'Y', + 'Ỷ' => 'Y', + 'Ỹ' => 'Y', + 'Ỵ' => 'Y', + 'ý' => 'y', + 'ỳ' => 'y', + 'ỷ' => 'y', + 'ỹ' => 'y', + 'ỵ' => 'y', + 'Đ' => 'D', + 'đ' => 'd', + ], + // Persian (Farsi) + 'fa' => [ + 'ا' => 'a', + 'ب' => 'b', + 'پ' => 'p', + 'ت' => 't', + 'ث' => 's', + 'ج' => 'j', + 'چ' => 'ch', + 'ح' => 'h', + 'خ' => 'kh', + 'د' => 'd', + 'ذ' => 'z', + 'ر' => 'r', + 'ز' => 'z', + 'س' => 's', + 'ش' => 'sh', + 'ص' => 's', + 'ض' => 'z', + 'ط' => 't', + 'ظ' => 'z', + 'ع' => 'a', + 'غ' => 'gh', + 'ف' => 'f', + 'ق' => 'gh', + 'ک' => 'k', + 'گ' => 'g', + 'ل' => 'l', + 'ژ' => 'zh', + 'ك' => 'k', + 'م' => 'm', + 'ن' => 'n', + 'ه' => 'h', + 'و' => 'o', + 'ی' => 'y', + 'آ' => 'a', + '٠' => '0', + '١' => '1', + '٢' => '2', + '٣' => '3', + '٤' => '4', + '٥' => '5', + '٦' => '6', + '٧' => '7', + '٨' => '8', + '٩' => '9', + ], + // Arabic + 'ar' => [ + 'أ' => 'a', + 'ب' => 'b', + 'ت' => 't', + 'ث' => 'th', + 'ج' => 'g', + 'ح' => 'h', + 'خ' => 'kh', + 'د' => 'd', + 'ذ' => 'th', + 'ر' => 'r', + 'ز' => 'z', + 'س' => 's', + 'ش' => 'sh', + 'ص' => 's', + 'ض' => 'd', + 'ط' => 't', + 'ظ' => 'th', + 'ع' => 'aa', + 'غ' => 'gh', + 'ف' => 'f', + 'ق' => 'k', + 'ك' => 'k', + 'ل' => 'l', + 'م' => 'm', + 'ن' => 'n', + 'ه' => 'h', + 'و' => 'o', + 'ي' => 'y', + 'ا' => 'a', + 'إ' => 'a', + 'آ' => 'a', + 'ؤ' => 'o', + 'ئ' => 'y', + 'ء' => 'aa', + '٠' => '0', + '١' => '1', + '٢' => '2', + '٣' => '3', + '٤' => '4', + '٥' => '5', + '٦' => '6', + '٧' => '7', + '٨' => '8', + '٩' => '9', + ], + // Serbian + 'sr' => [ + 'đ' => 'dj', + 'ž' => 'z', + 'ć' => 'c', + 'č' => 'c', + 'š' => 's', + 'Đ' => 'Dj', + 'Ž' => 'Z', + 'Ć' => 'C', + 'Č' => 'C', + 'Š' => 'S', + 'а' => 'a', + 'б' => 'b', + 'в' => 'v', + 'г' => 'g', + 'д' => 'd', + 'ђ' => 'dj', + 'е' => 'e', + 'ж' => 'z', + 'з' => 'z', + 'и' => 'i', + 'ј' => 'j', + 'к' => 'k', + 'л' => 'l', + 'љ' => 'lj', + 'м' => 'm', + 'н' => 'n', + 'њ' => 'nj', + 'о' => 'o', + 'п' => 'p', + 'р' => 'r', + 'с' => 's', + 'т' => 't', + 'ћ' => 'c', + 'у' => 'u', + 'ф' => 'f', + 'х' => 'h', + 'ц' => 'c', + 'ч' => 'c', + 'џ' => 'dz', + 'ш' => 's', + 'А' => 'A', + 'Б' => 'B', + 'В' => 'V', + 'Г' => 'G', + 'Д' => 'D', + 'Ђ' => 'Dj', + 'Е' => 'E', + 'Ж' => 'Z', + 'З' => 'Z', + 'И' => 'I', + 'Ј' => 'j', + 'К' => 'K', + 'Л' => 'L', + 'Љ' => 'Lj', + 'М' => 'M', + 'Н' => 'N', + 'Њ' => 'Nj', + 'О' => 'O', + 'П' => 'P', + 'Р' => 'R', + 'С' => 'S', + 'Т' => 'T', + 'Ћ' => 'C', + 'У' => 'U', + 'Ф' => 'F', + 'Х' => 'H', + 'Ц' => 'C', + 'Ч' => 'C', + 'Џ' => 'Dz', + 'Ш' => 'S', + ], + // Serbian - Cyrillic + 'sr__cyr' => [ + 'а' => 'a', + 'б' => 'b', + 'в' => 'v', + 'г' => 'g', + 'д' => 'd', + 'ђ' => 'dj', + 'е' => 'e', + 'ж' => 'z', + 'з' => 'z', + 'и' => 'i', + 'ј' => 'j', + 'к' => 'k', + 'л' => 'l', + 'љ' => 'lj', + 'м' => 'm', + 'н' => 'n', + 'њ' => 'nj', + 'о' => 'o', + 'п' => 'p', + 'р' => 'r', + 'с' => 's', + 'т' => 't', + 'ћ' => 'c', + 'у' => 'u', + 'ф' => 'f', + 'х' => 'h', + 'ц' => 'c', + 'ч' => 'c', + 'џ' => 'dz', + 'ш' => 's', + 'А' => 'A', + 'Б' => 'B', + 'В' => 'V', + 'Г' => 'G', + 'Д' => 'D', + 'Ђ' => 'Dj', + 'Е' => 'E', + 'Ж' => 'Z', + 'З' => 'Z', + 'И' => 'I', + 'Ј' => 'j', + 'К' => 'K', + 'Л' => 'L', + 'Љ' => 'Lj', + 'М' => 'M', + 'Н' => 'N', + 'Њ' => 'Nj', + 'О' => 'O', + 'П' => 'P', + 'Р' => 'R', + 'С' => 'S', + 'Т' => 'T', + 'Ћ' => 'C', + 'У' => 'U', + 'Ф' => 'F', + 'Х' => 'H', + 'Ц' => 'C', + 'Ч' => 'C', + 'Џ' => 'Dz', + 'Ш' => 'S', + ], + // Serbian - Latin + 'sr__lat' => [ + 'đ' => 'dj', + 'ž' => 'z', + 'ć' => 'c', + 'č' => 'c', + 'š' => 's', + 'Đ' => 'Dj', + 'Ž' => 'Z', + 'Ć' => 'C', + 'Č' => 'C', + 'Š' => 'S', + ], + // Azerbaijani + 'az' => [ + 'ç' => 'c', + 'ə' => 'e', + 'ğ' => 'g', + 'ı' => 'i', + 'ö' => 'o', + 'ş' => 's', + 'ü' => 'u', + 'Ç' => 'C', + 'Ə' => 'E', + 'Ğ' => 'G', + 'İ' => 'I', + 'Ö' => 'O', + 'Ş' => 'S', + 'Ü' => 'U', + ], + // Slovak + 'sk' => [ + 'á' => 'a', + 'ä' => 'a', + 'č' => 'c', + 'ď' => 'd', + 'é' => 'e', + 'í' => 'i', + 'ľ' => 'l', + 'ĺ' => 'l', + 'ň' => 'n', + 'ó' => 'o', + 'ô' => 'o', + 'ŕ' => 'r', + 'š' => 's', + 'ť' => 't', + 'ú' => 'u', + 'ý' => 'y', + 'ž' => 'z', + 'Á' => 'A', + 'Ä' => 'A', + 'Č' => 'C', + 'Ď' => 'D', + 'É' => 'E', + 'Í' => 'I', + 'Ľ' => 'L', + 'Ĺ' => 'L', + 'Ň' => 'N', + 'Ó' => 'O', + 'Ô' => 'O', + 'Ŕ' => 'R', + 'Š' => 'S', + 'Ť' => 'T', + 'Ú' => 'U', + 'Ý' => 'Y', + 'Ž' => 'Z', + ], + // French + 'fr' => [ + 'Æ' => 'AE', + 'æ' => 'ae', + 'Œ' => 'OE', + 'œ' => 'oe', + 'â' => 'a', + 'Â' => 'A', + 'à' => 'a', + 'À' => 'A', + 'ä' => 'a', + 'Ä' => 'A', + 'ç' => 'c', + 'Ç' => 'C', + 'é' => 'e', + 'É' => 'E', + 'ê' => 'e', + 'Ê' => 'E', + 'ë' => 'e', + 'Ë' => 'E', + 'è' => 'e', + 'È' => 'E', + 'ï' => 'i', + 'î' => 'i', + 'Ï' => 'I', + 'Î' => 'I', + 'ÿ' => 'y', + 'Ÿ' => 'Y', + 'ô' => 'o', + 'Ô' => 'O', + 'ö' => 'o', + 'Ö' => 'O', + 'û' => 'u', + 'Û' => 'U', + 'ù' => 'u', + 'Ù' => 'U', + 'ü' => 'u', + 'Ü' => 'U', + ], + // Austrian (French) + 'fr_at' => [ + 'ß' => 'sz', + 'ẞ' => 'SZ', + 'Æ' => 'AE', + 'æ' => 'ae', + 'Œ' => 'OE', + 'œ' => 'oe', + 'â' => 'a', + 'Â' => 'A', + 'à' => 'a', + 'À' => 'A', + 'ä' => 'a', + 'Ä' => 'A', + 'ç' => 'c', + 'Ç' => 'C', + 'é' => 'e', + 'É' => 'E', + 'ê' => 'e', + 'Ê' => 'E', + 'ë' => 'e', + 'Ë' => 'E', + 'è' => 'e', + 'È' => 'E', + 'ï' => 'i', + 'î' => 'i', + 'Ï' => 'I', + 'Î' => 'I', + 'ÿ' => 'y', + 'Ÿ' => 'Y', + 'ô' => 'o', + 'Ô' => 'O', + 'ö' => 'o', + 'Ö' => 'O', + 'û' => 'u', + 'Û' => 'U', + 'ù' => 'u', + 'Ù' => 'U', + 'ü' => 'u', + 'Ü' => 'U', + ], + // Switzerland (French) + 'fr_ch' => [ + 'ß' => 'ss', + 'ẞ' => 'SS', + 'Æ' => 'AE', + 'æ' => 'ae', + 'Œ' => 'OE', + 'œ' => 'oe', + 'â' => 'a', + 'Â' => 'A', + 'à' => 'a', + 'À' => 'A', + 'ä' => 'a', + 'Ä' => 'A', + 'ç' => 'c', + 'Ç' => 'C', + 'é' => 'e', + 'É' => 'E', + 'ê' => 'e', + 'Ê' => 'E', + 'ë' => 'e', + 'Ë' => 'E', + 'è' => 'e', + 'È' => 'E', + 'ï' => 'i', + 'î' => 'i', + 'Ï' => 'I', + 'Î' => 'I', + 'ÿ' => 'y', + 'Ÿ' => 'Y', + 'ô' => 'o', + 'Ô' => 'O', + 'ö' => 'o', + 'Ö' => 'O', + 'û' => 'u', + 'Û' => 'U', + 'ù' => 'u', + 'Ù' => 'U', + 'ü' => 'u', + 'Ü' => 'U', + ], + // German + 'de' => [ + 'Ä' => 'Ae', + 'Ö' => 'Oe', + 'Ü' => 'Ue', + 'ä' => 'ae', + 'ö' => 'oe', + 'ü' => 'ue', + 'ß' => 'ss', + 'ẞ' => 'SS', + ], + // Austrian (German) + 'de_at' => [ + 'Ä' => 'Ae', + 'Ö' => 'Oe', + 'Ü' => 'Ue', + 'ä' => 'ae', + 'ö' => 'oe', + 'ü' => 'ue', + 'ß' => 'sz', + 'ẞ' => 'SZ', + ], + // Switzerland (German) + 'de_ch' => [ + 'Ä' => 'Ae', + 'Ö' => 'Oe', + 'Ü' => 'Ue', + 'ä' => 'ae', + 'ö' => 'oe', + 'ü' => 'ue', + 'ß' => 'ss', + 'ẞ' => 'SS', + ], + // Bengali (Bangla) + 'bn' => [ + 'ভ্ল' => 'vl', + 'পশ' => 'psh', + 'ব্ধ' => 'bdh', + 'ব্জ' => 'bj', + 'ব্দ' => 'bd', + 'ব্ব' => 'bb', + 'ব্ল' => 'bl', + 'ভ' => 'v', + 'ব' => 'b', + 'চ্ঞ' => 'cNG', + 'চ্ছ' => 'cch', + 'চ্চ' => 'cc', + 'ছ' => 'ch', + 'চ' => 'c', + 'ধ্ন' => 'dhn', + 'ধ্ম' => 'dhm', + 'দ্ঘ' => 'dgh', + 'দ্ধ' => 'ddh', + 'দ্ভ' => 'dv', + 'দ্ম' => 'dm', + 'ড্ড' => 'DD', + 'ঢ' => 'Dh', + 'ধ' => 'dh', + 'দ্গ' => 'dg', + 'দ্দ' => 'dd', + 'ড' => 'D', + 'দ' => 'd', + '।' => '.', + 'ঘ্ন' => 'Ghn', + 'গ্ধ' => 'Gdh', + 'গ্ণ' => 'GN', + 'গ্ন' => 'Gn', + 'গ্ম' => 'Gm', + 'গ্ল' => 'Gl', + 'জ্ঞ' => 'jNG', + 'ঘ' => 'Gh', + 'গ' => 'g', + 'হ্ণ' => 'hN', + 'হ্ন' => 'hn', + 'হ্ম' => 'hm', + 'হ্ল' => 'hl', + 'হ' => 'h', + 'জ্ঝ' => 'jjh', + 'ঝ' => 'jh', + 'জ্জ' => 'jj', + 'জ' => 'j', + 'ক্ষ্ণ' => 'kxN', + 'ক্ষ্ম' => 'kxm', + 'ক্ষ' => 'ksh', + 'কশ' => 'ksh', + 'ক্ক' => 'kk', + 'ক্ট' => 'kT', + 'ক্ত' => 'kt', + 'ক্ল' => 'kl', + 'ক্স' => 'ks', + 'খ' => 'kh', + 'ক' => 'k', + 'ল্ভ' => 'lv', + 'ল্ধ' => 'ldh', + 'লখ' => 'lkh', + 'লঘ' => 'lgh', + 'লফ' => 'lph', + 'ল্ক' => 'lk', + 'ল্গ' => 'lg', + 'ল্ট' => 'lT', + 'ল্ড' => 'lD', + 'ল্প' => 'lp', + 'ল্ম' => 'lm', + 'ল্ল' => 'll', + 'ল্ব' => 'lb', + 'ল' => 'l', + 'ম্থ' => 'mth', + 'ম্ফ' => 'mf', + 'ম্ভ' => 'mv', + 'মপ্ল' => 'mpl', + 'ম্ন' => 'mn', + 'ম্প' => 'mp', + 'ম্ম' => 'mm', + 'ম্ল' => 'ml', + 'ম্ব' => 'mb', + 'ম' => 'm', + '০' => '0', + '১' => '1', + '২' => '2', + '৩' => '3', + '৪' => '4', + '৫' => '5', + '৬' => '6', + '৭' => '7', + '৮' => '8', + '৯' => '9', + 'ঙ্ক্ষ' => 'Ngkx', + 'ঞ্ছ' => 'nch', + 'ঙ্ঘ' => 'ngh', + 'ঙ্খ' => 'nkh', + 'ঞ্ঝ' => 'njh', + 'ঙ্গৌ' => 'ngOU', + 'ঙ্গৈ' => 'ngOI', + 'ঞ্চ' => 'nc', + 'ঙ্ক' => 'nk', + 'ঙ্ষ' => 'Ngx', + 'ঙ্গ' => 'ngo', + 'ঙ্ম' => 'Ngm', + 'ঞ্জ' => 'nj', + 'ন্ধ' => 'ndh', + 'ন্ঠ' => 'nTh', + 'ণ্ঠ' => 'NTh', + 'ন্থ' => 'nth', + 'ঙ্গা' => 'nga', + 'ঙ্গি' => 'ngi', + 'ঙ্গী' => 'ngI', + 'ঙ্গু' => 'ngu', + 'ঙ্গূ' => 'ngU', + 'ঙ্গে' => 'nge', + 'ঙ্গো' => 'ngO', + 'ণ্ঢ' => 'NDh', + 'নশ' => 'nsh', + 'ঙর' => 'Ngr', + 'ঞর' => 'NGr', + 'ংর' => 'ngr', + 'ঙ' => 'Ng', + 'ঞ' => 'NG', + 'ং' => 'ng', + 'ন্ন' => 'nn', + 'ণ্ণ' => 'NN', + 'ণ্ন' => 'Nn', + 'ন্ম' => 'nm', + 'ণ্ম' => 'Nm', + 'ন্দ' => 'nd', + 'ন্ট' => 'nT', + 'ণ্ট' => 'NT', + 'ন্ড' => 'nD', + 'ণ্ড' => 'ND', + 'ন্ত' => 'nt', + 'ন্স' => 'ns', + 'ন' => 'n', + 'ণ' => 'N', + 'ৈ' => 'OI', + 'ৌ' => 'OU', + 'ো' => 'O', + 'ঐ' => 'OI', + 'ঔ' => 'OU', + 'অ' => 'o', + 'ও' => 'oo', + 'ফ্ল' => 'fl', + 'প্ট' => 'pT', + 'প্ত' => 'pt', + 'প্ন' => 'pn', + 'প্প' => 'pp', + 'প্ল' => 'pl', + 'প্স' => 'ps', + 'ফ' => 'f', + 'প' => 'p', + 'ৃ' => 'rri', + 'ঋ' => 'rri', + 'রর্য' => 'rry', + '্র্য' => 'ry', + '্রর' => 'rr', + 'ড়্গ' => 'Rg', + 'ঢ়' => 'Rh', + 'ড়' => 'R', + 'র' => 'r', + '্র' => 'r', + 'শ্ছ' => 'Sch', + 'ষ্ঠ' => 'ShTh', + 'ষ্ফ' => 'Shf', + 'স্ক্ল' => 'skl', + 'স্খ' => 'skh', + 'স্থ' => 'sth', + 'স্ফ' => 'sf', + 'শ্চ' => 'Sc', + 'শ্ত' => 'St', + 'শ্ন' => 'Sn', + 'শ্ম' => 'Sm', + 'শ্ল' => 'Sl', + 'ষ্ক' => 'Shk', + 'ষ্ট' => 'ShT', + 'ষ্ণ' => 'ShN', + 'ষ্প' => 'Shp', + 'ষ্ম' => 'Shm', + 'স্প্ল' => 'spl', + 'স্ক' => 'sk', + 'স্ট' => 'sT', + 'স্ত' => 'st', + 'স্ন' => 'sn', + 'স্প' => 'sp', + 'স্ম' => 'sm', + 'স্ল' => 'sl', + 'শ' => 'S', + 'ষ' => 'Sh', + 'স' => 's', + 'ু' => 'u', + 'উ' => 'u', + 'অ্য' => 'oZ', + 'ত্থ' => 'tth', + 'ৎ' => 'tt', + 'ট্ট' => 'TT', + 'ট্ম' => 'Tm', + 'ঠ' => 'Th', + 'ত্ন' => 'tn', + 'ত্ম' => 'tm', + 'থ' => 'th', + 'ত্ত' => 'tt', + 'ট' => 'T', + 'ত' => 't', + 'অ্যা' => 'AZ', + 'া' => 'a', + 'আ' => 'a', + 'য়া' => 'ya', + 'য়' => 'y', + 'ি' => 'i', + 'ই' => 'i', + 'ী' => 'ee', + 'ঈ' => 'ee', + 'ূ' => 'uu', + 'ঊ' => 'uu', + 'ে' => 'e', + 'এ' => 'e', + 'য' => 'z', + '্য' => 'Z', + 'ইয়' => 'y', + 'ওয়' => 'w', + '্ব' => 'w', + 'এক্স' => 'x', + 'ঃ' => ':', + 'ঁ' => 'nn', + '্' => '', + ], + // English + 'en' => [ + ], + // Latin (+ Cyrillic ?) chars + // + // -> Mix of languages, but we need to keep this here, so that different languages can handle there own behavior. + 'latin' => [ + '˚' => '0', + '¹' => '1', + '²' => '2', + '³' => '3', + '⁴' => '4', + '⁵' => '5', + '⁶' => '6', + '⁷' => '7', + '⁸' => '8', + '⁹' => '9', + '₀' => '0', + '₁' => '1', + '₂' => '2', + '₃' => '3', + '₄' => '4', + '₅' => '5', + '₆' => '6', + '₇' => '7', + '₈' => '8', + '₉' => '9', + '௦' => '0', + '௧' => '1', + '௨' => '2', + '௩' => '3', + '௪' => '4', + '௫' => '5', + '௬' => '6', + '௭' => '7', + '௮' => '8', + '௯' => '9', + '௰' => '10', + '௱' => '100', + '௲' => '1000', + 'Ꜳ' => 'AA', + 'ꜳ' => 'aa', + 'Æ' => 'AE', + 'æ' => 'ae', + 'Ǽ' => 'AE', + 'ǽ' => 'ae', + 'Ꜵ' => 'AO', + 'ꜵ' => 'ao', + 'Ꜷ' => 'AU', + 'ꜷ' => 'au', + 'Ꜹ' => 'AV', + 'ꜹ' => 'av', + 'Ꜻ' => 'av', + 'ꜻ' => 'av', + 'Ꜽ' => 'AY', + 'ꜽ' => 'ay', + 'ȸ' => 'db', + 'ʣ' => 'dz', + 'ʥ' => 'dz', + 'ʤ' => 'dezh', + '🙰' => 'et', + 'ff' => 'ff', + 'ffi' => 'ffi', + 'ffl' => 'ffl', + 'fi' => 'fi', + 'fl' => 'fl', + 'ʩ' => 'feng', + 'IJ' => 'IJ', + 'ij' => 'ij', + 'ʪ' => 'ls', + 'ʫ' => 'lz', + 'ɮ' => 'lezh', + 'ȹ' => 'qp', + 'ʨ' => 'tc', + 'ʦ' => 'ts', + 'ʧ' => 'tesh', + 'Œ' => 'OE', + 'œ' => 'oe', + 'Ꝏ' => 'OO', + 'ꝏ' => 'oo', + 'ẞ' => 'SS', + 'ß' => 'ss', + 'st' => 'st', + 'ſt' => 'st', + 'Ꜩ' => 'TZ', + 'ꜩ' => 'tz', + 'ᵫ' => 'ue', + 'Aι' => 'Ai', + 'αι' => 'ai', + 'Ει' => 'Ei', + 'ει' => 'ei', + 'Οι' => 'Oi', + 'οι' => 'oi', + 'Ου' => 'Oy', + 'ου' => 'oy', + 'Υι' => 'Yi', + 'υι' => 'yi', + 'ἀ' => 'a', + 'ἁ' => 'a', + 'ἂ' => 'a', + 'ἃ' => 'a', + 'ἄ' => 'a', + 'ἅ' => 'a', + 'ἆ' => 'a', + 'ἇ' => 'a', + 'Ἀ' => 'A', + 'Ἁ' => 'A', + 'Ἂ' => 'A', + 'Ἃ' => 'A', + 'Ἄ' => 'A', + 'Ἅ' => 'A', + 'Ἆ' => 'A', + 'Ἇ' => 'A', + 'ᾰ' => 'a', + 'ᾱ' => 'a', + 'ᾲ' => 'a', + 'ᾳ' => 'a', + 'ᾴ' => 'a', + 'ᾶ' => 'a', + 'ᾷ' => 'a', + 'Ᾰ' => 'A', + 'Ᾱ' => 'A', + 'Ὰ' => 'A', + 'Ά' => 'A', + 'ᾼ' => 'A', + 'Ä' => 'A', + 'ä' => 'a', + 'À' => 'A', + 'à' => 'a', + 'Á' => 'A', + 'á' => 'a', + 'Â' => 'A', + 'â' => 'a', + 'Ã' => 'A', + 'ã' => 'a', + 'A̧' => 'A', + 'a̧' => 'a', + 'Ą' => 'A', + 'ą' => 'a', + 'Ⱥ' => 'A', + 'ⱥ' => 'a', + 'Å' => 'A', + 'å' => 'a', + 'Ǻ' => 'A', + 'ǻ' => 'a', + 'Ă' => 'A', + 'ă' => 'a', + 'Ǎ' => 'A', + 'ǎ' => 'a', + 'Ȧ' => 'A', + 'ȧ' => 'a', + 'Ạ' => 'A', + 'ạ' => 'a', + 'Ā' => 'A', + 'ā' => 'a', + 'ª' => 'a', + 'Ɓ' => 'B', + 'Ѣ' => 'E', + 'ѣ' => 'e', + 'Ç' => 'C', + 'ç' => 'c', + 'Ĉ' => 'C', + 'ĉ' => 'c', + 'C̈' => 'C', + 'c̈' => 'c', + 'C̨' => 'C', + 'c̨' => 'c', + 'Ȼ' => 'C', + 'ȼ' => 'c', + 'Č' => 'C', + 'č' => 'c', + 'Ć' => 'C', + 'ć' => 'c', + 'C̀' => 'C', + 'c̀' => 'c', + 'Ċ' => 'C', + 'ċ' => 'c', + 'C̣' => 'C', + 'c̣' => 'c', + 'C̄' => 'C', + 'c̄' => 'c', + 'C̃' => 'C', + 'c̃' => 'c', + 'Ð' => 'D', + 'Đ' => 'D', + 'ð' => 'd', + 'đ' => 'd', + 'È' => 'E', + 'É' => 'E', + 'Ê' => 'E', + 'Ë' => 'E', + 'Ĕ' => 'E', + 'Ė' => 'E', + 'Ȩ' => 'E', + 'ȩ' => 'e', + 'Ę' => 'E', + 'ę' => 'e', + 'Ɇ' => 'E', + 'ɇ' => 'e', + 'Ě' => 'E', + 'ě' => 'e', + 'Ẹ' => 'E', + 'ẹ' => 'e', + 'Ē' => 'E', + 'ē' => 'e', + 'Ẽ' => 'E', + 'ẽ' => 'e', + 'è' => 'e', + 'é' => 'e', + 'ê' => 'e', + 'ë' => 'e', + 'ĕ' => 'e', + 'ė' => 'e', + 'ƒ' => 'f', + 'Ѳ' => 'F', + 'ѳ' => 'f', + 'Ĝ' => 'G', + 'Ġ' => 'G', + 'ĝ' => 'g', + 'ġ' => 'g', + 'Ĥ' => 'H', + 'Ħ' => 'H', + 'ĥ' => 'h', + 'ħ' => 'h', + 'Ì' => 'I', + 'Í' => 'I', + 'Î' => 'I', + 'Ï' => 'I', + 'Ĩ' => 'I', + 'Ĭ' => 'I', + 'Ǐ' => 'I', + 'Į' => 'I', + 'ì' => 'i', + 'í' => 'i', + 'î' => 'i', + 'ï' => 'i', + 'ĩ' => 'i', + 'ĭ' => 'i', + 'ǐ' => 'i', + 'į' => 'i', + 'І' => 'I', + 'і' => 'i', + 'I̧' => 'I', + 'i̧' => 'i', + 'Ɨ' => 'I', + 'ɨ' => 'i', + 'İ' => 'I', + 'i' => 'i', + 'Ị' => 'I', + 'ị' => 'i', + 'Ī' => 'I', + 'ī' => 'i', + 'Ĵ' => 'J', + 'ĵ' => 'j', + 'J́́' => 'J', + 'j́' => 'j', + 'J̀̀' => 'J', + 'j̀' => 'j', + 'J̈' => 'J', + 'j̈' => 'j', + 'J̧' => 'J', + 'j̧' => 'j', + 'J̨' => 'J', + 'j̨' => 'j', + 'Ɉ' => 'J', + 'ɉ' => 'j', + 'J̌' => 'J', + 'ǰ' => 'j', + 'J̇' => 'J', + 'j' => 'j', + 'J̣' => 'J', + 'j̣' => 'j', + 'J̄' => 'J', + 'j̄' => 'j', + 'J̃' => 'J', + 'j̃' => 'j', + 'Й' => 'i', + 'й' => 'i', + 'ĸ' => 'k', + 'Ĺ' => 'L', + 'Ľ' => 'L', + 'Ŀ' => 'L', + 'ĺ' => 'l', + 'ľ' => 'l', + 'ŀ' => 'l', + 'L̀' => 'L', + 'l̀' => 'l', + 'L̂' => 'L', + 'l̂' => 'l', + 'L̈' => 'L', + 'l̈' => 'l', + 'Ļ' => 'L', + 'ļ' => 'l', + 'L̨' => 'L', + 'l̨' => 'l', + 'Ł' => 'L', + 'ł' => 'l', + 'Ƚ' => 'L', + 'ƚ' => 'l', + 'L̇' => 'L', + 'l̇' => 'l', + 'Ḷ' => 'L', + 'ḷ' => 'l', + 'L̄' => 'L', + 'l̄' => 'l', + 'L̃' => 'L', + 'l̃' => 'l', + 'Ñ' => 'N', + 'ñ' => 'n', + 'Ŋ' => 'N', + 'ŋ' => 'n', + 'ʼn' => 'n', + 'Ń' => 'N', + 'ń' => 'n', + 'Ǹ' => 'N', + 'ǹ' => 'n', + 'N̂' => 'N', + 'n̂' => 'n', + 'N̈' => 'N', + 'n̈' => 'n', + 'Ņ' => 'N', + 'ņ' => 'n', + 'N̨' => 'N', + 'n̨' => 'n', + 'Ꞥ' => 'N', + 'ꞥ' => 'n', + 'Ň' => 'N', + 'ň' => 'n', + 'Ṅ' => 'N', + 'ṅ' => 'n', + 'Ṇ' => 'N', + 'ṇ' => 'n', + 'N̄' => 'N', + 'n̄' => 'n', + 'Ö' => 'O', + 'Ò' => 'O', + 'Ó' => 'O', + 'Ô' => 'O', + 'Õ' => 'O', + 'Ō' => 'O', + 'Ŏ' => 'O', + 'Ǒ' => 'O', + 'Ő' => 'O', + 'Ơ' => 'O', + 'Ø' => 'O', + 'Ǿ' => 'O', + 'ö' => 'o', + 'ò' => 'o', + 'ó' => 'o', + 'ô' => 'o', + 'õ' => 'o', + 'ō' => 'o', + 'ŏ' => 'o', + 'ǒ' => 'o', + 'ő' => 'o', + 'ơ' => 'o', + 'ø' => 'o', + 'ǿ' => 'o', + 'º' => 'o', + 'O̧' => 'O', + 'o̧' => 'o', + 'Ǫ' => 'O', + 'ǫ' => 'o', + 'Ɵ' => 'O', + 'ɵ' => 'o', + 'Ȯ' => 'O', + 'ȯ' => 'o', + 'Ọ' => 'O', + 'ọ' => 'o', + 'Ŕ' => 'R', + 'Ŗ' => 'R', + 'ŕ' => 'r', + 'ŗ' => 'r', + 'Ŝ' => 'S', + 'Ș' => 'S', + 'ș' => 's', + 'Ś' => 'S', + 'ś' => 's', + 'S̀' => 'S', + 's̀' => 's', + 'Ŝ̀' => 'S', + 'ŝ' => 's', + 'S̈' => 'S', + 's̈' => 's', + 'Ş' => 'S', + 'ş' => 's', + 'S̨' => 'S', + 's̨' => 's', + 'Ꞩ' => 'S', + 'ꞩ' => 's', + 'Š' => 'S', + 'š' => 's', + 'Ṡ' => 'S', + 'ṡ' => 's', + 'Ṣ' => 'S', + 'ṣ' => 's', + 'S̄' => 'S', + 's̄' => 's', + 'S̃' => 'S', + 's̃' => 's', + 'ſ' => 's', + 'Ţ' => 'T', + 'Ț' => 'T', + 'Ŧ' => 'T', + 'Þ' => 'TH', + 'ţ' => 't', + 'ț' => 't', + 'ŧ' => 't', + 'þ' => 'th', + 'T́' => 'T', + 't́' => 't', + 'T̀' => 'T', + 't̀' => 't', + 'T̂' => 'T', + 't̂' => 't', + 'T̈' => 'T', + 'ẗ' => 't', + 'T̨' => 'T', + 't̨' => 't', + 'Ⱦ' => 'T', + 'ⱦ' => 't', + 'Ť' => 'T', + 'ť' => 't', + 'Ṫ' => 'T', + 'ṫ' => 't', + 'Ṭ' => 'T', + 'ṭ' => 't', + 'T̄' => 'T', + 't̄' => 't', + 'T̃' => 'T', + 't̃' => 't', + 'Ü' => 'U', + 'Ù' => 'U', + 'Ú' => 'U', + 'Û' => 'U', + 'Ũ' => 'U', + 'Ŭ' => 'U', + 'Ű' => 'U', + 'Ų' => 'U', + 'Ư' => 'U', + 'Ǔ' => 'U', + 'Ǖ' => 'U', + 'Ǘ' => 'U', + 'Ǚ' => 'U', + 'Ǜ' => 'U', + 'ü' => 'u', + 'ù' => 'u', + 'ú' => 'u', + 'û' => 'u', + 'ũ' => 'u', + 'ŭ' => 'u', + 'ű' => 'u', + 'ų' => 'u', + 'ư' => 'u', + 'ǔ' => 'u', + 'ǖ' => 'u', + 'ǘ' => 'u', + 'ǚ' => 'u', + 'ǜ' => 'u', + 'U̧' => 'U', + 'u̧' => 'u', + 'Ʉ' => 'U', + 'ʉ' => 'u', + 'U̇' => 'U', + 'u̇' => 'u', + 'Ụ' => 'U', + 'ụ' => 'u', + 'Ū' => 'U', + 'ū' => 'u', + 'Ʊ' => 'U', + 'ʊ' => 'u', + 'Ŵ' => 'W', + 'ŵ' => 'w', + 'Ẁ' => 'W', + 'ẁ' => 'w', + 'Ẃ' => 'W', + 'ẃ' => 'w', + 'Ẅ' => 'W', + 'ẅ' => 'w', + 'Ѵ' => 'I', + 'ѵ' => 'i', + 'Ꙗ' => 'Ja', + 'ꙗ' => 'ja', + 'Є' => 'Je', + 'є' => 'je', + 'Ѥ' => 'Je', + 'ѥ' => 'je', + 'Ѕ' => 'Dz', + 'ѕ' => 'dz', + 'Ꙋ' => 'U', + 'ꙋ' => 'u', + 'Ѡ' => 'O', + 'ѡ' => 'o', + 'Ѿ' => 'Ot', + 'ѿ' => 'ot', + 'Ѫ' => 'U', + 'ѫ' => 'u', + 'Ѧ' => 'Ja', + 'ѧ' => 'ja', + 'Ѭ' => 'Ju', + 'ѭ' => 'ju', + 'Ѩ' => 'Ja', + 'ѩ' => 'Ja', + 'Ѯ' => 'Ks', + 'ѯ' => 'ks', + 'Ѱ' => 'Ps', + 'ѱ' => 'ps', + 'Х' => 'X', + 'х' => 'x', + 'Ý' => 'Y', + 'Ÿ' => 'Y', + 'Ŷ' => 'Y', + 'ý' => 'y', + 'ÿ' => 'y', + 'ŷ' => 'y', + 'Ỳ' => 'Y', + 'ỳ' => 'y', + 'Y̧' => 'Y', + 'y̧' => 'y', + 'Y̨' => 'Y', + 'y̨' => 'y', + 'Ɏ' => 'Y', + 'ɏ' => 'y', + 'Y̌' => 'Y', + 'y̌' => 'y', + 'Ẏ' => 'Y', + 'ẏ' => 'y', + 'Ỵ' => 'Y', + 'ỵ' => 'y', + 'Ȳ' => 'Y', + 'ȳ' => 'y', + 'Ỹ' => 'Y', + 'ỹ' => 'y', + 'Щ' => 'Shh', + 'щ' => 'shh', + 'Ź' => 'Z', + 'ź' => 'z', + 'Z̀' => 'Z', + 'z̀' => 'z', + 'Ẑ' => 'Z', + 'ẑ' => 'z', + 'Z̈' => 'Z', + 'z̈' => 'z', + 'Z̧' => 'Z', + 'z̧' => 'z', + 'Z̨' => 'Z', + 'z̨' => 'z', + 'Ƶ' => 'Z', + 'ƶ' => 'z', + 'Ž' => 'Z', + 'ž' => 'z', + 'Ż' => 'Z', + 'ż' => 'z', + 'Ẓ' => 'Z', + 'ẓ' => 'z', + 'Z̄' => 'Z', + 'z̄' => 'z', + 'Z̃' => 'Z', + 'z̃' => 'z', + ], + // whitespace chars + ' ' => [ + "\xc2\xa0" => ' ', // 'NO-BREAK SPACE' + "\xe1\x9a\x80" => ' ', // 'OGHAM SPACE MARK' + "\xe2\x80\x80" => ' ', // 'EN QUAD' + "\xe2\x80\x81" => ' ', // 'EM QUAD' + "\xe2\x80\x82" => ' ', // 'EN SPACE' + "\xe2\x80\x83" => ' ', // 'EM SPACE' + "\xe2\x80\x84" => ' ', // 'THREE-PER-EM SPACE' + "\xe2\x80\x85" => ' ', // 'FOUR-PER-EM SPACE' + "\xe2\x80\x86" => ' ', // 'SIX-PER-EM SPACE' + "\xe2\x80\x87" => ' ', // 'FIGURE SPACE' + "\xe2\x80\x88" => ' ', // 'PUNCTUATION SPACE' + "\xe2\x80\x89" => ' ', // 'THIN SPACE' + "\xe2\x80\x8a" => ' ', // 'HAIR SPACE' + "\xe2\x80\xa8" => ' ', // 'LINE SEPARATOR' + "\xe2\x80\xa9" => ' ', // 'PARAGRAPH SEPARATOR' + "\xe2\x80\x8b" => ' ', // 'ZERO WIDTH SPACE' + "\xe2\x80\xaf" => ' ', // 'NARROW NO-BREAK SPACE' + "\xe2\x81\x9f" => ' ', // 'MEDIUM MATHEMATICAL SPACE' + "\xe3\x80\x80" => ' ', // 'IDEOGRAPHIC SPACE' + "\xef\xbe\xa0" => ' ', // 'HALFWIDTH HANGUL FILLER' + ], + // commonly used in Word documents + 'msword' => [ + "\xc2\xab" => '<<', // « (U+00AB) in UTF-8 + "\xc2\xbb" => '>>', // » (U+00BB) in UTF-8 + "\xe2\x80\x98" => "'", // ‘ (U+2018) in UTF-8 + "\xe2\x80\x99" => "'", // ’ (U+2019) in UTF-8 + "\xe2\x80\x9a" => "'", // ‚ (U+201A) in UTF-8 + "\xe2\x80\x9b" => "'", // ‛ (U+201B) in UTF-8 + "\xe2\x80\x9c" => '"', // “ (U+201C) in UTF-8 + "\xe2\x80\x9d" => '"', // ” (U+201D) in UTF-8 + "\xe2\x80\x9e" => '"', // „ (U+201E) in UTF-8 + "\xe2\x80\x9f" => '"', // ‟ (U+201F) in UTF-8 + "\xe2\x80\xb9" => "'", // ‹ (U+2039) in UTF-8 + "\xe2\x80\xba" => "'", // › (U+203A) in UTF-8 + "\xe2\x80\x93" => '-', // – (U+2013) in UTF-8 + "\xe2\x80\x94" => '-', // — (U+2014) in UTF-8 + "\xe2\x80\xa6" => '...', // … (U+2026) in UTF-8 + ], + // Currency + // + // url => https://en.wikipedia.org/wiki/Currency_symbol + 'currency_short' => [ + '€' => 'EUR', + '$' => '$', + '₢' => 'Cr', + '₣' => 'Fr.', + '£' => 'PS', + '₤' => 'L.', + 'ℳ' => 'M', + '₥' => 'mil', + '₦' => 'N', + '₧' => 'Pts', + '₨' => 'Rs', + 'රු' => 'LKR', + 'ரூ' => 'LKR', + '௹' => 'Rs', + 'रू' => 'NPR', + '₹' => 'Rs', + '૱' => 'Rs', + '₩' => 'W', + '₪' => 'NS', + '₸' => 'KZT', + '₫' => 'D', + '֏' => 'AMD', + '₭' => 'K', + '₺' => 'TL', + '₼' => 'AZN', + '₮' => 'T', + '₯' => 'Dr', + '₲' => 'PYG', + '₾' => 'GEL', + '₳' => 'ARA', + '₴' => 'UAH', + '₽' => 'RUB', + '₵' => 'GHS', + '₡' => 'CL', + '¢' => 'c', + '¥' => 'YEN', + '円' => 'JPY', + '৳' => 'BDT', + '元' => 'CNY', + '﷼' => 'SAR', + '៛' => 'KR', + '₠' => 'ECU', + '¤' => '$?', + '฿' => 'THB', + '؋' => 'AFN', + ], +]; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/ascii_extras_by_languages.php b/includes/libraries/anti-xss-master/src/voku/helper/data/ascii_extras_by_languages.php new file mode 100644 index 000000000..afe31ae2c --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/ascii_extras_by_languages.php @@ -0,0 +1,759 @@ + [ + '=' => ' gelijk ', + '%' => ' procent ', + '∑' => ' som ', + '∆' => ' delta ', + '∞' => ' oneindig ', + '♥' => ' love ', + '&' => ' en ', + '+' => ' plus ', + ], + // Italian + 'it' => [ + '=' => ' uguale ', + '%' => ' percent ', + '∑' => ' somma ', + '∆' => ' delta ', + '∞' => ' infinito ', + '♥' => ' amore ', + '&' => ' e ', + '+' => ' piu ', + ], + // Macedonian + 'mk' => [ + '=' => ' ednakva ', + '%' => ' procenti ', + '∑' => ' zbir ', + '∆' => ' delta ', + '∞' => ' beskonecnost ', + '♥' => ' loveubov ', + '&' => ' i ', + '+' => ' plus ', + ], + // Portuguese (Brazil) + 'pt' => [ + '=' => ' igual ', + '%' => ' por cento ', + '∑' => ' soma ', + '∆' => ' delta ', + '∞' => ' infinito ', + '♥' => ' amor ', + '&' => ' e ', + '+' => ' mais ', + ], + // Greek(lish) (Elláda) + 'el__greeklish' => [ + '=' => ' isos ', + '%' => ' tois ekato ', + '∑' => ' athroisma ', + '∆' => ' delta ', + '∞' => ' apeiro ', + '♥' => ' agape ', + '&' => ' kai ', + '+' => ' syn ', + ], + // Greek (Elláda) + 'el' => [ + '=' => ' isos ', + '%' => ' tois ekato ', + '∑' => ' athroisma ', + '∆' => ' delta ', + '∞' => ' apeiro ', + '♥' => ' agape ', + '&' => ' kai ', + '+' => ' syn ', + ], + // Hindi + 'hi' => [ + '=' => ' samana ', + '%' => ' paratisata ', + '∑' => ' yoga ', + '∆' => ' dalata ', + '∞' => ' anata ', + '♥' => ' payara ', + '&' => ' aura ', + '+' => ' palasa ', + ], + // Armenian + 'hy' => [ + '=' => ' havasar ', + '%' => ' tvokvos ', + '∑' => ' gvoumar ', + '∆' => ' delta ', + '∞' => ' ansahmanvouthyvoun ', + '♥' => ' ser ', + '&' => ' ev ', + '+' => ' gvoumarats ', + ], + // Swedish + 'sv' => [ + '=' => ' lika ', + '%' => ' procent ', + '∑' => ' summa ', + '∆' => ' delta ', + '∞' => ' oandlighet ', + '♥' => ' alskar ', + '&' => ' och ', + '+' => ' plus ', + ], + // Turkmen + 'tk' => [ + '=' => ' den ', + '%' => ' yuzde ', + '∑' => ' jem ', + '∆' => ' delta ', + '∞' => ' mudimilik ', + '♥' => ' soygi ', + '&' => ' we ', + '+' => ' yzy ', + ], + // Turkish + 'tr' => [ + '=' => ' esit ', + '%' => ' yuzde ', + '∑' => ' Toplam ', + '∆' => ' delta ', + '∞' => ' sonsuzluk ', + '♥' => ' ask ', + '&' => ' ve ', + '+' => ' arti ', + ], + // Bulgarian + 'bg' => [ + '=' => ' raven ', + '%' => ' na sto ', + '∑' => ' suma ', + '∆' => ' delta ', + '∞' => ' bezkrajnost ', + '♥' => ' obicam ', + '&' => ' i ', + '+' => ' plus ', + ], + // Hungarian + 'hu' => [ + '=' => ' Egyenlo ', + '%' => ' Szazalek ', + '∑' => ' osszeg ', + '∆' => ' delta ', + '∞' => ' vegtelenitett ', + '♥' => ' love ', + '&' => ' Es ', + '+' => ' Plusz ', + ], + // Myanmar (Burmese) + 'my' => [ + '=' => ' ttn:ttnnym? ', + '%' => ' raakhngnn:k ', + '∑' => ' ld ', + '∆' => ' m?cwk?n:pe? ', + '∞' => ' ach:m ', + '♥' => ' mettttaa ', + '&' => ' n ', + '+' => ' ape?ng: ', + ], + // Croatian (Hrvatska) + 'hr' => [ + '=' => ' Jednaki ', + '%' => ' Posto ', + '∑' => ' zbroj ', + '∆' => ' Delta ', + '∞' => ' beskonacno ', + '♥' => ' ljubav ', + '&' => ' I ', + '+' => ' Plus ', + ], + // Finnish + 'fi' => [ + '=' => ' Sama ', + '%' => ' Prosenttia ', + '∑' => ' sum ', + '∆' => ' delta ', + '∞' => ' aareton ', + '♥' => ' rakkautta ', + '&' => ' Ja ', + '+' => ' Plus ', + ], + // Georgian (Kartvelian) + 'ka' => [ + '=' => ' tanasts\'ori ', + '%' => ' p\'rotsent\'i ', + '∑' => ' tankha ', + '∆' => ' delt\'a ', + '∞' => ' usasrulo ', + '♥' => ' siq\'varuli ', + '&' => ' da ', + '+' => ' p\'lus ', + ], + // Russian + 'ru' => [ + '=' => ' ravnyj ', + '%' => ' procent ', + '∑' => ' summa ', + '∆' => ' del\'ta ', + '∞' => ' beskonecnost\' ', + '♥' => ' lublu ', + '&' => ' i ', + '+' => ' plus ', + ], + // Russian - GOST 7.79-2000(B) + 'ru__gost_2000_b' => [ + '=' => ' ravnyj ', + '%' => ' procent ', + '∑' => ' summa ', + '∆' => ' del\'ta ', + '∞' => ' beskonecnost\' ', + '♥' => ' lublu ', + '&' => ' i ', + '+' => ' plus ', + ], + // Russian - Passport (2013), ICAO + 'ru__passport_2013' => [ + '=' => ' ravnyj ', + '%' => ' procent ', + '∑' => ' summa ', + '∆' => ' del\'ta ', + '∞' => ' beskonecnost\' ', + '♥' => ' lublu ', + '&' => ' i ', + '+' => ' plus ', + ], + // Ukrainian + 'uk' => [ + '=' => ' rivnij ', + '%' => ' vidsotkiv ', + '∑' => ' suma ', + '∆' => ' del\'ta ', + '∞' => ' neskincennist\' ', + '♥' => ' lubov ', + '&' => ' i ', + '+' => ' plus ', + ], + // Kazakh + 'kk' => [ + '=' => ' ten\' ', + '%' => ' Pajyzdar ', + '∑' => ' zalpy ', + '∆' => ' ajyrmasylyk, ', + '∞' => ' seksiz ', + '♥' => ' mahabbat ', + '&' => ' z@ne ', + '+' => ' plus ', + ], + // Czech + 'cs' => [ + '=' => ' rovnat se ', + '%' => ' procento ', + '∑' => ' soucet ', + '∆' => ' delta ', + '∞' => ' nekonecno ', + '♥' => ' laska ', + '&' => ' a ', + '+' => ' plus ', + ], + // Danish + 'da' => [ + '=' => ' Lige ', + '%' => ' Prozent ', + '∑' => ' sum ', + '∆' => ' delta ', + '∞' => ' uendelig ', + '♥' => ' kaerlighed ', + '&' => ' Og ', + '+' => ' Plus ', + ], + // Polish + 'pl' => [ + '=' => ' rowny ', + '%' => ' procent ', + '∑' => ' suma ', + '∆' => ' delta ', + '∞' => ' nieskonczonosc ', + '♥' => ' milosc ', + '&' => ' i ', + '+' => ' plus ', + ], + // Romanian + 'ro' => [ + '=' => ' egal ', + '%' => ' la suta ', + '∑' => ' suma ', + '∆' => ' delta ', + '∞' => ' infinit ', + '♥' => ' dragoste ', + '&' => ' si ', + '+' => ' la care se adauga ', + ], + // Esperanto + 'eo' => [ + '=' => ' Egalaj ', + '%' => ' Procento ', + '∑' => ' sumo ', + '∆' => ' delto ', + '∞' => ' senfina ', + '♥' => ' amo ', + '&' => ' Kaj ', + '+' => ' Pli ', + ], + // Estonian + 'et' => [ + '=' => ' Vordsed ', + '%' => ' Protsenti ', + '∑' => ' summa ', + '∆' => ' o ', + '∞' => ' loputut ', + '♥' => ' armastus ', + '&' => ' Ja ', + '+' => ' Pluss ', + ], + // Latvian + 'lv' => [ + '=' => ' vienads ', + '%' => ' procents ', + '∑' => ' summa ', + '∆' => ' delta ', + '∞' => ' bezgaliba ', + '♥' => ' milestiba ', + '&' => ' un ', + '+' => ' pluss ', + ], + // Lithuanian + 'lt' => [ + '=' => ' lygus ', + '%' => ' procentu ', + '∑' => ' suma ', + '∆' => ' delta ', + '∞' => ' begalybe ', + '♥' => ' meile ', + '&' => ' ir ', + '+' => ' plius ', + ], + // Norwegian + 'no' => [ + '=' => ' Lik ', + '%' => ' Prosent ', + '∑' => ' sum ', + '∆' => ' delta ', + '∞' => ' uendelig ', + '♥' => ' kjaerlighet ', + '&' => ' Og ', + '+' => ' Pluss ', + ], + // Vietnamese + 'vi' => [ + '=' => ' cong bang ', + '%' => ' phan tram ', + '∑' => ' tong so ', + '∆' => ' dong bang ', + '∞' => ' vo cuc ', + '♥' => ' Yeu ', + '&' => ' va ', + '+' => ' them ', + ], + // Arabic + 'ar' => [ + '=' => ' mtsawy ', + '%' => ' nsbh mywyh ', + '∑' => ' mjmw\' ', + '∆' => ' dlta ', + '∞' => ' ma la nhayt ', + '♥' => ' hb ', + '&' => ' w ', + '+' => ' zayd ', + ], + // Persian (Farsi) + 'fa' => [ + '=' => ' brabr ', + '%' => ' dr sd ', + '∑' => ' mjmw\' ', + '∆' => ' dlta ', + '∞' => ' by nhayt ', + '♥' => ' \'shq ', + '&' => ' w ', + '+' => ' bh \'lawh ', + ], + // Serbian + 'sr' => [ + '=' => ' jednak ', + '%' => ' procenat ', + '∑' => ' zbir ', + '∆' => ' delta ', + '∞' => ' beskraj ', + '♥' => ' lubav ', + '&' => ' i ', + '+' => ' vise ', + ], + // Serbian - Cyrillic + 'sr__cyr' => [ + '=' => ' jednak ', + '%' => ' procenat ', + '∑' => ' zbir ', + '∆' => ' delta ', + '∞' => ' beskraj ', + '♥' => ' lubav ', + '&' => ' i ', + '+' => ' vise ', + ], + // Serbian - Latin + 'sr__lat' => [ + '=' => ' jednak ', + '%' => ' procenat ', + '∑' => ' zbir ', + '∆' => ' delta ', + '∞' => ' beskraj ', + '♥' => ' lubav ', + '&' => ' i ', + '+' => ' vise ', + ], + // Azerbaijani + 'az' => [ + '=' => ' b@rab@r ', + '%' => ' faiz ', + '∑' => ' m@bl@g ', + '∆' => ' delta ', + '∞' => ' sonsuzluq ', + '♥' => ' sevgi ', + '&' => ' v@ ', + '+' => ' plus ', + ], + // Slovak + 'sk' => [ + '=' => ' rovny ', + '%' => ' percento ', + '∑' => ' sucet ', + '∆' => ' delta ', + '∞' => ' infinity ', + '♥' => ' milovat ', + '&' => ' a ', + '+' => ' viac ', + ], + // French + 'fr' => [ + '=' => ' Egal ', + '%' => ' Pourcentage ', + '∑' => ' somme ', + '∆' => ' delta ', + '∞' => ' infini ', + '♥' => ' amour ', + '&' => ' Et ', + '+' => ' Plus ', + ], + // Austrian (French) + 'fr_at' => [ + '=' => ' Egal ', + '%' => ' Pourcentage ', + '∑' => ' somme ', + '∆' => ' delta ', + '∞' => ' infini ', + '♥' => ' amour ', + '&' => ' Et ', + '+' => ' Plus ', + ], + // Switzerland (French) + 'fr_ch' => [ + '=' => ' Egal ', + '%' => ' Pourcentage ', + '∑' => ' somme ', + '∆' => ' delta ', + '∞' => ' infini ', + '♥' => ' amour ', + '&' => ' Et ', + '+' => ' Plus ', + ], + // German + 'de' => [ + '=' => ' gleich ', + '%' => ' Prozent ', + '∑' => ' gesamt ', + '∆' => ' Unterschied ', + '∞' => ' undendlich ', + '♥' => ' liebe ', + '&' => ' und ', + '+' => ' plus ', + ], + // Austrian (German) + 'de_at' => [ + '=' => ' gleich ', + '%' => ' Prozent ', + '∑' => ' gesamt ', + '∆' => ' Unterschied ', + '∞' => ' undendlich ', + '♥' => ' liebe ', + '&' => ' und ', + '+' => ' plus ', + ], + // Switzerland (German) + 'de_ch' => [ + '=' => ' gleich ', + '%' => ' Prozent ', + '∑' => ' gesamt ', + '∆' => ' Unterschied ', + '∞' => ' undendlich ', + '♥' => ' liebe ', + '&' => ' und ', + '+' => ' plus ', + ], + // Bengali (Bangla) + 'bn' => [ + '=' => ' Saman ', + '%' => ' Satakora ', + '∑' => ' Samasti ', + '∆' => ' Badhip ', + '∞' => ' Ananta ', + '♥' => ' Valobasa ', + '&' => ' Abong ', + '+' => ' Songzojon ', + ], + // English + 'en' => [ + '=' => ' equal ', + '%' => ' percent ', + '∑' => ' sum ', + '∆' => ' delta ', + '∞' => ' infinity ', + '♥' => ' love ', + '&' => ' and ', + '+' => ' plus ', + ], + // Currency + // + // url: https://en.wikipedia.org/wiki/Currency_symbol + 'currency' => [ + '€' => ' Euro ', + '$' => ' Dollar ', + '₢' => ' cruzeiro ', + '₣' => ' French franc ', + '£' => ' pound ', + '₤' => ' lira ', // Italian + '₶' => ' livre tournois ', + 'ℳ' => ' mark ', + '₥' => ' mill ', + '₦' => ' naira ', + '₧' => ' peseta ', + '₨' => ' rupee ', + 'රු' => ' rupee ', // Sri Lankan + 'ரூ' => ' rupee ', // Sri Lankan + '௹' => ' rupee ', // Tamil + 'रू' => ' rupee ', // Nepalese + '₹' => ' rupee ', // Indian + '૱' => ' rupee ', // Gujarat + '₩' => ' won ', + '₪' => ' new shequel ', + '₸' => ' tenge ', + '₫' => ' dong ', + '֏' => ' dram ', + '₭' => ' kip ', + '₺' => ' lira ', // Turkish + '₼' => ' manat ', + '₮' => ' tugrik ', + '₯' => ' drachma ', + '₰' => ' pfennig ', + '₷' => ' spesmilo ', + '₱' => ' peso ', // Philippine + '﷼' => ' riyal ', + '₲' => ' guarani ', + '₾' => ' lari ', + '₳' => ' austral ', + '₴' => ' hryvnia ', + '₽' => ' ruble ', + '₵' => ' cedi ', + '₡' => ' colon ', + '¢' => ' cent ', + '¥' => ' yen ', + '円' => ' yen ', + '৳' => ' taka ', + '元' => ' yuan ', + '﷼' => ' riyal ', + '៛' => ' riel ', + '₠' => ' European Currency ', + '¤' => ' currency ', + '฿' => ' baht ', + '؋' => ' afghani ', + ], + // Temperature + // + // url: https://en.wikipedia.org/wiki/Conversion_of_units_of_temperature + 'temperature' => [ + '°De' => ' Delisle ', + '°Re' => ' Reaumur ', // Réaumur + '°Ro' => ' Romer ', // Rømer + '°R' => ' Rankine ', + '°C' => ' Celsius ', + '°F' => ' Fahrenheit ', + '°N' => ' Newton ', + ], + 'latin_symbols' => [ + '=' => '=', + '%' => '%', + '∑' => '∑', + '∆' => '∆', + '∞' => '∞', + '♥' => '♥', + '&' => '&', + '+' => '+', + // --- + '©' => ' (c) ', + '®' => ' (r) ', + '@' => ' (at) ', + '№' => ' No. ', + '℞' => ' Rx ', + '[' => '[', + '\' => '\\', + ']' => ']', + '^' => '^', + '_' => '_', + '`' => '`', + '‐' => '-', + '‑' => '-', + '‒' => '-', + '–' => '-', + '−' => '-', + '—' => '-', + '―' => '-', + '﹘' => '-', + '│' => '|', + '∖' => '\\', + '∕' => '/', + '⁄' => '/', + '←' => '<-', + '→' => '->', + '↑' => '|', + '↓' => '|', + '⁅' => '[', + '⁆' => ']', + '⁎' => '*', + '、' => ',', + '。' => '.', + '〈' => '<', + '〉' => '>', + '《' => '<<', + '》' => '>>', + '〔' => '[', + '〕' => ']', + '〘' => '[', + '〙' => ']', + '〚' => '[', + '〛' => ']', + '﹝' => '[', + '﹞' => ']', + '︹' => '[', + '︺' => ']', + '﹇' => '[', + '﹈' => ']', + '︐' => ',', + '︑' => ',', + '︒' => '.', + '︓' => ':', + '︔' => ';', + '︕' => '!', + '︖' => '?', + '︙' => '...', + '︰' => '..', + '︵' => '(', + '︶' => ')', + '﹙' => '(', + '﹚' => ')', + '︷' => '{', + '︸' => '}', + '﹛' => '{', + '﹜' => '}', + '︽' => '<<', + '︾' => '>>', + '︿' => '<', + '﹀' => '>', + '×' => '*', + '÷' => '/', + '≪' => '<<', + '≫' => '>>', + '⦅' => '((', + '⦆' => '))', + '〇' => '0', + '′' => '\'', + '〝' => '"', + '〞' => '"', + '«' => '<<', + '»' => '>>', + '‘' => "'", + '’' => "'", + '‚' => ',', + '‛' => "'", + '“' => '"', + '”' => '"', + '„' => '"', + '‟' => '"', + '‹' => '<', + '›' => '>', + '․' => '.', + '‥' => '..', + '…' => '...', + '″' => '"', + '‴' => '\'\'\'', + '‶' => '``', + '‷' => '```', + '‼' => '!!', + '⁇' => '??', + '⁈' => '?!', + '⁉' => '!?', + '⁗' => '````', + '⩴' => '::=', + '⩵' => '==', + '⩶' => '===', + '﹔' => ';', + '﹕' => ':', + '﹖' => '?', + '﹗' => '!', + '﹍' => '_', + '﹎' => '_', + '﹏' => '_', + '﹐' => ',', + '﹑' => ',', + '﹒' => '.', + '﹟' => '#', + '﹠' => '&', + '﹡' => '*', + '﹢' => '+', + '﹣' => '-', + '﹤' => '<', + '﹥' => '>', + '﹦' => '=', + '﹨' => '\\', + '﹩' => '$', + '﹪' => '%', + '﹫' => '@', + '!' => '!', + '"' => '"', + '#' => '#', + '$' => '$', + '%' => '%', + '&' => '&', + ''' => '\'', + '(' => '(', + ')' => ')', + '*' => '*', + '+' => '+', + ',' => ',', + '-' => '-', + '.' => '.', + '/' => '/', + ':' => ':', + ';' => ';', + '<' => '<', + '=' => '=', + '>' => '>', + '?' => '?', + '@' => '@', + '{' => '{', + '|' => '|', + '}' => '}', + '~' => '~', + '⦅' => '((', + '⦆' => '))', + '¬' => '!', + ' ̄' => '-', + '¦' => '|', + '■' => '#', + ], +]; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/ascii_language_max_key.php b/includes/libraries/anti-xss-master/src/voku/helper/data/ascii_language_max_key.php new file mode 100644 index 000000000..da81ae236 --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/ascii_language_max_key.php @@ -0,0 +1,65 @@ + 0, + 'tk' => 1, + 'th' => 0, + 'ps' => 0, + 'or' => 0, + 'mn' => 0, + 'ko' => 0, + 'ky' => 0, + 'hy' => 1, + 'bn' => 5, + 'be' => 0, + 'am' => 0, + 'ja' => 0, + 'zh' => 0, + 'nl' => 1, + 'it' => 1, + 'mk' => 1, + 'pt' => 1, + 'el__greeklish' => 2, + 'el' => 2, + 'hi' => 2, + 'sv' => 1, + 'tr' => 1, + 'bg' => 2, + 'hu' => 1, + 'my' => 5, + 'hr' => 2, + 'fi' => 1, + 'ka' => 1, + 'ru' => 1, + 'ru__gost_2000_b' => 1, + 'ru__passport_2013' => 1, + 'uk' => 1, + 'kk' => 1, + 'cs' => 1, + 'da' => 1, + 'pl' => 1, + 'ro' => 1, + 'eo' => 1, + 'et' => 1, + 'lv' => 1, + 'lt' => 1, + 'no' => 1, + 'vi' => 1, + 'ar' => 1, + 'fa' => 1, + 'sr' => 1, + 'sr__cyr' => 1, + 'sr__lat' => 1, + 'az' => 1, + 'sk' => 1, + 'fr' => 1, + 'fr_at' => 1, + 'fr_ch' => 1, + 'de' => 1, + 'de_at' => 1, + 'de_ch' => 1, + 'en' => 0, + 'latin' => 3, + ' ' => 1, + 'msword' => 1, +]; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/ascii_ord.php b/includes/libraries/anti-xss-master/src/voku/helper/data/ascii_ord.php new file mode 100644 index 000000000..142318c33 --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/ascii_ord.php @@ -0,0 +1 @@ + 0, "\x00" => 0, "\x01" => 1, "\x02" => 2, "\x03" => 3, "\x04" => 4, "\x05" => 5, "\x06" => 6, "\x07" => 7, "\x08" => 8, "\x09" => 9, "\x0A" => 10, "\x0B" => 11, "\x0C" => 12, "\x0D" => 13, "\x0E" => 14, "\x0F" => 15, "\x10" => 16, "\x11" => 17, "\x12" => 18, "\x13" => 19, "\x14" => 20, "\x15" => 21, "\x16" => 22, "\x17" => 23, "\x18" => 24, "\x19" => 25, "\x1A" => 26, "\x1B" => 27, "\x1C" => 28, "\x1D" => 29, "\x1E" => 30, "\x1F" => 31, "\x20" => 32, "\x21" => 33, "\x22" => 34, "\x23" => 35, "\x24" => 36, "\x25" => 37, "\x26" => 38, "\x27" => 39, "\x28" => 40, "\x29" => 41, "\x2A" => 42, "\x2B" => 43, "\x2C" => 44, "\x2D" => 45, "\x2E" => 46, "\x2F" => 47, "\x30" => 48, "\x31" => 49, "\x32" => 50, "\x33" => 51, "\x34" => 52, "\x35" => 53, "\x36" => 54, "\x37" => 55, "\x38" => 56, "\x39" => 57, "\x3A" => 58, "\x3B" => 59, "\x3C" => 60, "\x3D" => 61, "\x3E" => 62, "\x3F" => 63, "\x40" => 64, "\x41" => 65, "\x42" => 66, "\x43" => 67, "\x44" => 68, "\x45" => 69, "\x46" => 70, "\x47" => 71, "\x48" => 72, "\x49" => 73, "\x4A" => 74, "\x4B" => 75, "\x4C" => 76, "\x4D" => 77, "\x4E" => 78, "\x4F" => 79, "\x50" => 80, "\x51" => 81, "\x52" => 82, "\x53" => 83, "\x54" => 84, "\x55" => 85, "\x56" => 86, "\x57" => 87, "\x58" => 88, "\x59" => 89, "\x5A" => 90, "\x5B" => 91, "\x5C" => 92, "\x5D" => 93, "\x5E" => 94, "\x5F" => 95, "\x60" => 96, "\x61" => 97, "\x62" => 98, "\x63" => 99, "\x64" => 100, "\x65" => 101, "\x66" => 102, "\x67" => 103, "\x68" => 104, "\x69" => 105, "\x6A" => 106, "\x6B" => 107, "\x6C" => 108, "\x6D" => 109, "\x6E" => 110, "\x6F" => 111, "\x70" => 112, "\x71" => 113, "\x72" => 114, "\x73" => 115, "\x74" => 116, "\x75" => 117, "\x76" => 118, "\x77" => 119, "\x78" => 120, "\x79" => 121, "\x7A" => 122, "\x7B" => 123, "\x7C" => 124, "\x7D" => 125, "\x7E" => 126, "\x7F" => 127, "\x80" => 128, "\x81" => 129, "\x82" => 130, "\x83" => 131, "\x84" => 132, "\x85" => 133, "\x86" => 134, "\x87" => 135, "\x88" => 136, "\x89" => 137, "\x8A" => 138, "\x8B" => 139, "\x8C" => 140, "\x8D" => 141, "\x8E" => 142, "\x8F" => 143, "\x90" => 144, "\x91" => 145, "\x92" => 146, "\x93" => 147, "\x94" => 148, "\x95" => 149, "\x96" => 150, "\x97" => 151, "\x98" => 152, "\x99" => 153, "\x9A" => 154, "\x9B" => 155, "\x9C" => 156, "\x9D" => 157, "\x9E" => 158, "\x9F" => 159, "\xA0" => 160, "\xA1" => 161, "\xA2" => 162, "\xA3" => 163, "\xA4" => 164, "\xA5" => 165, "\xA6" => 166, "\xA7" => 167, "\xA8" => 168, "\xA9" => 169, "\xAA" => 170, "\xAB" => 171, "\xAC" => 172, "\xAD" => 173, "\xAE" => 174, "\xAF" => 175, "\xB0" => 176, "\xB1" => 177, "\xB2" => 178, "\xB3" => 179, "\xB4" => 180, "\xB5" => 181, "\xB6" => 182, "\xB7" => 183, "\xB8" => 184, "\xB9" => 185, "\xBA" => 186, "\xBB" => 187, "\xBC" => 188, "\xBD" => 189, "\xBE" => 190, "\xBF" => 191, "\xC0" => 192, "\xC1" => 193, "\xC2" => 194, "\xC3" => 195, "\xC4" => 196, "\xC5" => 197, "\xC6" => 198, "\xC7" => 199, "\xC8" => 200, "\xC9" => 201, "\xCA" => 202, "\xCB" => 203, "\xCC" => 204, "\xCD" => 205, "\xCE" => 206, "\xCF" => 207, "\xD0" => 208, "\xD1" => 209, "\xD2" => 210, "\xD3" => 211, "\xD4" => 212, "\xD5" => 213, "\xD6" => 214, "\xD7" => 215, "\xD8" => 216, "\xD9" => 217, "\xDA" => 218, "\xDB" => 219, "\xDC" => 220, "\xDD" => 221, "\xDE" => 222, "\xDF" => 223, "\xE0" => 224, "\xE1" => 225, "\xE2" => 226, "\xE3" => 227, "\xE4" => 228, "\xE5" => 229, "\xE6" => 230, "\xE7" => 231, "\xE8" => 232, "\xE9" => 233, "\xEA" => 234, "\xEB" => 235, "\xEC" => 236, "\xED" => 237, "\xEE" => 238, "\xEF" => 239, "\xF0" => 240, "\xF1" => 241, "\xF2" => 242, "\xF3" => 243, "\xF4" => 244, "\xF5" => 245, "\xF6" => 246, "\xF7" => 247, "\xF8" => 248, "\xF9" => 249, "\xFA" => 250, "\xFB" => 251, "\xFC" => 252, "\xFD" => 253, "\xFE" => 254, "\xFF" => 255]; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/caseFolding_full.php b/includes/libraries/anti-xss-master/src/voku/helper/data/caseFolding_full.php new file mode 100644 index 000000000..258104597 --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/caseFolding_full.php @@ -0,0 +1,218 @@ + [ + 0 => 'ß', + 1 => 'İ', + 2 => 'ʼn', + 3 => 'ǰ', + 4 => 'ΐ', + 5 => 'ΰ', + 6 => 'և', + 7 => 'ẖ', + 8 => 'ẗ', + 9 => 'ẘ', + 10 => 'ẙ', + 11 => 'ẚ', + 12 => 'ẞ', + 13 => 'ὐ', + 14 => 'ὒ', + 15 => 'ὔ', + 16 => 'ὖ', + 17 => 'ᾀ', + 18 => 'ᾁ', + 19 => 'ᾂ', + 20 => 'ᾃ', + 21 => 'ᾄ', + 22 => 'ᾅ', + 23 => 'ᾆ', + 24 => 'ᾇ', + 25 => 'ᾈ', + 26 => 'ᾉ', + 27 => 'ᾊ', + 28 => 'ᾋ', + 29 => 'ᾌ', + 30 => 'ᾍ', + 31 => 'ᾎ', + 32 => 'ᾏ', + 33 => 'ᾐ', + 34 => 'ᾑ', + 35 => 'ᾒ', + 36 => 'ᾓ', + 37 => 'ᾔ', + 38 => 'ᾕ', + 39 => 'ᾖ', + 40 => 'ᾗ', + 41 => 'ᾘ', + 42 => 'ᾙ', + 43 => 'ᾚ', + 44 => 'ᾛ', + 45 => 'ᾜ', + 46 => 'ᾝ', + 47 => 'ᾞ', + 48 => 'ᾟ', + 49 => 'ᾠ', + 50 => 'ᾡ', + 51 => 'ᾢ', + 52 => 'ᾣ', + 53 => 'ᾤ', + 54 => 'ᾥ', + 55 => 'ᾦ', + 56 => 'ᾧ', + 57 => 'ᾨ', + 58 => 'ᾩ', + 59 => 'ᾪ', + 60 => 'ᾫ', + 61 => 'ᾬ', + 62 => 'ᾭ', + 63 => 'ᾮ', + 64 => 'ᾯ', + 65 => 'ᾲ', + 66 => 'ᾳ', + 67 => 'ᾴ', + 68 => 'ᾶ', + 69 => 'ᾷ', + 70 => 'ᾼ', + 71 => 'ῂ', + 72 => 'ῃ', + 73 => 'ῄ', + 74 => 'ῆ', + 75 => 'ῇ', + 76 => 'ῌ', + 77 => 'ῒ', + 78 => 'ΐ', + 79 => 'ῖ', + 80 => 'ῗ', + 81 => 'ῢ', + 82 => 'ΰ', + 83 => 'ῤ', + 84 => 'ῦ', + 85 => 'ῧ', + 86 => 'ῲ', + 87 => 'ῳ', + 88 => 'ῴ', + 89 => 'ῶ', + 90 => 'ῷ', + 91 => 'ῼ', + 92 => 'ff', + 93 => 'fi', + 94 => 'fl', + 95 => 'ffi', + 96 => 'ffl', + 97 => 'ſt', + 98 => 'st', + 99 => 'ﬓ', + 100 => 'ﬔ', + 101 => 'ﬕ', + 102 => 'ﬖ', + 103 => 'ﬗ', + 104 => 'J̌̌', + ], + 1 => [ + 0 => 'ss', + 1 => 'i̇', + 2 => 'ʼn', + 3 => 'ǰ', + 4 => 'ΐ', + 5 => 'ΰ', + 6 => 'եւ', + 7 => 'ẖ', + 8 => 'ẗ', + 9 => 'ẘ', + 10 => 'ẙ', + 11 => 'aʾ', + 12 => 'ss', + 13 => 'ὐ', + 14 => 'ὒ', + 15 => 'ὔ', + 16 => 'ὖ', + 17 => 'ἀι', + 18 => 'ἁι', + 19 => 'ἂι', + 20 => 'ἃι', + 21 => 'ἄι', + 22 => 'ἅι', + 23 => 'ἆι', + 24 => 'ἇι', + 25 => 'ἀι', + 26 => 'ἁι', + 27 => 'ἂι', + 28 => 'ἃι', + 29 => 'ἄι', + 30 => 'ἅι', + 31 => 'ἆι', + 32 => 'ἇι', + 33 => 'ἠι', + 34 => 'ἡι', + 35 => 'ἢι', + 36 => 'ἣι', + 37 => 'ἤι', + 38 => 'ἥι', + 39 => 'ἦι', + 40 => 'ἧι', + 41 => 'ἠι', + 42 => 'ἡι', + 43 => 'ἢι', + 44 => 'ἣι', + 45 => 'ἤι', + 46 => 'ἥι', + 47 => 'ἦι', + 48 => 'ἧι', + 49 => 'ὠι', + 50 => 'ὡι', + 51 => 'ὢι', + 52 => 'ὣι', + 53 => 'ὤι', + 54 => 'ὥι', + 55 => 'ὦι', + 56 => 'ὧι', + 57 => 'ὠι', + 58 => 'ὡι', + 59 => 'ὢι', + 60 => 'ὣι', + 61 => 'ὤι', + 62 => 'ὥι', + 63 => 'ὦι', + 64 => 'ὧι', + 65 => 'ὰι', + 66 => 'αι', + 67 => 'άι', + 68 => 'ᾶ', + 69 => 'ᾶι', + 70 => 'αι', + 71 => 'ὴι', + 72 => 'ηι', + 73 => 'ήι', + 74 => 'ῆ', + 75 => 'ῆι', + 76 => 'ηι', + 77 => 'ῒ', + 78 => 'ΐ', + 79 => 'ῖ', + 80 => 'ῗ', + 81 => 'ῢ', + 82 => 'ΰ', + 83 => 'ῤ', + 84 => 'ῦ', + 85 => 'ῧ', + 86 => 'ὼι', + 87 => 'ωι', + 88 => 'ώι', + 89 => 'ῶ', + 90 => 'ῶι', + 91 => 'ωι', + 92 => 'ff', + 93 => 'fi', + 94 => 'fl', + 95 => 'ffi', + 96 => 'ffl', + 97 => 'st', + 98 => 'st', + 99 => 'մն', + 100 => 'մե', + 101 => 'մի', + 102 => 'վն', + 103 => 'մխ', + 104 => 'ǰ', + ], +]; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/chr.php b/includes/libraries/anti-xss-master/src/voku/helper/data/chr.php new file mode 100644 index 000000000..e20ffa647 --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/chr.php @@ -0,0 +1 @@ + "\x00", 1 => "\x01", 2 => "\x02", 3 => "\x03", 4 => "\x04", 5 => "\x05", 6 => "\x06", 7 => "\x07", 8 => "\x08", 9 => "\x09", 10 => "\x0A", 11 => "\x0B", 12 => "\x0C", 13 => "\x0D", 14 => "\x0E", 15 => "\x0F", 16 => "\x10", 17 => "\x11", 18 => "\x12", 19 => "\x13", 20 => "\x14", 21 => "\x15", 22 => "\x16", 23 => "\x17", 24 => "\x18", 25 => "\x19", 26 => "\x1A", 27 => "\x1B", 28 => "\x1C", 29 => "\x1D", 30 => "\x1E", 31 => "\x1F", 32 => "\x20", 33 => "\x21", 34 => "\x22", 35 => "\x23", 36 => "\x24", 37 => "\x25", 38 => "\x26", 39 => "\x27", 40 => "\x28", 41 => "\x29", 42 => "\x2A", 43 => "\x2B", 44 => "\x2C", 45 => "\x2D", 46 => "\x2E", 47 => "\x2F", 48 => "\x30", 49 => "\x31", 50 => "\x32", 51 => "\x33", 52 => "\x34", 53 => "\x35", 54 => "\x36", 55 => "\x37", 56 => "\x38", 57 => "\x39", 58 => "\x3A", 59 => "\x3B", 60 => "\x3C", 61 => "\x3D", 62 => "\x3E", 63 => "\x3F", 64 => "\x40", 65 => "\x41", 66 => "\x42", 67 => "\x43", 68 => "\x44", 69 => "\x45", 70 => "\x46", 71 => "\x47", 72 => "\x48", 73 => "\x49", 74 => "\x4A", 75 => "\x4B", 76 => "\x4C", 77 => "\x4D", 78 => "\x4E", 79 => "\x4F", 80 => "\x50", 81 => "\x51", 82 => "\x52", 83 => "\x53", 84 => "\x54", 85 => "\x55", 86 => "\x56", 87 => "\x57", 88 => "\x58", 89 => "\x59", 90 => "\x5A", 91 => "\x5B", 92 => "\x5C", 93 => "\x5D", 94 => "\x5E", 95 => "\x5F", 96 => "\x60", 97 => "\x61", 98 => "\x62", 99 => "\x63", 100 => "\x64", 101 => "\x65", 102 => "\x66", 103 => "\x67", 104 => "\x68", 105 => "\x69", 106 => "\x6A", 107 => "\x6B", 108 => "\x6C", 109 => "\x6D", 110 => "\x6E", 111 => "\x6F", 112 => "\x70", 113 => "\x71", 114 => "\x72", 115 => "\x73", 116 => "\x74", 117 => "\x75", 118 => "\x76", 119 => "\x77", 120 => "\x78", 121 => "\x79", 122 => "\x7A", 123 => "\x7B", 124 => "\x7C", 125 => "\x7D", 126 => "\x7E", 127 => "\x7F", 128 => "\x80", 129 => "\x81", 130 => "\x82", 131 => "\x83", 132 => "\x84", 133 => "\x85", 134 => "\x86", 135 => "\x87", 136 => "\x88", 137 => "\x89", 138 => "\x8A", 139 => "\x8B", 140 => "\x8C", 141 => "\x8D", 142 => "\x8E", 143 => "\x8F", 144 => "\x90", 145 => "\x91", 146 => "\x92", 147 => "\x93", 148 => "\x94", 149 => "\x95", 150 => "\x96", 151 => "\x97", 152 => "\x98", 153 => "\x99", 154 => "\x9A", 155 => "\x9B", 156 => "\x9C", 157 => "\x9D", 158 => "\x9E", 159 => "\x9F", 160 => "\xA0", 161 => "\xA1", 162 => "\xA2", 163 => "\xA3", 164 => "\xA4", 165 => "\xA5", 166 => "\xA6", 167 => "\xA7", 168 => "\xA8", 169 => "\xA9", 170 => "\xAA", 171 => "\xAB", 172 => "\xAC", 173 => "\xAD", 174 => "\xAE", 175 => "\xAF", 176 => "\xB0", 177 => "\xB1", 178 => "\xB2", 179 => "\xB3", 180 => "\xB4", 181 => "\xB5", 182 => "\xB6", 183 => "\xB7", 184 => "\xB8", 185 => "\xB9", 186 => "\xBA", 187 => "\xBB", 188 => "\xBC", 189 => "\xBD", 190 => "\xBE", 191 => "\xBF", 192 => "\xC0", 193 => "\xC1", 194 => "\xC2", 195 => "\xC3", 196 => "\xC4", 197 => "\xC5", 198 => "\xC6", 199 => "\xC7", 200 => "\xC8", 201 => "\xC9", 202 => "\xCA", 203 => "\xCB", 204 => "\xCC", 205 => "\xCD", 206 => "\xCE", 207 => "\xCF", 208 => "\xD0", 209 => "\xD1", 210 => "\xD2", 211 => "\xD3", 212 => "\xD4", 213 => "\xD5", 214 => "\xD6", 215 => "\xD7", 216 => "\xD8", 217 => "\xD9", 218 => "\xDA", 219 => "\xDB", 220 => "\xDC", 221 => "\xDD", 222 => "\xDE", 223 => "\xDF", 224 => "\xE0", 225 => "\xE1", 226 => "\xE2", 227 => "\xE3", 228 => "\xE4", 229 => "\xE5", 230 => "\xE6", 231 => "\xE7", 232 => "\xE8", 233 => "\xE9", 234 => "\xEA", 235 => "\xEB", 236 => "\xEC", 237 => "\xED", 238 => "\xEE", 239 => "\xEF", 240 => "\xF0", 241 => "\xF1", 242 => "\xF2", 243 => "\xF3", 244 => "\xF4", 245 => "\xF5", 246 => "\xF6", 247 => "\xF7", 248 => "\xF8", 249 => "\xF9", 250 => "\xFA", 251 => "\xFB", 252 => "\xFC", 253 => "\xFD", 254 => "\xFE", 255 => "\xFF"]; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/emoji.php b/includes/libraries/anti-xss-master/src/voku/helper/data/emoji.php new file mode 100644 index 000000000..ae10b33ef --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/emoji.php @@ -0,0 +1,7 @@ + "\u{1F600}", 'CHARACTER_BEAMING_FACE_WITH_SMILING_EYES' => "\u{1F601}", 'CHARACTER_FACE_WITH_TEARS_OF_JOY' => "\u{1F602}", 'CHARACTER_ROLLING_ON_THE_FLOOR_LAUGHING' => "\u{1F923}", 'CHARACTER_GRINNING_FACE_WITH_BIG_EYES' => "\u{1F603}", 'CHARACTER_GRINNING_FACE_WITH_SMILING_EYES' => "\u{1F604}", 'CHARACTER_GRINNING_FACE_WITH_SWEAT' => "\u{1F605}", 'CHARACTER_GRINNING_SQUINTING_FACE' => "\u{1F606}", 'CHARACTER_WINKING_FACE' => "\u{1F609}", 'CHARACTER_SMILING_FACE_WITH_SMILING_EYES' => "\u{1F60A}", 'CHARACTER_FACE_SAVORING_FOOD' => "\u{1F60B}", 'CHARACTER_SMILING_FACE_WITH_SUNGLASSES' => "\u{1F60E}", 'CHARACTER_SMILING_FACE_WITH_HEART_EYES' => "\u{1F60D}", 'CHARACTER_FACE_BLOWING_A_KISS' => "\u{1F618}", 'CHARACTER_SMILING_FACE_WITH_3_HEARTS' => "\u{1F970}", 'CHARACTER_KISSING_FACE' => "\u{1F617}", 'CHARACTER_KISSING_FACE_WITH_SMILING_EYES' => "\u{1F619}", 'CHARACTER_KISSING_FACE_WITH_CLOSED_EYES' => "\u{1F61A}", 'CHARACTER_SMILING_FACE' => "\u{263A}\u{FE0F}", 'CHARACTER_SLIGHTLY_SMILING_FACE' => "\u{1F642}", 'CHARACTER_HUGGING_FACE' => "\u{1F917}", 'CHARACTER_STAR_STRUCK' => "\u{1F929}", 'CHARACTER_THINKING_FACE' => "\u{1F914}", 'CHARACTER_FACE_WITH_RAISED_EYEBROW' => "\u{1F928}", 'CHARACTER_NEUTRAL_FACE' => "\u{1F610}", 'CHARACTER_EXPRESSIONLESS_FACE' => "\u{1F611}", 'CHARACTER_FACE_WITHOUT_MOUTH' => "\u{1F636}", 'CHARACTER_FACE_WITH_ROLLING_EYES' => "\u{1F644}", 'CHARACTER_SMIRKING_FACE' => "\u{1F60F}", 'CHARACTER_PERSEVERING_FACE' => "\u{1F623}", 'CHARACTER_SAD_BUT_RELIEVED_FACE' => "\u{1F625}", 'CHARACTER_FACE_WITH_OPEN_MOUTH' => "\u{1F62E}", 'CHARACTER_ZIPPER_MOUTH_FACE' => "\u{1F910}", 'CHARACTER_HUSHED_FACE' => "\u{1F62F}", 'CHARACTER_SLEEPY_FACE' => "\u{1F62A}", 'CHARACTER_TIRED_FACE' => "\u{1F62B}", 'CHARACTER_SLEEPING_FACE' => "\u{1F634}", 'CHARACTER_RELIEVED_FACE' => "\u{1F60C}", 'CHARACTER_FACE_WITH_TONGUE' => "\u{1F61B}", 'CHARACTER_WINKING_FACE_WITH_TONGUE' => "\u{1F61C}", 'CHARACTER_SQUINTING_FACE_WITH_TONGUE' => "\u{1F61D}", 'CHARACTER_DROOLING_FACE' => "\u{1F924}", 'CHARACTER_UNAMUSED_FACE' => "\u{1F612}", 'CHARACTER_DOWNCAST_FACE_WITH_SWEAT' => "\u{1F613}", 'CHARACTER_PENSIVE_FACE' => "\u{1F614}", 'CHARACTER_CONFUSED_FACE' => "\u{1F615}", 'CHARACTER_UPSIDE_DOWN_FACE' => "\u{1F643}", 'CHARACTER_MONEY_MOUTH_FACE' => "\u{1F911}", 'CHARACTER_ASTONISHED_FACE' => "\u{1F632}", 'CHARACTER_FROWNING_FACE' => "\u{2639}\u{FE0F}", 'CHARACTER_SLIGHTLY_FROWNING_FACE' => "\u{1F641}", 'CHARACTER_CONFOUNDED_FACE' => "\u{1F616}", 'CHARACTER_DISAPPOINTED_FACE' => "\u{1F61E}", 'CHARACTER_WORRIED_FACE' => "\u{1F61F}", 'CHARACTER_FACE_WITH_STEAM_FROM_NOSE' => "\u{1F624}", 'CHARACTER_CRYING_FACE' => "\u{1F622}", 'CHARACTER_LOUDLY_CRYING_FACE' => "\u{1F62D}", 'CHARACTER_FROWNING_FACE_WITH_OPEN_MOUTH' => "\u{1F626}", 'CHARACTER_ANGUISHED_FACE' => "\u{1F627}", 'CHARACTER_FEARFUL_FACE' => "\u{1F628}", 'CHARACTER_WEARY_FACE' => "\u{1F629}", 'CHARACTER_EXPLODING_HEAD' => "\u{1F92F}", 'CHARACTER_GRIMACING_FACE' => "\u{1F62C}", 'CHARACTER_ANXIOUS_FACE_WITH_SWEAT' => "\u{1F630}", 'CHARACTER_FACE_SCREAMING_IN_FEAR' => "\u{1F631}", 'CHARACTER_HOT_FACE' => "\u{1F975}", 'CHARACTER_COLD_FACE' => "\u{1F976}", 'CHARACTER_FLUSHED_FACE' => "\u{1F633}", 'CHARACTER_ZANY_FACE' => "\u{1F92A}", 'CHARACTER_DIZZY_FACE' => "\u{1F635}", 'CHARACTER_POUTING_FACE' => "\u{1F621}", 'CHARACTER_ANGRY_FACE' => "\u{1F620}", 'CHARACTER_FACE_WITH_SYMBOLS_ON_MOUTH' => "\u{1F92C}", 'CHARACTER_FACE_WITH_MEDICAL_MASK' => "\u{1F637}", 'CHARACTER_FACE_WITH_THERMOMETER' => "\u{1F912}", 'CHARACTER_FACE_WITH_HEAD_BANDAGE' => "\u{1F915}", 'CHARACTER_NAUSEATED_FACE' => "\u{1F922}", 'CHARACTER_FACE_VOMITING' => "\u{1F92E}", 'CHARACTER_SNEEZING_FACE' => "\u{1F927}", 'CHARACTER_SMILING_FACE_WITH_HALO' => "\u{1F607}", 'CHARACTER_COWBOY_HAT_FACE' => "\u{1F920}", 'CHARACTER_PARTYING_FACE' => "\u{1F973}", 'CHARACTER_WOOZY_FACE' => "\u{1F974}", 'CHARACTER_PLEADING_FACE' => "\u{1F97A}", 'CHARACTER_LYING_FACE' => "\u{1F925}", 'CHARACTER_SHUSHING_FACE' => "\u{1F92B}", 'CHARACTER_FACE_WITH_HAND_OVER_MOUTH' => "\u{1F92D}", 'CHARACTER_FACE_WITH_MONOCLE' => "\u{1F9D0}", 'CHARACTER_NERD_FACE' => "\u{1F913}", 'CHARACTER_SMILING_FACE_WITH_HORNS' => "\u{1F608}", 'CHARACTER_ANGRY_FACE_WITH_HORNS' => "\u{1F47F}", 'CHARACTER_CLOWN_FACE' => "\u{1F921}", 'CHARACTER_OGRE' => "\u{1F479}", 'CHARACTER_GOBLIN' => "\u{1F47A}", 'CHARACTER_SKULL' => "\u{1F480}", 'CHARACTER_SKULL_AND_CROSSBONES' => "\u{2620}\u{FE0F}", 'CHARACTER_GHOST' => "\u{1F47B}", 'CHARACTER_ALIEN' => "\u{1F47D}", 'CHARACTER_ALIEN_MONSTER' => "\u{1F47E}", 'CHARACTER_ROBOT_FACE' => "\u{1F916}", 'CHARACTER_PILE_OF_POO' => "\u{1F4A9}", 'CHARACTER_GRINNING_CAT_FACE' => "\u{1F63A}", 'CHARACTER_GRINNING_CAT_FACE_WITH_SMILING_EYES' => "\u{1F638}", 'CHARACTER_CAT_FACE_WITH_TEARS_OF_JOY' => "\u{1F639}", 'CHARACTER_SMILING_CAT_FACE_WITH_HEART_EYES' => "\u{1F63B}", 'CHARACTER_CAT_FACE_WITH_WRY_SMILE' => "\u{1F63C}", 'CHARACTER_KISSING_CAT_FACE' => "\u{1F63D}", 'CHARACTER_WEARY_CAT_FACE' => "\u{1F640}", 'CHARACTER_CRYING_CAT_FACE' => "\u{1F63F}", 'CHARACTER_POUTING_CAT_FACE' => "\u{1F63E}", 'CHARACTER_SEE_NO_EVIL_MONKEY' => "\u{1F648}", 'CHARACTER_HEAR_NO_EVIL_MONKEY' => "\u{1F649}", 'CHARACTER_SPEAK_NO_EVIL_MONKEY' => "\u{1F64A}", 'CHARACTER_LIGHT_SKIN_TONE' => "\u{1F3FB}", 'CHARACTER_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F3FC}", 'CHARACTER_MEDIUM_SKIN_TONE' => "\u{1F3FD}", 'CHARACTER_MEDIUM_DARK_SKIN_TONE' => "\u{1F3FE}", 'CHARACTER_DARK_SKIN_TONE' => "\u{1F3FF}", 'CHARACTER_BABY' => "\u{1F476}", 'CHARACTER_BABY_LIGHT_SKIN_TONE' => "\u{1F476}\u{1F3FB}", 'CHARACTER_BABY_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F476}\u{1F3FC}", 'CHARACTER_BABY_MEDIUM_SKIN_TONE' => "\u{1F476}\u{1F3FD}", 'CHARACTER_BABY_MEDIUM_DARK_SKIN_TONE' => "\u{1F476}\u{1F3FE}", 'CHARACTER_BABY_DARK_SKIN_TONE' => "\u{1F476}\u{1F3FF}", 'CHARACTER_CHILD' => "\u{1F9D2}", 'CHARACTER_CHILD_LIGHT_SKIN_TONE' => "\u{1F9D2}\u{1F3FB}", 'CHARACTER_CHILD_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9D2}\u{1F3FC}", 'CHARACTER_CHILD_MEDIUM_SKIN_TONE' => "\u{1F9D2}\u{1F3FD}", 'CHARACTER_CHILD_MEDIUM_DARK_SKIN_TONE' => "\u{1F9D2}\u{1F3FE}", 'CHARACTER_CHILD_DARK_SKIN_TONE' => "\u{1F9D2}\u{1F3FF}", 'CHARACTER_BOY' => "\u{1F466}", 'CHARACTER_BOY_LIGHT_SKIN_TONE' => "\u{1F466}\u{1F3FB}", 'CHARACTER_BOY_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F466}\u{1F3FC}", 'CHARACTER_BOY_MEDIUM_SKIN_TONE' => "\u{1F466}\u{1F3FD}", 'CHARACTER_BOY_MEDIUM_DARK_SKIN_TONE' => "\u{1F466}\u{1F3FE}", 'CHARACTER_BOY_DARK_SKIN_TONE' => "\u{1F466}\u{1F3FF}", 'CHARACTER_GIRL' => "\u{1F467}", 'CHARACTER_GIRL_LIGHT_SKIN_TONE' => "\u{1F467}\u{1F3FB}", 'CHARACTER_GIRL_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F467}\u{1F3FC}", 'CHARACTER_GIRL_MEDIUM_SKIN_TONE' => "\u{1F467}\u{1F3FD}", 'CHARACTER_GIRL_MEDIUM_DARK_SKIN_TONE' => "\u{1F467}\u{1F3FE}", 'CHARACTER_GIRL_DARK_SKIN_TONE' => "\u{1F467}\u{1F3FF}", 'CHARACTER_ADULT' => "\u{1F9D1}", 'CHARACTER_ADULT_LIGHT_SKIN_TONE' => "\u{1F9D1}\u{1F3FB}", 'CHARACTER_ADULT_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9D1}\u{1F3FC}", 'CHARACTER_ADULT_MEDIUM_SKIN_TONE' => "\u{1F9D1}\u{1F3FD}", 'CHARACTER_ADULT_MEDIUM_DARK_SKIN_TONE' => "\u{1F9D1}\u{1F3FE}", 'CHARACTER_ADULT_DARK_SKIN_TONE' => "\u{1F9D1}\u{1F3FF}", 'CHARACTER_MAN' => "\u{1F468}", 'CHARACTER_MAN_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FB}", 'CHARACTER_MAN_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FC}", 'CHARACTER_MAN_MEDIUM_SKIN_TONE' => "\u{1F468}\u{1F3FD}", 'CHARACTER_MAN_MEDIUM_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FE}", 'CHARACTER_MAN_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FF}", 'CHARACTER_WOMAN' => "\u{1F469}", 'CHARACTER_WOMAN_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FB}", 'CHARACTER_WOMAN_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FC}", 'CHARACTER_WOMAN_MEDIUM_SKIN_TONE' => "\u{1F469}\u{1F3FD}", 'CHARACTER_WOMAN_MEDIUM_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FE}", 'CHARACTER_WOMAN_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FF}", 'CHARACTER_OLDER_ADULT' => "\u{1F9D3}", 'CHARACTER_OLDER_ADULT_LIGHT_SKIN_TONE' => "\u{1F9D3}\u{1F3FB}", 'CHARACTER_OLDER_ADULT_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9D3}\u{1F3FC}", 'CHARACTER_OLDER_ADULT_MEDIUM_SKIN_TONE' => "\u{1F9D3}\u{1F3FD}", 'CHARACTER_OLDER_ADULT_MEDIUM_DARK_SKIN_TONE' => "\u{1F9D3}\u{1F3FE}", 'CHARACTER_OLDER_ADULT_DARK_SKIN_TONE' => "\u{1F9D3}\u{1F3FF}", 'CHARACTER_OLD_MAN' => "\u{1F474}", 'CHARACTER_OLD_MAN_LIGHT_SKIN_TONE' => "\u{1F474}\u{1F3FB}", 'CHARACTER_OLD_MAN_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F474}\u{1F3FC}", 'CHARACTER_OLD_MAN_MEDIUM_SKIN_TONE' => "\u{1F474}\u{1F3FD}", 'CHARACTER_OLD_MAN_MEDIUM_DARK_SKIN_TONE' => "\u{1F474}\u{1F3FE}", 'CHARACTER_OLD_MAN_DARK_SKIN_TONE' => "\u{1F474}\u{1F3FF}", 'CHARACTER_OLD_WOMAN' => "\u{1F475}", 'CHARACTER_OLD_WOMAN_LIGHT_SKIN_TONE' => "\u{1F475}\u{1F3FB}", 'CHARACTER_OLD_WOMAN_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F475}\u{1F3FC}", 'CHARACTER_OLD_WOMAN_MEDIUM_SKIN_TONE' => "\u{1F475}\u{1F3FD}", 'CHARACTER_OLD_WOMAN_MEDIUM_DARK_SKIN_TONE' => "\u{1F475}\u{1F3FE}", 'CHARACTER_OLD_WOMAN_DARK_SKIN_TONE' => "\u{1F475}\u{1F3FF}", 'CHARACTER_MAN_HEALTH_WORKER' => "\u{1F468}\u{200D}\u{2695}\u{FE0F}", 'CHARACTER_MAN_HEALTH_WORKER_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FB}\u{200D}\u{2695}\u{FE0F}", 'CHARACTER_MAN_HEALTH_WORKER_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FC}\u{200D}\u{2695}\u{FE0F}", 'CHARACTER_MAN_HEALTH_WORKER_MEDIUM_SKIN_TONE' => "\u{1F468}\u{1F3FD}\u{200D}\u{2695}\u{FE0F}", 'CHARACTER_MAN_HEALTH_WORKER_MEDIUM_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FE}\u{200D}\u{2695}\u{FE0F}", 'CHARACTER_MAN_HEALTH_WORKER_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FF}\u{200D}\u{2695}\u{FE0F}", 'CHARACTER_WOMAN_HEALTH_WORKER' => "\u{1F469}\u{200D}\u{2695}\u{FE0F}", 'CHARACTER_WOMAN_HEALTH_WORKER_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FB}\u{200D}\u{2695}\u{FE0F}", 'CHARACTER_WOMAN_HEALTH_WORKER_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FC}\u{200D}\u{2695}\u{FE0F}", 'CHARACTER_WOMAN_HEALTH_WORKER_MEDIUM_SKIN_TONE' => "\u{1F469}\u{1F3FD}\u{200D}\u{2695}\u{FE0F}", 'CHARACTER_WOMAN_HEALTH_WORKER_MEDIUM_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FE}\u{200D}\u{2695}\u{FE0F}", 'CHARACTER_WOMAN_HEALTH_WORKER_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FF}\u{200D}\u{2695}\u{FE0F}", 'CHARACTER_MAN_STUDENT' => "\u{1F468}\u{200D}\u{1F393}", 'CHARACTER_MAN_STUDENT_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FB}\u{200D}\u{1F393}", 'CHARACTER_MAN_STUDENT_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FC}\u{200D}\u{1F393}", 'CHARACTER_MAN_STUDENT_MEDIUM_SKIN_TONE' => "\u{1F468}\u{1F3FD}\u{200D}\u{1F393}", 'CHARACTER_MAN_STUDENT_MEDIUM_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FE}\u{200D}\u{1F393}", 'CHARACTER_MAN_STUDENT_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FF}\u{200D}\u{1F393}", 'CHARACTER_WOMAN_STUDENT' => "\u{1F469}\u{200D}\u{1F393}", 'CHARACTER_WOMAN_STUDENT_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FB}\u{200D}\u{1F393}", 'CHARACTER_WOMAN_STUDENT_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FC}\u{200D}\u{1F393}", 'CHARACTER_WOMAN_STUDENT_MEDIUM_SKIN_TONE' => "\u{1F469}\u{1F3FD}\u{200D}\u{1F393}", 'CHARACTER_WOMAN_STUDENT_MEDIUM_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FE}\u{200D}\u{1F393}", 'CHARACTER_WOMAN_STUDENT_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FF}\u{200D}\u{1F393}", 'CHARACTER_MAN_TEACHER' => "\u{1F468}\u{200D}\u{1F3EB}", 'CHARACTER_MAN_TEACHER_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FB}\u{200D}\u{1F3EB}", 'CHARACTER_MAN_TEACHER_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FC}\u{200D}\u{1F3EB}", 'CHARACTER_MAN_TEACHER_MEDIUM_SKIN_TONE' => "\u{1F468}\u{1F3FD}\u{200D}\u{1F3EB}", 'CHARACTER_MAN_TEACHER_MEDIUM_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FE}\u{200D}\u{1F3EB}", 'CHARACTER_MAN_TEACHER_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FF}\u{200D}\u{1F3EB}", 'CHARACTER_WOMAN_TEACHER' => "\u{1F469}\u{200D}\u{1F3EB}", 'CHARACTER_WOMAN_TEACHER_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FB}\u{200D}\u{1F3EB}", 'CHARACTER_WOMAN_TEACHER_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FC}\u{200D}\u{1F3EB}", 'CHARACTER_WOMAN_TEACHER_MEDIUM_SKIN_TONE' => "\u{1F469}\u{1F3FD}\u{200D}\u{1F3EB}", 'CHARACTER_WOMAN_TEACHER_MEDIUM_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FE}\u{200D}\u{1F3EB}", 'CHARACTER_WOMAN_TEACHER_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FF}\u{200D}\u{1F3EB}", 'CHARACTER_MAN_JUDGE' => "\u{1F468}\u{200D}\u{2696}\u{FE0F}", 'CHARACTER_MAN_JUDGE_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FB}\u{200D}\u{2696}\u{FE0F}", 'CHARACTER_MAN_JUDGE_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FC}\u{200D}\u{2696}\u{FE0F}", 'CHARACTER_MAN_JUDGE_MEDIUM_SKIN_TONE' => "\u{1F468}\u{1F3FD}\u{200D}\u{2696}\u{FE0F}", 'CHARACTER_MAN_JUDGE_MEDIUM_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FE}\u{200D}\u{2696}\u{FE0F}", 'CHARACTER_MAN_JUDGE_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FF}\u{200D}\u{2696}\u{FE0F}", 'CHARACTER_WOMAN_JUDGE' => "\u{1F469}\u{200D}\u{2696}\u{FE0F}", 'CHARACTER_WOMAN_JUDGE_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FB}\u{200D}\u{2696}\u{FE0F}", 'CHARACTER_WOMAN_JUDGE_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FC}\u{200D}\u{2696}\u{FE0F}", 'CHARACTER_WOMAN_JUDGE_MEDIUM_SKIN_TONE' => "\u{1F469}\u{1F3FD}\u{200D}\u{2696}\u{FE0F}", 'CHARACTER_WOMAN_JUDGE_MEDIUM_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FE}\u{200D}\u{2696}\u{FE0F}", 'CHARACTER_WOMAN_JUDGE_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FF}\u{200D}\u{2696}\u{FE0F}", 'CHARACTER_MAN_FARMER' => "\u{1F468}\u{200D}\u{1F33E}", 'CHARACTER_MAN_FARMER_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FB}\u{200D}\u{1F33E}", 'CHARACTER_MAN_FARMER_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FC}\u{200D}\u{1F33E}", 'CHARACTER_MAN_FARMER_MEDIUM_SKIN_TONE' => "\u{1F468}\u{1F3FD}\u{200D}\u{1F33E}", 'CHARACTER_MAN_FARMER_MEDIUM_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FE}\u{200D}\u{1F33E}", 'CHARACTER_MAN_FARMER_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FF}\u{200D}\u{1F33E}", 'CHARACTER_WOMAN_FARMER' => "\u{1F469}\u{200D}\u{1F33E}", 'CHARACTER_WOMAN_FARMER_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FB}\u{200D}\u{1F33E}", 'CHARACTER_WOMAN_FARMER_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FC}\u{200D}\u{1F33E}", 'CHARACTER_WOMAN_FARMER_MEDIUM_SKIN_TONE' => "\u{1F469}\u{1F3FD}\u{200D}\u{1F33E}", 'CHARACTER_WOMAN_FARMER_MEDIUM_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FE}\u{200D}\u{1F33E}", 'CHARACTER_WOMAN_FARMER_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FF}\u{200D}\u{1F33E}", 'CHARACTER_MAN_COOK' => "\u{1F468}\u{200D}\u{1F373}", 'CHARACTER_MAN_COOK_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FB}\u{200D}\u{1F373}", 'CHARACTER_MAN_COOK_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FC}\u{200D}\u{1F373}", 'CHARACTER_MAN_COOK_MEDIUM_SKIN_TONE' => "\u{1F468}\u{1F3FD}\u{200D}\u{1F373}", 'CHARACTER_MAN_COOK_MEDIUM_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FE}\u{200D}\u{1F373}", 'CHARACTER_MAN_COOK_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FF}\u{200D}\u{1F373}", 'CHARACTER_WOMAN_COOK' => "\u{1F469}\u{200D}\u{1F373}", 'CHARACTER_WOMAN_COOK_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FB}\u{200D}\u{1F373}", 'CHARACTER_WOMAN_COOK_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FC}\u{200D}\u{1F373}", 'CHARACTER_WOMAN_COOK_MEDIUM_SKIN_TONE' => "\u{1F469}\u{1F3FD}\u{200D}\u{1F373}", 'CHARACTER_WOMAN_COOK_MEDIUM_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FE}\u{200D}\u{1F373}", 'CHARACTER_WOMAN_COOK_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FF}\u{200D}\u{1F373}", 'CHARACTER_MAN_MECHANIC' => "\u{1F468}\u{200D}\u{1F527}", 'CHARACTER_MAN_MECHANIC_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FB}\u{200D}\u{1F527}", 'CHARACTER_MAN_MECHANIC_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FC}\u{200D}\u{1F527}", 'CHARACTER_MAN_MECHANIC_MEDIUM_SKIN_TONE' => "\u{1F468}\u{1F3FD}\u{200D}\u{1F527}", 'CHARACTER_MAN_MECHANIC_MEDIUM_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FE}\u{200D}\u{1F527}", 'CHARACTER_MAN_MECHANIC_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FF}\u{200D}\u{1F527}", 'CHARACTER_WOMAN_MECHANIC' => "\u{1F469}\u{200D}\u{1F527}", 'CHARACTER_WOMAN_MECHANIC_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FB}\u{200D}\u{1F527}", 'CHARACTER_WOMAN_MECHANIC_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FC}\u{200D}\u{1F527}", 'CHARACTER_WOMAN_MECHANIC_MEDIUM_SKIN_TONE' => "\u{1F469}\u{1F3FD}\u{200D}\u{1F527}", 'CHARACTER_WOMAN_MECHANIC_MEDIUM_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FE}\u{200D}\u{1F527}", 'CHARACTER_WOMAN_MECHANIC_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FF}\u{200D}\u{1F527}", 'CHARACTER_MAN_FACTORY_WORKER' => "\u{1F468}\u{200D}\u{1F3ED}", 'CHARACTER_MAN_FACTORY_WORKER_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FB}\u{200D}\u{1F3ED}", 'CHARACTER_MAN_FACTORY_WORKER_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FC}\u{200D}\u{1F3ED}", 'CHARACTER_MAN_FACTORY_WORKER_MEDIUM_SKIN_TONE' => "\u{1F468}\u{1F3FD}\u{200D}\u{1F3ED}", 'CHARACTER_MAN_FACTORY_WORKER_MEDIUM_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FE}\u{200D}\u{1F3ED}", 'CHARACTER_MAN_FACTORY_WORKER_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FF}\u{200D}\u{1F3ED}", 'CHARACTER_WOMAN_FACTORY_WORKER' => "\u{1F469}\u{200D}\u{1F3ED}", 'CHARACTER_WOMAN_FACTORY_WORKER_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FB}\u{200D}\u{1F3ED}", 'CHARACTER_WOMAN_FACTORY_WORKER_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FC}\u{200D}\u{1F3ED}", 'CHARACTER_WOMAN_FACTORY_WORKER_MEDIUM_SKIN_TONE' => "\u{1F469}\u{1F3FD}\u{200D}\u{1F3ED}", 'CHARACTER_WOMAN_FACTORY_WORKER_MEDIUM_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FE}\u{200D}\u{1F3ED}", 'CHARACTER_WOMAN_FACTORY_WORKER_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FF}\u{200D}\u{1F3ED}", 'CHARACTER_MAN_OFFICE_WORKER' => "\u{1F468}\u{200D}\u{1F4BC}", 'CHARACTER_MAN_OFFICE_WORKER_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FB}\u{200D}\u{1F4BC}", 'CHARACTER_MAN_OFFICE_WORKER_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FC}\u{200D}\u{1F4BC}", 'CHARACTER_MAN_OFFICE_WORKER_MEDIUM_SKIN_TONE' => "\u{1F468}\u{1F3FD}\u{200D}\u{1F4BC}", 'CHARACTER_MAN_OFFICE_WORKER_MEDIUM_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FE}\u{200D}\u{1F4BC}", 'CHARACTER_MAN_OFFICE_WORKER_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FF}\u{200D}\u{1F4BC}", 'CHARACTER_WOMAN_OFFICE_WORKER' => "\u{1F469}\u{200D}\u{1F4BC}", 'CHARACTER_WOMAN_OFFICE_WORKER_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FB}\u{200D}\u{1F4BC}", 'CHARACTER_WOMAN_OFFICE_WORKER_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FC}\u{200D}\u{1F4BC}", 'CHARACTER_WOMAN_OFFICE_WORKER_MEDIUM_SKIN_TONE' => "\u{1F469}\u{1F3FD}\u{200D}\u{1F4BC}", 'CHARACTER_WOMAN_OFFICE_WORKER_MEDIUM_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FE}\u{200D}\u{1F4BC}", 'CHARACTER_WOMAN_OFFICE_WORKER_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FF}\u{200D}\u{1F4BC}", 'CHARACTER_MAN_SCIENTIST' => "\u{1F468}\u{200D}\u{1F52C}", 'CHARACTER_MAN_SCIENTIST_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FB}\u{200D}\u{1F52C}", 'CHARACTER_MAN_SCIENTIST_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FC}\u{200D}\u{1F52C}", 'CHARACTER_MAN_SCIENTIST_MEDIUM_SKIN_TONE' => "\u{1F468}\u{1F3FD}\u{200D}\u{1F52C}", 'CHARACTER_MAN_SCIENTIST_MEDIUM_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FE}\u{200D}\u{1F52C}", 'CHARACTER_MAN_SCIENTIST_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FF}\u{200D}\u{1F52C}", 'CHARACTER_WOMAN_SCIENTIST' => "\u{1F469}\u{200D}\u{1F52C}", 'CHARACTER_WOMAN_SCIENTIST_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FB}\u{200D}\u{1F52C}", 'CHARACTER_WOMAN_SCIENTIST_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FC}\u{200D}\u{1F52C}", 'CHARACTER_WOMAN_SCIENTIST_MEDIUM_SKIN_TONE' => "\u{1F469}\u{1F3FD}\u{200D}\u{1F52C}", 'CHARACTER_WOMAN_SCIENTIST_MEDIUM_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FE}\u{200D}\u{1F52C}", 'CHARACTER_WOMAN_SCIENTIST_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FF}\u{200D}\u{1F52C}", 'CHARACTER_MAN_TECHNOLOGIST' => "\u{1F468}\u{200D}\u{1F4BB}", 'CHARACTER_MAN_TECHNOLOGIST_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FB}\u{200D}\u{1F4BB}", 'CHARACTER_MAN_TECHNOLOGIST_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FC}\u{200D}\u{1F4BB}", 'CHARACTER_MAN_TECHNOLOGIST_MEDIUM_SKIN_TONE' => "\u{1F468}\u{1F3FD}\u{200D}\u{1F4BB}", 'CHARACTER_MAN_TECHNOLOGIST_MEDIUM_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FE}\u{200D}\u{1F4BB}", 'CHARACTER_MAN_TECHNOLOGIST_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FF}\u{200D}\u{1F4BB}", 'CHARACTER_WOMAN_TECHNOLOGIST' => "\u{1F469}\u{200D}\u{1F4BB}", 'CHARACTER_WOMAN_TECHNOLOGIST_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FB}\u{200D}\u{1F4BB}", 'CHARACTER_WOMAN_TECHNOLOGIST_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FC}\u{200D}\u{1F4BB}", 'CHARACTER_WOMAN_TECHNOLOGIST_MEDIUM_SKIN_TONE' => "\u{1F469}\u{1F3FD}\u{200D}\u{1F4BB}", 'CHARACTER_WOMAN_TECHNOLOGIST_MEDIUM_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FE}\u{200D}\u{1F4BB}", 'CHARACTER_WOMAN_TECHNOLOGIST_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FF}\u{200D}\u{1F4BB}", 'CHARACTER_MAN_SINGER' => "\u{1F468}\u{200D}\u{1F3A4}", 'CHARACTER_MAN_SINGER_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FB}\u{200D}\u{1F3A4}", 'CHARACTER_MAN_SINGER_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FC}\u{200D}\u{1F3A4}", 'CHARACTER_MAN_SINGER_MEDIUM_SKIN_TONE' => "\u{1F468}\u{1F3FD}\u{200D}\u{1F3A4}", 'CHARACTER_MAN_SINGER_MEDIUM_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FE}\u{200D}\u{1F3A4}", 'CHARACTER_MAN_SINGER_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FF}\u{200D}\u{1F3A4}", 'CHARACTER_WOMAN_SINGER' => "\u{1F469}\u{200D}\u{1F3A4}", 'CHARACTER_WOMAN_SINGER_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FB}\u{200D}\u{1F3A4}", 'CHARACTER_WOMAN_SINGER_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FC}\u{200D}\u{1F3A4}", 'CHARACTER_WOMAN_SINGER_MEDIUM_SKIN_TONE' => "\u{1F469}\u{1F3FD}\u{200D}\u{1F3A4}", 'CHARACTER_WOMAN_SINGER_MEDIUM_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FE}\u{200D}\u{1F3A4}", 'CHARACTER_WOMAN_SINGER_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FF}\u{200D}\u{1F3A4}", 'CHARACTER_MAN_ARTIST' => "\u{1F468}\u{200D}\u{1F3A8}", 'CHARACTER_MAN_ARTIST_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FB}\u{200D}\u{1F3A8}", 'CHARACTER_MAN_ARTIST_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FC}\u{200D}\u{1F3A8}", 'CHARACTER_MAN_ARTIST_MEDIUM_SKIN_TONE' => "\u{1F468}\u{1F3FD}\u{200D}\u{1F3A8}", 'CHARACTER_MAN_ARTIST_MEDIUM_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FE}\u{200D}\u{1F3A8}", 'CHARACTER_MAN_ARTIST_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FF}\u{200D}\u{1F3A8}", 'CHARACTER_WOMAN_ARTIST' => "\u{1F469}\u{200D}\u{1F3A8}", 'CHARACTER_WOMAN_ARTIST_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FB}\u{200D}\u{1F3A8}", 'CHARACTER_WOMAN_ARTIST_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FC}\u{200D}\u{1F3A8}", 'CHARACTER_WOMAN_ARTIST_MEDIUM_SKIN_TONE' => "\u{1F469}\u{1F3FD}\u{200D}\u{1F3A8}", 'CHARACTER_WOMAN_ARTIST_MEDIUM_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FE}\u{200D}\u{1F3A8}", 'CHARACTER_WOMAN_ARTIST_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FF}\u{200D}\u{1F3A8}", 'CHARACTER_MAN_PILOT' => "\u{1F468}\u{200D}\u{2708}\u{FE0F}", 'CHARACTER_MAN_PILOT_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FB}\u{200D}\u{2708}\u{FE0F}", 'CHARACTER_MAN_PILOT_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FC}\u{200D}\u{2708}\u{FE0F}", 'CHARACTER_MAN_PILOT_MEDIUM_SKIN_TONE' => "\u{1F468}\u{1F3FD}\u{200D}\u{2708}\u{FE0F}", 'CHARACTER_MAN_PILOT_MEDIUM_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FE}\u{200D}\u{2708}\u{FE0F}", 'CHARACTER_MAN_PILOT_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FF}\u{200D}\u{2708}\u{FE0F}", 'CHARACTER_WOMAN_PILOT' => "\u{1F469}\u{200D}\u{2708}\u{FE0F}", 'CHARACTER_WOMAN_PILOT_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FB}\u{200D}\u{2708}\u{FE0F}", 'CHARACTER_WOMAN_PILOT_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FC}\u{200D}\u{2708}\u{FE0F}", 'CHARACTER_WOMAN_PILOT_MEDIUM_SKIN_TONE' => "\u{1F469}\u{1F3FD}\u{200D}\u{2708}\u{FE0F}", 'CHARACTER_WOMAN_PILOT_MEDIUM_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FE}\u{200D}\u{2708}\u{FE0F}", 'CHARACTER_WOMAN_PILOT_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FF}\u{200D}\u{2708}\u{FE0F}", 'CHARACTER_MAN_ASTRONAUT' => "\u{1F468}\u{200D}\u{1F680}", 'CHARACTER_MAN_ASTRONAUT_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FB}\u{200D}\u{1F680}", 'CHARACTER_MAN_ASTRONAUT_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FC}\u{200D}\u{1F680}", 'CHARACTER_MAN_ASTRONAUT_MEDIUM_SKIN_TONE' => "\u{1F468}\u{1F3FD}\u{200D}\u{1F680}", 'CHARACTER_MAN_ASTRONAUT_MEDIUM_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FE}\u{200D}\u{1F680}", 'CHARACTER_MAN_ASTRONAUT_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FF}\u{200D}\u{1F680}", 'CHARACTER_WOMAN_ASTRONAUT' => "\u{1F469}\u{200D}\u{1F680}", 'CHARACTER_WOMAN_ASTRONAUT_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FB}\u{200D}\u{1F680}", 'CHARACTER_WOMAN_ASTRONAUT_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FC}\u{200D}\u{1F680}", 'CHARACTER_WOMAN_ASTRONAUT_MEDIUM_SKIN_TONE' => "\u{1F469}\u{1F3FD}\u{200D}\u{1F680}", 'CHARACTER_WOMAN_ASTRONAUT_MEDIUM_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FE}\u{200D}\u{1F680}", 'CHARACTER_WOMAN_ASTRONAUT_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FF}\u{200D}\u{1F680}", 'CHARACTER_MAN_FIREFIGHTER' => "\u{1F468}\u{200D}\u{1F692}", 'CHARACTER_MAN_FIREFIGHTER_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FB}\u{200D}\u{1F692}", 'CHARACTER_MAN_FIREFIGHTER_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FC}\u{200D}\u{1F692}", 'CHARACTER_MAN_FIREFIGHTER_MEDIUM_SKIN_TONE' => "\u{1F468}\u{1F3FD}\u{200D}\u{1F692}", 'CHARACTER_MAN_FIREFIGHTER_MEDIUM_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FE}\u{200D}\u{1F692}", 'CHARACTER_MAN_FIREFIGHTER_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FF}\u{200D}\u{1F692}", 'CHARACTER_WOMAN_FIREFIGHTER' => "\u{1F469}\u{200D}\u{1F692}", 'CHARACTER_WOMAN_FIREFIGHTER_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FB}\u{200D}\u{1F692}", 'CHARACTER_WOMAN_FIREFIGHTER_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FC}\u{200D}\u{1F692}", 'CHARACTER_WOMAN_FIREFIGHTER_MEDIUM_SKIN_TONE' => "\u{1F469}\u{1F3FD}\u{200D}\u{1F692}", 'CHARACTER_WOMAN_FIREFIGHTER_MEDIUM_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FE}\u{200D}\u{1F692}", 'CHARACTER_WOMAN_FIREFIGHTER_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FF}\u{200D}\u{1F692}", 'CHARACTER_POLICE_OFFICER' => "\u{1F46E}", 'CHARACTER_POLICE_OFFICER_LIGHT_SKIN_TONE' => "\u{1F46E}\u{1F3FB}", 'CHARACTER_POLICE_OFFICER_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F46E}\u{1F3FC}", 'CHARACTER_POLICE_OFFICER_MEDIUM_SKIN_TONE' => "\u{1F46E}\u{1F3FD}", 'CHARACTER_POLICE_OFFICER_MEDIUM_DARK_SKIN_TONE' => "\u{1F46E}\u{1F3FE}", 'CHARACTER_POLICE_OFFICER_DARK_SKIN_TONE' => "\u{1F46E}\u{1F3FF}", 'CHARACTER_MAN_POLICE_OFFICER' => "\u{1F46E}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_POLICE_OFFICER_LIGHT_SKIN_TONE' => "\u{1F46E}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_POLICE_OFFICER_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F46E}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_POLICE_OFFICER_MEDIUM_SKIN_TONE' => "\u{1F46E}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_POLICE_OFFICER_MEDIUM_DARK_SKIN_TONE' => "\u{1F46E}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_POLICE_OFFICER_DARK_SKIN_TONE' => "\u{1F46E}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_POLICE_OFFICER' => "\u{1F46E}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_POLICE_OFFICER_LIGHT_SKIN_TONE' => "\u{1F46E}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_POLICE_OFFICER_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F46E}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_POLICE_OFFICER_MEDIUM_SKIN_TONE' => "\u{1F46E}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_POLICE_OFFICER_MEDIUM_DARK_SKIN_TONE' => "\u{1F46E}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_POLICE_OFFICER_DARK_SKIN_TONE' => "\u{1F46E}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_DETECTIVE' => "\u{1F575}\u{FE0F}", 'CHARACTER_DETECTIVE_LIGHT_SKIN_TONE' => "\u{1F575}\u{1F3FB}", 'CHARACTER_DETECTIVE_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F575}\u{1F3FC}", 'CHARACTER_DETECTIVE_MEDIUM_SKIN_TONE' => "\u{1F575}\u{1F3FD}", 'CHARACTER_DETECTIVE_MEDIUM_DARK_SKIN_TONE' => "\u{1F575}\u{1F3FE}", 'CHARACTER_DETECTIVE_DARK_SKIN_TONE' => "\u{1F575}\u{1F3FF}", 'CHARACTER_MAN_DETECTIVE' => "\u{1F575}\u{FE0F}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_DETECTIVE_LIGHT_SKIN_TONE' => "\u{1F575}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_DETECTIVE_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F575}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_DETECTIVE_MEDIUM_SKIN_TONE' => "\u{1F575}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_DETECTIVE_MEDIUM_DARK_SKIN_TONE' => "\u{1F575}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_DETECTIVE_DARK_SKIN_TONE' => "\u{1F575}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_DETECTIVE' => "\u{1F575}\u{FE0F}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_DETECTIVE_LIGHT_SKIN_TONE' => "\u{1F575}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_DETECTIVE_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F575}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_DETECTIVE_MEDIUM_SKIN_TONE' => "\u{1F575}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_DETECTIVE_MEDIUM_DARK_SKIN_TONE' => "\u{1F575}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_DETECTIVE_DARK_SKIN_TONE' => "\u{1F575}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_GUARD' => "\u{1F482}", 'CHARACTER_GUARD_LIGHT_SKIN_TONE' => "\u{1F482}\u{1F3FB}", 'CHARACTER_GUARD_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F482}\u{1F3FC}", 'CHARACTER_GUARD_MEDIUM_SKIN_TONE' => "\u{1F482}\u{1F3FD}", 'CHARACTER_GUARD_MEDIUM_DARK_SKIN_TONE' => "\u{1F482}\u{1F3FE}", 'CHARACTER_GUARD_DARK_SKIN_TONE' => "\u{1F482}\u{1F3FF}", 'CHARACTER_MAN_GUARD' => "\u{1F482}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GUARD_LIGHT_SKIN_TONE' => "\u{1F482}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GUARD_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F482}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GUARD_MEDIUM_SKIN_TONE' => "\u{1F482}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GUARD_MEDIUM_DARK_SKIN_TONE' => "\u{1F482}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GUARD_DARK_SKIN_TONE' => "\u{1F482}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_GUARD' => "\u{1F482}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GUARD_LIGHT_SKIN_TONE' => "\u{1F482}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GUARD_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F482}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GUARD_MEDIUM_SKIN_TONE' => "\u{1F482}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GUARD_MEDIUM_DARK_SKIN_TONE' => "\u{1F482}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GUARD_DARK_SKIN_TONE' => "\u{1F482}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_CONSTRUCTION_WORKER' => "\u{1F477}", 'CHARACTER_CONSTRUCTION_WORKER_LIGHT_SKIN_TONE' => "\u{1F477}\u{1F3FB}", 'CHARACTER_CONSTRUCTION_WORKER_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F477}\u{1F3FC}", 'CHARACTER_CONSTRUCTION_WORKER_MEDIUM_SKIN_TONE' => "\u{1F477}\u{1F3FD}", 'CHARACTER_CONSTRUCTION_WORKER_MEDIUM_DARK_SKIN_TONE' => "\u{1F477}\u{1F3FE}", 'CHARACTER_CONSTRUCTION_WORKER_DARK_SKIN_TONE' => "\u{1F477}\u{1F3FF}", 'CHARACTER_MAN_CONSTRUCTION_WORKER' => "\u{1F477}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_CONSTRUCTION_WORKER_LIGHT_SKIN_TONE' => "\u{1F477}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_CONSTRUCTION_WORKER_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F477}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_CONSTRUCTION_WORKER_MEDIUM_SKIN_TONE' => "\u{1F477}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_CONSTRUCTION_WORKER_MEDIUM_DARK_SKIN_TONE' => "\u{1F477}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_CONSTRUCTION_WORKER_DARK_SKIN_TONE' => "\u{1F477}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_CONSTRUCTION_WORKER' => "\u{1F477}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_CONSTRUCTION_WORKER_LIGHT_SKIN_TONE' => "\u{1F477}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_CONSTRUCTION_WORKER_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F477}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_CONSTRUCTION_WORKER_MEDIUM_SKIN_TONE' => "\u{1F477}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_CONSTRUCTION_WORKER_MEDIUM_DARK_SKIN_TONE' => "\u{1F477}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_CONSTRUCTION_WORKER_DARK_SKIN_TONE' => "\u{1F477}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PRINCE' => "\u{1F934}", 'CHARACTER_PRINCE_LIGHT_SKIN_TONE' => "\u{1F934}\u{1F3FB}", 'CHARACTER_PRINCE_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F934}\u{1F3FC}", 'CHARACTER_PRINCE_MEDIUM_SKIN_TONE' => "\u{1F934}\u{1F3FD}", 'CHARACTER_PRINCE_MEDIUM_DARK_SKIN_TONE' => "\u{1F934}\u{1F3FE}", 'CHARACTER_PRINCE_DARK_SKIN_TONE' => "\u{1F934}\u{1F3FF}", 'CHARACTER_PRINCESS' => "\u{1F478}", 'CHARACTER_PRINCESS_LIGHT_SKIN_TONE' => "\u{1F478}\u{1F3FB}", 'CHARACTER_PRINCESS_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F478}\u{1F3FC}", 'CHARACTER_PRINCESS_MEDIUM_SKIN_TONE' => "\u{1F478}\u{1F3FD}", 'CHARACTER_PRINCESS_MEDIUM_DARK_SKIN_TONE' => "\u{1F478}\u{1F3FE}", 'CHARACTER_PRINCESS_DARK_SKIN_TONE' => "\u{1F478}\u{1F3FF}", 'CHARACTER_PERSON_WEARING_TURBAN' => "\u{1F473}", 'CHARACTER_PERSON_WEARING_TURBAN_LIGHT_SKIN_TONE' => "\u{1F473}\u{1F3FB}", 'CHARACTER_PERSON_WEARING_TURBAN_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F473}\u{1F3FC}", 'CHARACTER_PERSON_WEARING_TURBAN_MEDIUM_SKIN_TONE' => "\u{1F473}\u{1F3FD}", 'CHARACTER_PERSON_WEARING_TURBAN_MEDIUM_DARK_SKIN_TONE' => "\u{1F473}\u{1F3FE}", 'CHARACTER_PERSON_WEARING_TURBAN_DARK_SKIN_TONE' => "\u{1F473}\u{1F3FF}", 'CHARACTER_MAN_WEARING_TURBAN' => "\u{1F473}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_WEARING_TURBAN_LIGHT_SKIN_TONE' => "\u{1F473}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_WEARING_TURBAN_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F473}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_WEARING_TURBAN_MEDIUM_SKIN_TONE' => "\u{1F473}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_WEARING_TURBAN_MEDIUM_DARK_SKIN_TONE' => "\u{1F473}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_WEARING_TURBAN_DARK_SKIN_TONE' => "\u{1F473}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_WEARING_TURBAN' => "\u{1F473}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_WEARING_TURBAN_LIGHT_SKIN_TONE' => "\u{1F473}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_WEARING_TURBAN_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F473}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_WEARING_TURBAN_MEDIUM_SKIN_TONE' => "\u{1F473}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_WEARING_TURBAN_MEDIUM_DARK_SKIN_TONE' => "\u{1F473}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_WEARING_TURBAN_DARK_SKIN_TONE' => "\u{1F473}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_MAN_WITH_CHINESE_CAP' => "\u{1F472}", 'CHARACTER_MAN_WITH_CHINESE_CAP_LIGHT_SKIN_TONE' => "\u{1F472}\u{1F3FB}", 'CHARACTER_MAN_WITH_CHINESE_CAP_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F472}\u{1F3FC}", 'CHARACTER_MAN_WITH_CHINESE_CAP_MEDIUM_SKIN_TONE' => "\u{1F472}\u{1F3FD}", 'CHARACTER_MAN_WITH_CHINESE_CAP_MEDIUM_DARK_SKIN_TONE' => "\u{1F472}\u{1F3FE}", 'CHARACTER_MAN_WITH_CHINESE_CAP_DARK_SKIN_TONE' => "\u{1F472}\u{1F3FF}", 'CHARACTER_WOMAN_WITH_HEADSCARF' => "\u{1F9D5}", 'CHARACTER_WOMAN_WITH_HEADSCARF_LIGHT_SKIN_TONE' => "\u{1F9D5}\u{1F3FB}", 'CHARACTER_WOMAN_WITH_HEADSCARF_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9D5}\u{1F3FC}", 'CHARACTER_WOMAN_WITH_HEADSCARF_MEDIUM_SKIN_TONE' => "\u{1F9D5}\u{1F3FD}", 'CHARACTER_WOMAN_WITH_HEADSCARF_MEDIUM_DARK_SKIN_TONE' => "\u{1F9D5}\u{1F3FE}", 'CHARACTER_WOMAN_WITH_HEADSCARF_DARK_SKIN_TONE' => "\u{1F9D5}\u{1F3FF}", 'CHARACTER_BEARDED_PERSON' => "\u{1F9D4}", 'CHARACTER_BEARDED_PERSON_LIGHT_SKIN_TONE' => "\u{1F9D4}\u{1F3FB}", 'CHARACTER_BEARDED_PERSON_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9D4}\u{1F3FC}", 'CHARACTER_BEARDED_PERSON_MEDIUM_SKIN_TONE' => "\u{1F9D4}\u{1F3FD}", 'CHARACTER_BEARDED_PERSON_MEDIUM_DARK_SKIN_TONE' => "\u{1F9D4}\u{1F3FE}", 'CHARACTER_BEARDED_PERSON_DARK_SKIN_TONE' => "\u{1F9D4}\u{1F3FF}", 'CHARACTER_BLOND_HAIRED_PERSON' => "\u{1F471}", 'CHARACTER_BLOND_HAIRED_PERSON_LIGHT_SKIN_TONE' => "\u{1F471}\u{1F3FB}", 'CHARACTER_BLOND_HAIRED_PERSON_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F471}\u{1F3FC}", 'CHARACTER_BLOND_HAIRED_PERSON_MEDIUM_SKIN_TONE' => "\u{1F471}\u{1F3FD}", 'CHARACTER_BLOND_HAIRED_PERSON_MEDIUM_DARK_SKIN_TONE' => "\u{1F471}\u{1F3FE}", 'CHARACTER_BLOND_HAIRED_PERSON_DARK_SKIN_TONE' => "\u{1F471}\u{1F3FF}", 'CHARACTER_BLOND_HAIRED_MAN' => "\u{1F471}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_BLOND_HAIRED_MAN_LIGHT_SKIN_TONE' => "\u{1F471}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_BLOND_HAIRED_MAN_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F471}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_BLOND_HAIRED_MAN_MEDIUM_SKIN_TONE' => "\u{1F471}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_BLOND_HAIRED_MAN_MEDIUM_DARK_SKIN_TONE' => "\u{1F471}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_BLOND_HAIRED_MAN_DARK_SKIN_TONE' => "\u{1F471}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_BLOND_HAIRED_WOMAN' => "\u{1F471}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_BLOND_HAIRED_WOMAN_LIGHT_SKIN_TONE' => "\u{1F471}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_BLOND_HAIRED_WOMAN_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F471}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_BLOND_HAIRED_WOMAN_MEDIUM_SKIN_TONE' => "\u{1F471}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_BLOND_HAIRED_WOMAN_MEDIUM_DARK_SKIN_TONE' => "\u{1F471}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_BLOND_HAIRED_WOMAN_DARK_SKIN_TONE' => "\u{1F471}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_MAN_RED_HAIRED' => "\u{1F468}\u{200D}\u{1F9B0}", 'CHARACTER_MAN_RED_HAIRED_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FB}\u{200D}\u{1F9B0}", 'CHARACTER_MAN_RED_HAIRED_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FC}\u{200D}\u{1F9B0}", 'CHARACTER_MAN_RED_HAIRED_MEDIUM_SKIN_TONE' => "\u{1F468}\u{1F3FD}\u{200D}\u{1F9B0}", 'CHARACTER_MAN_RED_HAIRED_MEDIUM_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FE}\u{200D}\u{1F9B0}", 'CHARACTER_MAN_RED_HAIRED_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FF}\u{200D}\u{1F9B0}", 'CHARACTER_WOMAN_RED_HAIRED' => "\u{1F469}\u{200D}\u{1F9B0}", 'CHARACTER_WOMAN_RED_HAIRED_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FB}\u{200D}\u{1F9B0}", 'CHARACTER_WOMAN_RED_HAIRED_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FC}\u{200D}\u{1F9B0}", 'CHARACTER_WOMAN_RED_HAIRED_MEDIUM_SKIN_TONE' => "\u{1F469}\u{1F3FD}\u{200D}\u{1F9B0}", 'CHARACTER_WOMAN_RED_HAIRED_MEDIUM_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FE}\u{200D}\u{1F9B0}", 'CHARACTER_WOMAN_RED_HAIRED_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FF}\u{200D}\u{1F9B0}", 'CHARACTER_MAN_CURLY_HAIRED' => "\u{1F468}\u{200D}\u{1F9B1}", 'CHARACTER_MAN_CURLY_HAIRED_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FB}\u{200D}\u{1F9B1}", 'CHARACTER_MAN_CURLY_HAIRED_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FC}\u{200D}\u{1F9B1}", 'CHARACTER_MAN_CURLY_HAIRED_MEDIUM_SKIN_TONE' => "\u{1F468}\u{1F3FD}\u{200D}\u{1F9B1}", 'CHARACTER_MAN_CURLY_HAIRED_MEDIUM_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FE}\u{200D}\u{1F9B1}", 'CHARACTER_MAN_CURLY_HAIRED_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FF}\u{200D}\u{1F9B1}", 'CHARACTER_WOMAN_CURLY_HAIRED' => "\u{1F469}\u{200D}\u{1F9B1}", 'CHARACTER_WOMAN_CURLY_HAIRED_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FB}\u{200D}\u{1F9B1}", 'CHARACTER_WOMAN_CURLY_HAIRED_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FC}\u{200D}\u{1F9B1}", 'CHARACTER_WOMAN_CURLY_HAIRED_MEDIUM_SKIN_TONE' => "\u{1F469}\u{1F3FD}\u{200D}\u{1F9B1}", 'CHARACTER_WOMAN_CURLY_HAIRED_MEDIUM_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FE}\u{200D}\u{1F9B1}", 'CHARACTER_WOMAN_CURLY_HAIRED_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FF}\u{200D}\u{1F9B1}", 'CHARACTER_MAN_BALD' => "\u{1F468}\u{200D}\u{1F9B2}", 'CHARACTER_MAN_BALD_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FB}\u{200D}\u{1F9B2}", 'CHARACTER_MAN_BALD_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FC}\u{200D}\u{1F9B2}", 'CHARACTER_MAN_BALD_MEDIUM_SKIN_TONE' => "\u{1F468}\u{1F3FD}\u{200D}\u{1F9B2}", 'CHARACTER_MAN_BALD_MEDIUM_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FE}\u{200D}\u{1F9B2}", 'CHARACTER_MAN_BALD_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FF}\u{200D}\u{1F9B2}", 'CHARACTER_WOMAN_BALD' => "\u{1F469}\u{200D}\u{1F9B2}", 'CHARACTER_WOMAN_BALD_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FB}\u{200D}\u{1F9B2}", 'CHARACTER_WOMAN_BALD_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FC}\u{200D}\u{1F9B2}", 'CHARACTER_WOMAN_BALD_MEDIUM_SKIN_TONE' => "\u{1F469}\u{1F3FD}\u{200D}\u{1F9B2}", 'CHARACTER_WOMAN_BALD_MEDIUM_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FE}\u{200D}\u{1F9B2}", 'CHARACTER_WOMAN_BALD_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FF}\u{200D}\u{1F9B2}", 'CHARACTER_MAN_WHITE_HAIRED' => "\u{1F468}\u{200D}\u{1F9B3}", 'CHARACTER_MAN_WHITE_HAIRED_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FB}\u{200D}\u{1F9B3}", 'CHARACTER_MAN_WHITE_HAIRED_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F468}\u{1F3FC}\u{200D}\u{1F9B3}", 'CHARACTER_MAN_WHITE_HAIRED_MEDIUM_SKIN_TONE' => "\u{1F468}\u{1F3FD}\u{200D}\u{1F9B3}", 'CHARACTER_MAN_WHITE_HAIRED_MEDIUM_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FE}\u{200D}\u{1F9B3}", 'CHARACTER_MAN_WHITE_HAIRED_DARK_SKIN_TONE' => "\u{1F468}\u{1F3FF}\u{200D}\u{1F9B3}", 'CHARACTER_WOMAN_WHITE_HAIRED' => "\u{1F469}\u{200D}\u{1F9B3}", 'CHARACTER_WOMAN_WHITE_HAIRED_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FB}\u{200D}\u{1F9B3}", 'CHARACTER_WOMAN_WHITE_HAIRED_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F469}\u{1F3FC}\u{200D}\u{1F9B3}", 'CHARACTER_WOMAN_WHITE_HAIRED_MEDIUM_SKIN_TONE' => "\u{1F469}\u{1F3FD}\u{200D}\u{1F9B3}", 'CHARACTER_WOMAN_WHITE_HAIRED_MEDIUM_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FE}\u{200D}\u{1F9B3}", 'CHARACTER_WOMAN_WHITE_HAIRED_DARK_SKIN_TONE' => "\u{1F469}\u{1F3FF}\u{200D}\u{1F9B3}", 'CHARACTER_MAN_IN_TUXEDO' => "\u{1F935}", 'CHARACTER_MAN_IN_TUXEDO_LIGHT_SKIN_TONE' => "\u{1F935}\u{1F3FB}", 'CHARACTER_MAN_IN_TUXEDO_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F935}\u{1F3FC}", 'CHARACTER_MAN_IN_TUXEDO_MEDIUM_SKIN_TONE' => "\u{1F935}\u{1F3FD}", 'CHARACTER_MAN_IN_TUXEDO_MEDIUM_DARK_SKIN_TONE' => "\u{1F935}\u{1F3FE}", 'CHARACTER_MAN_IN_TUXEDO_DARK_SKIN_TONE' => "\u{1F935}\u{1F3FF}", 'CHARACTER_BRIDE_WITH_VEIL' => "\u{1F470}", 'CHARACTER_BRIDE_WITH_VEIL_LIGHT_SKIN_TONE' => "\u{1F470}\u{1F3FB}", 'CHARACTER_BRIDE_WITH_VEIL_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F470}\u{1F3FC}", 'CHARACTER_BRIDE_WITH_VEIL_MEDIUM_SKIN_TONE' => "\u{1F470}\u{1F3FD}", 'CHARACTER_BRIDE_WITH_VEIL_MEDIUM_DARK_SKIN_TONE' => "\u{1F470}\u{1F3FE}", 'CHARACTER_BRIDE_WITH_VEIL_DARK_SKIN_TONE' => "\u{1F470}\u{1F3FF}", 'CHARACTER_PREGNANT_WOMAN' => "\u{1F930}", 'CHARACTER_PREGNANT_WOMAN_LIGHT_SKIN_TONE' => "\u{1F930}\u{1F3FB}", 'CHARACTER_PREGNANT_WOMAN_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F930}\u{1F3FC}", 'CHARACTER_PREGNANT_WOMAN_MEDIUM_SKIN_TONE' => "\u{1F930}\u{1F3FD}", 'CHARACTER_PREGNANT_WOMAN_MEDIUM_DARK_SKIN_TONE' => "\u{1F930}\u{1F3FE}", 'CHARACTER_PREGNANT_WOMAN_DARK_SKIN_TONE' => "\u{1F930}\u{1F3FF}", 'CHARACTER_BREAST_FEEDING' => "\u{1F931}", 'CHARACTER_BREAST_FEEDING_LIGHT_SKIN_TONE' => "\u{1F931}\u{1F3FB}", 'CHARACTER_BREAST_FEEDING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F931}\u{1F3FC}", 'CHARACTER_BREAST_FEEDING_MEDIUM_SKIN_TONE' => "\u{1F931}\u{1F3FD}", 'CHARACTER_BREAST_FEEDING_MEDIUM_DARK_SKIN_TONE' => "\u{1F931}\u{1F3FE}", 'CHARACTER_BREAST_FEEDING_DARK_SKIN_TONE' => "\u{1F931}\u{1F3FF}", 'CHARACTER_BABY_ANGEL' => "\u{1F47C}", 'CHARACTER_BABY_ANGEL_LIGHT_SKIN_TONE' => "\u{1F47C}\u{1F3FB}", 'CHARACTER_BABY_ANGEL_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F47C}\u{1F3FC}", 'CHARACTER_BABY_ANGEL_MEDIUM_SKIN_TONE' => "\u{1F47C}\u{1F3FD}", 'CHARACTER_BABY_ANGEL_MEDIUM_DARK_SKIN_TONE' => "\u{1F47C}\u{1F3FE}", 'CHARACTER_BABY_ANGEL_DARK_SKIN_TONE' => "\u{1F47C}\u{1F3FF}", 'CHARACTER_SANTA_CLAUS' => "\u{1F385}", 'CHARACTER_SANTA_CLAUS_LIGHT_SKIN_TONE' => "\u{1F385}\u{1F3FB}", 'CHARACTER_SANTA_CLAUS_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F385}\u{1F3FC}", 'CHARACTER_SANTA_CLAUS_MEDIUM_SKIN_TONE' => "\u{1F385}\u{1F3FD}", 'CHARACTER_SANTA_CLAUS_MEDIUM_DARK_SKIN_TONE' => "\u{1F385}\u{1F3FE}", 'CHARACTER_SANTA_CLAUS_DARK_SKIN_TONE' => "\u{1F385}\u{1F3FF}", 'CHARACTER_MRS_CLAUS' => "\u{1F936}", 'CHARACTER_MRS_CLAUS_LIGHT_SKIN_TONE' => "\u{1F936}\u{1F3FB}", 'CHARACTER_MRS_CLAUS_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F936}\u{1F3FC}", 'CHARACTER_MRS_CLAUS_MEDIUM_SKIN_TONE' => "\u{1F936}\u{1F3FD}", 'CHARACTER_MRS_CLAUS_MEDIUM_DARK_SKIN_TONE' => "\u{1F936}\u{1F3FE}", 'CHARACTER_MRS_CLAUS_DARK_SKIN_TONE' => "\u{1F936}\u{1F3FF}", 'CHARACTER_SUPERHERO' => "\u{1F9B8}", 'CHARACTER_SUPERHERO_LIGHT_SKIN_TONE' => "\u{1F9B8}\u{1F3FB}", 'CHARACTER_SUPERHERO_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9B8}\u{1F3FC}", 'CHARACTER_SUPERHERO_MEDIUM_SKIN_TONE' => "\u{1F9B8}\u{1F3FD}", 'CHARACTER_SUPERHERO_MEDIUM_DARK_SKIN_TONE' => "\u{1F9B8}\u{1F3FE}", 'CHARACTER_SUPERHERO_DARK_SKIN_TONE' => "\u{1F9B8}\u{1F3FF}", 'CHARACTER_WOMAN_SUPERHERO' => "\u{1F9B8}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SUPERHERO_LIGHT_SKIN_TONE' => "\u{1F9B8}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SUPERHERO_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9B8}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SUPERHERO_MEDIUM_SKIN_TONE' => "\u{1F9B8}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SUPERHERO_MEDIUM_DARK_SKIN_TONE' => "\u{1F9B8}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SUPERHERO_DARK_SKIN_TONE' => "\u{1F9B8}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_MAN_SUPERHERO' => "\u{1F9B8}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SUPERHERO_LIGHT_SKIN_TONE' => "\u{1F9B8}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SUPERHERO_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9B8}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SUPERHERO_MEDIUM_SKIN_TONE' => "\u{1F9B8}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SUPERHERO_MEDIUM_DARK_SKIN_TONE' => "\u{1F9B8}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SUPERHERO_DARK_SKIN_TONE' => "\u{1F9B8}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_SUPERVILLAIN' => "\u{1F9B9}", 'CHARACTER_SUPERVILLAIN_LIGHT_SKIN_TONE' => "\u{1F9B9}\u{1F3FB}", 'CHARACTER_SUPERVILLAIN_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9B9}\u{1F3FC}", 'CHARACTER_SUPERVILLAIN_MEDIUM_SKIN_TONE' => "\u{1F9B9}\u{1F3FD}", 'CHARACTER_SUPERVILLAIN_MEDIUM_DARK_SKIN_TONE' => "\u{1F9B9}\u{1F3FE}", 'CHARACTER_SUPERVILLAIN_DARK_SKIN_TONE' => "\u{1F9B9}\u{1F3FF}", 'CHARACTER_WOMAN_SUPERVILLAIN' => "\u{1F9B9}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SUPERVILLAIN_LIGHT_SKIN_TONE' => "\u{1F9B9}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SUPERVILLAIN_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9B9}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SUPERVILLAIN_MEDIUM_SKIN_TONE' => "\u{1F9B9}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SUPERVILLAIN_MEDIUM_DARK_SKIN_TONE' => "\u{1F9B9}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SUPERVILLAIN_DARK_SKIN_TONE' => "\u{1F9B9}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_MAN_SUPERVILLAIN' => "\u{1F9B9}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SUPERVILLAIN_LIGHT_SKIN_TONE' => "\u{1F9B9}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SUPERVILLAIN_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9B9}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SUPERVILLAIN_MEDIUM_SKIN_TONE' => "\u{1F9B9}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SUPERVILLAIN_MEDIUM_DARK_SKIN_TONE' => "\u{1F9B9}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SUPERVILLAIN_DARK_SKIN_TONE' => "\u{1F9B9}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAGE' => "\u{1F9D9}", 'CHARACTER_MAGE_LIGHT_SKIN_TONE' => "\u{1F9D9}\u{1F3FB}", 'CHARACTER_MAGE_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9D9}\u{1F3FC}", 'CHARACTER_MAGE_MEDIUM_SKIN_TONE' => "\u{1F9D9}\u{1F3FD}", 'CHARACTER_MAGE_MEDIUM_DARK_SKIN_TONE' => "\u{1F9D9}\u{1F3FE}", 'CHARACTER_MAGE_DARK_SKIN_TONE' => "\u{1F9D9}\u{1F3FF}", 'CHARACTER_WOMAN_MAGE' => "\u{1F9D9}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_MAGE_LIGHT_SKIN_TONE' => "\u{1F9D9}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_MAGE_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9D9}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_MAGE_MEDIUM_SKIN_TONE' => "\u{1F9D9}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_MAGE_MEDIUM_DARK_SKIN_TONE' => "\u{1F9D9}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_MAGE_DARK_SKIN_TONE' => "\u{1F9D9}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_MAN_MAGE' => "\u{1F9D9}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_MAGE_LIGHT_SKIN_TONE' => "\u{1F9D9}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_MAGE_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9D9}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_MAGE_MEDIUM_SKIN_TONE' => "\u{1F9D9}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_MAGE_MEDIUM_DARK_SKIN_TONE' => "\u{1F9D9}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_MAGE_DARK_SKIN_TONE' => "\u{1F9D9}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_FAIRY' => "\u{1F9DA}", 'CHARACTER_FAIRY_LIGHT_SKIN_TONE' => "\u{1F9DA}\u{1F3FB}", 'CHARACTER_FAIRY_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9DA}\u{1F3FC}", 'CHARACTER_FAIRY_MEDIUM_SKIN_TONE' => "\u{1F9DA}\u{1F3FD}", 'CHARACTER_FAIRY_MEDIUM_DARK_SKIN_TONE' => "\u{1F9DA}\u{1F3FE}", 'CHARACTER_FAIRY_DARK_SKIN_TONE' => "\u{1F9DA}\u{1F3FF}", 'CHARACTER_WOMAN_FAIRY' => "\u{1F9DA}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_FAIRY_LIGHT_SKIN_TONE' => "\u{1F9DA}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_FAIRY_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9DA}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_FAIRY_MEDIUM_SKIN_TONE' => "\u{1F9DA}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_FAIRY_MEDIUM_DARK_SKIN_TONE' => "\u{1F9DA}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_FAIRY_DARK_SKIN_TONE' => "\u{1F9DA}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_MAN_FAIRY' => "\u{1F9DA}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_FAIRY_LIGHT_SKIN_TONE' => "\u{1F9DA}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_FAIRY_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9DA}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_FAIRY_MEDIUM_SKIN_TONE' => "\u{1F9DA}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_FAIRY_MEDIUM_DARK_SKIN_TONE' => "\u{1F9DA}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_FAIRY_DARK_SKIN_TONE' => "\u{1F9DA}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_VAMPIRE' => "\u{1F9DB}", 'CHARACTER_VAMPIRE_LIGHT_SKIN_TONE' => "\u{1F9DB}\u{1F3FB}", 'CHARACTER_VAMPIRE_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9DB}\u{1F3FC}", 'CHARACTER_VAMPIRE_MEDIUM_SKIN_TONE' => "\u{1F9DB}\u{1F3FD}", 'CHARACTER_VAMPIRE_MEDIUM_DARK_SKIN_TONE' => "\u{1F9DB}\u{1F3FE}", 'CHARACTER_VAMPIRE_DARK_SKIN_TONE' => "\u{1F9DB}\u{1F3FF}", 'CHARACTER_WOMAN_VAMPIRE' => "\u{1F9DB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_VAMPIRE_LIGHT_SKIN_TONE' => "\u{1F9DB}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_VAMPIRE_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9DB}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_VAMPIRE_MEDIUM_SKIN_TONE' => "\u{1F9DB}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_VAMPIRE_MEDIUM_DARK_SKIN_TONE' => "\u{1F9DB}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_VAMPIRE_DARK_SKIN_TONE' => "\u{1F9DB}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_MAN_VAMPIRE' => "\u{1F9DB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_VAMPIRE_LIGHT_SKIN_TONE' => "\u{1F9DB}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_VAMPIRE_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9DB}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_VAMPIRE_MEDIUM_SKIN_TONE' => "\u{1F9DB}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_VAMPIRE_MEDIUM_DARK_SKIN_TONE' => "\u{1F9DB}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_VAMPIRE_DARK_SKIN_TONE' => "\u{1F9DB}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MERPERSON' => "\u{1F9DC}", 'CHARACTER_MERPERSON_LIGHT_SKIN_TONE' => "\u{1F9DC}\u{1F3FB}", 'CHARACTER_MERPERSON_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9DC}\u{1F3FC}", 'CHARACTER_MERPERSON_MEDIUM_SKIN_TONE' => "\u{1F9DC}\u{1F3FD}", 'CHARACTER_MERPERSON_MEDIUM_DARK_SKIN_TONE' => "\u{1F9DC}\u{1F3FE}", 'CHARACTER_MERPERSON_DARK_SKIN_TONE' => "\u{1F9DC}\u{1F3FF}", 'CHARACTER_MERMAID' => "\u{1F9DC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_MERMAID_LIGHT_SKIN_TONE' => "\u{1F9DC}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_MERMAID_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9DC}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_MERMAID_MEDIUM_SKIN_TONE' => "\u{1F9DC}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_MERMAID_MEDIUM_DARK_SKIN_TONE' => "\u{1F9DC}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_MERMAID_DARK_SKIN_TONE' => "\u{1F9DC}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_MERMAN' => "\u{1F9DC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MERMAN_LIGHT_SKIN_TONE' => "\u{1F9DC}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MERMAN_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9DC}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MERMAN_MEDIUM_SKIN_TONE' => "\u{1F9DC}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MERMAN_MEDIUM_DARK_SKIN_TONE' => "\u{1F9DC}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MERMAN_DARK_SKIN_TONE' => "\u{1F9DC}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_ELF' => "\u{1F9DD}", 'CHARACTER_ELF_LIGHT_SKIN_TONE' => "\u{1F9DD}\u{1F3FB}", 'CHARACTER_ELF_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9DD}\u{1F3FC}", 'CHARACTER_ELF_MEDIUM_SKIN_TONE' => "\u{1F9DD}\u{1F3FD}", 'CHARACTER_ELF_MEDIUM_DARK_SKIN_TONE' => "\u{1F9DD}\u{1F3FE}", 'CHARACTER_ELF_DARK_SKIN_TONE' => "\u{1F9DD}\u{1F3FF}", 'CHARACTER_WOMAN_ELF' => "\u{1F9DD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_ELF_LIGHT_SKIN_TONE' => "\u{1F9DD}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_ELF_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9DD}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_ELF_MEDIUM_SKIN_TONE' => "\u{1F9DD}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_ELF_MEDIUM_DARK_SKIN_TONE' => "\u{1F9DD}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_ELF_DARK_SKIN_TONE' => "\u{1F9DD}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_MAN_ELF' => "\u{1F9DD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_ELF_LIGHT_SKIN_TONE' => "\u{1F9DD}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_ELF_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9DD}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_ELF_MEDIUM_SKIN_TONE' => "\u{1F9DD}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_ELF_MEDIUM_DARK_SKIN_TONE' => "\u{1F9DD}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_ELF_DARK_SKIN_TONE' => "\u{1F9DD}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_GENIE' => "\u{1F9DE}", 'CHARACTER_WOMAN_GENIE' => "\u{1F9DE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_MAN_GENIE' => "\u{1F9DE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_ZOMBIE' => "\u{1F9DF}", 'CHARACTER_WOMAN_ZOMBIE' => "\u{1F9DF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_MAN_ZOMBIE' => "\u{1F9DF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_PERSON_FROWNING' => "\u{1F64D}", 'CHARACTER_PERSON_FROWNING_LIGHT_SKIN_TONE' => "\u{1F64D}\u{1F3FB}", 'CHARACTER_PERSON_FROWNING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F64D}\u{1F3FC}", 'CHARACTER_PERSON_FROWNING_MEDIUM_SKIN_TONE' => "\u{1F64D}\u{1F3FD}", 'CHARACTER_PERSON_FROWNING_MEDIUM_DARK_SKIN_TONE' => "\u{1F64D}\u{1F3FE}", 'CHARACTER_PERSON_FROWNING_DARK_SKIN_TONE' => "\u{1F64D}\u{1F3FF}", 'CHARACTER_MAN_FROWNING' => "\u{1F64D}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_FROWNING_LIGHT_SKIN_TONE' => "\u{1F64D}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_FROWNING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F64D}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_FROWNING_MEDIUM_SKIN_TONE' => "\u{1F64D}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_FROWNING_MEDIUM_DARK_SKIN_TONE' => "\u{1F64D}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_FROWNING_DARK_SKIN_TONE' => "\u{1F64D}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_FROWNING' => "\u{1F64D}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_FROWNING_LIGHT_SKIN_TONE' => "\u{1F64D}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_FROWNING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F64D}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_FROWNING_MEDIUM_SKIN_TONE' => "\u{1F64D}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_FROWNING_MEDIUM_DARK_SKIN_TONE' => "\u{1F64D}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_FROWNING_DARK_SKIN_TONE' => "\u{1F64D}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PERSON_POUTING' => "\u{1F64E}", 'CHARACTER_PERSON_POUTING_LIGHT_SKIN_TONE' => "\u{1F64E}\u{1F3FB}", 'CHARACTER_PERSON_POUTING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F64E}\u{1F3FC}", 'CHARACTER_PERSON_POUTING_MEDIUM_SKIN_TONE' => "\u{1F64E}\u{1F3FD}", 'CHARACTER_PERSON_POUTING_MEDIUM_DARK_SKIN_TONE' => "\u{1F64E}\u{1F3FE}", 'CHARACTER_PERSON_POUTING_DARK_SKIN_TONE' => "\u{1F64E}\u{1F3FF}", 'CHARACTER_MAN_POUTING' => "\u{1F64E}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_POUTING_LIGHT_SKIN_TONE' => "\u{1F64E}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_POUTING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F64E}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_POUTING_MEDIUM_SKIN_TONE' => "\u{1F64E}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_POUTING_MEDIUM_DARK_SKIN_TONE' => "\u{1F64E}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_POUTING_DARK_SKIN_TONE' => "\u{1F64E}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_POUTING' => "\u{1F64E}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_POUTING_LIGHT_SKIN_TONE' => "\u{1F64E}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_POUTING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F64E}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_POUTING_MEDIUM_SKIN_TONE' => "\u{1F64E}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_POUTING_MEDIUM_DARK_SKIN_TONE' => "\u{1F64E}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_POUTING_DARK_SKIN_TONE' => "\u{1F64E}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PERSON_GESTURING_NO' => "\u{1F645}", 'CHARACTER_PERSON_GESTURING_NO_LIGHT_SKIN_TONE' => "\u{1F645}\u{1F3FB}", 'CHARACTER_PERSON_GESTURING_NO_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F645}\u{1F3FC}", 'CHARACTER_PERSON_GESTURING_NO_MEDIUM_SKIN_TONE' => "\u{1F645}\u{1F3FD}", 'CHARACTER_PERSON_GESTURING_NO_MEDIUM_DARK_SKIN_TONE' => "\u{1F645}\u{1F3FE}", 'CHARACTER_PERSON_GESTURING_NO_DARK_SKIN_TONE' => "\u{1F645}\u{1F3FF}", 'CHARACTER_MAN_GESTURING_NO' => "\u{1F645}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GESTURING_NO_LIGHT_SKIN_TONE' => "\u{1F645}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GESTURING_NO_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F645}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GESTURING_NO_MEDIUM_SKIN_TONE' => "\u{1F645}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GESTURING_NO_MEDIUM_DARK_SKIN_TONE' => "\u{1F645}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GESTURING_NO_DARK_SKIN_TONE' => "\u{1F645}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_GESTURING_NO' => "\u{1F645}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GESTURING_NO_LIGHT_SKIN_TONE' => "\u{1F645}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GESTURING_NO_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F645}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GESTURING_NO_MEDIUM_SKIN_TONE' => "\u{1F645}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GESTURING_NO_MEDIUM_DARK_SKIN_TONE' => "\u{1F645}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GESTURING_NO_DARK_SKIN_TONE' => "\u{1F645}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PERSON_GESTURING_OK' => "\u{1F646}", 'CHARACTER_PERSON_GESTURING_OK_LIGHT_SKIN_TONE' => "\u{1F646}\u{1F3FB}", 'CHARACTER_PERSON_GESTURING_OK_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F646}\u{1F3FC}", 'CHARACTER_PERSON_GESTURING_OK_MEDIUM_SKIN_TONE' => "\u{1F646}\u{1F3FD}", 'CHARACTER_PERSON_GESTURING_OK_MEDIUM_DARK_SKIN_TONE' => "\u{1F646}\u{1F3FE}", 'CHARACTER_PERSON_GESTURING_OK_DARK_SKIN_TONE' => "\u{1F646}\u{1F3FF}", 'CHARACTER_MAN_GESTURING_OK' => "\u{1F646}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GESTURING_OK_LIGHT_SKIN_TONE' => "\u{1F646}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GESTURING_OK_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F646}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GESTURING_OK_MEDIUM_SKIN_TONE' => "\u{1F646}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GESTURING_OK_MEDIUM_DARK_SKIN_TONE' => "\u{1F646}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GESTURING_OK_DARK_SKIN_TONE' => "\u{1F646}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_GESTURING_OK' => "\u{1F646}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GESTURING_OK_LIGHT_SKIN_TONE' => "\u{1F646}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GESTURING_OK_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F646}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GESTURING_OK_MEDIUM_SKIN_TONE' => "\u{1F646}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GESTURING_OK_MEDIUM_DARK_SKIN_TONE' => "\u{1F646}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GESTURING_OK_DARK_SKIN_TONE' => "\u{1F646}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PERSON_TIPPING_HAND' => "\u{1F481}", 'CHARACTER_PERSON_TIPPING_HAND_LIGHT_SKIN_TONE' => "\u{1F481}\u{1F3FB}", 'CHARACTER_PERSON_TIPPING_HAND_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F481}\u{1F3FC}", 'CHARACTER_PERSON_TIPPING_HAND_MEDIUM_SKIN_TONE' => "\u{1F481}\u{1F3FD}", 'CHARACTER_PERSON_TIPPING_HAND_MEDIUM_DARK_SKIN_TONE' => "\u{1F481}\u{1F3FE}", 'CHARACTER_PERSON_TIPPING_HAND_DARK_SKIN_TONE' => "\u{1F481}\u{1F3FF}", 'CHARACTER_MAN_TIPPING_HAND' => "\u{1F481}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_TIPPING_HAND_LIGHT_SKIN_TONE' => "\u{1F481}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_TIPPING_HAND_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F481}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_TIPPING_HAND_MEDIUM_SKIN_TONE' => "\u{1F481}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_TIPPING_HAND_MEDIUM_DARK_SKIN_TONE' => "\u{1F481}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_TIPPING_HAND_DARK_SKIN_TONE' => "\u{1F481}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_TIPPING_HAND' => "\u{1F481}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_TIPPING_HAND_LIGHT_SKIN_TONE' => "\u{1F481}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_TIPPING_HAND_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F481}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_TIPPING_HAND_MEDIUM_SKIN_TONE' => "\u{1F481}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_TIPPING_HAND_MEDIUM_DARK_SKIN_TONE' => "\u{1F481}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_TIPPING_HAND_DARK_SKIN_TONE' => "\u{1F481}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PERSON_RAISING_HAND' => "\u{1F64B}", 'CHARACTER_PERSON_RAISING_HAND_LIGHT_SKIN_TONE' => "\u{1F64B}\u{1F3FB}", 'CHARACTER_PERSON_RAISING_HAND_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F64B}\u{1F3FC}", 'CHARACTER_PERSON_RAISING_HAND_MEDIUM_SKIN_TONE' => "\u{1F64B}\u{1F3FD}", 'CHARACTER_PERSON_RAISING_HAND_MEDIUM_DARK_SKIN_TONE' => "\u{1F64B}\u{1F3FE}", 'CHARACTER_PERSON_RAISING_HAND_DARK_SKIN_TONE' => "\u{1F64B}\u{1F3FF}", 'CHARACTER_MAN_RAISING_HAND' => "\u{1F64B}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_RAISING_HAND_LIGHT_SKIN_TONE' => "\u{1F64B}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_RAISING_HAND_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F64B}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_RAISING_HAND_MEDIUM_SKIN_TONE' => "\u{1F64B}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_RAISING_HAND_MEDIUM_DARK_SKIN_TONE' => "\u{1F64B}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_RAISING_HAND_DARK_SKIN_TONE' => "\u{1F64B}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_RAISING_HAND' => "\u{1F64B}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_RAISING_HAND_LIGHT_SKIN_TONE' => "\u{1F64B}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_RAISING_HAND_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F64B}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_RAISING_HAND_MEDIUM_SKIN_TONE' => "\u{1F64B}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_RAISING_HAND_MEDIUM_DARK_SKIN_TONE' => "\u{1F64B}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_RAISING_HAND_DARK_SKIN_TONE' => "\u{1F64B}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PERSON_BOWING' => "\u{1F647}", 'CHARACTER_PERSON_BOWING_LIGHT_SKIN_TONE' => "\u{1F647}\u{1F3FB}", 'CHARACTER_PERSON_BOWING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F647}\u{1F3FC}", 'CHARACTER_PERSON_BOWING_MEDIUM_SKIN_TONE' => "\u{1F647}\u{1F3FD}", 'CHARACTER_PERSON_BOWING_MEDIUM_DARK_SKIN_TONE' => "\u{1F647}\u{1F3FE}", 'CHARACTER_PERSON_BOWING_DARK_SKIN_TONE' => "\u{1F647}\u{1F3FF}", 'CHARACTER_MAN_BOWING' => "\u{1F647}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_BOWING_LIGHT_SKIN_TONE' => "\u{1F647}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_BOWING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F647}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_BOWING_MEDIUM_SKIN_TONE' => "\u{1F647}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_BOWING_MEDIUM_DARK_SKIN_TONE' => "\u{1F647}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_BOWING_DARK_SKIN_TONE' => "\u{1F647}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_BOWING' => "\u{1F647}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_BOWING_LIGHT_SKIN_TONE' => "\u{1F647}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_BOWING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F647}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_BOWING_MEDIUM_SKIN_TONE' => "\u{1F647}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_BOWING_MEDIUM_DARK_SKIN_TONE' => "\u{1F647}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_BOWING_DARK_SKIN_TONE' => "\u{1F647}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PERSON_FACEPALMING' => "\u{1F926}", 'CHARACTER_PERSON_FACEPALMING_LIGHT_SKIN_TONE' => "\u{1F926}\u{1F3FB}", 'CHARACTER_PERSON_FACEPALMING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F926}\u{1F3FC}", 'CHARACTER_PERSON_FACEPALMING_MEDIUM_SKIN_TONE' => "\u{1F926}\u{1F3FD}", 'CHARACTER_PERSON_FACEPALMING_MEDIUM_DARK_SKIN_TONE' => "\u{1F926}\u{1F3FE}", 'CHARACTER_PERSON_FACEPALMING_DARK_SKIN_TONE' => "\u{1F926}\u{1F3FF}", 'CHARACTER_MAN_FACEPALMING' => "\u{1F926}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_FACEPALMING_LIGHT_SKIN_TONE' => "\u{1F926}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_FACEPALMING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F926}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_FACEPALMING_MEDIUM_SKIN_TONE' => "\u{1F926}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_FACEPALMING_MEDIUM_DARK_SKIN_TONE' => "\u{1F926}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_FACEPALMING_DARK_SKIN_TONE' => "\u{1F926}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_FACEPALMING' => "\u{1F926}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_FACEPALMING_LIGHT_SKIN_TONE' => "\u{1F926}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_FACEPALMING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F926}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_FACEPALMING_MEDIUM_SKIN_TONE' => "\u{1F926}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_FACEPALMING_MEDIUM_DARK_SKIN_TONE' => "\u{1F926}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_FACEPALMING_DARK_SKIN_TONE' => "\u{1F926}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PERSON_SHRUGGING' => "\u{1F937}", 'CHARACTER_PERSON_SHRUGGING_LIGHT_SKIN_TONE' => "\u{1F937}\u{1F3FB}", 'CHARACTER_PERSON_SHRUGGING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F937}\u{1F3FC}", 'CHARACTER_PERSON_SHRUGGING_MEDIUM_SKIN_TONE' => "\u{1F937}\u{1F3FD}", 'CHARACTER_PERSON_SHRUGGING_MEDIUM_DARK_SKIN_TONE' => "\u{1F937}\u{1F3FE}", 'CHARACTER_PERSON_SHRUGGING_DARK_SKIN_TONE' => "\u{1F937}\u{1F3FF}", 'CHARACTER_MAN_SHRUGGING' => "\u{1F937}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SHRUGGING_LIGHT_SKIN_TONE' => "\u{1F937}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SHRUGGING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F937}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SHRUGGING_MEDIUM_SKIN_TONE' => "\u{1F937}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SHRUGGING_MEDIUM_DARK_SKIN_TONE' => "\u{1F937}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SHRUGGING_DARK_SKIN_TONE' => "\u{1F937}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_SHRUGGING' => "\u{1F937}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SHRUGGING_LIGHT_SKIN_TONE' => "\u{1F937}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SHRUGGING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F937}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SHRUGGING_MEDIUM_SKIN_TONE' => "\u{1F937}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SHRUGGING_MEDIUM_DARK_SKIN_TONE' => "\u{1F937}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SHRUGGING_DARK_SKIN_TONE' => "\u{1F937}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PERSON_GETTING_MASSAGE' => "\u{1F486}", 'CHARACTER_PERSON_GETTING_MASSAGE_LIGHT_SKIN_TONE' => "\u{1F486}\u{1F3FB}", 'CHARACTER_PERSON_GETTING_MASSAGE_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F486}\u{1F3FC}", 'CHARACTER_PERSON_GETTING_MASSAGE_MEDIUM_SKIN_TONE' => "\u{1F486}\u{1F3FD}", 'CHARACTER_PERSON_GETTING_MASSAGE_MEDIUM_DARK_SKIN_TONE' => "\u{1F486}\u{1F3FE}", 'CHARACTER_PERSON_GETTING_MASSAGE_DARK_SKIN_TONE' => "\u{1F486}\u{1F3FF}", 'CHARACTER_MAN_GETTING_MASSAGE' => "\u{1F486}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GETTING_MASSAGE_LIGHT_SKIN_TONE' => "\u{1F486}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GETTING_MASSAGE_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F486}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GETTING_MASSAGE_MEDIUM_SKIN_TONE' => "\u{1F486}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GETTING_MASSAGE_MEDIUM_DARK_SKIN_TONE' => "\u{1F486}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GETTING_MASSAGE_DARK_SKIN_TONE' => "\u{1F486}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_GETTING_MASSAGE' => "\u{1F486}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GETTING_MASSAGE_LIGHT_SKIN_TONE' => "\u{1F486}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GETTING_MASSAGE_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F486}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GETTING_MASSAGE_MEDIUM_SKIN_TONE' => "\u{1F486}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GETTING_MASSAGE_MEDIUM_DARK_SKIN_TONE' => "\u{1F486}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GETTING_MASSAGE_DARK_SKIN_TONE' => "\u{1F486}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PERSON_GETTING_HAIRCUT' => "\u{1F487}", 'CHARACTER_PERSON_GETTING_HAIRCUT_LIGHT_SKIN_TONE' => "\u{1F487}\u{1F3FB}", 'CHARACTER_PERSON_GETTING_HAIRCUT_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F487}\u{1F3FC}", 'CHARACTER_PERSON_GETTING_HAIRCUT_MEDIUM_SKIN_TONE' => "\u{1F487}\u{1F3FD}", 'CHARACTER_PERSON_GETTING_HAIRCUT_MEDIUM_DARK_SKIN_TONE' => "\u{1F487}\u{1F3FE}", 'CHARACTER_PERSON_GETTING_HAIRCUT_DARK_SKIN_TONE' => "\u{1F487}\u{1F3FF}", 'CHARACTER_MAN_GETTING_HAIRCUT' => "\u{1F487}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GETTING_HAIRCUT_LIGHT_SKIN_TONE' => "\u{1F487}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GETTING_HAIRCUT_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F487}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GETTING_HAIRCUT_MEDIUM_SKIN_TONE' => "\u{1F487}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GETTING_HAIRCUT_MEDIUM_DARK_SKIN_TONE' => "\u{1F487}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GETTING_HAIRCUT_DARK_SKIN_TONE' => "\u{1F487}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_GETTING_HAIRCUT' => "\u{1F487}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GETTING_HAIRCUT_LIGHT_SKIN_TONE' => "\u{1F487}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GETTING_HAIRCUT_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F487}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GETTING_HAIRCUT_MEDIUM_SKIN_TONE' => "\u{1F487}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GETTING_HAIRCUT_MEDIUM_DARK_SKIN_TONE' => "\u{1F487}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GETTING_HAIRCUT_DARK_SKIN_TONE' => "\u{1F487}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PERSON_WALKING' => "\u{1F6B6}", 'CHARACTER_PERSON_WALKING_LIGHT_SKIN_TONE' => "\u{1F6B6}\u{1F3FB}", 'CHARACTER_PERSON_WALKING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F6B6}\u{1F3FC}", 'CHARACTER_PERSON_WALKING_MEDIUM_SKIN_TONE' => "\u{1F6B6}\u{1F3FD}", 'CHARACTER_PERSON_WALKING_MEDIUM_DARK_SKIN_TONE' => "\u{1F6B6}\u{1F3FE}", 'CHARACTER_PERSON_WALKING_DARK_SKIN_TONE' => "\u{1F6B6}\u{1F3FF}", 'CHARACTER_MAN_WALKING' => "\u{1F6B6}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_WALKING_LIGHT_SKIN_TONE' => "\u{1F6B6}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_WALKING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F6B6}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_WALKING_MEDIUM_SKIN_TONE' => "\u{1F6B6}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_WALKING_MEDIUM_DARK_SKIN_TONE' => "\u{1F6B6}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_WALKING_DARK_SKIN_TONE' => "\u{1F6B6}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_WALKING' => "\u{1F6B6}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_WALKING_LIGHT_SKIN_TONE' => "\u{1F6B6}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_WALKING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F6B6}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_WALKING_MEDIUM_SKIN_TONE' => "\u{1F6B6}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_WALKING_MEDIUM_DARK_SKIN_TONE' => "\u{1F6B6}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_WALKING_DARK_SKIN_TONE' => "\u{1F6B6}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PERSON_RUNNING' => "\u{1F3C3}", 'CHARACTER_PERSON_RUNNING_LIGHT_SKIN_TONE' => "\u{1F3C3}\u{1F3FB}", 'CHARACTER_PERSON_RUNNING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F3C3}\u{1F3FC}", 'CHARACTER_PERSON_RUNNING_MEDIUM_SKIN_TONE' => "\u{1F3C3}\u{1F3FD}", 'CHARACTER_PERSON_RUNNING_MEDIUM_DARK_SKIN_TONE' => "\u{1F3C3}\u{1F3FE}", 'CHARACTER_PERSON_RUNNING_DARK_SKIN_TONE' => "\u{1F3C3}\u{1F3FF}", 'CHARACTER_MAN_RUNNING' => "\u{1F3C3}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_RUNNING_LIGHT_SKIN_TONE' => "\u{1F3C3}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_RUNNING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F3C3}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_RUNNING_MEDIUM_SKIN_TONE' => "\u{1F3C3}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_RUNNING_MEDIUM_DARK_SKIN_TONE' => "\u{1F3C3}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_RUNNING_DARK_SKIN_TONE' => "\u{1F3C3}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_RUNNING' => "\u{1F3C3}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_RUNNING_LIGHT_SKIN_TONE' => "\u{1F3C3}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_RUNNING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F3C3}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_RUNNING_MEDIUM_SKIN_TONE' => "\u{1F3C3}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_RUNNING_MEDIUM_DARK_SKIN_TONE' => "\u{1F3C3}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_RUNNING_DARK_SKIN_TONE' => "\u{1F3C3}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_DANCING' => "\u{1F483}", 'CHARACTER_WOMAN_DANCING_LIGHT_SKIN_TONE' => "\u{1F483}\u{1F3FB}", 'CHARACTER_WOMAN_DANCING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F483}\u{1F3FC}", 'CHARACTER_WOMAN_DANCING_MEDIUM_SKIN_TONE' => "\u{1F483}\u{1F3FD}", 'CHARACTER_WOMAN_DANCING_MEDIUM_DARK_SKIN_TONE' => "\u{1F483}\u{1F3FE}", 'CHARACTER_WOMAN_DANCING_DARK_SKIN_TONE' => "\u{1F483}\u{1F3FF}", 'CHARACTER_MAN_DANCING' => "\u{1F57A}", 'CHARACTER_MAN_DANCING_LIGHT_SKIN_TONE' => "\u{1F57A}\u{1F3FB}", 'CHARACTER_MAN_DANCING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F57A}\u{1F3FC}", 'CHARACTER_MAN_DANCING_MEDIUM_SKIN_TONE' => "\u{1F57A}\u{1F3FD}", 'CHARACTER_MAN_DANCING_MEDIUM_DARK_SKIN_TONE' => "\u{1F57A}\u{1F3FE}", 'CHARACTER_MAN_DANCING_DARK_SKIN_TONE' => "\u{1F57A}\u{1F3FF}", 'CHARACTER_PEOPLE_WITH_BUNNY_EARS' => "\u{1F46F}", 'CHARACTER_MEN_WITH_BUNNY_EARS' => "\u{1F46F}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMEN_WITH_BUNNY_EARS' => "\u{1F46F}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PERSON_IN_STEAMY_ROOM' => "\u{1F9D6}", 'CHARACTER_PERSON_IN_STEAMY_ROOM_LIGHT_SKIN_TONE' => "\u{1F9D6}\u{1F3FB}", 'CHARACTER_PERSON_IN_STEAMY_ROOM_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9D6}\u{1F3FC}", 'CHARACTER_PERSON_IN_STEAMY_ROOM_MEDIUM_SKIN_TONE' => "\u{1F9D6}\u{1F3FD}", 'CHARACTER_PERSON_IN_STEAMY_ROOM_MEDIUM_DARK_SKIN_TONE' => "\u{1F9D6}\u{1F3FE}", 'CHARACTER_PERSON_IN_STEAMY_ROOM_DARK_SKIN_TONE' => "\u{1F9D6}\u{1F3FF}", 'CHARACTER_WOMAN_IN_STEAMY_ROOM' => "\u{1F9D6}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_IN_STEAMY_ROOM_LIGHT_SKIN_TONE' => "\u{1F9D6}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_IN_STEAMY_ROOM_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9D6}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_IN_STEAMY_ROOM_MEDIUM_SKIN_TONE' => "\u{1F9D6}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_IN_STEAMY_ROOM_MEDIUM_DARK_SKIN_TONE' => "\u{1F9D6}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_IN_STEAMY_ROOM_DARK_SKIN_TONE' => "\u{1F9D6}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_MAN_IN_STEAMY_ROOM' => "\u{1F9D6}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_IN_STEAMY_ROOM_LIGHT_SKIN_TONE' => "\u{1F9D6}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_IN_STEAMY_ROOM_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9D6}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_IN_STEAMY_ROOM_MEDIUM_SKIN_TONE' => "\u{1F9D6}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_IN_STEAMY_ROOM_MEDIUM_DARK_SKIN_TONE' => "\u{1F9D6}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_IN_STEAMY_ROOM_DARK_SKIN_TONE' => "\u{1F9D6}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_PERSON_CLIMBING' => "\u{1F9D7}", 'CHARACTER_PERSON_CLIMBING_LIGHT_SKIN_TONE' => "\u{1F9D7}\u{1F3FB}", 'CHARACTER_PERSON_CLIMBING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9D7}\u{1F3FC}", 'CHARACTER_PERSON_CLIMBING_MEDIUM_SKIN_TONE' => "\u{1F9D7}\u{1F3FD}", 'CHARACTER_PERSON_CLIMBING_MEDIUM_DARK_SKIN_TONE' => "\u{1F9D7}\u{1F3FE}", 'CHARACTER_PERSON_CLIMBING_DARK_SKIN_TONE' => "\u{1F9D7}\u{1F3FF}", 'CHARACTER_WOMAN_CLIMBING' => "\u{1F9D7}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_CLIMBING_LIGHT_SKIN_TONE' => "\u{1F9D7}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_CLIMBING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9D7}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_CLIMBING_MEDIUM_SKIN_TONE' => "\u{1F9D7}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_CLIMBING_MEDIUM_DARK_SKIN_TONE' => "\u{1F9D7}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_CLIMBING_DARK_SKIN_TONE' => "\u{1F9D7}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_MAN_CLIMBING' => "\u{1F9D7}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_CLIMBING_LIGHT_SKIN_TONE' => "\u{1F9D7}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_CLIMBING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9D7}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_CLIMBING_MEDIUM_SKIN_TONE' => "\u{1F9D7}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_CLIMBING_MEDIUM_DARK_SKIN_TONE' => "\u{1F9D7}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_CLIMBING_DARK_SKIN_TONE' => "\u{1F9D7}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_PERSON_IN_LOTUS_POSITION' => "\u{1F9D8}", 'CHARACTER_PERSON_IN_LOTUS_POSITION_LIGHT_SKIN_TONE' => "\u{1F9D8}\u{1F3FB}", 'CHARACTER_PERSON_IN_LOTUS_POSITION_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9D8}\u{1F3FC}", 'CHARACTER_PERSON_IN_LOTUS_POSITION_MEDIUM_SKIN_TONE' => "\u{1F9D8}\u{1F3FD}", 'CHARACTER_PERSON_IN_LOTUS_POSITION_MEDIUM_DARK_SKIN_TONE' => "\u{1F9D8}\u{1F3FE}", 'CHARACTER_PERSON_IN_LOTUS_POSITION_DARK_SKIN_TONE' => "\u{1F9D8}\u{1F3FF}", 'CHARACTER_WOMAN_IN_LOTUS_POSITION' => "\u{1F9D8}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_IN_LOTUS_POSITION_LIGHT_SKIN_TONE' => "\u{1F9D8}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_IN_LOTUS_POSITION_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9D8}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_IN_LOTUS_POSITION_MEDIUM_SKIN_TONE' => "\u{1F9D8}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_IN_LOTUS_POSITION_MEDIUM_DARK_SKIN_TONE' => "\u{1F9D8}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_IN_LOTUS_POSITION_DARK_SKIN_TONE' => "\u{1F9D8}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_MAN_IN_LOTUS_POSITION' => "\u{1F9D8}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_IN_LOTUS_POSITION_LIGHT_SKIN_TONE' => "\u{1F9D8}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_IN_LOTUS_POSITION_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9D8}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_IN_LOTUS_POSITION_MEDIUM_SKIN_TONE' => "\u{1F9D8}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_IN_LOTUS_POSITION_MEDIUM_DARK_SKIN_TONE' => "\u{1F9D8}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_IN_LOTUS_POSITION_DARK_SKIN_TONE' => "\u{1F9D8}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_PERSON_TAKING_BATH' => "\u{1F6C0}", 'CHARACTER_PERSON_TAKING_BATH_LIGHT_SKIN_TONE' => "\u{1F6C0}\u{1F3FB}", 'CHARACTER_PERSON_TAKING_BATH_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F6C0}\u{1F3FC}", 'CHARACTER_PERSON_TAKING_BATH_MEDIUM_SKIN_TONE' => "\u{1F6C0}\u{1F3FD}", 'CHARACTER_PERSON_TAKING_BATH_MEDIUM_DARK_SKIN_TONE' => "\u{1F6C0}\u{1F3FE}", 'CHARACTER_PERSON_TAKING_BATH_DARK_SKIN_TONE' => "\u{1F6C0}\u{1F3FF}", 'CHARACTER_PERSON_IN_BED' => "\u{1F6CC}", 'CHARACTER_PERSON_IN_BED_LIGHT_SKIN_TONE' => "\u{1F6CC}\u{1F3FB}", 'CHARACTER_PERSON_IN_BED_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F6CC}\u{1F3FC}", 'CHARACTER_PERSON_IN_BED_MEDIUM_SKIN_TONE' => "\u{1F6CC}\u{1F3FD}", 'CHARACTER_PERSON_IN_BED_MEDIUM_DARK_SKIN_TONE' => "\u{1F6CC}\u{1F3FE}", 'CHARACTER_PERSON_IN_BED_DARK_SKIN_TONE' => "\u{1F6CC}\u{1F3FF}", 'CHARACTER_MAN_IN_SUIT_LEVITATING' => "\u{1F574}\u{FE0F}", 'CHARACTER_MAN_IN_SUIT_LEVITATING_LIGHT_SKIN_TONE' => "\u{1F574}\u{1F3FB}", 'CHARACTER_MAN_IN_SUIT_LEVITATING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F574}\u{1F3FC}", 'CHARACTER_MAN_IN_SUIT_LEVITATING_MEDIUM_SKIN_TONE' => "\u{1F574}\u{1F3FD}", 'CHARACTER_MAN_IN_SUIT_LEVITATING_MEDIUM_DARK_SKIN_TONE' => "\u{1F574}\u{1F3FE}", 'CHARACTER_MAN_IN_SUIT_LEVITATING_DARK_SKIN_TONE' => "\u{1F574}\u{1F3FF}", 'CHARACTER_SPEAKING_HEAD' => "\u{1F5E3}\u{FE0F}", 'CHARACTER_BUST_IN_SILHOUETTE' => "\u{1F464}", 'CHARACTER_BUSTS_IN_SILHOUETTE' => "\u{1F465}", 'CHARACTER_PERSON_FENCING' => "\u{1F93A}", 'CHARACTER_HORSE_RACING' => "\u{1F3C7}", 'CHARACTER_HORSE_RACING_LIGHT_SKIN_TONE' => "\u{1F3C7}\u{1F3FB}", 'CHARACTER_HORSE_RACING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F3C7}\u{1F3FC}", 'CHARACTER_HORSE_RACING_MEDIUM_SKIN_TONE' => "\u{1F3C7}\u{1F3FD}", 'CHARACTER_HORSE_RACING_MEDIUM_DARK_SKIN_TONE' => "\u{1F3C7}\u{1F3FE}", 'CHARACTER_HORSE_RACING_DARK_SKIN_TONE' => "\u{1F3C7}\u{1F3FF}", 'CHARACTER_SKIER' => "\u{26F7}\u{FE0F}", 'CHARACTER_SNOWBOARDER' => "\u{1F3C2}", 'CHARACTER_SNOWBOARDER_LIGHT_SKIN_TONE' => "\u{1F3C2}\u{1F3FB}", 'CHARACTER_SNOWBOARDER_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F3C2}\u{1F3FC}", 'CHARACTER_SNOWBOARDER_MEDIUM_SKIN_TONE' => "\u{1F3C2}\u{1F3FD}", 'CHARACTER_SNOWBOARDER_MEDIUM_DARK_SKIN_TONE' => "\u{1F3C2}\u{1F3FE}", 'CHARACTER_SNOWBOARDER_DARK_SKIN_TONE' => "\u{1F3C2}\u{1F3FF}", 'CHARACTER_PERSON_GOLFING' => "\u{1F3CC}\u{FE0F}", 'CHARACTER_PERSON_GOLFING_LIGHT_SKIN_TONE' => "\u{1F3CC}\u{1F3FB}", 'CHARACTER_PERSON_GOLFING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F3CC}\u{1F3FC}", 'CHARACTER_PERSON_GOLFING_MEDIUM_SKIN_TONE' => "\u{1F3CC}\u{1F3FD}", 'CHARACTER_PERSON_GOLFING_MEDIUM_DARK_SKIN_TONE' => "\u{1F3CC}\u{1F3FE}", 'CHARACTER_PERSON_GOLFING_DARK_SKIN_TONE' => "\u{1F3CC}\u{1F3FF}", 'CHARACTER_MAN_GOLFING' => "\u{1F3CC}\u{FE0F}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GOLFING_LIGHT_SKIN_TONE' => "\u{1F3CC}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GOLFING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F3CC}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GOLFING_MEDIUM_SKIN_TONE' => "\u{1F3CC}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GOLFING_MEDIUM_DARK_SKIN_TONE' => "\u{1F3CC}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_GOLFING_DARK_SKIN_TONE' => "\u{1F3CC}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_GOLFING' => "\u{1F3CC}\u{FE0F}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GOLFING_LIGHT_SKIN_TONE' => "\u{1F3CC}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GOLFING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F3CC}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GOLFING_MEDIUM_SKIN_TONE' => "\u{1F3CC}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GOLFING_MEDIUM_DARK_SKIN_TONE' => "\u{1F3CC}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_GOLFING_DARK_SKIN_TONE' => "\u{1F3CC}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PERSON_SURFING' => "\u{1F3C4}", 'CHARACTER_PERSON_SURFING_LIGHT_SKIN_TONE' => "\u{1F3C4}\u{1F3FB}", 'CHARACTER_PERSON_SURFING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F3C4}\u{1F3FC}", 'CHARACTER_PERSON_SURFING_MEDIUM_SKIN_TONE' => "\u{1F3C4}\u{1F3FD}", 'CHARACTER_PERSON_SURFING_MEDIUM_DARK_SKIN_TONE' => "\u{1F3C4}\u{1F3FE}", 'CHARACTER_PERSON_SURFING_DARK_SKIN_TONE' => "\u{1F3C4}\u{1F3FF}", 'CHARACTER_MAN_SURFING' => "\u{1F3C4}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SURFING_LIGHT_SKIN_TONE' => "\u{1F3C4}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SURFING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F3C4}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SURFING_MEDIUM_SKIN_TONE' => "\u{1F3C4}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SURFING_MEDIUM_DARK_SKIN_TONE' => "\u{1F3C4}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SURFING_DARK_SKIN_TONE' => "\u{1F3C4}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_SURFING' => "\u{1F3C4}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SURFING_LIGHT_SKIN_TONE' => "\u{1F3C4}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SURFING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F3C4}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SURFING_MEDIUM_SKIN_TONE' => "\u{1F3C4}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SURFING_MEDIUM_DARK_SKIN_TONE' => "\u{1F3C4}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SURFING_DARK_SKIN_TONE' => "\u{1F3C4}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PERSON_ROWING_BOAT' => "\u{1F6A3}", 'CHARACTER_PERSON_ROWING_BOAT_LIGHT_SKIN_TONE' => "\u{1F6A3}\u{1F3FB}", 'CHARACTER_PERSON_ROWING_BOAT_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F6A3}\u{1F3FC}", 'CHARACTER_PERSON_ROWING_BOAT_MEDIUM_SKIN_TONE' => "\u{1F6A3}\u{1F3FD}", 'CHARACTER_PERSON_ROWING_BOAT_MEDIUM_DARK_SKIN_TONE' => "\u{1F6A3}\u{1F3FE}", 'CHARACTER_PERSON_ROWING_BOAT_DARK_SKIN_TONE' => "\u{1F6A3}\u{1F3FF}", 'CHARACTER_MAN_ROWING_BOAT' => "\u{1F6A3}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_ROWING_BOAT_LIGHT_SKIN_TONE' => "\u{1F6A3}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_ROWING_BOAT_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F6A3}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_ROWING_BOAT_MEDIUM_SKIN_TONE' => "\u{1F6A3}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_ROWING_BOAT_MEDIUM_DARK_SKIN_TONE' => "\u{1F6A3}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_ROWING_BOAT_DARK_SKIN_TONE' => "\u{1F6A3}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_ROWING_BOAT' => "\u{1F6A3}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_ROWING_BOAT_LIGHT_SKIN_TONE' => "\u{1F6A3}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_ROWING_BOAT_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F6A3}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_ROWING_BOAT_MEDIUM_SKIN_TONE' => "\u{1F6A3}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_ROWING_BOAT_MEDIUM_DARK_SKIN_TONE' => "\u{1F6A3}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_ROWING_BOAT_DARK_SKIN_TONE' => "\u{1F6A3}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PERSON_SWIMMING' => "\u{1F3CA}", 'CHARACTER_PERSON_SWIMMING_LIGHT_SKIN_TONE' => "\u{1F3CA}\u{1F3FB}", 'CHARACTER_PERSON_SWIMMING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F3CA}\u{1F3FC}", 'CHARACTER_PERSON_SWIMMING_MEDIUM_SKIN_TONE' => "\u{1F3CA}\u{1F3FD}", 'CHARACTER_PERSON_SWIMMING_MEDIUM_DARK_SKIN_TONE' => "\u{1F3CA}\u{1F3FE}", 'CHARACTER_PERSON_SWIMMING_DARK_SKIN_TONE' => "\u{1F3CA}\u{1F3FF}", 'CHARACTER_MAN_SWIMMING' => "\u{1F3CA}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SWIMMING_LIGHT_SKIN_TONE' => "\u{1F3CA}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SWIMMING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F3CA}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SWIMMING_MEDIUM_SKIN_TONE' => "\u{1F3CA}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SWIMMING_MEDIUM_DARK_SKIN_TONE' => "\u{1F3CA}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_SWIMMING_DARK_SKIN_TONE' => "\u{1F3CA}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_SWIMMING' => "\u{1F3CA}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SWIMMING_LIGHT_SKIN_TONE' => "\u{1F3CA}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SWIMMING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F3CA}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SWIMMING_MEDIUM_SKIN_TONE' => "\u{1F3CA}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SWIMMING_MEDIUM_DARK_SKIN_TONE' => "\u{1F3CA}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_SWIMMING_DARK_SKIN_TONE' => "\u{1F3CA}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PERSON_BOUNCING_BALL' => "\u{26F9}\u{FE0F}", 'CHARACTER_PERSON_BOUNCING_BALL_LIGHT_SKIN_TONE' => "\u{26F9}\u{1F3FB}", 'CHARACTER_PERSON_BOUNCING_BALL_MEDIUM_LIGHT_SKIN_TONE' => "\u{26F9}\u{1F3FC}", 'CHARACTER_PERSON_BOUNCING_BALL_MEDIUM_SKIN_TONE' => "\u{26F9}\u{1F3FD}", 'CHARACTER_PERSON_BOUNCING_BALL_MEDIUM_DARK_SKIN_TONE' => "\u{26F9}\u{1F3FE}", 'CHARACTER_PERSON_BOUNCING_BALL_DARK_SKIN_TONE' => "\u{26F9}\u{1F3FF}", 'CHARACTER_MAN_BOUNCING_BALL' => "\u{26F9}\u{FE0F}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_BOUNCING_BALL_LIGHT_SKIN_TONE' => "\u{26F9}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_BOUNCING_BALL_MEDIUM_LIGHT_SKIN_TONE' => "\u{26F9}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_BOUNCING_BALL_MEDIUM_SKIN_TONE' => "\u{26F9}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_BOUNCING_BALL_MEDIUM_DARK_SKIN_TONE' => "\u{26F9}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_BOUNCING_BALL_DARK_SKIN_TONE' => "\u{26F9}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_BOUNCING_BALL' => "\u{26F9}\u{FE0F}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_BOUNCING_BALL_LIGHT_SKIN_TONE' => "\u{26F9}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_BOUNCING_BALL_MEDIUM_LIGHT_SKIN_TONE' => "\u{26F9}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_BOUNCING_BALL_MEDIUM_SKIN_TONE' => "\u{26F9}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_BOUNCING_BALL_MEDIUM_DARK_SKIN_TONE' => "\u{26F9}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_BOUNCING_BALL_DARK_SKIN_TONE' => "\u{26F9}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PERSON_LIFTING_WEIGHTS' => "\u{1F3CB}\u{FE0F}", 'CHARACTER_PERSON_LIFTING_WEIGHTS_LIGHT_SKIN_TONE' => "\u{1F3CB}\u{1F3FB}", 'CHARACTER_PERSON_LIFTING_WEIGHTS_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F3CB}\u{1F3FC}", 'CHARACTER_PERSON_LIFTING_WEIGHTS_MEDIUM_SKIN_TONE' => "\u{1F3CB}\u{1F3FD}", 'CHARACTER_PERSON_LIFTING_WEIGHTS_MEDIUM_DARK_SKIN_TONE' => "\u{1F3CB}\u{1F3FE}", 'CHARACTER_PERSON_LIFTING_WEIGHTS_DARK_SKIN_TONE' => "\u{1F3CB}\u{1F3FF}", 'CHARACTER_MAN_LIFTING_WEIGHTS' => "\u{1F3CB}\u{FE0F}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_LIFTING_WEIGHTS_LIGHT_SKIN_TONE' => "\u{1F3CB}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_LIFTING_WEIGHTS_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F3CB}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_LIFTING_WEIGHTS_MEDIUM_SKIN_TONE' => "\u{1F3CB}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_LIFTING_WEIGHTS_MEDIUM_DARK_SKIN_TONE' => "\u{1F3CB}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_LIFTING_WEIGHTS_DARK_SKIN_TONE' => "\u{1F3CB}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_LIFTING_WEIGHTS' => "\u{1F3CB}\u{FE0F}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_LIFTING_WEIGHTS_LIGHT_SKIN_TONE' => "\u{1F3CB}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_LIFTING_WEIGHTS_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F3CB}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_LIFTING_WEIGHTS_MEDIUM_SKIN_TONE' => "\u{1F3CB}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_LIFTING_WEIGHTS_MEDIUM_DARK_SKIN_TONE' => "\u{1F3CB}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_LIFTING_WEIGHTS_DARK_SKIN_TONE' => "\u{1F3CB}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PERSON_BIKING' => "\u{1F6B4}", 'CHARACTER_PERSON_BIKING_LIGHT_SKIN_TONE' => "\u{1F6B4}\u{1F3FB}", 'CHARACTER_PERSON_BIKING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F6B4}\u{1F3FC}", 'CHARACTER_PERSON_BIKING_MEDIUM_SKIN_TONE' => "\u{1F6B4}\u{1F3FD}", 'CHARACTER_PERSON_BIKING_MEDIUM_DARK_SKIN_TONE' => "\u{1F6B4}\u{1F3FE}", 'CHARACTER_PERSON_BIKING_DARK_SKIN_TONE' => "\u{1F6B4}\u{1F3FF}", 'CHARACTER_MAN_BIKING' => "\u{1F6B4}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_BIKING_LIGHT_SKIN_TONE' => "\u{1F6B4}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_BIKING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F6B4}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_BIKING_MEDIUM_SKIN_TONE' => "\u{1F6B4}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_BIKING_MEDIUM_DARK_SKIN_TONE' => "\u{1F6B4}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_BIKING_DARK_SKIN_TONE' => "\u{1F6B4}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_BIKING' => "\u{1F6B4}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_BIKING_LIGHT_SKIN_TONE' => "\u{1F6B4}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_BIKING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F6B4}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_BIKING_MEDIUM_SKIN_TONE' => "\u{1F6B4}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_BIKING_MEDIUM_DARK_SKIN_TONE' => "\u{1F6B4}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_BIKING_DARK_SKIN_TONE' => "\u{1F6B4}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PERSON_MOUNTAIN_BIKING' => "\u{1F6B5}", 'CHARACTER_PERSON_MOUNTAIN_BIKING_LIGHT_SKIN_TONE' => "\u{1F6B5}\u{1F3FB}", 'CHARACTER_PERSON_MOUNTAIN_BIKING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F6B5}\u{1F3FC}", 'CHARACTER_PERSON_MOUNTAIN_BIKING_MEDIUM_SKIN_TONE' => "\u{1F6B5}\u{1F3FD}", 'CHARACTER_PERSON_MOUNTAIN_BIKING_MEDIUM_DARK_SKIN_TONE' => "\u{1F6B5}\u{1F3FE}", 'CHARACTER_PERSON_MOUNTAIN_BIKING_DARK_SKIN_TONE' => "\u{1F6B5}\u{1F3FF}", 'CHARACTER_MAN_MOUNTAIN_BIKING' => "\u{1F6B5}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_MOUNTAIN_BIKING_LIGHT_SKIN_TONE' => "\u{1F6B5}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_MOUNTAIN_BIKING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F6B5}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_MOUNTAIN_BIKING_MEDIUM_SKIN_TONE' => "\u{1F6B5}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_MOUNTAIN_BIKING_MEDIUM_DARK_SKIN_TONE' => "\u{1F6B5}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_MOUNTAIN_BIKING_DARK_SKIN_TONE' => "\u{1F6B5}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_MOUNTAIN_BIKING' => "\u{1F6B5}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_MOUNTAIN_BIKING_LIGHT_SKIN_TONE' => "\u{1F6B5}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_MOUNTAIN_BIKING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F6B5}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_MOUNTAIN_BIKING_MEDIUM_SKIN_TONE' => "\u{1F6B5}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_MOUNTAIN_BIKING_MEDIUM_DARK_SKIN_TONE' => "\u{1F6B5}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_MOUNTAIN_BIKING_DARK_SKIN_TONE' => "\u{1F6B5}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_RACING_CAR' => "\u{1F3CE}\u{FE0F}", 'CHARACTER_MOTORCYCLE' => "\u{1F3CD}\u{FE0F}", 'CHARACTER_PERSON_CARTWHEELING' => "\u{1F938}", 'CHARACTER_PERSON_CARTWHEELING_LIGHT_SKIN_TONE' => "\u{1F938}\u{1F3FB}", 'CHARACTER_PERSON_CARTWHEELING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F938}\u{1F3FC}", 'CHARACTER_PERSON_CARTWHEELING_MEDIUM_SKIN_TONE' => "\u{1F938}\u{1F3FD}", 'CHARACTER_PERSON_CARTWHEELING_MEDIUM_DARK_SKIN_TONE' => "\u{1F938}\u{1F3FE}", 'CHARACTER_PERSON_CARTWHEELING_DARK_SKIN_TONE' => "\u{1F938}\u{1F3FF}", 'CHARACTER_MAN_CARTWHEELING' => "\u{1F938}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_CARTWHEELING_LIGHT_SKIN_TONE' => "\u{1F938}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_CARTWHEELING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F938}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_CARTWHEELING_MEDIUM_SKIN_TONE' => "\u{1F938}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_CARTWHEELING_MEDIUM_DARK_SKIN_TONE' => "\u{1F938}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_CARTWHEELING_DARK_SKIN_TONE' => "\u{1F938}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_CARTWHEELING' => "\u{1F938}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_CARTWHEELING_LIGHT_SKIN_TONE' => "\u{1F938}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_CARTWHEELING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F938}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_CARTWHEELING_MEDIUM_SKIN_TONE' => "\u{1F938}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_CARTWHEELING_MEDIUM_DARK_SKIN_TONE' => "\u{1F938}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_CARTWHEELING_DARK_SKIN_TONE' => "\u{1F938}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PEOPLE_WRESTLING' => "\u{1F93C}", 'CHARACTER_MEN_WRESTLING' => "\u{1F93C}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMEN_WRESTLING' => "\u{1F93C}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PERSON_PLAYING_WATER_POLO' => "\u{1F93D}", 'CHARACTER_PERSON_PLAYING_WATER_POLO_LIGHT_SKIN_TONE' => "\u{1F93D}\u{1F3FB}", 'CHARACTER_PERSON_PLAYING_WATER_POLO_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F93D}\u{1F3FC}", 'CHARACTER_PERSON_PLAYING_WATER_POLO_MEDIUM_SKIN_TONE' => "\u{1F93D}\u{1F3FD}", 'CHARACTER_PERSON_PLAYING_WATER_POLO_MEDIUM_DARK_SKIN_TONE' => "\u{1F93D}\u{1F3FE}", 'CHARACTER_PERSON_PLAYING_WATER_POLO_DARK_SKIN_TONE' => "\u{1F93D}\u{1F3FF}", 'CHARACTER_MAN_PLAYING_WATER_POLO' => "\u{1F93D}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_PLAYING_WATER_POLO_LIGHT_SKIN_TONE' => "\u{1F93D}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_PLAYING_WATER_POLO_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F93D}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_PLAYING_WATER_POLO_MEDIUM_SKIN_TONE' => "\u{1F93D}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_PLAYING_WATER_POLO_MEDIUM_DARK_SKIN_TONE' => "\u{1F93D}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_PLAYING_WATER_POLO_DARK_SKIN_TONE' => "\u{1F93D}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_PLAYING_WATER_POLO' => "\u{1F93D}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_PLAYING_WATER_POLO_LIGHT_SKIN_TONE' => "\u{1F93D}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_PLAYING_WATER_POLO_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F93D}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_PLAYING_WATER_POLO_MEDIUM_SKIN_TONE' => "\u{1F93D}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_PLAYING_WATER_POLO_MEDIUM_DARK_SKIN_TONE' => "\u{1F93D}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_PLAYING_WATER_POLO_DARK_SKIN_TONE' => "\u{1F93D}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PERSON_PLAYING_HANDBALL' => "\u{1F93E}", 'CHARACTER_PERSON_PLAYING_HANDBALL_LIGHT_SKIN_TONE' => "\u{1F93E}\u{1F3FB}", 'CHARACTER_PERSON_PLAYING_HANDBALL_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F93E}\u{1F3FC}", 'CHARACTER_PERSON_PLAYING_HANDBALL_MEDIUM_SKIN_TONE' => "\u{1F93E}\u{1F3FD}", 'CHARACTER_PERSON_PLAYING_HANDBALL_MEDIUM_DARK_SKIN_TONE' => "\u{1F93E}\u{1F3FE}", 'CHARACTER_PERSON_PLAYING_HANDBALL_DARK_SKIN_TONE' => "\u{1F93E}\u{1F3FF}", 'CHARACTER_MAN_PLAYING_HANDBALL' => "\u{1F93E}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_PLAYING_HANDBALL_LIGHT_SKIN_TONE' => "\u{1F93E}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_PLAYING_HANDBALL_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F93E}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_PLAYING_HANDBALL_MEDIUM_SKIN_TONE' => "\u{1F93E}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_PLAYING_HANDBALL_MEDIUM_DARK_SKIN_TONE' => "\u{1F93E}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_PLAYING_HANDBALL_DARK_SKIN_TONE' => "\u{1F93E}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_PLAYING_HANDBALL' => "\u{1F93E}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_PLAYING_HANDBALL_LIGHT_SKIN_TONE' => "\u{1F93E}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_PLAYING_HANDBALL_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F93E}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_PLAYING_HANDBALL_MEDIUM_SKIN_TONE' => "\u{1F93E}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_PLAYING_HANDBALL_MEDIUM_DARK_SKIN_TONE' => "\u{1F93E}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_PLAYING_HANDBALL_DARK_SKIN_TONE' => "\u{1F93E}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_PERSON_JUGGLING' => "\u{1F939}", 'CHARACTER_PERSON_JUGGLING_LIGHT_SKIN_TONE' => "\u{1F939}\u{1F3FB}", 'CHARACTER_PERSON_JUGGLING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F939}\u{1F3FC}", 'CHARACTER_PERSON_JUGGLING_MEDIUM_SKIN_TONE' => "\u{1F939}\u{1F3FD}", 'CHARACTER_PERSON_JUGGLING_MEDIUM_DARK_SKIN_TONE' => "\u{1F939}\u{1F3FE}", 'CHARACTER_PERSON_JUGGLING_DARK_SKIN_TONE' => "\u{1F939}\u{1F3FF}", 'CHARACTER_MAN_JUGGLING' => "\u{1F939}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_JUGGLING_LIGHT_SKIN_TONE' => "\u{1F939}\u{1F3FB}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_JUGGLING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F939}\u{1F3FC}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_JUGGLING_MEDIUM_SKIN_TONE' => "\u{1F939}\u{1F3FD}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_JUGGLING_MEDIUM_DARK_SKIN_TONE' => "\u{1F939}\u{1F3FE}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_MAN_JUGGLING_DARK_SKIN_TONE' => "\u{1F939}\u{1F3FF}\u{200D}\u{2642}\u{FE0F}", 'CHARACTER_WOMAN_JUGGLING' => "\u{1F939}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_JUGGLING_LIGHT_SKIN_TONE' => "\u{1F939}\u{1F3FB}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_JUGGLING_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F939}\u{1F3FC}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_JUGGLING_MEDIUM_SKIN_TONE' => "\u{1F939}\u{1F3FD}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_JUGGLING_MEDIUM_DARK_SKIN_TONE' => "\u{1F939}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_WOMAN_JUGGLING_DARK_SKIN_TONE' => "\u{1F939}\u{1F3FF}\u{200D}\u{2640}\u{FE0F}", 'CHARACTER_MAN_AND_WOMAN_HOLDING_HANDS' => "\u{1F46B}", 'CHARACTER_TWO_MEN_HOLDING_HANDS' => "\u{1F46C}", 'CHARACTER_TWO_WOMEN_HOLDING_HANDS' => "\u{1F46D}", 'CHARACTER_KISS' => "\u{1F48F}", 'CHARACTER_KISS_WOMAN_MAN' => "\u{1F469}\u{200D}\u{2764}\u{FE0F}\u{200D}\u{1F48B}\u{200D}\u{1F468}", 'CHARACTER_KISS_MAN_MAN' => "\u{1F468}\u{200D}\u{2764}\u{FE0F}\u{200D}\u{1F48B}\u{200D}\u{1F468}", 'CHARACTER_KISS_WOMAN_WOMAN' => "\u{1F469}\u{200D}\u{2764}\u{FE0F}\u{200D}\u{1F48B}\u{200D}\u{1F469}", 'CHARACTER_COUPLE_WITH_HEART' => "\u{1F491}", 'CHARACTER_COUPLE_WITH_HEART_WOMAN_MAN' => "\u{1F469}\u{200D}\u{2764}\u{FE0F}\u{200D}\u{1F468}", 'CHARACTER_COUPLE_WITH_HEART_MAN_MAN' => "\u{1F468}\u{200D}\u{2764}\u{FE0F}\u{200D}\u{1F468}", 'CHARACTER_COUPLE_WITH_HEART_WOMAN_WOMAN' => "\u{1F469}\u{200D}\u{2764}\u{FE0F}\u{200D}\u{1F469}", 'CHARACTER_FAMILY' => "\u{1F46A}", 'CHARACTER_FAMILY_MAN_WOMAN_BOY' => "\u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F466}", 'CHARACTER_FAMILY_MAN_WOMAN_GIRL' => "\u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F467}", 'CHARACTER_FAMILY_MAN_WOMAN_GIRL_BOY' => "\u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F467}\u{200D}\u{1F466}", 'CHARACTER_FAMILY_MAN_WOMAN_BOY_BOY' => "\u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F466}\u{200D}\u{1F466}", 'CHARACTER_FAMILY_MAN_WOMAN_GIRL_GIRL' => "\u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F467}\u{200D}\u{1F467}", 'CHARACTER_FAMILY_MAN_MAN_BOY' => "\u{1F468}\u{200D}\u{1F468}\u{200D}\u{1F466}", 'CHARACTER_FAMILY_MAN_MAN_GIRL' => "\u{1F468}\u{200D}\u{1F468}\u{200D}\u{1F467}", 'CHARACTER_FAMILY_MAN_MAN_GIRL_BOY' => "\u{1F468}\u{200D}\u{1F468}\u{200D}\u{1F467}\u{200D}\u{1F466}", 'CHARACTER_FAMILY_MAN_MAN_BOY_BOY' => "\u{1F468}\u{200D}\u{1F468}\u{200D}\u{1F466}\u{200D}\u{1F466}", 'CHARACTER_FAMILY_MAN_MAN_GIRL_GIRL' => "\u{1F468}\u{200D}\u{1F468}\u{200D}\u{1F467}\u{200D}\u{1F467}", 'CHARACTER_FAMILY_WOMAN_WOMAN_BOY' => "\u{1F469}\u{200D}\u{1F469}\u{200D}\u{1F466}", 'CHARACTER_FAMILY_WOMAN_WOMAN_GIRL' => "\u{1F469}\u{200D}\u{1F469}\u{200D}\u{1F467}", 'CHARACTER_FAMILY_WOMAN_WOMAN_GIRL_BOY' => "\u{1F469}\u{200D}\u{1F469}\u{200D}\u{1F467}\u{200D}\u{1F466}", 'CHARACTER_FAMILY_WOMAN_WOMAN_BOY_BOY' => "\u{1F469}\u{200D}\u{1F469}\u{200D}\u{1F466}\u{200D}\u{1F466}", 'CHARACTER_FAMILY_WOMAN_WOMAN_GIRL_GIRL' => "\u{1F469}\u{200D}\u{1F469}\u{200D}\u{1F467}\u{200D}\u{1F467}", 'CHARACTER_FAMILY_MAN_BOY' => "\u{1F468}\u{200D}\u{1F466}", 'CHARACTER_FAMILY_MAN_BOY_BOY' => "\u{1F468}\u{200D}\u{1F466}\u{200D}\u{1F466}", 'CHARACTER_FAMILY_MAN_GIRL' => "\u{1F468}\u{200D}\u{1F467}", 'CHARACTER_FAMILY_MAN_GIRL_BOY' => "\u{1F468}\u{200D}\u{1F467}\u{200D}\u{1F466}", 'CHARACTER_FAMILY_MAN_GIRL_GIRL' => "\u{1F468}\u{200D}\u{1F467}\u{200D}\u{1F467}", 'CHARACTER_FAMILY_WOMAN_BOY' => "\u{1F469}\u{200D}\u{1F466}", 'CHARACTER_FAMILY_WOMAN_BOY_BOY' => "\u{1F469}\u{200D}\u{1F466}\u{200D}\u{1F466}", 'CHARACTER_FAMILY_WOMAN_GIRL' => "\u{1F469}\u{200D}\u{1F467}", 'CHARACTER_FAMILY_WOMAN_GIRL_BOY' => "\u{1F469}\u{200D}\u{1F467}\u{200D}\u{1F466}", 'CHARACTER_FAMILY_WOMAN_GIRL_GIRL' => "\u{1F469}\u{200D}\u{1F467}\u{200D}\u{1F467}", 'CHARACTER_SELFIE' => "\u{1F933}", 'CHARACTER_SELFIE_LIGHT_SKIN_TONE' => "\u{1F933}\u{1F3FB}", 'CHARACTER_SELFIE_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F933}\u{1F3FC}", 'CHARACTER_SELFIE_MEDIUM_SKIN_TONE' => "\u{1F933}\u{1F3FD}", 'CHARACTER_SELFIE_MEDIUM_DARK_SKIN_TONE' => "\u{1F933}\u{1F3FE}", 'CHARACTER_SELFIE_DARK_SKIN_TONE' => "\u{1F933}\u{1F3FF}", 'CHARACTER_FLEXED_BICEPS' => "\u{1F4AA}", 'CHARACTER_FLEXED_BICEPS_LIGHT_SKIN_TONE' => "\u{1F4AA}\u{1F3FB}", 'CHARACTER_FLEXED_BICEPS_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F4AA}\u{1F3FC}", 'CHARACTER_FLEXED_BICEPS_MEDIUM_SKIN_TONE' => "\u{1F4AA}\u{1F3FD}", 'CHARACTER_FLEXED_BICEPS_MEDIUM_DARK_SKIN_TONE' => "\u{1F4AA}\u{1F3FE}", 'CHARACTER_FLEXED_BICEPS_DARK_SKIN_TONE' => "\u{1F4AA}\u{1F3FF}", 'CHARACTER_LEG' => "\u{1F9B5}", 'CHARACTER_LEG_LIGHT_SKIN_TONE' => "\u{1F9B5}\u{1F3FB}", 'CHARACTER_LEG_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9B5}\u{1F3FC}", 'CHARACTER_LEG_MEDIUM_SKIN_TONE' => "\u{1F9B5}\u{1F3FD}", 'CHARACTER_LEG_MEDIUM_DARK_SKIN_TONE' => "\u{1F9B5}\u{1F3FE}", 'CHARACTER_LEG_DARK_SKIN_TONE' => "\u{1F9B5}\u{1F3FF}", 'CHARACTER_FOOT' => "\u{1F9B6}", 'CHARACTER_FOOT_LIGHT_SKIN_TONE' => "\u{1F9B6}\u{1F3FB}", 'CHARACTER_FOOT_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F9B6}\u{1F3FC}", 'CHARACTER_FOOT_MEDIUM_SKIN_TONE' => "\u{1F9B6}\u{1F3FD}", 'CHARACTER_FOOT_MEDIUM_DARK_SKIN_TONE' => "\u{1F9B6}\u{1F3FE}", 'CHARACTER_FOOT_DARK_SKIN_TONE' => "\u{1F9B6}\u{1F3FF}", 'CHARACTER_BACKHAND_INDEX_POINTING_LEFT' => "\u{1F448}", 'CHARACTER_BACKHAND_INDEX_POINTING_LEFT_LIGHT_SKIN_TONE' => "\u{1F448}\u{1F3FB}", 'CHARACTER_BACKHAND_INDEX_POINTING_LEFT_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F448}\u{1F3FC}", 'CHARACTER_BACKHAND_INDEX_POINTING_LEFT_MEDIUM_SKIN_TONE' => "\u{1F448}\u{1F3FD}", 'CHARACTER_BACKHAND_INDEX_POINTING_LEFT_MEDIUM_DARK_SKIN_TONE' => "\u{1F448}\u{1F3FE}", 'CHARACTER_BACKHAND_INDEX_POINTING_LEFT_DARK_SKIN_TONE' => "\u{1F448}\u{1F3FF}", 'CHARACTER_BACKHAND_INDEX_POINTING_RIGHT' => "\u{1F449}", 'CHARACTER_BACKHAND_INDEX_POINTING_RIGHT_LIGHT_SKIN_TONE' => "\u{1F449}\u{1F3FB}", 'CHARACTER_BACKHAND_INDEX_POINTING_RIGHT_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F449}\u{1F3FC}", 'CHARACTER_BACKHAND_INDEX_POINTING_RIGHT_MEDIUM_SKIN_TONE' => "\u{1F449}\u{1F3FD}", 'CHARACTER_BACKHAND_INDEX_POINTING_RIGHT_MEDIUM_DARK_SKIN_TONE' => "\u{1F449}\u{1F3FE}", 'CHARACTER_BACKHAND_INDEX_POINTING_RIGHT_DARK_SKIN_TONE' => "\u{1F449}\u{1F3FF}", 'CHARACTER_INDEX_POINTING_UP' => "\u{261D}\u{FE0F}", 'CHARACTER_INDEX_POINTING_UP_LIGHT_SKIN_TONE' => "\u{261D}\u{1F3FB}", 'CHARACTER_INDEX_POINTING_UP_MEDIUM_LIGHT_SKIN_TONE' => "\u{261D}\u{1F3FC}", 'CHARACTER_INDEX_POINTING_UP_MEDIUM_SKIN_TONE' => "\u{261D}\u{1F3FD}", 'CHARACTER_INDEX_POINTING_UP_MEDIUM_DARK_SKIN_TONE' => "\u{261D}\u{1F3FE}", 'CHARACTER_INDEX_POINTING_UP_DARK_SKIN_TONE' => "\u{261D}\u{1F3FF}", 'CHARACTER_BACKHAND_INDEX_POINTING_UP' => "\u{1F446}", 'CHARACTER_BACKHAND_INDEX_POINTING_UP_LIGHT_SKIN_TONE' => "\u{1F446}\u{1F3FB}", 'CHARACTER_BACKHAND_INDEX_POINTING_UP_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F446}\u{1F3FC}", 'CHARACTER_BACKHAND_INDEX_POINTING_UP_MEDIUM_SKIN_TONE' => "\u{1F446}\u{1F3FD}", 'CHARACTER_BACKHAND_INDEX_POINTING_UP_MEDIUM_DARK_SKIN_TONE' => "\u{1F446}\u{1F3FE}", 'CHARACTER_BACKHAND_INDEX_POINTING_UP_DARK_SKIN_TONE' => "\u{1F446}\u{1F3FF}", 'CHARACTER_MIDDLE_FINGER' => "\u{1F595}", 'CHARACTER_MIDDLE_FINGER_LIGHT_SKIN_TONE' => "\u{1F595}\u{1F3FB}", 'CHARACTER_MIDDLE_FINGER_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F595}\u{1F3FC}", 'CHARACTER_MIDDLE_FINGER_MEDIUM_SKIN_TONE' => "\u{1F595}\u{1F3FD}", 'CHARACTER_MIDDLE_FINGER_MEDIUM_DARK_SKIN_TONE' => "\u{1F595}\u{1F3FE}", 'CHARACTER_MIDDLE_FINGER_DARK_SKIN_TONE' => "\u{1F595}\u{1F3FF}", 'CHARACTER_BACKHAND_INDEX_POINTING_DOWN' => "\u{1F447}", 'CHARACTER_BACKHAND_INDEX_POINTING_DOWN_LIGHT_SKIN_TONE' => "\u{1F447}\u{1F3FB}", 'CHARACTER_BACKHAND_INDEX_POINTING_DOWN_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F447}\u{1F3FC}", 'CHARACTER_BACKHAND_INDEX_POINTING_DOWN_MEDIUM_SKIN_TONE' => "\u{1F447}\u{1F3FD}", 'CHARACTER_BACKHAND_INDEX_POINTING_DOWN_MEDIUM_DARK_SKIN_TONE' => "\u{1F447}\u{1F3FE}", 'CHARACTER_BACKHAND_INDEX_POINTING_DOWN_DARK_SKIN_TONE' => "\u{1F447}\u{1F3FF}", 'CHARACTER_VICTORY_HAND' => "\u{270C}\u{FE0F}", 'CHARACTER_VICTORY_HAND_LIGHT_SKIN_TONE' => "\u{270C}\u{1F3FB}", 'CHARACTER_VICTORY_HAND_MEDIUM_LIGHT_SKIN_TONE' => "\u{270C}\u{1F3FC}", 'CHARACTER_VICTORY_HAND_MEDIUM_SKIN_TONE' => "\u{270C}\u{1F3FD}", 'CHARACTER_VICTORY_HAND_MEDIUM_DARK_SKIN_TONE' => "\u{270C}\u{1F3FE}", 'CHARACTER_VICTORY_HAND_DARK_SKIN_TONE' => "\u{270C}\u{1F3FF}", 'CHARACTER_CROSSED_FINGERS' => "\u{1F91E}", 'CHARACTER_CROSSED_FINGERS_LIGHT_SKIN_TONE' => "\u{1F91E}\u{1F3FB}", 'CHARACTER_CROSSED_FINGERS_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F91E}\u{1F3FC}", 'CHARACTER_CROSSED_FINGERS_MEDIUM_SKIN_TONE' => "\u{1F91E}\u{1F3FD}", 'CHARACTER_CROSSED_FINGERS_MEDIUM_DARK_SKIN_TONE' => "\u{1F91E}\u{1F3FE}", 'CHARACTER_CROSSED_FINGERS_DARK_SKIN_TONE' => "\u{1F91E}\u{1F3FF}", 'CHARACTER_VULCAN_SALUTE' => "\u{1F596}", 'CHARACTER_VULCAN_SALUTE_LIGHT_SKIN_TONE' => "\u{1F596}\u{1F3FB}", 'CHARACTER_VULCAN_SALUTE_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F596}\u{1F3FC}", 'CHARACTER_VULCAN_SALUTE_MEDIUM_SKIN_TONE' => "\u{1F596}\u{1F3FD}", 'CHARACTER_VULCAN_SALUTE_MEDIUM_DARK_SKIN_TONE' => "\u{1F596}\u{1F3FE}", 'CHARACTER_VULCAN_SALUTE_DARK_SKIN_TONE' => "\u{1F596}\u{1F3FF}", 'CHARACTER_SIGN_OF_THE_HORNS' => "\u{1F918}", 'CHARACTER_SIGN_OF_THE_HORNS_LIGHT_SKIN_TONE' => "\u{1F918}\u{1F3FB}", 'CHARACTER_SIGN_OF_THE_HORNS_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F918}\u{1F3FC}", 'CHARACTER_SIGN_OF_THE_HORNS_MEDIUM_SKIN_TONE' => "\u{1F918}\u{1F3FD}", 'CHARACTER_SIGN_OF_THE_HORNS_MEDIUM_DARK_SKIN_TONE' => "\u{1F918}\u{1F3FE}", 'CHARACTER_SIGN_OF_THE_HORNS_DARK_SKIN_TONE' => "\u{1F918}\u{1F3FF}", 'CHARACTER_CALL_ME_HAND' => "\u{1F919}", 'CHARACTER_CALL_ME_HAND_LIGHT_SKIN_TONE' => "\u{1F919}\u{1F3FB}", 'CHARACTER_CALL_ME_HAND_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F919}\u{1F3FC}", 'CHARACTER_CALL_ME_HAND_MEDIUM_SKIN_TONE' => "\u{1F919}\u{1F3FD}", 'CHARACTER_CALL_ME_HAND_MEDIUM_DARK_SKIN_TONE' => "\u{1F919}\u{1F3FE}", 'CHARACTER_CALL_ME_HAND_DARK_SKIN_TONE' => "\u{1F919}\u{1F3FF}", 'CHARACTER_HAND_WITH_FINGERS_SPLAYED' => "\u{1F590}\u{FE0F}", 'CHARACTER_HAND_WITH_FINGERS_SPLAYED_LIGHT_SKIN_TONE' => "\u{1F590}\u{1F3FB}", 'CHARACTER_HAND_WITH_FINGERS_SPLAYED_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F590}\u{1F3FC}", 'CHARACTER_HAND_WITH_FINGERS_SPLAYED_MEDIUM_SKIN_TONE' => "\u{1F590}\u{1F3FD}", 'CHARACTER_HAND_WITH_FINGERS_SPLAYED_MEDIUM_DARK_SKIN_TONE' => "\u{1F590}\u{1F3FE}", 'CHARACTER_HAND_WITH_FINGERS_SPLAYED_DARK_SKIN_TONE' => "\u{1F590}\u{1F3FF}", 'CHARACTER_RAISED_HAND' => "\u{270B}", 'CHARACTER_RAISED_HAND_LIGHT_SKIN_TONE' => "\u{270B}\u{1F3FB}", 'CHARACTER_RAISED_HAND_MEDIUM_LIGHT_SKIN_TONE' => "\u{270B}\u{1F3FC}", 'CHARACTER_RAISED_HAND_MEDIUM_SKIN_TONE' => "\u{270B}\u{1F3FD}", 'CHARACTER_RAISED_HAND_MEDIUM_DARK_SKIN_TONE' => "\u{270B}\u{1F3FE}", 'CHARACTER_RAISED_HAND_DARK_SKIN_TONE' => "\u{270B}\u{1F3FF}", 'CHARACTER_OK_HAND' => "\u{1F44C}", 'CHARACTER_OK_HAND_LIGHT_SKIN_TONE' => "\u{1F44C}\u{1F3FB}", 'CHARACTER_OK_HAND_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F44C}\u{1F3FC}", 'CHARACTER_OK_HAND_MEDIUM_SKIN_TONE' => "\u{1F44C}\u{1F3FD}", 'CHARACTER_OK_HAND_MEDIUM_DARK_SKIN_TONE' => "\u{1F44C}\u{1F3FE}", 'CHARACTER_OK_HAND_DARK_SKIN_TONE' => "\u{1F44C}\u{1F3FF}", 'CHARACTER_THUMBS_UP' => "\u{1F44D}", 'CHARACTER_THUMBS_UP_LIGHT_SKIN_TONE' => "\u{1F44D}\u{1F3FB}", 'CHARACTER_THUMBS_UP_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F44D}\u{1F3FC}", 'CHARACTER_THUMBS_UP_MEDIUM_SKIN_TONE' => "\u{1F44D}\u{1F3FD}", 'CHARACTER_THUMBS_UP_MEDIUM_DARK_SKIN_TONE' => "\u{1F44D}\u{1F3FE}", 'CHARACTER_THUMBS_UP_DARK_SKIN_TONE' => "\u{1F44D}\u{1F3FF}", 'CHARACTER_THUMBS_DOWN' => "\u{1F44E}", 'CHARACTER_THUMBS_DOWN_LIGHT_SKIN_TONE' => "\u{1F44E}\u{1F3FB}", 'CHARACTER_THUMBS_DOWN_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F44E}\u{1F3FC}", 'CHARACTER_THUMBS_DOWN_MEDIUM_SKIN_TONE' => "\u{1F44E}\u{1F3FD}", 'CHARACTER_THUMBS_DOWN_MEDIUM_DARK_SKIN_TONE' => "\u{1F44E}\u{1F3FE}", 'CHARACTER_THUMBS_DOWN_DARK_SKIN_TONE' => "\u{1F44E}\u{1F3FF}", 'CHARACTER_RAISED_FIST' => "\u{270A}", 'CHARACTER_RAISED_FIST_LIGHT_SKIN_TONE' => "\u{270A}\u{1F3FB}", 'CHARACTER_RAISED_FIST_MEDIUM_LIGHT_SKIN_TONE' => "\u{270A}\u{1F3FC}", 'CHARACTER_RAISED_FIST_MEDIUM_SKIN_TONE' => "\u{270A}\u{1F3FD}", 'CHARACTER_RAISED_FIST_MEDIUM_DARK_SKIN_TONE' => "\u{270A}\u{1F3FE}", 'CHARACTER_RAISED_FIST_DARK_SKIN_TONE' => "\u{270A}\u{1F3FF}", 'CHARACTER_ONCOMING_FIST' => "\u{1F44A}", 'CHARACTER_ONCOMING_FIST_LIGHT_SKIN_TONE' => "\u{1F44A}\u{1F3FB}", 'CHARACTER_ONCOMING_FIST_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F44A}\u{1F3FC}", 'CHARACTER_ONCOMING_FIST_MEDIUM_SKIN_TONE' => "\u{1F44A}\u{1F3FD}", 'CHARACTER_ONCOMING_FIST_MEDIUM_DARK_SKIN_TONE' => "\u{1F44A}\u{1F3FE}", 'CHARACTER_ONCOMING_FIST_DARK_SKIN_TONE' => "\u{1F44A}\u{1F3FF}", 'CHARACTER_LEFT_FACING_FIST' => "\u{1F91B}", 'CHARACTER_LEFT_FACING_FIST_LIGHT_SKIN_TONE' => "\u{1F91B}\u{1F3FB}", 'CHARACTER_LEFT_FACING_FIST_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F91B}\u{1F3FC}", 'CHARACTER_LEFT_FACING_FIST_MEDIUM_SKIN_TONE' => "\u{1F91B}\u{1F3FD}", 'CHARACTER_LEFT_FACING_FIST_MEDIUM_DARK_SKIN_TONE' => "\u{1F91B}\u{1F3FE}", 'CHARACTER_LEFT_FACING_FIST_DARK_SKIN_TONE' => "\u{1F91B}\u{1F3FF}", 'CHARACTER_RIGHT_FACING_FIST' => "\u{1F91C}", 'CHARACTER_RIGHT_FACING_FIST_LIGHT_SKIN_TONE' => "\u{1F91C}\u{1F3FB}", 'CHARACTER_RIGHT_FACING_FIST_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F91C}\u{1F3FC}", 'CHARACTER_RIGHT_FACING_FIST_MEDIUM_SKIN_TONE' => "\u{1F91C}\u{1F3FD}", 'CHARACTER_RIGHT_FACING_FIST_MEDIUM_DARK_SKIN_TONE' => "\u{1F91C}\u{1F3FE}", 'CHARACTER_RIGHT_FACING_FIST_DARK_SKIN_TONE' => "\u{1F91C}\u{1F3FF}", 'CHARACTER_RAISED_BACK_OF_HAND' => "\u{1F91A}", 'CHARACTER_RAISED_BACK_OF_HAND_LIGHT_SKIN_TONE' => "\u{1F91A}\u{1F3FB}", 'CHARACTER_RAISED_BACK_OF_HAND_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F91A}\u{1F3FC}", 'CHARACTER_RAISED_BACK_OF_HAND_MEDIUM_SKIN_TONE' => "\u{1F91A}\u{1F3FD}", 'CHARACTER_RAISED_BACK_OF_HAND_MEDIUM_DARK_SKIN_TONE' => "\u{1F91A}\u{1F3FE}", 'CHARACTER_RAISED_BACK_OF_HAND_DARK_SKIN_TONE' => "\u{1F91A}\u{1F3FF}", 'CHARACTER_WAVING_HAND' => "\u{1F44B}", 'CHARACTER_WAVING_HAND_LIGHT_SKIN_TONE' => "\u{1F44B}\u{1F3FB}", 'CHARACTER_WAVING_HAND_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F44B}\u{1F3FC}", 'CHARACTER_WAVING_HAND_MEDIUM_SKIN_TONE' => "\u{1F44B}\u{1F3FD}", 'CHARACTER_WAVING_HAND_MEDIUM_DARK_SKIN_TONE' => "\u{1F44B}\u{1F3FE}", 'CHARACTER_WAVING_HAND_DARK_SKIN_TONE' => "\u{1F44B}\u{1F3FF}", 'CHARACTER_LOVE_YOU_GESTURE' => "\u{1F91F}", 'CHARACTER_LOVE_YOU_GESTURE_LIGHT_SKIN_TONE' => "\u{1F91F}\u{1F3FB}", 'CHARACTER_LOVE_YOU_GESTURE_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F91F}\u{1F3FC}", 'CHARACTER_LOVE_YOU_GESTURE_MEDIUM_SKIN_TONE' => "\u{1F91F}\u{1F3FD}", 'CHARACTER_LOVE_YOU_GESTURE_MEDIUM_DARK_SKIN_TONE' => "\u{1F91F}\u{1F3FE}", 'CHARACTER_LOVE_YOU_GESTURE_DARK_SKIN_TONE' => "\u{1F91F}\u{1F3FF}", 'CHARACTER_WRITING_HAND' => "\u{270D}\u{FE0F}", 'CHARACTER_WRITING_HAND_LIGHT_SKIN_TONE' => "\u{270D}\u{1F3FB}", 'CHARACTER_WRITING_HAND_MEDIUM_LIGHT_SKIN_TONE' => "\u{270D}\u{1F3FC}", 'CHARACTER_WRITING_HAND_MEDIUM_SKIN_TONE' => "\u{270D}\u{1F3FD}", 'CHARACTER_WRITING_HAND_MEDIUM_DARK_SKIN_TONE' => "\u{270D}\u{1F3FE}", 'CHARACTER_WRITING_HAND_DARK_SKIN_TONE' => "\u{270D}\u{1F3FF}", 'CHARACTER_CLAPPING_HANDS' => "\u{1F44F}", 'CHARACTER_CLAPPING_HANDS_LIGHT_SKIN_TONE' => "\u{1F44F}\u{1F3FB}", 'CHARACTER_CLAPPING_HANDS_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F44F}\u{1F3FC}", 'CHARACTER_CLAPPING_HANDS_MEDIUM_SKIN_TONE' => "\u{1F44F}\u{1F3FD}", 'CHARACTER_CLAPPING_HANDS_MEDIUM_DARK_SKIN_TONE' => "\u{1F44F}\u{1F3FE}", 'CHARACTER_CLAPPING_HANDS_DARK_SKIN_TONE' => "\u{1F44F}\u{1F3FF}", 'CHARACTER_OPEN_HANDS' => "\u{1F450}", 'CHARACTER_OPEN_HANDS_LIGHT_SKIN_TONE' => "\u{1F450}\u{1F3FB}", 'CHARACTER_OPEN_HANDS_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F450}\u{1F3FC}", 'CHARACTER_OPEN_HANDS_MEDIUM_SKIN_TONE' => "\u{1F450}\u{1F3FD}", 'CHARACTER_OPEN_HANDS_MEDIUM_DARK_SKIN_TONE' => "\u{1F450}\u{1F3FE}", 'CHARACTER_OPEN_HANDS_DARK_SKIN_TONE' => "\u{1F450}\u{1F3FF}", 'CHARACTER_RAISING_HANDS' => "\u{1F64C}", 'CHARACTER_RAISING_HANDS_LIGHT_SKIN_TONE' => "\u{1F64C}\u{1F3FB}", 'CHARACTER_RAISING_HANDS_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F64C}\u{1F3FC}", 'CHARACTER_RAISING_HANDS_MEDIUM_SKIN_TONE' => "\u{1F64C}\u{1F3FD}", 'CHARACTER_RAISING_HANDS_MEDIUM_DARK_SKIN_TONE' => "\u{1F64C}\u{1F3FE}", 'CHARACTER_RAISING_HANDS_DARK_SKIN_TONE' => "\u{1F64C}\u{1F3FF}", 'CHARACTER_PALMS_UP_TOGETHER' => "\u{1F932}", 'CHARACTER_PALMS_UP_TOGETHER_LIGHT_SKIN_TONE' => "\u{1F932}\u{1F3FB}", 'CHARACTER_PALMS_UP_TOGETHER_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F932}\u{1F3FC}", 'CHARACTER_PALMS_UP_TOGETHER_MEDIUM_SKIN_TONE' => "\u{1F932}\u{1F3FD}", 'CHARACTER_PALMS_UP_TOGETHER_MEDIUM_DARK_SKIN_TONE' => "\u{1F932}\u{1F3FE}", 'CHARACTER_PALMS_UP_TOGETHER_DARK_SKIN_TONE' => "\u{1F932}\u{1F3FF}", 'CHARACTER_FOLDED_HANDS' => "\u{1F64F}", 'CHARACTER_FOLDED_HANDS_LIGHT_SKIN_TONE' => "\u{1F64F}\u{1F3FB}", 'CHARACTER_FOLDED_HANDS_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F64F}\u{1F3FC}", 'CHARACTER_FOLDED_HANDS_MEDIUM_SKIN_TONE' => "\u{1F64F}\u{1F3FD}", 'CHARACTER_FOLDED_HANDS_MEDIUM_DARK_SKIN_TONE' => "\u{1F64F}\u{1F3FE}", 'CHARACTER_FOLDED_HANDS_DARK_SKIN_TONE' => "\u{1F64F}\u{1F3FF}", 'CHARACTER_HANDSHAKE' => "\u{1F91D}", 'CHARACTER_NAIL_POLISH' => "\u{1F485}", 'CHARACTER_NAIL_POLISH_LIGHT_SKIN_TONE' => "\u{1F485}\u{1F3FB}", 'CHARACTER_NAIL_POLISH_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F485}\u{1F3FC}", 'CHARACTER_NAIL_POLISH_MEDIUM_SKIN_TONE' => "\u{1F485}\u{1F3FD}", 'CHARACTER_NAIL_POLISH_MEDIUM_DARK_SKIN_TONE' => "\u{1F485}\u{1F3FE}", 'CHARACTER_NAIL_POLISH_DARK_SKIN_TONE' => "\u{1F485}\u{1F3FF}", 'CHARACTER_EAR' => "\u{1F442}", 'CHARACTER_EAR_LIGHT_SKIN_TONE' => "\u{1F442}\u{1F3FB}", 'CHARACTER_EAR_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F442}\u{1F3FC}", 'CHARACTER_EAR_MEDIUM_SKIN_TONE' => "\u{1F442}\u{1F3FD}", 'CHARACTER_EAR_MEDIUM_DARK_SKIN_TONE' => "\u{1F442}\u{1F3FE}", 'CHARACTER_EAR_DARK_SKIN_TONE' => "\u{1F442}\u{1F3FF}", 'CHARACTER_NOSE' => "\u{1F443}", 'CHARACTER_NOSE_LIGHT_SKIN_TONE' => "\u{1F443}\u{1F3FB}", 'CHARACTER_NOSE_MEDIUM_LIGHT_SKIN_TONE' => "\u{1F443}\u{1F3FC}", 'CHARACTER_NOSE_MEDIUM_SKIN_TONE' => "\u{1F443}\u{1F3FD}", 'CHARACTER_NOSE_MEDIUM_DARK_SKIN_TONE' => "\u{1F443}\u{1F3FE}", 'CHARACTER_NOSE_DARK_SKIN_TONE' => "\u{1F443}\u{1F3FF}", 'CHARACTER_RED_HAIRED' => "\u{1F9B0}", 'CHARACTER_CURLY_HAIRED' => "\u{1F9B1}", 'CHARACTER_BALD' => "\u{1F9B2}", 'CHARACTER_WHITE_HAIRED' => "\u{1F9B3}", 'CHARACTER_FOOTPRINTS' => "\u{1F463}", 'CHARACTER_EYES' => "\u{1F440}", 'CHARACTER_EYE' => "\u{1F441}\u{FE0F}", 'CHARACTER_EYE_IN_SPEECH_BUBBLE' => "\u{1F441}\u{FE0F}\u{200D}\u{1F5E8}\u{FE0F}", 'CHARACTER_BRAIN' => "\u{1F9E0}", 'CHARACTER_BONE' => "\u{1F9B4}", 'CHARACTER_TOOTH' => "\u{1F9B7}", 'CHARACTER_TONGUE' => "\u{1F445}", 'CHARACTER_MOUTH' => "\u{1F444}", 'CHARACTER_KISS_MARK' => "\u{1F48B}", 'CHARACTER_HEART_WITH_ARROW' => "\u{1F498}", 'CHARACTER_RED_HEART' => "\u{2764}\u{FE0F}", 'CHARACTER_BEATING_HEART' => "\u{1F493}", 'CHARACTER_BROKEN_HEART' => "\u{1F494}", 'CHARACTER_TWO_HEARTS' => "\u{1F495}", 'CHARACTER_SPARKLING_HEART' => "\u{1F496}", 'CHARACTER_GROWING_HEART' => "\u{1F497}", 'CHARACTER_BLUE_HEART' => "\u{1F499}", 'CHARACTER_GREEN_HEART' => "\u{1F49A}", 'CHARACTER_YELLOW_HEART' => "\u{1F49B}", 'CHARACTER_ORANGE_HEART' => "\u{1F9E1}", 'CHARACTER_PURPLE_HEART' => "\u{1F49C}", 'CHARACTER_BLACK_HEART' => "\u{1F5A4}", 'CHARACTER_HEART_WITH_RIBBON' => "\u{1F49D}", 'CHARACTER_REVOLVING_HEARTS' => "\u{1F49E}", 'CHARACTER_HEART_DECORATION' => "\u{1F49F}", 'CHARACTER_HEAVY_HEART_EXCLAMATION' => "\u{2763}\u{FE0F}", 'CHARACTER_LOVE_LETTER' => "\u{1F48C}", 'CHARACTER_ZZZ' => "\u{1F4A4}", 'CHARACTER_ANGER_SYMBOL' => "\u{1F4A2}", 'CHARACTER_BOMB' => "\u{1F4A3}", 'CHARACTER_COLLISION' => "\u{1F4A5}", 'CHARACTER_SWEAT_DROPLETS' => "\u{1F4A6}", 'CHARACTER_DASHING_AWAY' => "\u{1F4A8}", 'CHARACTER_DIZZY' => "\u{1F4AB}", 'CHARACTER_SPEECH_BALLOON' => "\u{1F4AC}", 'CHARACTER_LEFT_SPEECH_BUBBLE' => "\u{1F5E8}\u{FE0F}", 'CHARACTER_RIGHT_ANGER_BUBBLE' => "\u{1F5EF}\u{FE0F}", 'CHARACTER_THOUGHT_BALLOON' => "\u{1F4AD}", 'CHARACTER_HOLE' => "\u{1F573}\u{FE0F}", 'CHARACTER_GLASSES' => "\u{1F453}", 'CHARACTER_SUNGLASSES' => "\u{1F576}\u{FE0F}", 'CHARACTER_GOGGLES' => "\u{1F97D}", 'CHARACTER_LAB_COAT' => "\u{1F97C}", 'CHARACTER_NECKTIE' => "\u{1F454}", 'CHARACTER_T_SHIRT' => "\u{1F455}", 'CHARACTER_JEANS' => "\u{1F456}", 'CHARACTER_SCARF' => "\u{1F9E3}", 'CHARACTER_GLOVES' => "\u{1F9E4}", 'CHARACTER_COAT' => "\u{1F9E5}", 'CHARACTER_SOCKS' => "\u{1F9E6}", 'CHARACTER_DRESS' => "\u{1F457}", 'CHARACTER_KIMONO' => "\u{1F458}", 'CHARACTER_BIKINI' => "\u{1F459}", 'CHARACTER_WOMAN_S_CLOTHES' => "\u{1F45A}", 'CHARACTER_PURSE' => "\u{1F45B}", 'CHARACTER_HANDBAG' => "\u{1F45C}", 'CHARACTER_CLUTCH_BAG' => "\u{1F45D}", 'CHARACTER_SHOPPING_BAGS' => "\u{1F6CD}\u{FE0F}", 'CHARACTER_SCHOOL_BACKPACK' => "\u{1F392}", 'CHARACTER_MAN_S_SHOE' => "\u{1F45E}", 'CHARACTER_RUNNING_SHOE' => "\u{1F45F}", 'CHARACTER_HIKING_BOOT' => "\u{1F97E}", 'CHARACTER_WOMAN_S_FLAT_SHOE' => "\u{1F97F}", 'CHARACTER_HIGH_HEELED_SHOE' => "\u{1F460}", 'CHARACTER_WOMAN_S_SANDAL' => "\u{1F461}", 'CHARACTER_WOMAN_S_BOOT' => "\u{1F462}", 'CHARACTER_CROWN' => "\u{1F451}", 'CHARACTER_WOMAN_S_HAT' => "\u{1F452}", 'CHARACTER_TOP_HAT' => "\u{1F3A9}", 'CHARACTER_GRADUATION_CAP' => "\u{1F393}", 'CHARACTER_BILLED_CAP' => "\u{1F9E2}", 'CHARACTER_RESCUE_WORKER_S_HELMET' => "\u{26D1}\u{FE0F}", 'CHARACTER_PRAYER_BEADS' => "\u{1F4FF}", 'CHARACTER_LIPSTICK' => "\u{1F484}", 'CHARACTER_RING' => "\u{1F48D}", 'CHARACTER_GEM_STONE' => "\u{1F48E}", 'CHARACTER_MONKEY_FACE' => "\u{1F435}", 'CHARACTER_MONKEY' => "\u{1F412}", 'CHARACTER_GORILLA' => "\u{1F98D}", 'CHARACTER_DOG_FACE' => "\u{1F436}", 'CHARACTER_DOG' => "\u{1F415}", 'CHARACTER_POODLE' => "\u{1F429}", 'CHARACTER_WOLF_FACE' => "\u{1F43A}", 'CHARACTER_FOX_FACE' => "\u{1F98A}", 'CHARACTER_RACCOON' => "\u{1F99D}", 'CHARACTER_CAT_FACE' => "\u{1F431}", 'CHARACTER_CAT' => "\u{1F408}", 'CHARACTER_LION_FACE' => "\u{1F981}", 'CHARACTER_TIGER_FACE' => "\u{1F42F}", 'CHARACTER_TIGER' => "\u{1F405}", 'CHARACTER_LEOPARD' => "\u{1F406}", 'CHARACTER_HORSE_FACE' => "\u{1F434}", 'CHARACTER_HORSE' => "\u{1F40E}", 'CHARACTER_UNICORN_FACE' => "\u{1F984}", 'CHARACTER_ZEBRA' => "\u{1F993}", 'CHARACTER_DEER' => "\u{1F98C}", 'CHARACTER_COW_FACE' => "\u{1F42E}", 'CHARACTER_OX' => "\u{1F402}", 'CHARACTER_WATER_BUFFALO' => "\u{1F403}", 'CHARACTER_COW' => "\u{1F404}", 'CHARACTER_PIG_FACE' => "\u{1F437}", 'CHARACTER_PIG' => "\u{1F416}", 'CHARACTER_BOAR' => "\u{1F417}", 'CHARACTER_PIG_NOSE' => "\u{1F43D}", 'CHARACTER_RAM' => "\u{1F40F}", 'CHARACTER_EWE' => "\u{1F411}", 'CHARACTER_GOAT' => "\u{1F410}", 'CHARACTER_CAMEL' => "\u{1F42A}", 'CHARACTER_TWO_HUMP_CAMEL' => "\u{1F42B}", 'CHARACTER_LLAMA' => "\u{1F999}", 'CHARACTER_GIRAFFE' => "\u{1F992}", 'CHARACTER_ELEPHANT' => "\u{1F418}", 'CHARACTER_RHINOCEROS' => "\u{1F98F}", 'CHARACTER_HIPPOPOTAMUS' => "\u{1F99B}", 'CHARACTER_MOUSE_FACE' => "\u{1F42D}", 'CHARACTER_MOUSE' => "\u{1F401}", 'CHARACTER_RAT' => "\u{1F400}", 'CHARACTER_HAMSTER_FACE' => "\u{1F439}", 'CHARACTER_RABBIT_FACE' => "\u{1F430}", 'CHARACTER_RABBIT' => "\u{1F407}", 'CHARACTER_CHIPMUNK' => "\u{1F43F}\u{FE0F}", 'CHARACTER_HEDGEHOG' => "\u{1F994}", 'CHARACTER_BAT' => "\u{1F987}", 'CHARACTER_BEAR_FACE' => "\u{1F43B}", 'CHARACTER_KOALA' => "\u{1F428}", 'CHARACTER_PANDA_FACE' => "\u{1F43C}", 'CHARACTER_KANGAROO' => "\u{1F998}", 'CHARACTER_BADGER' => "\u{1F9A1}", 'CHARACTER_PAW_PRINTS' => "\u{1F43E}", 'CHARACTER_TURKEY' => "\u{1F983}", 'CHARACTER_CHICKEN' => "\u{1F414}", 'CHARACTER_ROOSTER' => "\u{1F413}", 'CHARACTER_HATCHING_CHICK' => "\u{1F423}", 'CHARACTER_BABY_CHICK' => "\u{1F424}", 'CHARACTER_FRONT_FACING_BABY_CHICK' => "\u{1F425}", 'CHARACTER_BIRD' => "\u{1F426}", 'CHARACTER_PENGUIN' => "\u{1F427}", 'CHARACTER_DOVE' => "\u{1F54A}\u{FE0F}", 'CHARACTER_EAGLE' => "\u{1F985}", 'CHARACTER_DUCK' => "\u{1F986}", 'CHARACTER_SWAN' => "\u{1F9A2}", 'CHARACTER_OWL' => "\u{1F989}", 'CHARACTER_PEACOCK' => "\u{1F99A}", 'CHARACTER_PARROT' => "\u{1F99C}", 'CHARACTER_FROG_FACE' => "\u{1F438}", 'CHARACTER_CROCODILE' => "\u{1F40A}", 'CHARACTER_TURTLE' => "\u{1F422}", 'CHARACTER_LIZARD' => "\u{1F98E}", 'CHARACTER_SNAKE' => "\u{1F40D}", 'CHARACTER_DRAGON_FACE' => "\u{1F432}", 'CHARACTER_DRAGON' => "\u{1F409}", 'CHARACTER_SAUROPOD' => "\u{1F995}", 'CHARACTER_T_REX' => "\u{1F996}", 'CHARACTER_SPOUTING_WHALE' => "\u{1F433}", 'CHARACTER_WHALE' => "\u{1F40B}", 'CHARACTER_DOLPHIN' => "\u{1F42C}", 'CHARACTER_FISH' => "\u{1F41F}", 'CHARACTER_TROPICAL_FISH' => "\u{1F420}", 'CHARACTER_BLOWFISH' => "\u{1F421}", 'CHARACTER_SHARK' => "\u{1F988}", 'CHARACTER_OCTOPUS' => "\u{1F419}", 'CHARACTER_SPIRAL_SHELL' => "\u{1F41A}", 'CHARACTER_CRAB' => "\u{1F980}", 'CHARACTER_LOBSTER' => "\u{1F99E}", 'CHARACTER_SHRIMP' => "\u{1F990}", 'CHARACTER_SQUID' => "\u{1F991}", 'CHARACTER_SNAIL' => "\u{1F40C}", 'CHARACTER_BUTTERFLY' => "\u{1F98B}", 'CHARACTER_BUG' => "\u{1F41B}", 'CHARACTER_ANT' => "\u{1F41C}", 'CHARACTER_HONEYBEE' => "\u{1F41D}", 'CHARACTER_LADY_BEETLE' => "\u{1F41E}", 'CHARACTER_CRICKET' => "\u{1F997}", 'CHARACTER_SPIDER' => "\u{1F577}\u{FE0F}", 'CHARACTER_SPIDER_WEB' => "\u{1F578}\u{FE0F}", 'CHARACTER_SCORPION' => "\u{1F982}", 'CHARACTER_MOSQUITO' => "\u{1F99F}", 'CHARACTER_MICROBE' => "\u{1F9A0}", 'CHARACTER_BOUQUET' => "\u{1F490}", 'CHARACTER_CHERRY_BLOSSOM' => "\u{1F338}", 'CHARACTER_WHITE_FLOWER' => "\u{1F4AE}", 'CHARACTER_ROSETTE' => "\u{1F3F5}\u{FE0F}", 'CHARACTER_ROSE' => "\u{1F339}", 'CHARACTER_WILTED_FLOWER' => "\u{1F940}", 'CHARACTER_HIBISCUS' => "\u{1F33A}", 'CHARACTER_SUNFLOWER' => "\u{1F33B}", 'CHARACTER_BLOSSOM' => "\u{1F33C}", 'CHARACTER_TULIP' => "\u{1F337}", 'CHARACTER_SEEDLING' => "\u{1F331}", 'CHARACTER_EVERGREEN_TREE' => "\u{1F332}", 'CHARACTER_DECIDUOUS_TREE' => "\u{1F333}", 'CHARACTER_PALM_TREE' => "\u{1F334}", 'CHARACTER_CACTUS' => "\u{1F335}", 'CHARACTER_SHEAF_OF_RICE' => "\u{1F33E}", 'CHARACTER_HERB' => "\u{1F33F}", 'CHARACTER_SHAMROCK' => "\u{2618}\u{FE0F}", 'CHARACTER_FOUR_LEAF_CLOVER' => "\u{1F340}", 'CHARACTER_MAPLE_LEAF' => "\u{1F341}", 'CHARACTER_FALLEN_LEAF' => "\u{1F342}", 'CHARACTER_LEAF_FLUTTERING_IN_WIND' => "\u{1F343}", 'CHARACTER_GRAPES' => "\u{1F347}", 'CHARACTER_MELON' => "\u{1F348}", 'CHARACTER_WATERMELON' => "\u{1F349}", 'CHARACTER_TANGERINE' => "\u{1F34A}", 'CHARACTER_LEMON' => "\u{1F34B}", 'CHARACTER_BANANA' => "\u{1F34C}", 'CHARACTER_PINEAPPLE' => "\u{1F34D}", 'CHARACTER_MANGO' => "\u{1F96D}", 'CHARACTER_RED_APPLE' => "\u{1F34E}", 'CHARACTER_GREEN_APPLE' => "\u{1F34F}", 'CHARACTER_PEAR' => "\u{1F350}", 'CHARACTER_PEACH' => "\u{1F351}", 'CHARACTER_CHERRIES' => "\u{1F352}", 'CHARACTER_STRAWBERRY' => "\u{1F353}", 'CHARACTER_KIWI_FRUIT' => "\u{1F95D}", 'CHARACTER_TOMATO' => "\u{1F345}", 'CHARACTER_COCONUT' => "\u{1F965}", 'CHARACTER_AVOCADO' => "\u{1F951}", 'CHARACTER_EGGPLANT' => "\u{1F346}", 'CHARACTER_POTATO' => "\u{1F954}", 'CHARACTER_CARROT' => "\u{1F955}", 'CHARACTER_EAR_OF_CORN' => "\u{1F33D}", 'CHARACTER_HOT_PEPPER' => "\u{1F336}\u{FE0F}", 'CHARACTER_CUCUMBER' => "\u{1F952}", 'CHARACTER_LEAFY_GREEN' => "\u{1F96C}", 'CHARACTER_BROCCOLI' => "\u{1F966}", 'CHARACTER_MUSHROOM' => "\u{1F344}", 'CHARACTER_PEANUTS' => "\u{1F95C}", 'CHARACTER_CHESTNUT' => "\u{1F330}", 'CHARACTER_BREAD' => "\u{1F35E}", 'CHARACTER_CROISSANT' => "\u{1F950}", 'CHARACTER_BAGUETTE_BREAD' => "\u{1F956}", 'CHARACTER_PRETZEL' => "\u{1F968}", 'CHARACTER_BAGEL' => "\u{1F96F}", 'CHARACTER_PANCAKES' => "\u{1F95E}", 'CHARACTER_CHEESE_WEDGE' => "\u{1F9C0}", 'CHARACTER_MEAT_ON_BONE' => "\u{1F356}", 'CHARACTER_POULTRY_LEG' => "\u{1F357}", 'CHARACTER_CUT_OF_MEAT' => "\u{1F969}", 'CHARACTER_BACON' => "\u{1F953}", 'CHARACTER_HAMBURGER' => "\u{1F354}", 'CHARACTER_FRENCH_FRIES' => "\u{1F35F}", 'CHARACTER_PIZZA' => "\u{1F355}", 'CHARACTER_HOT_DOG' => "\u{1F32D}", 'CHARACTER_SANDWICH' => "\u{1F96A}", 'CHARACTER_TACO' => "\u{1F32E}", 'CHARACTER_BURRITO' => "\u{1F32F}", 'CHARACTER_STUFFED_FLATBREAD' => "\u{1F959}", 'CHARACTER_EGG' => "\u{1F95A}", 'CHARACTER_COOKING' => "\u{1F373}", 'CHARACTER_SHALLOW_PAN_OF_FOOD' => "\u{1F958}", 'CHARACTER_POT_OF_FOOD' => "\u{1F372}", 'CHARACTER_BOWL_WITH_SPOON' => "\u{1F963}", 'CHARACTER_GREEN_SALAD' => "\u{1F957}", 'CHARACTER_POPCORN' => "\u{1F37F}", 'CHARACTER_SALT' => "\u{1F9C2}", 'CHARACTER_CANNED_FOOD' => "\u{1F96B}", 'CHARACTER_BENTO_BOX' => "\u{1F371}", 'CHARACTER_RICE_CRACKER' => "\u{1F358}", 'CHARACTER_RICE_BALL' => "\u{1F359}", 'CHARACTER_COOKED_RICE' => "\u{1F35A}", 'CHARACTER_CURRY_RICE' => "\u{1F35B}", 'CHARACTER_STEAMING_BOWL' => "\u{1F35C}", 'CHARACTER_SPAGHETTI' => "\u{1F35D}", 'CHARACTER_ROASTED_SWEET_POTATO' => "\u{1F360}", 'CHARACTER_ODEN' => "\u{1F362}", 'CHARACTER_SUSHI' => "\u{1F363}", 'CHARACTER_FRIED_SHRIMP' => "\u{1F364}", 'CHARACTER_FISH_CAKE_WITH_SWIRL' => "\u{1F365}", 'CHARACTER_MOON_CAKE' => "\u{1F96E}", 'CHARACTER_DANGO' => "\u{1F361}", 'CHARACTER_DUMPLING' => "\u{1F95F}", 'CHARACTER_FORTUNE_COOKIE' => "\u{1F960}", 'CHARACTER_TAKEOUT_BOX' => "\u{1F961}", 'CHARACTER_SOFT_ICE_CREAM' => "\u{1F366}", 'CHARACTER_SHAVED_ICE' => "\u{1F367}", 'CHARACTER_ICE_CREAM' => "\u{1F368}", 'CHARACTER_DOUGHNUT' => "\u{1F369}", 'CHARACTER_COOKIE' => "\u{1F36A}", 'CHARACTER_BIRTHDAY_CAKE' => "\u{1F382}", 'CHARACTER_SHORTCAKE' => "\u{1F370}", 'CHARACTER_CUPCAKE' => "\u{1F9C1}", 'CHARACTER_PIE' => "\u{1F967}", 'CHARACTER_CHOCOLATE_BAR' => "\u{1F36B}", 'CHARACTER_CANDY' => "\u{1F36C}", 'CHARACTER_LOLLIPOP' => "\u{1F36D}", 'CHARACTER_CUSTARD' => "\u{1F36E}", 'CHARACTER_HONEY_POT' => "\u{1F36F}", 'CHARACTER_BABY_BOTTLE' => "\u{1F37C}", 'CHARACTER_GLASS_OF_MILK' => "\u{1F95B}", 'CHARACTER_HOT_BEVERAGE' => "\u{2615}", 'CHARACTER_TEACUP_WITHOUT_HANDLE' => "\u{1F375}", 'CHARACTER_SAKE' => "\u{1F376}", 'CHARACTER_BOTTLE_WITH_POPPING_CORK' => "\u{1F37E}", 'CHARACTER_WINE_GLASS' => "\u{1F377}", 'CHARACTER_COCKTAIL_GLASS' => "\u{1F378}", 'CHARACTER_TROPICAL_DRINK' => "\u{1F379}", 'CHARACTER_BEER_MUG' => "\u{1F37A}", 'CHARACTER_CLINKING_BEER_MUGS' => "\u{1F37B}", 'CHARACTER_CLINKING_GLASSES' => "\u{1F942}", 'CHARACTER_TUMBLER_GLASS' => "\u{1F943}", 'CHARACTER_CUP_WITH_STRAW' => "\u{1F964}", 'CHARACTER_CHOPSTICKS' => "\u{1F962}", 'CHARACTER_FORK_AND_KNIFE_WITH_PLATE' => "\u{1F37D}\u{FE0F}", 'CHARACTER_FORK_AND_KNIFE' => "\u{1F374}", 'CHARACTER_SPOON' => "\u{1F944}", 'CHARACTER_KITCHEN_KNIFE' => "\u{1F52A}", 'CHARACTER_AMPHORA' => "\u{1F3FA}", 'CHARACTER_GLOBE_SHOWING_EUROPE_AFRICA' => "\u{1F30D}", 'CHARACTER_GLOBE_SHOWING_AMERICAS' => "\u{1F30E}", 'CHARACTER_GLOBE_SHOWING_ASIA_AUSTRALIA' => "\u{1F30F}", 'CHARACTER_GLOBE_WITH_MERIDIANS' => "\u{1F310}", 'CHARACTER_WORLD_MAP' => "\u{1F5FA}\u{FE0F}", 'CHARACTER_MAP_OF_JAPAN' => "\u{1F5FE}", 'CHARACTER_COMPASS' => "\u{1F9ED}", 'CHARACTER_SNOW_CAPPED_MOUNTAIN' => "\u{1F3D4}\u{FE0F}", 'CHARACTER_MOUNTAIN' => "\u{26F0}\u{FE0F}", 'CHARACTER_VOLCANO' => "\u{1F30B}", 'CHARACTER_MOUNT_FUJI' => "\u{1F5FB}", 'CHARACTER_CAMPING' => "\u{1F3D5}\u{FE0F}", 'CHARACTER_BEACH_WITH_UMBRELLA' => "\u{1F3D6}\u{FE0F}", 'CHARACTER_DESERT' => "\u{1F3DC}\u{FE0F}", 'CHARACTER_DESERT_ISLAND' => "\u{1F3DD}\u{FE0F}", 'CHARACTER_NATIONAL_PARK' => "\u{1F3DE}\u{FE0F}", 'CHARACTER_STADIUM' => "\u{1F3DF}\u{FE0F}", 'CHARACTER_CLASSICAL_BUILDING' => "\u{1F3DB}\u{FE0F}", 'CHARACTER_BUILDING_CONSTRUCTION' => "\u{1F3D7}\u{FE0F}", 'CHARACTER_BRICKS' => "\u{1F9F1}", 'CHARACTER_HOUSES' => "\u{1F3D8}\u{FE0F}", 'CHARACTER_DERELICT_HOUSE' => "\u{1F3DA}\u{FE0F}", 'CHARACTER_HOUSE' => "\u{1F3E0}", 'CHARACTER_HOUSE_WITH_GARDEN' => "\u{1F3E1}", 'CHARACTER_OFFICE_BUILDING' => "\u{1F3E2}", 'CHARACTER_JAPANESE_POST_OFFICE' => "\u{1F3E3}", 'CHARACTER_POST_OFFICE' => "\u{1F3E4}", 'CHARACTER_HOSPITAL' => "\u{1F3E5}", 'CHARACTER_BANK' => "\u{1F3E6}", 'CHARACTER_HOTEL' => "\u{1F3E8}", 'CHARACTER_LOVE_HOTEL' => "\u{1F3E9}", 'CHARACTER_CONVENIENCE_STORE' => "\u{1F3EA}", 'CHARACTER_SCHOOL' => "\u{1F3EB}", 'CHARACTER_DEPARTMENT_STORE' => "\u{1F3EC}", 'CHARACTER_FACTORY' => "\u{1F3ED}", 'CHARACTER_JAPANESE_CASTLE' => "\u{1F3EF}", 'CHARACTER_CASTLE' => "\u{1F3F0}", 'CHARACTER_WEDDING' => "\u{1F492}", 'CHARACTER_TOKYO_TOWER' => "\u{1F5FC}", 'CHARACTER_STATUE_OF_LIBERTY' => "\u{1F5FD}", 'CHARACTER_CHURCH' => "\u{26EA}", 'CHARACTER_MOSQUE' => "\u{1F54C}", 'CHARACTER_SYNAGOGUE' => "\u{1F54D}", 'CHARACTER_SHINTO_SHRINE' => "\u{26E9}\u{FE0F}", 'CHARACTER_KAABA' => "\u{1F54B}", 'CHARACTER_FOUNTAIN' => "\u{26F2}", 'CHARACTER_TENT' => "\u{26FA}", 'CHARACTER_FOGGY' => "\u{1F301}", 'CHARACTER_NIGHT_WITH_STARS' => "\u{1F303}", 'CHARACTER_CITYSCAPE' => "\u{1F3D9}\u{FE0F}", 'CHARACTER_SUNRISE_OVER_MOUNTAINS' => "\u{1F304}", 'CHARACTER_SUNRISE' => "\u{1F305}", 'CHARACTER_CITYSCAPE_AT_DUSK' => "\u{1F306}", 'CHARACTER_SUNSET' => "\u{1F307}", 'CHARACTER_BRIDGE_AT_NIGHT' => "\u{1F309}", 'CHARACTER_HOT_SPRINGS' => "\u{2668}\u{FE0F}", 'CHARACTER_MILKY_WAY' => "\u{1F30C}", 'CHARACTER_CAROUSEL_HORSE' => "\u{1F3A0}", 'CHARACTER_FERRIS_WHEEL' => "\u{1F3A1}", 'CHARACTER_ROLLER_COASTER' => "\u{1F3A2}", 'CHARACTER_BARBER_POLE' => "\u{1F488}", 'CHARACTER_CIRCUS_TENT' => "\u{1F3AA}", 'CHARACTER_LOCOMOTIVE' => "\u{1F682}", 'CHARACTER_RAILWAY_CAR' => "\u{1F683}", 'CHARACTER_HIGH_SPEED_TRAIN' => "\u{1F684}", 'CHARACTER_BULLET_TRAIN' => "\u{1F685}", 'CHARACTER_TRAIN' => "\u{1F686}", 'CHARACTER_METRO' => "\u{1F687}", 'CHARACTER_LIGHT_RAIL' => "\u{1F688}", 'CHARACTER_STATION' => "\u{1F689}", 'CHARACTER_TRAM' => "\u{1F68A}", 'CHARACTER_MONORAIL' => "\u{1F69D}", 'CHARACTER_MOUNTAIN_RAILWAY' => "\u{1F69E}", 'CHARACTER_TRAM_CAR' => "\u{1F68B}", 'CHARACTER_BUS' => "\u{1F68C}", 'CHARACTER_ONCOMING_BUS' => "\u{1F68D}", 'CHARACTER_TROLLEYBUS' => "\u{1F68E}", 'CHARACTER_MINIBUS' => "\u{1F690}", 'CHARACTER_AMBULANCE' => "\u{1F691}", 'CHARACTER_FIRE_ENGINE' => "\u{1F692}", 'CHARACTER_POLICE_CAR' => "\u{1F693}", 'CHARACTER_ONCOMING_POLICE_CAR' => "\u{1F694}", 'CHARACTER_TAXI' => "\u{1F695}", 'CHARACTER_ONCOMING_TAXI' => "\u{1F696}", 'CHARACTER_AUTOMOBILE' => "\u{1F697}", 'CHARACTER_ONCOMING_AUTOMOBILE' => "\u{1F698}", 'CHARACTER_SPORT_UTILITY_VEHICLE' => "\u{1F699}", 'CHARACTER_DELIVERY_TRUCK' => "\u{1F69A}", 'CHARACTER_ARTICULATED_LORRY' => "\u{1F69B}", 'CHARACTER_TRACTOR' => "\u{1F69C}", 'CHARACTER_BICYCLE' => "\u{1F6B2}", 'CHARACTER_KICK_SCOOTER' => "\u{1F6F4}", 'CHARACTER_SKATEBOARD' => "\u{1F6F9}", 'CHARACTER_MOTOR_SCOOTER' => "\u{1F6F5}", 'CHARACTER_BUS_STOP' => "\u{1F68F}", 'CHARACTER_MOTORWAY' => "\u{1F6E3}\u{FE0F}", 'CHARACTER_RAILWAY_TRACK' => "\u{1F6E4}\u{FE0F}", 'CHARACTER_OIL_DRUM' => "\u{1F6E2}\u{FE0F}", 'CHARACTER_FUEL_PUMP' => "\u{26FD}", 'CHARACTER_POLICE_CAR_LIGHT' => "\u{1F6A8}", 'CHARACTER_HORIZONTAL_TRAFFIC_LIGHT' => "\u{1F6A5}", 'CHARACTER_VERTICAL_TRAFFIC_LIGHT' => "\u{1F6A6}", 'CHARACTER_STOP_SIGN' => "\u{1F6D1}", 'CHARACTER_CONSTRUCTION' => "\u{1F6A7}", 'CHARACTER_ANCHOR' => "\u{2693}", 'CHARACTER_SAILBOAT' => "\u{26F5}", 'CHARACTER_CANOE' => "\u{1F6F6}", 'CHARACTER_SPEEDBOAT' => "\u{1F6A4}", 'CHARACTER_PASSENGER_SHIP' => "\u{1F6F3}\u{FE0F}", 'CHARACTER_FERRY' => "\u{26F4}\u{FE0F}", 'CHARACTER_MOTOR_BOAT' => "\u{1F6E5}\u{FE0F}", 'CHARACTER_SHIP' => "\u{1F6A2}", 'CHARACTER_AIRPLANE' => "\u{2708}\u{FE0F}", 'CHARACTER_SMALL_AIRPLANE' => "\u{1F6E9}\u{FE0F}", 'CHARACTER_AIRPLANE_DEPARTURE' => "\u{1F6EB}", 'CHARACTER_AIRPLANE_ARRIVAL' => "\u{1F6EC}", 'CHARACTER_SEAT' => "\u{1F4BA}", 'CHARACTER_HELICOPTER' => "\u{1F681}", 'CHARACTER_SUSPENSION_RAILWAY' => "\u{1F69F}", 'CHARACTER_MOUNTAIN_CABLEWAY' => "\u{1F6A0}", 'CHARACTER_AERIAL_TRAMWAY' => "\u{1F6A1}", 'CHARACTER_SATELLITE' => "\u{1F6F0}\u{FE0F}", 'CHARACTER_ROCKET' => "\u{1F680}", 'CHARACTER_FLYING_SAUCER' => "\u{1F6F8}", 'CHARACTER_BELLHOP_BELL' => "\u{1F6CE}\u{FE0F}", 'CHARACTER_LUGGAGE' => "\u{1F9F3}", 'CHARACTER_HOURGLASS_DONE' => "\u{231B}", 'CHARACTER_HOURGLASS_NOT_DONE' => "\u{23F3}", 'CHARACTER_WATCH' => "\u{231A}", 'CHARACTER_ALARM_CLOCK' => "\u{23F0}", 'CHARACTER_STOPWATCH' => "\u{23F1}\u{FE0F}", 'CHARACTER_TIMER_CLOCK' => "\u{23F2}\u{FE0F}", 'CHARACTER_MANTELPIECE_CLOCK' => "\u{1F570}\u{FE0F}", 'CHARACTER_TWELVE_O_CLOCK' => "\u{1F55B}", 'CHARACTER_TWELVE_THIRTY' => "\u{1F567}", 'CHARACTER_ONE_O_CLOCK' => "\u{1F550}", 'CHARACTER_ONE_THIRTY' => "\u{1F55C}", 'CHARACTER_TWO_O_CLOCK' => "\u{1F551}", 'CHARACTER_TWO_THIRTY' => "\u{1F55D}", 'CHARACTER_THREE_O_CLOCK' => "\u{1F552}", 'CHARACTER_THREE_THIRTY' => "\u{1F55E}", 'CHARACTER_FOUR_O_CLOCK' => "\u{1F553}", 'CHARACTER_FOUR_THIRTY' => "\u{1F55F}", 'CHARACTER_FIVE_O_CLOCK' => "\u{1F554}", 'CHARACTER_FIVE_THIRTY' => "\u{1F560}", 'CHARACTER_SIX_O_CLOCK' => "\u{1F555}", 'CHARACTER_SIX_THIRTY' => "\u{1F561}", 'CHARACTER_SEVEN_O_CLOCK' => "\u{1F556}", 'CHARACTER_SEVEN_THIRTY' => "\u{1F562}", 'CHARACTER_EIGHT_O_CLOCK' => "\u{1F557}", 'CHARACTER_EIGHT_THIRTY' => "\u{1F563}", 'CHARACTER_NINE_O_CLOCK' => "\u{1F558}", 'CHARACTER_NINE_THIRTY' => "\u{1F564}", 'CHARACTER_TEN_O_CLOCK' => "\u{1F559}", 'CHARACTER_TEN_THIRTY' => "\u{1F565}", 'CHARACTER_ELEVEN_O_CLOCK' => "\u{1F55A}", 'CHARACTER_ELEVEN_THIRTY' => "\u{1F566}", 'CHARACTER_NEW_MOON' => "\u{1F311}", 'CHARACTER_WAXING_CRESCENT_MOON' => "\u{1F312}", 'CHARACTER_FIRST_QUARTER_MOON' => "\u{1F313}", 'CHARACTER_WAXING_GIBBOUS_MOON' => "\u{1F314}", 'CHARACTER_FULL_MOON' => "\u{1F315}", 'CHARACTER_WANING_GIBBOUS_MOON' => "\u{1F316}", 'CHARACTER_LAST_QUARTER_MOON' => "\u{1F317}", 'CHARACTER_WANING_CRESCENT_MOON' => "\u{1F318}", 'CHARACTER_CRESCENT_MOON' => "\u{1F319}", 'CHARACTER_NEW_MOON_FACE' => "\u{1F31A}", 'CHARACTER_FIRST_QUARTER_MOON_FACE' => "\u{1F31B}", 'CHARACTER_LAST_QUARTER_MOON_FACE' => "\u{1F31C}", 'CHARACTER_THERMOMETER' => "\u{1F321}\u{FE0F}", 'CHARACTER_SUN' => "\u{2600}\u{FE0F}", 'CHARACTER_FULL_MOON_FACE' => "\u{1F31D}", 'CHARACTER_SUN_WITH_FACE' => "\u{1F31E}", 'CHARACTER_STAR' => "\u{2B50}", 'CHARACTER_GLOWING_STAR' => "\u{1F31F}", 'CHARACTER_SHOOTING_STAR' => "\u{1F320}", 'CHARACTER_CLOUD' => "\u{2601}\u{FE0F}", 'CHARACTER_SUN_BEHIND_CLOUD' => "\u{26C5}", 'CHARACTER_CLOUD_WITH_LIGHTNING_AND_RAIN' => "\u{26C8}\u{FE0F}", 'CHARACTER_SUN_BEHIND_SMALL_CLOUD' => "\u{1F324}\u{FE0F}", 'CHARACTER_SUN_BEHIND_LARGE_CLOUD' => "\u{1F325}\u{FE0F}", 'CHARACTER_SUN_BEHIND_RAIN_CLOUD' => "\u{1F326}\u{FE0F}", 'CHARACTER_CLOUD_WITH_RAIN' => "\u{1F327}\u{FE0F}", 'CHARACTER_CLOUD_WITH_SNOW' => "\u{1F328}\u{FE0F}", 'CHARACTER_CLOUD_WITH_LIGHTNING' => "\u{1F329}\u{FE0F}", 'CHARACTER_TORNADO' => "\u{1F32A}\u{FE0F}", 'CHARACTER_FOG' => "\u{1F32B}\u{FE0F}", 'CHARACTER_WIND_FACE' => "\u{1F32C}\u{FE0F}", 'CHARACTER_CYCLONE' => "\u{1F300}", 'CHARACTER_RAINBOW' => "\u{1F308}", 'CHARACTER_CLOSED_UMBRELLA' => "\u{1F302}", 'CHARACTER_UMBRELLA' => "\u{2602}\u{FE0F}", 'CHARACTER_UMBRELLA_WITH_RAIN_DROPS' => "\u{2614}", 'CHARACTER_UMBRELLA_ON_GROUND' => "\u{26F1}\u{FE0F}", 'CHARACTER_HIGH_VOLTAGE' => "\u{26A1}", 'CHARACTER_SNOWFLAKE' => "\u{2744}\u{FE0F}", 'CHARACTER_SNOWMAN' => "\u{2603}\u{FE0F}", 'CHARACTER_SNOWMAN_WITHOUT_SNOW' => "\u{26C4}", 'CHARACTER_COMET' => "\u{2604}\u{FE0F}", 'CHARACTER_FIRE' => "\u{1F525}", 'CHARACTER_DROPLET' => "\u{1F4A7}", 'CHARACTER_WATER_WAVE' => "\u{1F30A}", 'CHARACTER_JACK_O_LANTERN' => "\u{1F383}", 'CHARACTER_CHRISTMAS_TREE' => "\u{1F384}", 'CHARACTER_FIREWORKS' => "\u{1F386}", 'CHARACTER_SPARKLER' => "\u{1F387}", 'CHARACTER_FIRECRACKER' => "\u{1F9E8}", 'CHARACTER_SPARKLES' => "\u{2728}", 'CHARACTER_BALLOON' => "\u{1F388}", 'CHARACTER_PARTY_POPPER' => "\u{1F389}", 'CHARACTER_CONFETTI_BALL' => "\u{1F38A}", 'CHARACTER_TANABATA_TREE' => "\u{1F38B}", 'CHARACTER_PINE_DECORATION' => "\u{1F38D}", 'CHARACTER_JAPANESE_DOLLS' => "\u{1F38E}", 'CHARACTER_CARP_STREAMER' => "\u{1F38F}", 'CHARACTER_WIND_CHIME' => "\u{1F390}", 'CHARACTER_MOON_VIEWING_CEREMONY' => "\u{1F391}", 'CHARACTER_RED_ENVELOPE' => "\u{1F9E7}", 'CHARACTER_RIBBON' => "\u{1F380}", 'CHARACTER_WRAPPED_GIFT' => "\u{1F381}", 'CHARACTER_REMINDER_RIBBON' => "\u{1F397}\u{FE0F}", 'CHARACTER_ADMISSION_TICKETS' => "\u{1F39F}\u{FE0F}", 'CHARACTER_TICKET' => "\u{1F3AB}", 'CHARACTER_MILITARY_MEDAL' => "\u{1F396}\u{FE0F}", 'CHARACTER_TROPHY' => "\u{1F3C6}", 'CHARACTER_SPORTS_MEDAL' => "\u{1F3C5}", 'CHARACTER_1ST_PLACE_MEDAL' => "\u{1F947}", 'CHARACTER_2ND_PLACE_MEDAL' => "\u{1F948}", 'CHARACTER_3RD_PLACE_MEDAL' => "\u{1F949}", 'CHARACTER_SOCCER_BALL' => "\u{26BD}", 'CHARACTER_BASEBALL' => "\u{26BE}", 'CHARACTER_SOFTBALL' => "\u{1F94E}", 'CHARACTER_BASKETBALL' => "\u{1F3C0}", 'CHARACTER_VOLLEYBALL' => "\u{1F3D0}", 'CHARACTER_AMERICAN_FOOTBALL' => "\u{1F3C8}", 'CHARACTER_RUGBY_FOOTBALL' => "\u{1F3C9}", 'CHARACTER_TENNIS' => "\u{1F3BE}", 'CHARACTER_FLYING_DISC' => "\u{1F94F}", 'CHARACTER_BOWLING' => "\u{1F3B3}", 'CHARACTER_CRICKET_GAME' => "\u{1F3CF}", 'CHARACTER_FIELD_HOCKEY' => "\u{1F3D1}", 'CHARACTER_ICE_HOCKEY' => "\u{1F3D2}", 'CHARACTER_LACROSSE' => "\u{1F94D}", 'CHARACTER_PING_PONG' => "\u{1F3D3}", 'CHARACTER_BADMINTON' => "\u{1F3F8}", 'CHARACTER_BOXING_GLOVE' => "\u{1F94A}", 'CHARACTER_MARTIAL_ARTS_UNIFORM' => "\u{1F94B}", 'CHARACTER_GOAL_NET' => "\u{1F945}", 'CHARACTER_FLAG_IN_HOLE' => "\u{26F3}", 'CHARACTER_ICE_SKATE' => "\u{26F8}\u{FE0F}", 'CHARACTER_FISHING_POLE' => "\u{1F3A3}", 'CHARACTER_RUNNING_SHIRT' => "\u{1F3BD}", 'CHARACTER_SKIS' => "\u{1F3BF}", 'CHARACTER_SLED' => "\u{1F6F7}", 'CHARACTER_CURLING_STONE' => "\u{1F94C}", 'CHARACTER_DIRECT_HIT' => "\u{1F3AF}", 'CHARACTER_POOL_8_BALL' => "\u{1F3B1}", 'CHARACTER_CRYSTAL_BALL' => "\u{1F52E}", 'CHARACTER_NAZAR_AMULET' => "\u{1F9FF}", 'CHARACTER_VIDEO_GAME' => "\u{1F3AE}", 'CHARACTER_JOYSTICK' => "\u{1F579}\u{FE0F}", 'CHARACTER_SLOT_MACHINE' => "\u{1F3B0}", 'CHARACTER_GAME_DIE' => "\u{1F3B2}", 'CHARACTER_JIGSAW' => "\u{1F9E9}", 'CHARACTER_TEDDY_BEAR' => "\u{1F9F8}", 'CHARACTER_SPADE_SUIT' => "\u{2660}\u{FE0F}", 'CHARACTER_HEART_SUIT' => "\u{2665}\u{FE0F}", 'CHARACTER_DIAMOND_SUIT' => "\u{2666}\u{FE0F}", 'CHARACTER_CLUB_SUIT' => "\u{2663}\u{FE0F}", 'CHARACTER_CHESS_PAWN' => "\u{265F}\u{FE0F}", 'CHARACTER_JOKER' => "\u{1F0CF}", 'CHARACTER_MAHJONG_RED_DRAGON' => "\u{1F004}", 'CHARACTER_FLOWER_PLAYING_CARDS' => "\u{1F3B4}", 'CHARACTER_PERFORMING_ARTS' => "\u{1F3AD}", 'CHARACTER_FRAMED_PICTURE' => "\u{1F5BC}\u{FE0F}", 'CHARACTER_ARTIST_PALETTE' => "\u{1F3A8}", 'CHARACTER_THREAD' => "\u{1F9F5}", 'CHARACTER_YARN' => "\u{1F9F6}", 'CHARACTER_MUTED_SPEAKER' => "\u{1F507}", 'CHARACTER_SPEAKER_LOW_VOLUME' => "\u{1F508}", 'CHARACTER_SPEAKER_MEDIUM_VOLUME' => "\u{1F509}", 'CHARACTER_SPEAKER_HIGH_VOLUME' => "\u{1F50A}", 'CHARACTER_LOUDSPEAKER' => "\u{1F4E2}", 'CHARACTER_MEGAPHONE' => "\u{1F4E3}", 'CHARACTER_POSTAL_HORN' => "\u{1F4EF}", 'CHARACTER_BELL' => "\u{1F514}", 'CHARACTER_BELL_WITH_SLASH' => "\u{1F515}", 'CHARACTER_MUSICAL_SCORE' => "\u{1F3BC}", 'CHARACTER_MUSICAL_NOTE' => "\u{1F3B5}", 'CHARACTER_MUSICAL_NOTES' => "\u{1F3B6}", 'CHARACTER_STUDIO_MICROPHONE' => "\u{1F399}\u{FE0F}", 'CHARACTER_LEVEL_SLIDER' => "\u{1F39A}\u{FE0F}", 'CHARACTER_CONTROL_KNOBS' => "\u{1F39B}\u{FE0F}", 'CHARACTER_MICROPHONE' => "\u{1F3A4}", 'CHARACTER_HEADPHONE' => "\u{1F3A7}", 'CHARACTER_RADIO' => "\u{1F4FB}", 'CHARACTER_SAXOPHONE' => "\u{1F3B7}", 'CHARACTER_GUITAR' => "\u{1F3B8}", 'CHARACTER_MUSICAL_KEYBOARD' => "\u{1F3B9}", 'CHARACTER_TRUMPET' => "\u{1F3BA}", 'CHARACTER_VIOLIN' => "\u{1F3BB}", 'CHARACTER_DRUM' => "\u{1F941}", 'CHARACTER_MOBILE_PHONE' => "\u{1F4F1}", 'CHARACTER_MOBILE_PHONE_WITH_ARROW' => "\u{1F4F2}", 'CHARACTER_TELEPHONE' => "\u{260E}\u{FE0F}", 'CHARACTER_TELEPHONE_RECEIVER' => "\u{1F4DE}", 'CHARACTER_PAGER' => "\u{1F4DF}", 'CHARACTER_FAX_MACHINE' => "\u{1F4E0}", 'CHARACTER_BATTERY' => "\u{1F50B}", 'CHARACTER_ELECTRIC_PLUG' => "\u{1F50C}", 'CHARACTER_LAPTOP_COMPUTER' => "\u{1F4BB}", 'CHARACTER_DESKTOP_COMPUTER' => "\u{1F5A5}\u{FE0F}", 'CHARACTER_PRINTER' => "\u{1F5A8}\u{FE0F}", 'CHARACTER_KEYBOARD' => "\u{2328}\u{FE0F}", 'CHARACTER_COMPUTER_MOUSE' => "\u{1F5B1}\u{FE0F}", 'CHARACTER_TRACKBALL' => "\u{1F5B2}\u{FE0F}", 'CHARACTER_COMPUTER_DISK' => "\u{1F4BD}", 'CHARACTER_FLOPPY_DISK' => "\u{1F4BE}", 'CHARACTER_OPTICAL_DISK' => "\u{1F4BF}", 'CHARACTER_DVD' => "\u{1F4C0}", 'CHARACTER_ABACUS' => "\u{1F9EE}", 'CHARACTER_MOVIE_CAMERA' => "\u{1F3A5}", 'CHARACTER_FILM_FRAMES' => "\u{1F39E}\u{FE0F}", 'CHARACTER_FILM_PROJECTOR' => "\u{1F4FD}\u{FE0F}", 'CHARACTER_CLAPPER_BOARD' => "\u{1F3AC}", 'CHARACTER_TELEVISION' => "\u{1F4FA}", 'CHARACTER_CAMERA' => "\u{1F4F7}", 'CHARACTER_CAMERA_WITH_FLASH' => "\u{1F4F8}", 'CHARACTER_VIDEO_CAMERA' => "\u{1F4F9}", 'CHARACTER_VIDEOCASSETTE' => "\u{1F4FC}", 'CHARACTER_MAGNIFYING_GLASS_TILTED_LEFT' => "\u{1F50D}", 'CHARACTER_MAGNIFYING_GLASS_TILTED_RIGHT' => "\u{1F50E}", 'CHARACTER_CANDLE' => "\u{1F56F}\u{FE0F}", 'CHARACTER_LIGHT_BULB' => "\u{1F4A1}", 'CHARACTER_FLASHLIGHT' => "\u{1F526}", 'CHARACTER_RED_PAPER_LANTERN' => "\u{1F3EE}", 'CHARACTER_NOTEBOOK_WITH_DECORATIVE_COVER' => "\u{1F4D4}", 'CHARACTER_CLOSED_BOOK' => "\u{1F4D5}", 'CHARACTER_OPEN_BOOK' => "\u{1F4D6}", 'CHARACTER_GREEN_BOOK' => "\u{1F4D7}", 'CHARACTER_BLUE_BOOK' => "\u{1F4D8}", 'CHARACTER_ORANGE_BOOK' => "\u{1F4D9}", 'CHARACTER_BOOKS' => "\u{1F4DA}", 'CHARACTER_NOTEBOOK' => "\u{1F4D3}", 'CHARACTER_LEDGER' => "\u{1F4D2}", 'CHARACTER_PAGE_WITH_CURL' => "\u{1F4C3}", 'CHARACTER_SCROLL' => "\u{1F4DC}", 'CHARACTER_PAGE_FACING_UP' => "\u{1F4C4}", 'CHARACTER_NEWSPAPER' => "\u{1F4F0}", 'CHARACTER_ROLLED_UP_NEWSPAPER' => "\u{1F5DE}\u{FE0F}", 'CHARACTER_BOOKMARK_TABS' => "\u{1F4D1}", 'CHARACTER_BOOKMARK' => "\u{1F516}", 'CHARACTER_LABEL' => "\u{1F3F7}\u{FE0F}", 'CHARACTER_MONEY_BAG' => "\u{1F4B0}", 'CHARACTER_YEN_BANKNOTE' => "\u{1F4B4}", 'CHARACTER_DOLLAR_BANKNOTE' => "\u{1F4B5}", 'CHARACTER_EURO_BANKNOTE' => "\u{1F4B6}", 'CHARACTER_POUND_BANKNOTE' => "\u{1F4B7}", 'CHARACTER_MONEY_WITH_WINGS' => "\u{1F4B8}", 'CHARACTER_CREDIT_CARD' => "\u{1F4B3}", 'CHARACTER_RECEIPT' => "\u{1F9FE}", 'CHARACTER_CHART_INCREASING_WITH_YEN' => "\u{1F4B9}", 'CHARACTER_CURRENCY_EXCHANGE' => "\u{1F4B1}", 'CHARACTER_HEAVY_DOLLAR_SIGN' => "\u{1F4B2}", 'CHARACTER_ENVELOPE' => "\u{2709}\u{FE0F}", 'CHARACTER_E_MAIL' => "\u{1F4E7}", 'CHARACTER_INCOMING_ENVELOPE' => "\u{1F4E8}", 'CHARACTER_ENVELOPE_WITH_ARROW' => "\u{1F4E9}", 'CHARACTER_OUTBOX_TRAY' => "\u{1F4E4}", 'CHARACTER_INBOX_TRAY' => "\u{1F4E5}", 'CHARACTER_PACKAGE' => "\u{1F4E6}", 'CHARACTER_CLOSED_MAILBOX_WITH_RAISED_FLAG' => "\u{1F4EB}", 'CHARACTER_CLOSED_MAILBOX_WITH_LOWERED_FLAG' => "\u{1F4EA}", 'CHARACTER_OPEN_MAILBOX_WITH_RAISED_FLAG' => "\u{1F4EC}", 'CHARACTER_OPEN_MAILBOX_WITH_LOWERED_FLAG' => "\u{1F4ED}", 'CHARACTER_POSTBOX' => "\u{1F4EE}", 'CHARACTER_BALLOT_BOX_WITH_BALLOT' => "\u{1F5F3}\u{FE0F}", 'CHARACTER_PENCIL' => "\u{270F}\u{FE0F}", 'CHARACTER_BLACK_NIB' => "\u{2712}\u{FE0F}", 'CHARACTER_FOUNTAIN_PEN' => "\u{1F58B}\u{FE0F}", 'CHARACTER_PEN' => "\u{1F58A}\u{FE0F}", 'CHARACTER_PAINTBRUSH' => "\u{1F58C}\u{FE0F}", 'CHARACTER_CRAYON' => "\u{1F58D}\u{FE0F}", 'CHARACTER_MEMO' => "\u{1F4DD}", 'CHARACTER_BRIEFCASE' => "\u{1F4BC}", 'CHARACTER_FILE_FOLDER' => "\u{1F4C1}", 'CHARACTER_OPEN_FILE_FOLDER' => "\u{1F4C2}", 'CHARACTER_CARD_INDEX_DIVIDERS' => "\u{1F5C2}\u{FE0F}", 'CHARACTER_CALENDAR' => "\u{1F4C5}", 'CHARACTER_TEAR_OFF_CALENDAR' => "\u{1F4C6}", 'CHARACTER_SPIRAL_NOTEPAD' => "\u{1F5D2}\u{FE0F}", 'CHARACTER_SPIRAL_CALENDAR' => "\u{1F5D3}\u{FE0F}", 'CHARACTER_CARD_INDEX' => "\u{1F4C7}", 'CHARACTER_CHART_INCREASING' => "\u{1F4C8}", 'CHARACTER_CHART_DECREASING' => "\u{1F4C9}", 'CHARACTER_BAR_CHART' => "\u{1F4CA}", 'CHARACTER_CLIPBOARD' => "\u{1F4CB}", 'CHARACTER_PUSHPIN' => "\u{1F4CC}", 'CHARACTER_ROUND_PUSHPIN' => "\u{1F4CD}", 'CHARACTER_PAPERCLIP' => "\u{1F4CE}", 'CHARACTER_LINKED_PAPERCLIPS' => "\u{1F587}\u{FE0F}", 'CHARACTER_STRAIGHT_RULER' => "\u{1F4CF}", 'CHARACTER_TRIANGULAR_RULER' => "\u{1F4D0}", 'CHARACTER_SCISSORS' => "\u{2702}\u{FE0F}", 'CHARACTER_CARD_FILE_BOX' => "\u{1F5C3}\u{FE0F}", 'CHARACTER_FILE_CABINET' => "\u{1F5C4}\u{FE0F}", 'CHARACTER_WASTEBASKET' => "\u{1F5D1}\u{FE0F}", 'CHARACTER_LOCKED' => "\u{1F512}", 'CHARACTER_UNLOCKED' => "\u{1F513}", 'CHARACTER_LOCKED_WITH_PEN' => "\u{1F50F}", 'CHARACTER_LOCKED_WITH_KEY' => "\u{1F510}", 'CHARACTER_KEY' => "\u{1F511}", 'CHARACTER_OLD_KEY' => "\u{1F5DD}\u{FE0F}", 'CHARACTER_HAMMER' => "\u{1F528}", 'CHARACTER_PICK' => "\u{26CF}\u{FE0F}", 'CHARACTER_HAMMER_AND_PICK' => "\u{2692}\u{FE0F}", 'CHARACTER_HAMMER_AND_WRENCH' => "\u{1F6E0}\u{FE0F}", 'CHARACTER_DAGGER' => "\u{1F5E1}\u{FE0F}", 'CHARACTER_CROSSED_SWORDS' => "\u{2694}\u{FE0F}", 'CHARACTER_PISTOL' => "\u{1F52B}", 'CHARACTER_BOW_AND_ARROW' => "\u{1F3F9}", 'CHARACTER_SHIELD' => "\u{1F6E1}\u{FE0F}", 'CHARACTER_WRENCH' => "\u{1F527}", 'CHARACTER_NUT_AND_BOLT' => "\u{1F529}", 'CHARACTER_GEAR' => "\u{2699}\u{FE0F}", 'CHARACTER_CLAMP' => "\u{1F5DC}\u{FE0F}", 'CHARACTER_BALANCE_SCALE' => "\u{2696}\u{FE0F}", 'CHARACTER_LINK' => "\u{1F517}", 'CHARACTER_CHAINS' => "\u{26D3}\u{FE0F}", 'CHARACTER_TOOLBOX' => "\u{1F9F0}", 'CHARACTER_MAGNET' => "\u{1F9F2}", 'CHARACTER_ALEMBIC' => "\u{2697}\u{FE0F}", 'CHARACTER_TEST_TUBE' => "\u{1F9EA}", 'CHARACTER_PETRI_DISH' => "\u{1F9EB}", 'CHARACTER_DNA' => "\u{1F9EC}", 'CHARACTER_MICROSCOPE' => "\u{1F52C}", 'CHARACTER_TELESCOPE' => "\u{1F52D}", 'CHARACTER_SATELLITE_ANTENNA' => "\u{1F4E1}", 'CHARACTER_SYRINGE' => "\u{1F489}", 'CHARACTER_PILL' => "\u{1F48A}", 'CHARACTER_DOOR' => "\u{1F6AA}", 'CHARACTER_BED' => "\u{1F6CF}\u{FE0F}", 'CHARACTER_COUCH_AND_LAMP' => "\u{1F6CB}\u{FE0F}", 'CHARACTER_TOILET' => "\u{1F6BD}", 'CHARACTER_SHOWER' => "\u{1F6BF}", 'CHARACTER_BATHTUB' => "\u{1F6C1}", 'CHARACTER_LOTION_BOTTLE' => "\u{1F9F4}", 'CHARACTER_SAFETY_PIN' => "\u{1F9F7}", 'CHARACTER_BROOM' => "\u{1F9F9}", 'CHARACTER_BASKET' => "\u{1F9FA}", 'CHARACTER_ROLL_OF_PAPER' => "\u{1F9FB}", 'CHARACTER_SOAP' => "\u{1F9FC}", 'CHARACTER_SPONGE' => "\u{1F9FD}", 'CHARACTER_FIRE_EXTINGUISHER' => "\u{1F9EF}", 'CHARACTER_SHOPPING_CART' => "\u{1F6D2}", 'CHARACTER_CIGARETTE' => "\u{1F6AC}", 'CHARACTER_COFFIN' => "\u{26B0}\u{FE0F}", 'CHARACTER_FUNERAL_URN' => "\u{26B1}\u{FE0F}", 'CHARACTER_MOAI' => "\u{1F5FF}", 'CHARACTER_ATM_SIGN' => "\u{1F3E7}", 'CHARACTER_LITTER_IN_BIN_SIGN' => "\u{1F6AE}", 'CHARACTER_POTABLE_WATER' => "\u{1F6B0}", 'CHARACTER_WHEELCHAIR_SYMBOL' => "\u{267F}", 'CHARACTER_MEN_S_ROOM' => "\u{1F6B9}", 'CHARACTER_WOMEN_S_ROOM' => "\u{1F6BA}", 'CHARACTER_RESTROOM' => "\u{1F6BB}", 'CHARACTER_BABY_SYMBOL' => "\u{1F6BC}", 'CHARACTER_WATER_CLOSET' => "\u{1F6BE}", 'CHARACTER_PASSPORT_CONTROL' => "\u{1F6C2}", 'CHARACTER_CUSTOMS' => "\u{1F6C3}", 'CHARACTER_BAGGAGE_CLAIM' => "\u{1F6C4}", 'CHARACTER_LEFT_LUGGAGE' => "\u{1F6C5}", 'CHARACTER_WARNING' => "\u{26A0}\u{FE0F}", 'CHARACTER_CHILDREN_CROSSING' => "\u{1F6B8}", 'CHARACTER_NO_ENTRY' => "\u{26D4}", 'CHARACTER_PROHIBITED' => "\u{1F6AB}", 'CHARACTER_NO_BICYCLES' => "\u{1F6B3}", 'CHARACTER_NO_SMOKING' => "\u{1F6AD}", 'CHARACTER_NO_LITTERING' => "\u{1F6AF}", 'CHARACTER_NON_POTABLE_WATER' => "\u{1F6B1}", 'CHARACTER_NO_PEDESTRIANS' => "\u{1F6B7}", 'CHARACTER_NO_MOBILE_PHONES' => "\u{1F4F5}", 'CHARACTER_NO_ONE_UNDER_EIGHTEEN' => "\u{1F51E}", 'CHARACTER_RADIOACTIVE' => "\u{2622}\u{FE0F}", 'CHARACTER_BIOHAZARD' => "\u{2623}\u{FE0F}", 'CHARACTER_UP_ARROW' => "\u{2B06}\u{FE0F}", 'CHARACTER_UP_RIGHT_ARROW' => "\u{2197}\u{FE0F}", 'CHARACTER_RIGHT_ARROW' => "\u{27A1}\u{FE0F}", 'CHARACTER_DOWN_RIGHT_ARROW' => "\u{2198}\u{FE0F}", 'CHARACTER_DOWN_ARROW' => "\u{2B07}\u{FE0F}", 'CHARACTER_DOWN_LEFT_ARROW' => "\u{2199}\u{FE0F}", 'CHARACTER_LEFT_ARROW' => "\u{2B05}\u{FE0F}", 'CHARACTER_UP_LEFT_ARROW' => "\u{2196}\u{FE0F}", 'CHARACTER_UP_DOWN_ARROW' => "\u{2195}\u{FE0F}", 'CHARACTER_LEFT_RIGHT_ARROW' => "\u{2194}\u{FE0F}", 'CHARACTER_RIGHT_ARROW_CURVING_LEFT' => "\u{21A9}\u{FE0F}", 'CHARACTER_LEFT_ARROW_CURVING_RIGHT' => "\u{21AA}\u{FE0F}", 'CHARACTER_RIGHT_ARROW_CURVING_UP' => "\u{2934}\u{FE0F}", 'CHARACTER_RIGHT_ARROW_CURVING_DOWN' => "\u{2935}\u{FE0F}", 'CHARACTER_CLOCKWISE_VERTICAL_ARROWS' => "\u{1F503}", 'CHARACTER_COUNTERCLOCKWISE_ARROWS_BUTTON' => "\u{1F504}", 'CHARACTER_BACK_ARROW' => "\u{1F519}", 'CHARACTER_END_ARROW' => "\u{1F51A}", 'CHARACTER_ON_ARROW' => "\u{1F51B}", 'CHARACTER_SOON_ARROW' => "\u{1F51C}", 'CHARACTER_TOP_ARROW' => "\u{1F51D}", 'CHARACTER_PLACE_OF_WORSHIP' => "\u{1F6D0}", 'CHARACTER_ATOM_SYMBOL' => "\u{269B}\u{FE0F}", 'CHARACTER_OM' => "\u{1F549}\u{FE0F}", 'CHARACTER_STAR_OF_DAVID' => "\u{2721}\u{FE0F}", 'CHARACTER_WHEEL_OF_DHARMA' => "\u{2638}\u{FE0F}", 'CHARACTER_YIN_YANG' => "\u{262F}\u{FE0F}", 'CHARACTER_LATIN_CROSS' => "\u{271D}\u{FE0F}", 'CHARACTER_ORTHODOX_CROSS' => "\u{2626}\u{FE0F}", 'CHARACTER_STAR_AND_CRESCENT' => "\u{262A}\u{FE0F}", 'CHARACTER_PEACE_SYMBOL' => "\u{262E}\u{FE0F}", 'CHARACTER_MENORAH' => "\u{1F54E}", 'CHARACTER_DOTTED_SIX_POINTED_STAR' => "\u{1F52F}", 'CHARACTER_ARIES' => "\u{2648}", 'CHARACTER_TAURUS' => "\u{2649}", 'CHARACTER_GEMINI' => "\u{264A}", 'CHARACTER_CANCER' => "\u{264B}", 'CHARACTER_LEO' => "\u{264C}", 'CHARACTER_VIRGO' => "\u{264D}", 'CHARACTER_LIBRA' => "\u{264E}", 'CHARACTER_SCORPIO' => "\u{264F}", 'CHARACTER_SAGITTARIUS' => "\u{2650}", 'CHARACTER_CAPRICORN' => "\u{2651}", 'CHARACTER_AQUARIUS' => "\u{2652}", 'CHARACTER_PISCES' => "\u{2653}", 'CHARACTER_OPHIUCHUS' => "\u{26CE}", 'CHARACTER_SHUFFLE_TRACKS_BUTTON' => "\u{1F500}", 'CHARACTER_REPEAT_BUTTON' => "\u{1F501}", 'CHARACTER_REPEAT_SINGLE_BUTTON' => "\u{1F502}", 'CHARACTER_PLAY_BUTTON' => "\u{25B6}\u{FE0F}", 'CHARACTER_FAST_FORWARD_BUTTON' => "\u{23E9}", 'CHARACTER_NEXT_TRACK_BUTTON' => "\u{23ED}\u{FE0F}", 'CHARACTER_PLAY_OR_PAUSE_BUTTON' => "\u{23EF}\u{FE0F}", 'CHARACTER_REVERSE_BUTTON' => "\u{25C0}\u{FE0F}", 'CHARACTER_FAST_REVERSE_BUTTON' => "\u{23EA}", 'CHARACTER_LAST_TRACK_BUTTON' => "\u{23EE}\u{FE0F}", 'CHARACTER_UPWARDS_BUTTON' => "\u{1F53C}", 'CHARACTER_FAST_UP_BUTTON' => "\u{23EB}", 'CHARACTER_DOWNWARDS_BUTTON' => "\u{1F53D}", 'CHARACTER_FAST_DOWN_BUTTON' => "\u{23EC}", 'CHARACTER_PAUSE_BUTTON' => "\u{23F8}\u{FE0F}", 'CHARACTER_STOP_BUTTON' => "\u{23F9}\u{FE0F}", 'CHARACTER_RECORD_BUTTON' => "\u{23FA}\u{FE0F}", 'CHARACTER_EJECT_BUTTON' => "\u{23CF}\u{FE0F}", 'CHARACTER_CINEMA' => "\u{1F3A6}", 'CHARACTER_DIM_BUTTON' => "\u{1F505}", 'CHARACTER_BRIGHT_BUTTON' => "\u{1F506}", 'CHARACTER_ANTENNA_BARS' => "\u{1F4F6}", 'CHARACTER_VIBRATION_MODE' => "\u{1F4F3}", 'CHARACTER_MOBILE_PHONE_OFF' => "\u{1F4F4}", 'CHARACTER_FEMALE_SIGN' => "\u{2640}\u{FE0F}", 'CHARACTER_MALE_SIGN' => "\u{2642}\u{FE0F}", 'CHARACTER_MEDICAL_SYMBOL' => "\u{2695}\u{FE0F}", 'CHARACTER_INFINITY' => "\u{267E}\u{FE0F}", 'CHARACTER_RECYCLING_SYMBOL' => "\u{267B}\u{FE0F}", 'CHARACTER_FLEUR_DE_LIS' => "\u{269C}\u{FE0F}", 'CHARACTER_TRIDENT_EMBLEM' => "\u{1F531}", 'CHARACTER_NAME_BADGE' => "\u{1F4DB}", 'CHARACTER_JAPANESE_SYMBOL_FOR_BEGINNER' => "\u{1F530}", 'CHARACTER_HEAVY_LARGE_CIRCLE' => "\u{2B55}", 'CHARACTER_WHITE_HEAVY_CHECK_MARK' => "\u{2705}", 'CHARACTER_BALLOT_BOX_WITH_CHECK' => "\u{2611}\u{FE0F}", 'CHARACTER_HEAVY_CHECK_MARK' => "\u{2714}\u{FE0F}", 'CHARACTER_HEAVY_MULTIPLICATION_X' => "\u{2716}\u{FE0F}", 'CHARACTER_CROSS_MARK' => "\u{274C}", 'CHARACTER_CROSS_MARK_BUTTON' => "\u{274E}", 'CHARACTER_HEAVY_PLUS_SIGN' => "\u{2795}", 'CHARACTER_HEAVY_MINUS_SIGN' => "\u{2796}", 'CHARACTER_HEAVY_DIVISION_SIGN' => "\u{2797}", 'CHARACTER_CURLY_LOOP' => "\u{27B0}", 'CHARACTER_DOUBLE_CURLY_LOOP' => "\u{27BF}", 'CHARACTER_PART_ALTERNATION_MARK' => "\u{303D}\u{FE0F}", 'CHARACTER_EIGHT_SPOKED_ASTERISK' => "\u{2733}\u{FE0F}", 'CHARACTER_EIGHT_POINTED_STAR' => "\u{2734}\u{FE0F}", 'CHARACTER_SPARKLE' => "\u{2747}\u{FE0F}", 'CHARACTER_DOUBLE_EXCLAMATION_MARK' => "\u{203C}\u{FE0F}", 'CHARACTER_EXCLAMATION_QUESTION_MARK' => "\u{2049}\u{FE0F}", 'CHARACTER_QUESTION_MARK' => "\u{2753}", 'CHARACTER_WHITE_QUESTION_MARK' => "\u{2754}", 'CHARACTER_WHITE_EXCLAMATION_MARK' => "\u{2755}", 'CHARACTER_EXCLAMATION_MARK' => "\u{2757}", 'CHARACTER_WAVY_DASH' => "\u{3030}\u{FE0F}", 'CHARACTER_COPYRIGHT' => "\u{00A9}\u{FE0F}", 'CHARACTER_REGISTERED' => "\u{00AE}\u{FE0F}", 'CHARACTER_TRADE_MARK' => "\u{2122}\u{FE0F}", 'CHARACTER_KEYCAP_HASH' => "\u{0023}\u{FE0F}\u{20E3}", 'CHARACTER_KEYCAP_ASTERISK' => "\u{002A}\u{FE0F}\u{20E3}", 'CHARACTER_KEYCAP_0' => "\u{0030}\u{FE0F}\u{20E3}", 'CHARACTER_KEYCAP_1' => "\u{0031}\u{FE0F}\u{20E3}", 'CHARACTER_KEYCAP_2' => "\u{0032}\u{FE0F}\u{20E3}", 'CHARACTER_KEYCAP_3' => "\u{0033}\u{FE0F}\u{20E3}", 'CHARACTER_KEYCAP_4' => "\u{0034}\u{FE0F}\u{20E3}", 'CHARACTER_KEYCAP_5' => "\u{0035}\u{FE0F}\u{20E3}", 'CHARACTER_KEYCAP_6' => "\u{0036}\u{FE0F}\u{20E3}", 'CHARACTER_KEYCAP_7' => "\u{0037}\u{FE0F}\u{20E3}", 'CHARACTER_KEYCAP_8' => "\u{0038}\u{FE0F}\u{20E3}", 'CHARACTER_KEYCAP_9' => "\u{0039}\u{FE0F}\u{20E3}", 'CHARACTER_KEYCAP_10' => "\u{1F51F}", 'CHARACTER_HUNDRED_POINTS' => "\u{1F4AF}", 'CHARACTER_INPUT_LATIN_UPPERCASE' => "\u{1F520}", 'CHARACTER_INPUT_LATIN_LOWERCASE' => "\u{1F521}", 'CHARACTER_INPUT_NUMBERS' => "\u{1F522}", 'CHARACTER_INPUT_SYMBOLS' => "\u{1F523}", 'CHARACTER_INPUT_LATIN_LETTERS' => "\u{1F524}", 'CHARACTER_A_BUTTON_BLOOD_TYPE' => "\u{1F170}\u{FE0F}", 'CHARACTER_AB_BUTTON_BLOOD_TYPE' => "\u{1F18E}", 'CHARACTER_B_BUTTON_BLOOD_TYPE' => "\u{1F171}\u{FE0F}", 'CHARACTER_CL_BUTTON' => "\u{1F191}", 'CHARACTER_COOL_BUTTON' => "\u{1F192}", 'CHARACTER_FREE_BUTTON' => "\u{1F193}", 'CHARACTER_INFORMATION' => "\u{2139}\u{FE0F}", 'CHARACTER_ID_BUTTON' => "\u{1F194}", 'CHARACTER_CIRCLED_M' => "\u{24C2}\u{FE0F}", 'CHARACTER_NEW_BUTTON' => "\u{1F195}", 'CHARACTER_NG_BUTTON' => "\u{1F196}", 'CHARACTER_O_BUTTON_BLOOD_TYPE' => "\u{1F17E}\u{FE0F}", 'CHARACTER_OK_BUTTON' => "\u{1F197}", 'CHARACTER_P_BUTTON' => "\u{1F17F}\u{FE0F}", 'CHARACTER_SOS_BUTTON' => "\u{1F198}", 'CHARACTER_UP_BUTTON' => "\u{1F199}", 'CHARACTER_VS_BUTTON' => "\u{1F19A}", 'CHARACTER_JAPANESE_HERE_BUTTON' => "\u{1F201}", 'CHARACTER_JAPANESE_SERVICE_CHARGE_BUTTON' => "\u{1F202}\u{FE0F}", 'CHARACTER_JAPANESE_MONTHLY_AMOUNT_BUTTON' => "\u{1F237}\u{FE0F}", 'CHARACTER_JAPANESE_NOT_FREE_OF_CHARGE_BUTTON' => "\u{1F236}", 'CHARACTER_JAPANESE_RESERVED_BUTTON' => "\u{1F22F}", 'CHARACTER_JAPANESE_BARGAIN_BUTTON' => "\u{1F250}", 'CHARACTER_JAPANESE_DISCOUNT_BUTTON' => "\u{1F239}", 'CHARACTER_JAPANESE_FREE_OF_CHARGE_BUTTON' => "\u{1F21A}", 'CHARACTER_JAPANESE_PROHIBITED_BUTTON' => "\u{1F232}", 'CHARACTER_JAPANESE_ACCEPTABLE_BUTTON' => "\u{1F251}", 'CHARACTER_JAPANESE_APPLICATION_BUTTON' => "\u{1F238}", 'CHARACTER_JAPANESE_PASSING_GRADE_BUTTON' => "\u{1F234}", 'CHARACTER_JAPANESE_VACANCY_BUTTON' => "\u{1F233}", 'CHARACTER_JAPANESE_CONGRATULATIONS_BUTTON' => "\u{3297}\u{FE0F}", 'CHARACTER_JAPANESE_SECRET_BUTTON' => "\u{3299}\u{FE0F}", 'CHARACTER_JAPANESE_OPEN_FOR_BUSINESS_BUTTON' => "\u{1F23A}", 'CHARACTER_JAPANESE_NO_VACANCY_BUTTON' => "\u{1F235}", 'CHARACTER_BLACK_SMALL_SQUARE' => "\u{25AA}\u{FE0F}", 'CHARACTER_WHITE_SMALL_SQUARE' => "\u{25AB}\u{FE0F}", 'CHARACTER_WHITE_MEDIUM_SQUARE' => "\u{25FB}\u{FE0F}", 'CHARACTER_BLACK_MEDIUM_SQUARE' => "\u{25FC}\u{FE0F}", 'CHARACTER_WHITE_MEDIUM_SMALL_SQUARE' => "\u{25FD}", 'CHARACTER_BLACK_MEDIUM_SMALL_SQUARE' => "\u{25FE}", 'CHARACTER_BLACK_LARGE_SQUARE' => "\u{2B1B}", 'CHARACTER_WHITE_LARGE_SQUARE' => "\u{2B1C}", 'CHARACTER_LARGE_ORANGE_DIAMOND' => "\u{1F536}", 'CHARACTER_LARGE_BLUE_DIAMOND' => "\u{1F537}", 'CHARACTER_SMALL_ORANGE_DIAMOND' => "\u{1F538}", 'CHARACTER_SMALL_BLUE_DIAMOND' => "\u{1F539}", 'CHARACTER_RED_TRIANGLE_POINTED_UP' => "\u{1F53A}", 'CHARACTER_RED_TRIANGLE_POINTED_DOWN' => "\u{1F53B}", 'CHARACTER_DIAMOND_WITH_A_DOT' => "\u{1F4A0}", 'CHARACTER_RADIO_BUTTON' => "\u{1F518}", 'CHARACTER_BLACK_SQUARE_BUTTON' => "\u{1F532}", 'CHARACTER_WHITE_SQUARE_BUTTON' => "\u{1F533}", 'CHARACTER_WHITE_CIRCLE' => "\u{26AA}", 'CHARACTER_BLACK_CIRCLE' => "\u{26AB}", 'CHARACTER_RED_CIRCLE' => "\u{1F534}", 'CHARACTER_BLUE_CIRCLE' => "\u{1F535}", 'CHARACTER_CHEQUERED_FLAG' => "\u{1F3C1}", 'CHARACTER_TRIANGULAR_FLAG' => "\u{1F6A9}", 'CHARACTER_CROSSED_FLAGS' => "\u{1F38C}", 'CHARACTER_BLACK_FLAG' => "\u{1F3F4}", 'CHARACTER_WHITE_FLAG' => "\u{1F3F3}\u{FE0F}", 'CHARACTER_RAINBOW_FLAG' => "\u{1F3F3}\u{FE0F}\u{200D}\u{1F308}", 'CHARACTER_PIRATE_FLAG' => "\u{1F3F4}\u{200D}\u{2620}\u{FE0F}", 'CHARACTER_FLAGS_FOR_ASCENSION_ISLAND' => "\u{1F1E6}\u{1F1E8}", 'CHARACTER_FLAGS_FOR_ANDORRA' => "\u{1F1E6}\u{1F1E9}", 'CHARACTER_FLAGS_FOR_UNITED_ARAB_EMIRATES' => "\u{1F1E6}\u{1F1EA}", 'CHARACTER_FLAGS_FOR_AFGHANISTAN' => "\u{1F1E6}\u{1F1EB}", 'CHARACTER_FLAGS_FOR_ANTIGUA_AND_BARBUDA' => "\u{1F1E6}\u{1F1EC}", 'CHARACTER_FLAGS_FOR_ANGUILLA' => "\u{1F1E6}\u{1F1EE}", 'CHARACTER_FLAGS_FOR_ALBANIA' => "\u{1F1E6}\u{1F1F1}", 'CHARACTER_FLAGS_FOR_ARMENIA' => "\u{1F1E6}\u{1F1F2}", 'CHARACTER_FLAGS_FOR_ANGOLA' => "\u{1F1E6}\u{1F1F4}", 'CHARACTER_FLAGS_FOR_ANTARCTICA' => "\u{1F1E6}\u{1F1F6}", 'CHARACTER_FLAGS_FOR_ARGENTINA' => "\u{1F1E6}\u{1F1F7}", 'CHARACTER_FLAGS_FOR_AMERICAN_SAMOA' => "\u{1F1E6}\u{1F1F8}", 'CHARACTER_FLAGS_FOR_AUSTRIA' => "\u{1F1E6}\u{1F1F9}", 'CHARACTER_FLAGS_FOR_AUSTRALIA' => "\u{1F1E6}\u{1F1FA}", 'CHARACTER_FLAGS_FOR_ARUBA' => "\u{1F1E6}\u{1F1FC}", 'CHARACTER_FLAGS_FOR_ALAND_ISLANDS' => "\u{1F1E6}\u{1F1FD}", 'CHARACTER_FLAGS_FOR_AZERBAIJAN' => "\u{1F1E6}\u{1F1FF}", 'CHARACTER_FLAGS_FOR_BOSNIA_AND_HERZEGOVINA' => "\u{1F1E7}\u{1F1E6}", 'CHARACTER_FLAGS_FOR_BARBADOS' => "\u{1F1E7}\u{1F1E7}", 'CHARACTER_FLAGS_FOR_BANGLADESH' => "\u{1F1E7}\u{1F1E9}", 'CHARACTER_FLAGS_FOR_BELGIUM' => "\u{1F1E7}\u{1F1EA}", 'CHARACTER_FLAGS_FOR_BURKINA_FASO' => "\u{1F1E7}\u{1F1EB}", 'CHARACTER_FLAGS_FOR_BULGARIA' => "\u{1F1E7}\u{1F1EC}", 'CHARACTER_FLAGS_FOR_BAHRAIN' => "\u{1F1E7}\u{1F1ED}", 'CHARACTER_FLAGS_FOR_BURUNDI' => "\u{1F1E7}\u{1F1EE}", 'CHARACTER_FLAGS_FOR_BENIN' => "\u{1F1E7}\u{1F1EF}", 'CHARACTER_FLAGS_FOR_ST_BARTHELEMY' => "\u{1F1E7}\u{1F1F1}", 'CHARACTER_FLAGS_FOR_BERMUDA' => "\u{1F1E7}\u{1F1F2}", 'CHARACTER_FLAGS_FOR_BRUNEI' => "\u{1F1E7}\u{1F1F3}", 'CHARACTER_FLAGS_FOR_BOLIVIA' => "\u{1F1E7}\u{1F1F4}", 'CHARACTER_FLAGS_FOR_CARIBBEAN_NETHERLANDS' => "\u{1F1E7}\u{1F1F6}", 'CHARACTER_FLAGS_FOR_BRAZIL' => "\u{1F1E7}\u{1F1F7}", 'CHARACTER_FLAGS_FOR_BAHAMAS' => "\u{1F1E7}\u{1F1F8}", 'CHARACTER_FLAGS_FOR_BHUTAN' => "\u{1F1E7}\u{1F1F9}", 'CHARACTER_FLAGS_FOR_BOUVET_ISLAND' => "\u{1F1E7}\u{1F1FB}", 'CHARACTER_FLAGS_FOR_BOTSWANA' => "\u{1F1E7}\u{1F1FC}", 'CHARACTER_FLAGS_FOR_BELARUS' => "\u{1F1E7}\u{1F1FE}", 'CHARACTER_FLAGS_FOR_BELIZE' => "\u{1F1E7}\u{1F1FF}", 'CHARACTER_FLAGS_FOR_CANADA' => "\u{1F1E8}\u{1F1E6}", 'CHARACTER_FLAGS_FOR_COCOS_KEELING_ISLANDS' => "\u{1F1E8}\u{1F1E8}", 'CHARACTER_FLAGS_FOR_CONGO_KINSHASA' => "\u{1F1E8}\u{1F1E9}", 'CHARACTER_FLAGS_FOR_CENTRAL_AFRICAN_REPUBLIC' => "\u{1F1E8}\u{1F1EB}", 'CHARACTER_FLAGS_FOR_CONGO_BRAZZAVILLE' => "\u{1F1E8}\u{1F1EC}", 'CHARACTER_FLAGS_FOR_SWITZERLAND' => "\u{1F1E8}\u{1F1ED}", 'CHARACTER_FLAGS_FOR_COTE_D_IVOIRE' => "\u{1F1E8}\u{1F1EE}", 'CHARACTER_FLAGS_FOR_COOK_ISLANDS' => "\u{1F1E8}\u{1F1F0}", 'CHARACTER_FLAGS_FOR_CHILE' => "\u{1F1E8}\u{1F1F1}", 'CHARACTER_FLAGS_FOR_CAMEROON' => "\u{1F1E8}\u{1F1F2}", 'CHARACTER_FLAGS_FOR_CHINA' => "\u{1F1E8}\u{1F1F3}", 'CHARACTER_FLAGS_FOR_COLOMBIA' => "\u{1F1E8}\u{1F1F4}", 'CHARACTER_FLAGS_FOR_CLIPPERTON_ISLAND' => "\u{1F1E8}\u{1F1F5}", 'CHARACTER_FLAGS_FOR_COSTA_RICA' => "\u{1F1E8}\u{1F1F7}", 'CHARACTER_FLAGS_FOR_CUBA' => "\u{1F1E8}\u{1F1FA}", 'CHARACTER_FLAGS_FOR_CAPE_VERDE' => "\u{1F1E8}\u{1F1FB}", 'CHARACTER_FLAGS_FOR_CURACAO' => "\u{1F1E8}\u{1F1FC}", 'CHARACTER_FLAGS_FOR_CHRISTMAS_ISLAND' => "\u{1F1E8}\u{1F1FD}", 'CHARACTER_FLAGS_FOR_CYPRUS' => "\u{1F1E8}\u{1F1FE}", 'CHARACTER_FLAGS_FOR_CZECHIA' => "\u{1F1E8}\u{1F1FF}", 'CHARACTER_FLAGS_FOR_GERMANY' => "\u{1F1E9}\u{1F1EA}", 'CHARACTER_FLAGS_FOR_DIEGO_GARCIA' => "\u{1F1E9}\u{1F1EC}", 'CHARACTER_FLAGS_FOR_DJIBOUTI' => "\u{1F1E9}\u{1F1EF}", 'CHARACTER_FLAGS_FOR_DENMARK' => "\u{1F1E9}\u{1F1F0}", 'CHARACTER_FLAGS_FOR_DOMINICA' => "\u{1F1E9}\u{1F1F2}", 'CHARACTER_FLAGS_FOR_DOMINICAN_REPUBLIC' => "\u{1F1E9}\u{1F1F4}", 'CHARACTER_FLAGS_FOR_ALGERIA' => "\u{1F1E9}\u{1F1FF}", 'CHARACTER_FLAGS_FOR_CEUTA_AND_MELILLA' => "\u{1F1EA}\u{1F1E6}", 'CHARACTER_FLAGS_FOR_ECUADOR' => "\u{1F1EA}\u{1F1E8}", 'CHARACTER_FLAGS_FOR_ESTONIA' => "\u{1F1EA}\u{1F1EA}", 'CHARACTER_FLAGS_FOR_EGYPT' => "\u{1F1EA}\u{1F1EC}", 'CHARACTER_FLAGS_FOR_WESTERN_SAHARA' => "\u{1F1EA}\u{1F1ED}", 'CHARACTER_FLAGS_FOR_ERITREA' => "\u{1F1EA}\u{1F1F7}", 'CHARACTER_FLAGS_FOR_SPAIN' => "\u{1F1EA}\u{1F1F8}", 'CHARACTER_FLAGS_FOR_ETHIOPIA' => "\u{1F1EA}\u{1F1F9}", 'CHARACTER_FLAGS_FOR_EUROPEAN_UNION' => "\u{1F1EA}\u{1F1FA}", 'CHARACTER_FLAGS_FOR_FINLAND' => "\u{1F1EB}\u{1F1EE}", 'CHARACTER_FLAGS_FOR_FIJI' => "\u{1F1EB}\u{1F1EF}", 'CHARACTER_FLAGS_FOR_FALKLAND_ISLANDS' => "\u{1F1EB}\u{1F1F0}", 'CHARACTER_FLAGS_FOR_MICRONESIA' => "\u{1F1EB}\u{1F1F2}", 'CHARACTER_FLAGS_FOR_FAROE_ISLANDS' => "\u{1F1EB}\u{1F1F4}", 'CHARACTER_FLAGS_FOR_FRANCE' => "\u{1F1EB}\u{1F1F7}", 'CHARACTER_FLAGS_FOR_GABON' => "\u{1F1EC}\u{1F1E6}", 'CHARACTER_FLAGS_FOR_UNITED_KINGDOM' => "\u{1F1EC}\u{1F1E7}", 'CHARACTER_FLAGS_FOR_GRENADA' => "\u{1F1EC}\u{1F1E9}", 'CHARACTER_FLAGS_FOR_GEORGIA' => "\u{1F1EC}\u{1F1EA}", 'CHARACTER_FLAGS_FOR_FRENCH_GUIANA' => "\u{1F1EC}\u{1F1EB}", 'CHARACTER_FLAGS_FOR_GUERNSEY' => "\u{1F1EC}\u{1F1EC}", 'CHARACTER_FLAGS_FOR_GHANA' => "\u{1F1EC}\u{1F1ED}", 'CHARACTER_FLAGS_FOR_GIBRALTAR' => "\u{1F1EC}\u{1F1EE}", 'CHARACTER_FLAGS_FOR_GREENLAND' => "\u{1F1EC}\u{1F1F1}", 'CHARACTER_FLAGS_FOR_GAMBIA' => "\u{1F1EC}\u{1F1F2}", 'CHARACTER_FLAGS_FOR_GUINEA' => "\u{1F1EC}\u{1F1F3}", 'CHARACTER_FLAGS_FOR_GUADELOUPE' => "\u{1F1EC}\u{1F1F5}", 'CHARACTER_FLAGS_FOR_EQUATORIAL_GUINEA' => "\u{1F1EC}\u{1F1F6}", 'CHARACTER_FLAGS_FOR_GREECE' => "\u{1F1EC}\u{1F1F7}", 'CHARACTER_FLAGS_FOR_SOUTH_GEORGIA_AND_SOUTH_SANDWICH_ISLANDS' => "\u{1F1EC}\u{1F1F8}", 'CHARACTER_FLAGS_FOR_GUATEMALA' => "\u{1F1EC}\u{1F1F9}", 'CHARACTER_FLAGS_FOR_GUAM' => "\u{1F1EC}\u{1F1FA}", 'CHARACTER_FLAGS_FOR_GUINEA_BISSAU' => "\u{1F1EC}\u{1F1FC}", 'CHARACTER_FLAGS_FOR_GUYANA' => "\u{1F1EC}\u{1F1FE}", 'CHARACTER_FLAGS_FOR_HONG_KONG_SAR_CHINA' => "\u{1F1ED}\u{1F1F0}", 'CHARACTER_FLAGS_FOR_HEARD_AND_MCDONALD_ISLANDS' => "\u{1F1ED}\u{1F1F2}", 'CHARACTER_FLAGS_FOR_HONDURAS' => "\u{1F1ED}\u{1F1F3}", 'CHARACTER_FLAGS_FOR_CROATIA' => "\u{1F1ED}\u{1F1F7}", 'CHARACTER_FLAGS_FOR_HAITI' => "\u{1F1ED}\u{1F1F9}", 'CHARACTER_FLAGS_FOR_HUNGARY' => "\u{1F1ED}\u{1F1FA}", 'CHARACTER_FLAGS_FOR_CANARY_ISLANDS' => "\u{1F1EE}\u{1F1E8}", 'CHARACTER_FLAGS_FOR_INDONESIA' => "\u{1F1EE}\u{1F1E9}", 'CHARACTER_FLAGS_FOR_IRELAND' => "\u{1F1EE}\u{1F1EA}", 'CHARACTER_FLAGS_FOR_ISRAEL' => "\u{1F1EE}\u{1F1F1}", 'CHARACTER_FLAGS_FOR_ISLE_OF_MAN' => "\u{1F1EE}\u{1F1F2}", 'CHARACTER_FLAGS_FOR_INDIA' => "\u{1F1EE}\u{1F1F3}", 'CHARACTER_FLAGS_FOR_BRITISH_INDIAN_OCEAN_TERRITORY' => "\u{1F1EE}\u{1F1F4}", 'CHARACTER_FLAGS_FOR_IRAQ' => "\u{1F1EE}\u{1F1F6}", 'CHARACTER_FLAGS_FOR_IRAN' => "\u{1F1EE}\u{1F1F7}", 'CHARACTER_FLAGS_FOR_ICELAND' => "\u{1F1EE}\u{1F1F8}", 'CHARACTER_FLAGS_FOR_ITALY' => "\u{1F1EE}\u{1F1F9}", 'CHARACTER_FLAGS_FOR_JERSEY' => "\u{1F1EF}\u{1F1EA}", 'CHARACTER_FLAGS_FOR_JAMAICA' => "\u{1F1EF}\u{1F1F2}", 'CHARACTER_FLAGS_FOR_JORDAN' => "\u{1F1EF}\u{1F1F4}", 'CHARACTER_FLAGS_FOR_JAPAN' => "\u{1F1EF}\u{1F1F5}", 'CHARACTER_FLAGS_FOR_KENYA' => "\u{1F1F0}\u{1F1EA}", 'CHARACTER_FLAGS_FOR_KYRGYZSTAN' => "\u{1F1F0}\u{1F1EC}", 'CHARACTER_FLAGS_FOR_CAMBODIA' => "\u{1F1F0}\u{1F1ED}", 'CHARACTER_FLAGS_FOR_KIRIBATI' => "\u{1F1F0}\u{1F1EE}", 'CHARACTER_FLAGS_FOR_COMOROS' => "\u{1F1F0}\u{1F1F2}", 'CHARACTER_FLAGS_FOR_ST_KITTS_AND_NEVIS' => "\u{1F1F0}\u{1F1F3}", 'CHARACTER_FLAGS_FOR_NORTH_KOREA' => "\u{1F1F0}\u{1F1F5}", 'CHARACTER_FLAGS_FOR_SOUTH_KOREA' => "\u{1F1F0}\u{1F1F7}", 'CHARACTER_FLAGS_FOR_KUWAIT' => "\u{1F1F0}\u{1F1FC}", 'CHARACTER_FLAGS_FOR_CAYMAN_ISLANDS' => "\u{1F1F0}\u{1F1FE}", 'CHARACTER_FLAGS_FOR_KAZAKHSTAN' => "\u{1F1F0}\u{1F1FF}", 'CHARACTER_FLAGS_FOR_LAOS' => "\u{1F1F1}\u{1F1E6}", 'CHARACTER_FLAGS_FOR_LEBANON' => "\u{1F1F1}\u{1F1E7}", 'CHARACTER_FLAGS_FOR_ST_LUCIA' => "\u{1F1F1}\u{1F1E8}", 'CHARACTER_FLAGS_FOR_LIECHTENSTEIN' => "\u{1F1F1}\u{1F1EE}", 'CHARACTER_FLAGS_FOR_SRI_LANKA' => "\u{1F1F1}\u{1F1F0}", 'CHARACTER_FLAGS_FOR_LIBERIA' => "\u{1F1F1}\u{1F1F7}", 'CHARACTER_FLAGS_FOR_LESOTHO' => "\u{1F1F1}\u{1F1F8}", 'CHARACTER_FLAGS_FOR_LITHUANIA' => "\u{1F1F1}\u{1F1F9}", 'CHARACTER_FLAGS_FOR_LUXEMBOURG' => "\u{1F1F1}\u{1F1FA}", 'CHARACTER_FLAGS_FOR_LATVIA' => "\u{1F1F1}\u{1F1FB}", 'CHARACTER_FLAGS_FOR_LIBYA' => "\u{1F1F1}\u{1F1FE}", 'CHARACTER_FLAGS_FOR_MOROCCO' => "\u{1F1F2}\u{1F1E6}", 'CHARACTER_FLAGS_FOR_MONACO' => "\u{1F1F2}\u{1F1E8}", 'CHARACTER_FLAGS_FOR_MOLDOVA' => "\u{1F1F2}\u{1F1E9}", 'CHARACTER_FLAGS_FOR_MONTENEGRO' => "\u{1F1F2}\u{1F1EA}", 'CHARACTER_FLAGS_FOR_ST_MARTIN' => "\u{1F1F2}\u{1F1EB}", 'CHARACTER_FLAGS_FOR_MADAGASCAR' => "\u{1F1F2}\u{1F1EC}", 'CHARACTER_FLAGS_FOR_MARSHALL_ISLANDS' => "\u{1F1F2}\u{1F1ED}", 'CHARACTER_FLAGS_FOR_MACEDONIA' => "\u{1F1F2}\u{1F1F0}", 'CHARACTER_FLAGS_FOR_MALI' => "\u{1F1F2}\u{1F1F1}", 'CHARACTER_FLAGS_FOR_MYANMAR_BURMA' => "\u{1F1F2}\u{1F1F2}", 'CHARACTER_FLAGS_FOR_MONGOLIA' => "\u{1F1F2}\u{1F1F3}", 'CHARACTER_FLAGS_FOR_MACAU_SAR_CHINA' => "\u{1F1F2}\u{1F1F4}", 'CHARACTER_FLAGS_FOR_NORTHERN_MARIANA_ISLANDS' => "\u{1F1F2}\u{1F1F5}", 'CHARACTER_FLAGS_FOR_MARTINIQUE' => "\u{1F1F2}\u{1F1F6}", 'CHARACTER_FLAGS_FOR_MAURITANIA' => "\u{1F1F2}\u{1F1F7}", 'CHARACTER_FLAGS_FOR_MONTSERRAT' => "\u{1F1F2}\u{1F1F8}", 'CHARACTER_FLAGS_FOR_MALTA' => "\u{1F1F2}\u{1F1F9}", 'CHARACTER_FLAGS_FOR_MAURITIUS' => "\u{1F1F2}\u{1F1FA}", 'CHARACTER_FLAGS_FOR_MALDIVES' => "\u{1F1F2}\u{1F1FB}", 'CHARACTER_FLAGS_FOR_MALAWI' => "\u{1F1F2}\u{1F1FC}", 'CHARACTER_FLAGS_FOR_MEXICO' => "\u{1F1F2}\u{1F1FD}", 'CHARACTER_FLAGS_FOR_MALAYSIA' => "\u{1F1F2}\u{1F1FE}", 'CHARACTER_FLAGS_FOR_MOZAMBIQUE' => "\u{1F1F2}\u{1F1FF}", 'CHARACTER_FLAGS_FOR_NAMIBIA' => "\u{1F1F3}\u{1F1E6}", 'CHARACTER_FLAGS_FOR_NEW_CALEDONIA' => "\u{1F1F3}\u{1F1E8}", 'CHARACTER_FLAGS_FOR_NIGER' => "\u{1F1F3}\u{1F1EA}", 'CHARACTER_FLAGS_FOR_NORFOLK_ISLAND' => "\u{1F1F3}\u{1F1EB}", 'CHARACTER_FLAGS_FOR_NIGERIA' => "\u{1F1F3}\u{1F1EC}", 'CHARACTER_FLAGS_FOR_NICARAGUA' => "\u{1F1F3}\u{1F1EE}", 'CHARACTER_FLAGS_FOR_NETHERLANDS' => "\u{1F1F3}\u{1F1F1}", 'CHARACTER_FLAGS_FOR_NORWAY' => "\u{1F1F3}\u{1F1F4}", 'CHARACTER_FLAGS_FOR_NEPAL' => "\u{1F1F3}\u{1F1F5}", 'CHARACTER_FLAGS_FOR_NAURU' => "\u{1F1F3}\u{1F1F7}", 'CHARACTER_FLAGS_FOR_NIUE' => "\u{1F1F3}\u{1F1FA}", 'CHARACTER_FLAGS_FOR_NEW_ZEALAND' => "\u{1F1F3}\u{1F1FF}", 'CHARACTER_FLAGS_FOR_OMAN' => "\u{1F1F4}\u{1F1F2}", 'CHARACTER_FLAGS_FOR_PANAMA' => "\u{1F1F5}\u{1F1E6}", 'CHARACTER_FLAGS_FOR_PERU' => "\u{1F1F5}\u{1F1EA}", 'CHARACTER_FLAGS_FOR_FRENCH_POLYNESIA' => "\u{1F1F5}\u{1F1EB}", 'CHARACTER_FLAGS_FOR_PAPUA_NEW_GUINEA' => "\u{1F1F5}\u{1F1EC}", 'CHARACTER_FLAGS_FOR_PHILIPPINES' => "\u{1F1F5}\u{1F1ED}", 'CHARACTER_FLAGS_FOR_PAKISTAN' => "\u{1F1F5}\u{1F1F0}", 'CHARACTER_FLAGS_FOR_POLAND' => "\u{1F1F5}\u{1F1F1}", 'CHARACTER_FLAGS_FOR_ST_PIERRE_AND_MIQUELON' => "\u{1F1F5}\u{1F1F2}", 'CHARACTER_FLAGS_FOR_PITCAIRN_ISLANDS' => "\u{1F1F5}\u{1F1F3}", 'CHARACTER_FLAGS_FOR_PUERTO_RICO' => "\u{1F1F5}\u{1F1F7}", 'CHARACTER_FLAGS_FOR_PALESTINIAN_TERRITORIES' => "\u{1F1F5}\u{1F1F8}", 'CHARACTER_FLAGS_FOR_PORTUGAL' => "\u{1F1F5}\u{1F1F9}", 'CHARACTER_FLAGS_FOR_PALAU' => "\u{1F1F5}\u{1F1FC}", 'CHARACTER_FLAGS_FOR_PARAGUAY' => "\u{1F1F5}\u{1F1FE}", 'CHARACTER_FLAGS_FOR_QATAR' => "\u{1F1F6}\u{1F1E6}", 'CHARACTER_FLAGS_FOR_REUNION' => "\u{1F1F7}\u{1F1EA}", 'CHARACTER_FLAGS_FOR_ROMANIA' => "\u{1F1F7}\u{1F1F4}", 'CHARACTER_FLAGS_FOR_SERBIA' => "\u{1F1F7}\u{1F1F8}", 'CHARACTER_FLAGS_FOR_RUSSIA' => "\u{1F1F7}\u{1F1FA}", 'CHARACTER_FLAGS_FOR_RWANDA' => "\u{1F1F7}\u{1F1FC}", 'CHARACTER_FLAGS_FOR_SAUDI_ARABIA' => "\u{1F1F8}\u{1F1E6}", 'CHARACTER_FLAGS_FOR_SOLOMON_ISLANDS' => "\u{1F1F8}\u{1F1E7}", 'CHARACTER_FLAGS_FOR_SEYCHELLES' => "\u{1F1F8}\u{1F1E8}", 'CHARACTER_FLAGS_FOR_SUDAN' => "\u{1F1F8}\u{1F1E9}", 'CHARACTER_FLAGS_FOR_SWEDEN' => "\u{1F1F8}\u{1F1EA}", 'CHARACTER_FLAGS_FOR_SINGAPORE' => "\u{1F1F8}\u{1F1EC}", 'CHARACTER_FLAGS_FOR_ST_HELENA' => "\u{1F1F8}\u{1F1ED}", 'CHARACTER_FLAGS_FOR_SLOVENIA' => "\u{1F1F8}\u{1F1EE}", 'CHARACTER_FLAGS_FOR_SVALBARD_AND_JAN_MAYEN' => "\u{1F1F8}\u{1F1EF}", 'CHARACTER_FLAGS_FOR_SLOVAKIA' => "\u{1F1F8}\u{1F1F0}", 'CHARACTER_FLAGS_FOR_SIERRA_LEONE' => "\u{1F1F8}\u{1F1F1}", 'CHARACTER_FLAGS_FOR_SAN_MARINO' => "\u{1F1F8}\u{1F1F2}", 'CHARACTER_FLAGS_FOR_SENEGAL' => "\u{1F1F8}\u{1F1F3}", 'CHARACTER_FLAGS_FOR_SOMALIA' => "\u{1F1F8}\u{1F1F4}", 'CHARACTER_FLAGS_FOR_SURINAME' => "\u{1F1F8}\u{1F1F7}", 'CHARACTER_FLAGS_FOR_SOUTH_SUDAN' => "\u{1F1F8}\u{1F1F8}", 'CHARACTER_FLAGS_FOR_SAO_TOME_AND_PRINCIPE' => "\u{1F1F8}\u{1F1F9}", 'CHARACTER_FLAGS_FOR_EL_SALVADOR' => "\u{1F1F8}\u{1F1FB}", 'CHARACTER_FLAGS_FOR_SINT_MAARTEN' => "\u{1F1F8}\u{1F1FD}", 'CHARACTER_FLAGS_FOR_SYRIA' => "\u{1F1F8}\u{1F1FE}", 'CHARACTER_FLAGS_FOR_SWAZILAND' => "\u{1F1F8}\u{1F1FF}", 'CHARACTER_FLAGS_FOR_TRISTAN_DA_CUNHA' => "\u{1F1F9}\u{1F1E6}", 'CHARACTER_FLAGS_FOR_TURKS_AND_CAICOS_ISLANDS' => "\u{1F1F9}\u{1F1E8}", 'CHARACTER_FLAGS_FOR_CHAD' => "\u{1F1F9}\u{1F1E9}", 'CHARACTER_FLAGS_FOR_FRENCH_SOUTHERN_TERRITORIES' => "\u{1F1F9}\u{1F1EB}", 'CHARACTER_FLAGS_FOR_TOGO' => "\u{1F1F9}\u{1F1EC}", 'CHARACTER_FLAGS_FOR_THAILAND' => "\u{1F1F9}\u{1F1ED}", 'CHARACTER_FLAGS_FOR_TAJIKISTAN' => "\u{1F1F9}\u{1F1EF}", 'CHARACTER_FLAGS_FOR_TOKELAU' => "\u{1F1F9}\u{1F1F0}", 'CHARACTER_FLAGS_FOR_TIMOR_LESTE' => "\u{1F1F9}\u{1F1F1}", 'CHARACTER_FLAGS_FOR_TURKMENISTAN' => "\u{1F1F9}\u{1F1F2}", 'CHARACTER_FLAGS_FOR_TUNISIA' => "\u{1F1F9}\u{1F1F3}", 'CHARACTER_FLAGS_FOR_TONGA' => "\u{1F1F9}\u{1F1F4}", 'CHARACTER_FLAGS_FOR_TURKEY' => "\u{1F1F9}\u{1F1F7}", 'CHARACTER_FLAGS_FOR_TRINIDAD_AND_TOBAGO' => "\u{1F1F9}\u{1F1F9}", 'CHARACTER_FLAGS_FOR_TUVALU' => "\u{1F1F9}\u{1F1FB}", 'CHARACTER_FLAGS_FOR_TAIWAN' => "\u{1F1F9}\u{1F1FC}", 'CHARACTER_FLAGS_FOR_TANZANIA' => "\u{1F1F9}\u{1F1FF}", 'CHARACTER_FLAGS_FOR_UKRAINE' => "\u{1F1FA}\u{1F1E6}", 'CHARACTER_FLAGS_FOR_UGANDA' => "\u{1F1FA}\u{1F1EC}", 'CHARACTER_FLAGS_FOR_US_OUTLYING_ISLANDS' => "\u{1F1FA}\u{1F1F2}", 'CHARACTER_FLAGS_FOR_UNITED_NATIONS' => "\u{1F1FA}\u{1F1F3}", 'CHARACTER_FLAGS_FOR_UNITED_STATES' => "\u{1F1FA}\u{1F1F8}", 'CHARACTER_FLAGS_FOR_URUGUAY' => "\u{1F1FA}\u{1F1FE}", 'CHARACTER_FLAGS_FOR_UZBEKISTAN' => "\u{1F1FA}\u{1F1FF}", 'CHARACTER_FLAGS_FOR_VATICAN_CITY' => "\u{1F1FB}\u{1F1E6}", 'CHARACTER_FLAGS_FOR_ST_VINCENT_AND_GRENADINES' => "\u{1F1FB}\u{1F1E8}", 'CHARACTER_FLAGS_FOR_VENEZUELA' => "\u{1F1FB}\u{1F1EA}", 'CHARACTER_FLAGS_FOR_BRITISH_VIRGIN_ISLANDS' => "\u{1F1FB}\u{1F1EC}", 'CHARACTER_FLAGS_FOR_US_VIRGIN_ISLANDS' => "\u{1F1FB}\u{1F1EE}", 'CHARACTER_FLAGS_FOR_VIETNAM' => "\u{1F1FB}\u{1F1F3}", 'CHARACTER_FLAGS_FOR_VANUATU' => "\u{1F1FB}\u{1F1FA}", 'CHARACTER_FLAGS_FOR_WALLIS_AND_FUTUNA' => "\u{1F1FC}\u{1F1EB}", 'CHARACTER_FLAGS_FOR_SAMOA' => "\u{1F1FC}\u{1F1F8}", 'CHARACTER_FLAGS_FOR_KOSOVO' => "\u{1F1FD}\u{1F1F0}", 'CHARACTER_FLAGS_FOR_YEMEN' => "\u{1F1FE}\u{1F1EA}", 'CHARACTER_FLAGS_FOR_MAYOTTE' => "\u{1F1FE}\u{1F1F9}", 'CHARACTER_FLAGS_FOR_SOUTH_AFRICA' => "\u{1F1FF}\u{1F1E6}", 'CHARACTER_FLAGS_FOR_ZAMBIA' => "\u{1F1FF}\u{1F1F2}", 'CHARACTER_FLAGS_FOR_ZIMBABWE' => "\u{1F1FF}\u{1F1FC}", 'CHARACTER_FLAGS_FOR_ENGLAND' => "\u{1F3F4}\u{E0067}\u{E0062}\u{E0065}\u{E006E}\u{E0067}\u{E007F}", 'CHARACTER_FLAGS_FOR_SCOTLAND' => "\u{1F3F4}\u{E0067}\u{E0062}\u{E0073}\u{E0063}\u{E0074}\u{E007F}", 'CHARACTER_FLAGS_FOR_WALES' => "\u{1F3F4}\u{E0067}\u{E0062}\u{E0077}\u{E006C}\u{E0073}\u{E007F}"]; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/encodings.php b/includes/libraries/anti-xss-master/src/voku/helper/data/encodings.php new file mode 100644 index 000000000..87d907048 --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/encodings.php @@ -0,0 +1 @@ + 0, "\x00" => 0, "\x01" => 1, "\x02" => 2, "\x03" => 3, "\x04" => 4, "\x05" => 5, "\x06" => 6, "\x07" => 7, "\x08" => 8, "\x09" => 9, "\x0A" => 10, "\x0B" => 11, "\x0C" => 12, "\x0D" => 13, "\x0E" => 14, "\x0F" => 15, "\x10" => 16, "\x11" => 17, "\x12" => 18, "\x13" => 19, "\x14" => 20, "\x15" => 21, "\x16" => 22, "\x17" => 23, "\x18" => 24, "\x19" => 25, "\x1A" => 26, "\x1B" => 27, "\x1C" => 28, "\x1D" => 29, "\x1E" => 30, "\x1F" => 31, "\x20" => 32, "\x21" => 33, "\x22" => 34, "\x23" => 35, "\x24" => 36, "\x25" => 37, "\x26" => 38, "\x27" => 39, "\x28" => 40, "\x29" => 41, "\x2A" => 42, "\x2B" => 43, "\x2C" => 44, "\x2D" => 45, "\x2E" => 46, "\x2F" => 47, "\x30" => 48, "\x31" => 49, "\x32" => 50, "\x33" => 51, "\x34" => 52, "\x35" => 53, "\x36" => 54, "\x37" => 55, "\x38" => 56, "\x39" => 57, "\x3A" => 58, "\x3B" => 59, "\x3C" => 60, "\x3D" => 61, "\x3E" => 62, "\x3F" => 63, "\x40" => 64, "\x41" => 65, "\x42" => 66, "\x43" => 67, "\x44" => 68, "\x45" => 69, "\x46" => 70, "\x47" => 71, "\x48" => 72, "\x49" => 73, "\x4A" => 74, "\x4B" => 75, "\x4C" => 76, "\x4D" => 77, "\x4E" => 78, "\x4F" => 79, "\x50" => 80, "\x51" => 81, "\x52" => 82, "\x53" => 83, "\x54" => 84, "\x55" => 85, "\x56" => 86, "\x57" => 87, "\x58" => 88, "\x59" => 89, "\x5A" => 90, "\x5B" => 91, "\x5C" => 92, "\x5D" => 93, "\x5E" => 94, "\x5F" => 95, "\x60" => 96, "\x61" => 97, "\x62" => 98, "\x63" => 99, "\x64" => 100, "\x65" => 101, "\x66" => 102, "\x67" => 103, "\x68" => 104, "\x69" => 105, "\x6A" => 106, "\x6B" => 107, "\x6C" => 108, "\x6D" => 109, "\x6E" => 110, "\x6F" => 111, "\x70" => 112, "\x71" => 113, "\x72" => 114, "\x73" => 115, "\x74" => 116, "\x75" => 117, "\x76" => 118, "\x77" => 119, "\x78" => 120, "\x79" => 121, "\x7A" => 122, "\x7B" => 123, "\x7C" => 124, "\x7D" => 125, "\x7E" => 126, "\x7F" => 127, "\x80" => 128, "\x81" => 129, "\x82" => 130, "\x83" => 131, "\x84" => 132, "\x85" => 133, "\x86" => 134, "\x87" => 135, "\x88" => 136, "\x89" => 137, "\x8A" => 138, "\x8B" => 139, "\x8C" => 140, "\x8D" => 141, "\x8E" => 142, "\x8F" => 143, "\x90" => 144, "\x91" => 145, "\x92" => 146, "\x93" => 147, "\x94" => 148, "\x95" => 149, "\x96" => 150, "\x97" => 151, "\x98" => 152, "\x99" => 153, "\x9A" => 154, "\x9B" => 155, "\x9C" => 156, "\x9D" => 157, "\x9E" => 158, "\x9F" => 159, "\xA0" => 160, "\xA1" => 161, "\xA2" => 162, "\xA3" => 163, "\xA4" => 164, "\xA5" => 165, "\xA6" => 166, "\xA7" => 167, "\xA8" => 168, "\xA9" => 169, "\xAA" => 170, "\xAB" => 171, "\xAC" => 172, "\xAD" => 173, "\xAE" => 174, "\xAF" => 175, "\xB0" => 176, "\xB1" => 177, "\xB2" => 178, "\xB3" => 179, "\xB4" => 180, "\xB5" => 181, "\xB6" => 182, "\xB7" => 183, "\xB8" => 184, "\xB9" => 185, "\xBA" => 186, "\xBB" => 187, "\xBC" => 188, "\xBD" => 189, "\xBE" => 190, "\xBF" => 191, "\xC0" => 192, "\xC1" => 193, "\xC2" => 194, "\xC3" => 195, "\xC4" => 196, "\xC5" => 197, "\xC6" => 198, "\xC7" => 199, "\xC8" => 200, "\xC9" => 201, "\xCA" => 202, "\xCB" => 203, "\xCC" => 204, "\xCD" => 205, "\xCE" => 206, "\xCF" => 207, "\xD0" => 208, "\xD1" => 209, "\xD2" => 210, "\xD3" => 211, "\xD4" => 212, "\xD5" => 213, "\xD6" => 214, "\xD7" => 215, "\xD8" => 216, "\xD9" => 217, "\xDA" => 218, "\xDB" => 219, "\xDC" => 220, "\xDD" => 221, "\xDE" => 222, "\xDF" => 223, "\xE0" => 224, "\xE1" => 225, "\xE2" => 226, "\xE3" => 227, "\xE4" => 228, "\xE5" => 229, "\xE6" => 230, "\xE7" => 231, "\xE8" => 232, "\xE9" => 233, "\xEA" => 234, "\xEB" => 235, "\xEC" => 236, "\xED" => 237, "\xEE" => 238, "\xEF" => 239, "\xF0" => 240, "\xF1" => 241, "\xF2" => 242, "\xF3" => 243, "\xF4" => 244, "\xF5" => 245, "\xF6" => 246, "\xF7" => 247, "\xF8" => 248, "\xF9" => 249, "\xFA" => 250, "\xFB" => 251, "\xFC" => 252, "\xFD" => 253, "\xFE" => 254, "\xFF" => 255]; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/transliterator_list.php b/includes/libraries/anti-xss-master/src/voku/helper/data/transliterator_list.php new file mode 100644 index 000000000..91ddf13c6 --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/transliterator_list.php @@ -0,0 +1 @@ + 'ASCII-Latin', 1 => 'Accents-Any', 2 => 'Amharic-Latin/BGN', 3 => 'Any-Accents', 4 => 'Any-Publishing', 5 => 'Arab-Latn', 6 => 'Arabic-Latin', 7 => 'Arabic-Latin/BGN', 8 => 'Armenian-Latin', 9 => 'Armenian-Latin/BGN', 10 => 'Armn-Latn', 11 => 'Azerbaijani-Latin/BGN', 12 => 'Belarusian-Latin/BGN', 13 => 'Beng-Arab', 14 => 'Beng-Deva', 15 => 'Beng-Gujr', 16 => 'Beng-Guru', 17 => 'Beng-Knda', 18 => 'Beng-Latn', 19 => 'Beng-Mlym', 20 => 'Beng-Orya', 21 => 'Beng-Taml', 22 => 'Beng-Telu', 23 => 'Beng-ur', 24 => 'Bengali-Arabic', 25 => 'Bengali-Devanagari', 26 => 'Bengali-Gujarati', 27 => 'Bengali-Gurmukhi', 28 => 'Bengali-Kannada', 29 => 'Bengali-Latin', 30 => 'Bengali-Malayalam', 31 => 'Bengali-Oriya', 32 => 'Bengali-Tamil', 33 => 'Bengali-Telugu', 34 => 'Bopo-Latn', 35 => 'Bopomofo-Latin', 36 => 'Bulgarian-Latin/BGN', 37 => 'Cyrillic-Latin', 38 => 'Cyrl-Latn', 39 => 'Deva-Arab', 40 => 'Deva-Beng', 41 => 'Deva-Gujr', 42 => 'Deva-Guru', 43 => 'Deva-Knda', 44 => 'Deva-Latn', 45 => 'Deva-Mlym', 46 => 'Deva-Orya', 47 => 'Deva-Taml', 48 => 'Deva-Telu', 49 => 'Deva-ur', 50 => 'Devanagari-Arabic', 51 => 'Devanagari-Bengali', 52 => 'Devanagari-Gujarati', 53 => 'Devanagari-Gurmukhi', 54 => 'Devanagari-Kannada', 55 => 'Devanagari-Latin', 56 => 'Devanagari-Malayalam', 57 => 'Devanagari-Oriya', 58 => 'Devanagari-Tamil', 59 => 'Devanagari-Telugu', 60 => 'Digit-Tone', 61 => 'Fullwidth-Halfwidth', 62 => 'Geor-Latn', 63 => 'Georgian-Latin', 64 => 'Georgian-Latin/BGN', 65 => 'Greek-Latin', 66 => 'Greek-Latin/BGN', 67 => 'Greek-Latin/UNGEGN', 68 => 'Grek-Latn', 69 => 'Grek-Latn/UNGEGN', 70 => 'Gujarati-Arabic', 71 => 'Gujarati-Bengali', 72 => 'Gujarati-Devanagari', 73 => 'Gujarati-Gurmukhi', 74 => 'Gujarati-Kannada', 75 => 'Gujarati-Latin', 76 => 'Gujarati-Malayalam', 77 => 'Gujarati-Oriya', 78 => 'Gujarati-Tamil', 79 => 'Gujarati-Telugu', 80 => 'Gujr-Arab', 81 => 'Gujr-Beng', 82 => 'Gujr-Deva', 83 => 'Gujr-Guru', 84 => 'Gujr-Knda', 85 => 'Gujr-Latn', 86 => 'Gujr-Mlym', 87 => 'Gujr-Orya', 88 => 'Gujr-Taml', 89 => 'Gujr-Telu', 90 => 'Gujr-ur', 91 => 'Gurmukhi-Arabic', 92 => 'Gurmukhi-Bengali', 93 => 'Gurmukhi-Devanagari', 94 => 'Gurmukhi-Gujarati', 95 => 'Gurmukhi-Kannada', 96 => 'Gurmukhi-Latin', 97 => 'Gurmukhi-Malayalam', 98 => 'Gurmukhi-Oriya', 99 => 'Gurmukhi-Tamil', 100 => 'Gurmukhi-Telugu', 101 => 'Guru-Arab', 102 => 'Guru-Beng', 103 => 'Guru-Deva', 104 => 'Guru-Gujr', 105 => 'Guru-Knda', 106 => 'Guru-Latn', 107 => 'Guru-Mlym', 108 => 'Guru-Orya', 109 => 'Guru-Taml', 110 => 'Guru-Telu', 111 => 'Guru-ur', 112 => 'Halfwidth-Fullwidth', 113 => 'Han-Latin', 114 => 'Han-Latin/Names', 115 => 'Hang-Latn', 116 => 'Hangul-Latin', 117 => 'Hani-Latn', 118 => 'Hans-Hant', 119 => 'Hant-Hans', 120 => 'Hebr-Latn', 121 => 'Hebrew-Latin', 122 => 'Hebrew-Latin/BGN', 123 => 'Hira-Kana', 124 => 'Hira-Latn', 125 => 'Hiragana-Katakana', 126 => 'Hiragana-Latin', 127 => 'IPA-XSampa', 128 => 'Jamo-Latin', 129 => 'Jamo-Latn', 130 => 'Kana-Hira', 131 => 'Kana-Latn', 132 => 'Kannada-Arabic', 133 => 'Kannada-Bengali', 134 => 'Kannada-Devanagari', 135 => 'Kannada-Gujarati', 136 => 'Kannada-Gurmukhi', 137 => 'Kannada-Latin', 138 => 'Kannada-Malayalam', 139 => 'Kannada-Oriya', 140 => 'Kannada-Tamil', 141 => 'Kannada-Telugu', 142 => 'Katakana-Hiragana', 143 => 'Katakana-Latin', 144 => 'Katakana-Latin/BGN', 145 => 'Kazakh-Latin/BGN', 146 => 'Kirghiz-Latin/BGN', 147 => 'Knda-Arab', 148 => 'Knda-Beng', 149 => 'Knda-Deva', 150 => 'Knda-Gujr', 151 => 'Knda-Guru', 152 => 'Knda-Latn', 153 => 'Knda-Mlym', 154 => 'Knda-Orya', 155 => 'Knda-Taml', 156 => 'Knda-Telu', 157 => 'Knda-ur', 158 => 'Korean-Latin/BGN', 159 => 'Latin-ASCII', 160 => 'Latin-Arabic', 161 => 'Latin-Armenian', 162 => 'Latin-Bengali', 163 => 'Latin-Bopomofo', 164 => 'Latin-Cyrillic', 165 => 'Latin-Devanagari', 166 => 'Latin-Georgian', 167 => 'Latin-Greek', 168 => 'Latin-Greek/UNGEGN', 169 => 'Latin-Gujarati', 170 => 'Latin-Gurmukhi', 171 => 'Latin-Hangul', 172 => 'Latin-Hebrew', 173 => 'Latin-Hiragana', 174 => 'Latin-Jamo', 175 => 'Latin-Kannada', 176 => 'Latin-Katakana', 177 => 'Latin-Malayalam', 178 => 'Latin-NumericPinyin', 179 => 'Latin-Oriya', 180 => 'Latin-Russian/BGN', 181 => 'Latin-Syriac', 182 => 'Latin-Tamil', 183 => 'Latin-Telugu', 184 => 'Latin-Thaana', 185 => 'Latin-Thai', 186 => 'Latn-Arab', 187 => 'Latn-Armn', 188 => 'Latn-Beng', 189 => 'Latn-Bopo', 190 => 'Latn-Cyrl', 191 => 'Latn-Deva', 192 => 'Latn-Geor', 193 => 'Latn-Grek', 194 => 'Latn-Grek/UNGEGN', 195 => 'Latn-Gujr', 196 => 'Latn-Guru', 197 => 'Latn-Hang', 198 => 'Latn-Hebr', 199 => 'Latn-Hira', 200 => 'Latn-Jamo', 201 => 'Latn-Kana', 202 => 'Latn-Knda', 203 => 'Latn-Mlym', 204 => 'Latn-Orya', 205 => 'Latn-Syrc', 206 => 'Latn-Taml', 207 => 'Latn-Telu', 208 => 'Latn-Thaa', 209 => 'Latn-Thai', 210 => 'Macedonian-Latin/BGN', 211 => 'Malayalam-Arabic', 212 => 'Malayalam-Bengali', 213 => 'Malayalam-Devanagari', 214 => 'Malayalam-Gujarati', 215 => 'Malayalam-Gurmukhi', 216 => 'Malayalam-Kannada', 217 => 'Malayalam-Latin', 218 => 'Malayalam-Oriya', 219 => 'Malayalam-Tamil', 220 => 'Malayalam-Telugu', 221 => 'Maldivian-Latin/BGN', 222 => 'Mlym-Arab', 223 => 'Mlym-Beng', 224 => 'Mlym-Deva', 225 => 'Mlym-Gujr', 226 => 'Mlym-Guru', 227 => 'Mlym-Knda', 228 => 'Mlym-Latn', 229 => 'Mlym-Orya', 230 => 'Mlym-Taml', 231 => 'Mlym-Telu', 232 => 'Mlym-ur', 233 => 'Mongolian-Latin/BGN', 234 => 'NumericPinyin-Latin', 235 => 'NumericPinyin-Pinyin', 236 => 'Oriya-Arabic', 237 => 'Oriya-Bengali', 238 => 'Oriya-Devanagari', 239 => 'Oriya-Gujarati', 240 => 'Oriya-Gurmukhi', 241 => 'Oriya-Kannada', 242 => 'Oriya-Latin', 243 => 'Oriya-Malayalam', 244 => 'Oriya-Tamil', 245 => 'Oriya-Telugu', 246 => 'Orya-Arab', 247 => 'Orya-Beng', 248 => 'Orya-Deva', 249 => 'Orya-Gujr', 250 => 'Orya-Guru', 251 => 'Orya-Knda', 252 => 'Orya-Latn', 253 => 'Orya-Mlym', 254 => 'Orya-Taml', 255 => 'Orya-Telu', 256 => 'Orya-ur', 257 => 'Pashto-Latin/BGN', 258 => 'Persian-Latin/BGN', 259 => 'Pinyin-NumericPinyin', 260 => 'Publishing-Any', 261 => 'Russian-Latin/BGN', 262 => 'Serbian-Latin/BGN', 263 => 'Simplified-Traditional', 264 => 'Syrc-Latn', 265 => 'Syriac-Latin', 266 => 'Tamil-Arabic', 267 => 'Tamil-Bengali', 268 => 'Tamil-Devanagari', 269 => 'Tamil-Gujarati', 270 => 'Tamil-Gurmukhi', 271 => 'Tamil-Kannada', 272 => 'Tamil-Latin', 273 => 'Tamil-Malayalam', 274 => 'Tamil-Oriya', 275 => 'Tamil-Telugu', 276 => 'Taml-Arab', 277 => 'Taml-Beng', 278 => 'Taml-Deva', 279 => 'Taml-Gujr', 280 => 'Taml-Guru', 281 => 'Taml-Knda', 282 => 'Taml-Latn', 283 => 'Taml-Mlym', 284 => 'Taml-Orya', 285 => 'Taml-Telu', 286 => 'Taml-ur', 287 => 'Telu-Arab', 288 => 'Telu-Beng', 289 => 'Telu-Deva', 290 => 'Telu-Gujr', 291 => 'Telu-Guru', 292 => 'Telu-Knda', 293 => 'Telu-Latn', 294 => 'Telu-Mlym', 295 => 'Telu-Orya', 296 => 'Telu-Taml', 297 => 'Telu-ur', 298 => 'Telugu-Arabic', 299 => 'Telugu-Bengali', 300 => 'Telugu-Devanagari', 301 => 'Telugu-Gujarati', 302 => 'Telugu-Gurmukhi', 303 => 'Telugu-Kannada', 304 => 'Telugu-Latin', 305 => 'Telugu-Malayalam', 306 => 'Telugu-Oriya', 307 => 'Telugu-Tamil', 308 => 'Thaa-Latn', 309 => 'Thaana-Latin', 310 => 'Thai-Latin', 311 => 'Thai-Latn', 312 => 'Tone-Digit', 313 => 'Traditional-Simplified', 314 => 'Turkmen-Latin/BGN', 315 => 'Ukrainian-Latin/BGN', 316 => 'Uzbek-Latin/BGN', 317 => 'XSampa-IPA', 318 => 'Zawgyi-my', 319 => 'am-am_FONIPA', 320 => 'am-am_Latn/BGN', 321 => 'am-ar', 322 => 'am-chr', 323 => 'am-fa', 324 => 'am_FONIPA-am', 325 => 'ar-ar_Latn/BGN', 326 => 'az-Lower', 327 => 'az-Title', 328 => 'az-Upper', 329 => 'az_Cyrl-az/BGN', 330 => 'be-be_Latn/BGN', 331 => 'bg-bg_Latn/BGN', 332 => 'blt-blt_FONIPA', 333 => 'ch-am', 334 => 'ch-ar', 335 => 'ch-ch_FONIPA', 336 => 'ch-chr', 337 => 'ch-fa', 338 => 'chr-chr_FONIPA', 339 => 'cs-am', 340 => 'cs-ar', 341 => 'cs-chr', 342 => 'cs-cs_FONIPA', 343 => 'cs-fa', 344 => 'cs-ja', 345 => 'cs-ko', 346 => 'cs_FONIPA-ja', 347 => 'cs_FONIPA-ko', 348 => 'cy-cy_FONIPA', 349 => 'de-ASCII', 350 => 'dsb-dsb_FONIPA', 351 => 'dv-dv_Latn/BGN', 352 => 'el-Lower', 353 => 'el-Title', 354 => 'el-Upper', 355 => 'el-el_Latn/BGN', 356 => 'eo-am', 357 => 'eo-ar', 358 => 'eo-chr', 359 => 'eo-eo_FONIPA', 360 => 'eo-fa', 361 => 'es-am', 362 => 'es-ar', 363 => 'es-chr', 364 => 'es-es_FONIPA', 365 => 'es-fa', 366 => 'es-ja', 367 => 'es-zh', 368 => 'es_419-am', 369 => 'es_419-ar', 370 => 'es_419-chr', 371 => 'es_419-fa', 372 => 'es_419-ja', 373 => 'es_419-zh', 374 => 'es_FONIPA-am', 375 => 'es_FONIPA-es_419_FONIPA', 376 => 'es_FONIPA-ja', 377 => 'es_FONIPA-zh', 378 => 'fa-fa_FONIPA', 379 => 'fa-fa_Latn/BGN', 380 => 'ha-ha_NE', 381 => 'he-he_Latn/BGN', 382 => 'hy-am', 383 => 'hy-ar', 384 => 'hy-chr', 385 => 'hy-fa', 386 => 'hy-hy_FONIPA', 387 => 'hy-hy_Latn/BGN', 388 => 'hy_AREVMDA-am', 389 => 'hy_AREVMDA-ar', 390 => 'hy_AREVMDA-chr', 391 => 'hy_AREVMDA-fa', 392 => 'hy_AREVMDA-hy_AREVMDA_FONIPA', 393 => 'ia-am', 394 => 'ia-ar', 395 => 'ia-chr', 396 => 'ia-fa', 397 => 'ia-ia_FONIPA', 398 => 'it-am', 399 => 'it-ja', 400 => 'ja_Hrkt-ja_Latn/BGN', 401 => 'ja_Latn-ko', 402 => 'ja_Latn-ru', 403 => 'ka-ka_Latn/BGN', 404 => 'ka-ka_Latn/BGN_1981', 405 => 'kk-am', 406 => 'kk-ar', 407 => 'kk-chr', 408 => 'kk-fa', 409 => 'kk-kk_FONIPA', 410 => 'kk-kk_Latn/BGN', 411 => 'ko-ko_Latn/BGN', 412 => 'ky-am', 413 => 'ky-ar', 414 => 'ky-chr', 415 => 'ky-fa', 416 => 'ky-ky_FONIPA', 417 => 'ky-ky_Latn/BGN', 418 => 'la-la_FONIPA', 419 => 'lt-Lower', 420 => 'lt-Title', 421 => 'lt-Upper', 422 => 'mk-mk_Latn/BGN', 423 => 'mn-mn_Latn/BGN', 424 => 'mn-mn_Latn/MNS', 425 => 'my-Zawgyi', 426 => 'my-am', 427 => 'my-ar', 428 => 'my-chr', 429 => 'my-fa', 430 => 'my-my_FONIPA', 431 => 'nl-Title', 432 => 'nv-nv_FONIPA', 433 => 'pl-am', 434 => 'pl-ar', 435 => 'pl-chr', 436 => 'pl-fa', 437 => 'pl-ja', 438 => 'pl-pl_FONIPA', 439 => 'pl_FONIPA-ja', 440 => 'ps-ps_Latn/BGN', 441 => 'rm_SURSILV-am', 442 => 'rm_SURSILV-ar', 443 => 'rm_SURSILV-chr', 444 => 'rm_SURSILV-fa', 445 => 'rm_SURSILV-rm_FONIPA_SURSILV', 446 => 'ro-am', 447 => 'ro-ar', 448 => 'ro-chr', 449 => 'ro-fa', 450 => 'ro-ja', 451 => 'ro-ro_FONIPA', 452 => 'ro_FONIPA-ja', 453 => 'ru-ja', 454 => 'ru-ru_Latn/BGN', 455 => 'ru-zh', 456 => 'ru_Latn-ru/BGN', 457 => 'sat-am', 458 => 'sat-ar', 459 => 'sat-chr', 460 => 'sat-fa', 461 => 'sat_Olck-sat_FONIPA', 462 => 'si-am', 463 => 'si-ar', 464 => 'si-chr', 465 => 'si-fa', 466 => 'si-si_FONIPA', 467 => 'si-si_Latn', 468 => 'sk-am', 469 => 'sk-ar', 470 => 'sk-chr', 471 => 'sk-fa', 472 => 'sk-ja', 473 => 'sk-sk_FONIPA', 474 => 'sk_FONIPA-ja', 475 => 'sr-sr_Latn/BGN', 476 => 'ta-ta_FONIPA', 477 => 'tk_Cyrl-tk/BGN', 478 => 'tlh-am', 479 => 'tlh-ar', 480 => 'tlh-chr', 481 => 'tlh-fa', 482 => 'tlh-tlh_FONIPA', 483 => 'tr-Lower', 484 => 'tr-Title', 485 => 'tr-Upper', 486 => 'ug-ug_FONIPA', 487 => 'uk-uk_Latn/BGN', 488 => 'und_FONIPA-ar', 489 => 'und_FONIPA-chr', 490 => 'und_FONIPA-fa', 491 => 'und_FONIPA-und_FONXSAMP', 492 => 'und_FONXSAMP-und_FONIPA', 493 => 'uz_Cyrl-uz/BGN', 494 => 'uz_Cyrl-uz_Latn', 495 => 'uz_Latn-uz_Cyrl', 496 => 'vec-vec_FONIPA', 497 => 'xh-am', 498 => 'xh-ar', 499 => 'xh-chr', 500 => 'xh-fa', 501 => 'xh-xh_FONIPA', 502 => 'yo-yo_BJ', 503 => 'zh_Latn_PINYIN-ru', 504 => 'zu-am', 505 => 'zu-ar', 506 => 'zu-chr', 507 => 'zu-fa', 508 => 'zu-zu_FONIPA', 509 => 'Any-Null', 510 => 'Any-Lower', 511 => 'Any-Upper', 512 => 'Any-Title', 513 => 'Any-Name', 514 => 'Name-Any', 515 => 'Any-Remove', 516 => 'Any-Hex/Unicode', 517 => 'Any-Hex/Java', 518 => 'Any-Hex/C', 519 => 'Any-Hex/XML', 520 => 'Any-Hex/XML10', 521 => 'Any-Hex/Perl', 522 => 'Any-Hex', 523 => 'Hex-Any/Unicode', 524 => 'Hex-Any/Java', 525 => 'Hex-Any/C', 526 => 'Hex-Any/XML', 527 => 'Hex-Any/XML10', 528 => 'Hex-Any/Perl', 529 => 'Hex-Any', 530 => 'Any-NFC', 531 => 'Any-NFKC', 532 => 'Any-NFD', 533 => 'Any-NFKD', 534 => 'Any-FCD', 535 => 'Any-FCC', 536 => 'Any-fa', 537 => 'Any-ar', 538 => 'Any-chr', 539 => 'Any-rm_FONIPA_SURSILV', 540 => 'Any-am', 541 => 'Any-Latn', 542 => 'Any-dv_Latn/BGN', 543 => 'Any-ro_FONIPA', 544 => 'Any-dsb_FONIPA', 545 => 'Any-Latin', 546 => 'Any-he_Latn/BGN', 547 => 'Any-el_Latn/BGN', 548 => 'Any-eo_FONIPA', 549 => 'Any-si_Latn', 550 => 'Any-si_FONIPA', 551 => 'Any-zh', 552 => 'Any-es_FONIPA', 553 => 'Any-sk_FONIPA', 554 => 'Any-und_FONIPA', 555 => 'Any-und_FONXSAMP', 556 => 'Any-az/BGN', 557 => 'Any-Deva', 558 => 'Any-Arab', 559 => 'Any-Telu', 560 => 'Any-Beng', 561 => 'Any-ur', 562 => 'Any-Orya', 563 => 'Any-Guru', 564 => 'Any-Taml', 565 => 'Any-Gujr', 566 => 'Any-Knda', 567 => 'Any-Armenian', 568 => 'Any-Thaana', 569 => 'Any-Hiragana', 570 => 'Any-Syriac', 571 => 'Any-Jamo', 572 => 'Any-Hangul', 573 => 'Any-Kannada', 574 => 'Any-Georgian', 575 => 'Any-Telugu', 576 => 'Any-Cyrillic', 577 => 'Any-Thai', 578 => 'Any-Oriya', 579 => 'Any-Bopomofo', 580 => 'Any-Malayalam', 581 => 'Any-Gurmukhi', 582 => 'Any-Gujarati', 583 => 'Any-Tamil', 584 => 'Any-Katakana', 585 => 'Any-Hebrew', 586 => 'Any-Bengali', 587 => 'Any-Arabic', 588 => 'Any-Greek', 589 => 'Any-Greek/UNGEGN', 590 => 'Any-Devanagari', 591 => 'Any-fa_FONIPA', 592 => 'Any-fa_Latn/BGN', 593 => 'Any-ta_FONIPA', 594 => 'Any-Mlym', 595 => 'Any-Any', 596 => 'Any-Hant', 597 => 'Any-Hans', 598 => 'Any-uz_Cyrl', 599 => 'Any-blt_FONIPA', 600 => 'Any-ug_FONIPA', 601 => 'Any-uk_Latn/BGN', 602 => 'Any-ha_NE', 603 => 'Any-hy_AREVMDA_FONIPA', 604 => 'Any-hy_FONIPA', 605 => 'Any-hy_Latn/BGN', 606 => 'Any-ia_FONIPA', 607 => 'Any-uz/BGN', 608 => 'Any-uz_Latn', 609 => 'Any-vec_FONIPA', 610 => 'Any-xh_FONIPA', 611 => 'Any-ka_Latn/BGN', 612 => 'Any-ka_Latn/BGN_1981', 613 => 'Any-kk_FONIPA', 614 => 'Any-kk_Latn/BGN', 615 => 'Any-yo_BJ', 616 => 'Any-ky_FONIPA', 617 => 'Any-ky_Latn/BGN', 618 => 'Any-la_FONIPA', 619 => 'Any-ru_Latn/BGN', 620 => 'Any-chr_FONIPA', 621 => 'Any-zu_FONIPA', 622 => 'Any-ru', 623 => 'Any-Geor', 624 => 'Any-Cyrl', 625 => 'Any-Armn', 626 => 'Any-Thaa', 627 => 'Any-Hebr', 628 => 'Any-Grek', 629 => 'Any-Grek/UNGEGN', 630 => 'Any-Syrc', 631 => 'Any-Hira', 632 => 'Any-Hang', 633 => 'Any-Kana', 634 => 'Any-Bopo', 635 => 'Any-mn_Latn/BGN', 636 => 'Any-mn_Latn/MNS', 637 => 'Any-my_FONIPA', 638 => 'Any-sr_Latn/BGN', 639 => 'Any-nv_FONIPA', 640 => 'Any-sat_FONIPA', 641 => 'Any-my', 642 => 'Any-am_FONIPA', 643 => 'Any-am_Latn/BGN', 644 => 'Any-ar_Latn/BGN', 645 => 'Any-mk_Latn/BGN', 646 => 'Any-be_Latn/BGN', 647 => 'Any-bg_Latn/BGN', 648 => 'Any-es_419_FONIPA', 649 => 'Any-pl_FONIPA', 650 => 'Any-ps_Latn/BGN', 651 => 'Any-tk/BGN', 652 => 'Any-ch_FONIPA', 653 => 'Any-cs_FONIPA', 654 => 'Any-cy_FONIPA']; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/utf8_fix.php b/includes/libraries/anti-xss-master/src/voku/helper/data/utf8_fix.php new file mode 100644 index 000000000..e61623f29 --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/utf8_fix.php @@ -0,0 +1,152 @@ + '‚', + '„' => '„', + '…' => '…', + '‡' => '‡', + '‰' => '‰', + '‹' => '‹', + '‘' => '‘', + '’' => '’', + '“' => '“', + '•' => '•', + '–' => '–', + '—' => '—', + 'â„¢' => '™', + '›' => '›', + '€' => '€', + // 2 char errors + "\xc2\x80" => "\xe2\x82\xac", // EURO SIGN + "\xc2\x82" => "\xe2\x80\x9a", // SINGLE LOW-9 QUOTATION MARK + "\xc2\x83" => "\xc6\x92", // LATIN SMALL LETTER F WITH HOOK + "\xc2\x84" => "\xe2\x80\x9e", // DOUBLE LOW-9 QUOTATION MARK + "\xc2\x85" => "\xe2\x80\xa6", // HORIZONTAL ELLIPSIS + "\xc2\x86" => "\xe2\x80\xa0", // DAGGER + "\xc2\x87" => "\xe2\x80\xa1", // DOUBLE DAGGER + "\xc2\x88" => "\xcb\x86", // MODIFIER LETTER CIRCUMFLEX ACCENT + "\xc2\x89" => "\xe2\x80\xb0", // PER MILLE SIGN + "\xc2\x8a" => "\xc5\xa0", // LATIN CAPITAL LETTER S WITH CARON + "\xc2\x8b" => "\xe2\x80\xb9", // SINGLE LEFT-POINTING ANGLE QUOTE + "\xc2\x8c" => "\xc5\x92", // LATIN CAPITAL LIGATURE OE + "\xc2\x8e" => "\xc5\xbd", // LATIN CAPITAL LETTER Z WITH CARON + "\xc2\x91" => "\xe2\x80\x98", // LEFT SINGLE QUOTATION MARK + "\xc2\x92" => "\xe2\x80\x99", // RIGHT SINGLE QUOTATION MARK + "\xc2\x93" => "\xe2\x80\x9c", // LEFT DOUBLE QUOTATION MARK + "\xc2\x94" => "\xe2\x80\x9d", // RIGHT DOUBLE QUOTATION MARK + "\xc2\x95" => "\xe2\x80\xa2", // BULLET + "\xc2\x96" => "\xe2\x80\x93", // EN DASH + "\xc2\x97" => "\xe2\x80\x94", // EM DASH + "\xc2\x98" => "\xcb\x9c", // SMALL TILDE + 'Â' => 'Â', + 'Æ’' => 'ƒ', + 'Ã' => 'Ã', + 'Ä' => 'Ä', + 'Ã…' => 'Å', + //'â€' => '†', // duplicate key + 'Æ' => 'Æ', + 'Ç' => 'Ç', + 'ˆ' => 'ˆ', + 'È' => 'È', + 'É' => 'É', + 'Ê' => 'Ê', + 'Ë' => 'Ë', + 'Å’' => 'Œ', + 'ÃŒ' => 'Ì', + 'Ž' => 'Ž', + 'ÃŽ' => 'Î', + 'Ñ' => 'Ñ', + 'Ã’' => 'Ò', + 'Ó' => 'Ó', + 'â€' => '”', + 'Ô' => 'Ô', + 'Õ' => 'Õ', + 'Ö' => 'Ö', + '×' => '×', + 'Ëœ' => '˜', + 'Ø' => 'Ø', + 'Ù' => 'Ù', + 'Å¡' => 'š', + 'Ú' => 'Ú', + 'Û' => 'Û', + 'Å“' => 'œ', + 'Ãœ' => 'Ü', + 'ž' => 'ž', + 'Þ' => 'Þ', + 'Ÿ' => 'Ÿ', + 'ß' => 'ß', + '¡' => '¡', + 'á' => 'á', + '¢' => '¢', + 'â' => 'â', + '£' => '£', + 'ã' => 'ã', + '¤' => '¤', + 'ä' => 'ä', + 'Â¥' => '¥', + 'Ã¥' => 'å', + '¦' => '¦', + 'æ' => 'æ', + '§' => '§', + 'ç' => 'ç', + '¨' => '¨', + 'è' => 'è', + '©' => '©', + 'é' => 'é', + 'ª' => 'ª', + 'ê' => 'ê', + '«' => '«', + 'ë' => 'ë', + '¬' => '¬', + 'ì' => 'ì', + '®' => '®', + 'î' => 'î', + '¯' => '¯', + 'ï' => 'ï', + '°' => '°', + 'ð' => 'ð', + '±' => '±', + 'ñ' => 'ñ', + '²' => '²', + 'ò' => 'ò', + '³' => '³', + 'ó' => 'ó', + '´' => '´', + 'ô' => 'ô', + 'µ' => 'µ', + 'õ' => 'õ', + '¶' => '¶', + 'ö' => 'ö', + '·' => '·', + '÷' => '÷', + '¸' => '¸', + 'ø' => 'ø', + '¹' => '¹', + 'ù' => 'ù', + 'º' => 'º', + 'ú' => 'ú', + '»' => '»', + 'û' => 'û', + '¼' => '¼', + 'ü' => 'ü', + '½' => '½', + 'ý' => 'ý', + '¾' => '¾', + 'þ' => 'þ', + '¿' => '¿', + 'ÿ' => 'ÿ', + 'À' => 'À', + // 1 char errors last (don't use them, because of false-positives) + //'Ã' => 'Á', + //'Å' => 'Š', + //'Ã' => 'Í', + //'Ã' => 'Ï', + //'Ã' => 'Ð', + //'Ã' => 'Ý', + //'Ã' => 'à', + //'Ã' => 'í', +]; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/win1252_to_utf8.php b/includes/libraries/anti-xss-master/src/voku/helper/data/win1252_to_utf8.php new file mode 100644 index 000000000..46ad53c6c --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/win1252_to_utf8.php @@ -0,0 +1,126 @@ + "\xe2\x82\xac", // € + 0x82 => "\xe2\x80\x9a", // ‚ + 0x83 => "\xc6\x92", // ƒ + 0x84 => "\xe2\x80\x9e", // „ + 0x85 => "\xe2\x80\xa6", // … + 0x86 => "\xe2\x80\xa0", // † + 0x87 => "\xe2\x80\xa1", // ‡ + 0x88 => "\xcb\x86", // ˆ + 0x89 => "\xe2\x80\xb0", // ‰ + 0x8a => "\xc5\xa0", // Š + 0x8b => "\xe2\x80\xb9", // ‹ + 0x8c => "\xc5\x92", // Œ + 0x8e => "\xc5\xbd", // Ž + 0x91 => "\xe2\x80\x98", // ‘ + 0x92 => "\xe2\x80\x99", // ’ + 0x93 => "\xe2\x80\x9c", // “ + 0x94 => "\xe2\x80\x9d", // ” + 0x95 => "\xe2\x80\xa2", // • + 0x96 => "\xe2\x80\x93", // – + 0x97 => "\xe2\x80\x94", // — + 0x98 => "\xcb\x9c", // ˜ + 0x99 => "\xe2\x84\xa2", // ™ + 0x9a => "\xc5\xa1", // š + 0x9b => "\xe2\x80\xba", // › + 0x9c => "\xc5\x93", // œ + 0x9e => "\xc5\xbe", // ž + 0x9f => "\xc5\xb8", // Ÿ + 0xa0 => "\xc2\xa0", + 0xa1 => "\xc2\xa1", // ¡ + 0xa2 => "\xc2\xa2", // ¢ + 0xa3 => "\xc2\xa3", // £ + 0xa4 => "\xc2\xa4", // ¤ + 0xa5 => "\xc2\xa5", // ¥ + 0xa6 => "\xc2\xa6", // ¦ + 0xa7 => "\xc2\xa7", // § + 0xa8 => "\xc2\xa8", // ¨ + 0xa9 => "\xc2\xa9", // © + 0xaa => "\xc2\xaa", // ª + 0xab => "\xc2\xab", // « + 0xac => "\xc2\xac", // ¬ + 0xad => "\xc2\xad", // + 0xae => "\xc2\xae", // ® + 0xaf => "\xc2\xaf", // ¯ + 0xb0 => "\xc2\xb0", // ° + 0xb1 => "\xc2\xb1", // ± + 0xb2 => "\xc2\xb2", // ² + 0xb3 => "\xc2\xb3", // ³ + 0xb4 => "\xc2\xb4", // ´ + 0xb5 => "\xc2\xb5", // µ + 0xb6 => "\xc2\xb6", // ¶ + 0xb7 => "\xc2\xb7", // · + 0xb8 => "\xc2\xb8", // ¸ + 0xb9 => "\xc2\xb9", // ¹ + 0xba => "\xc2\xba", // º + 0xbb => "\xc2\xbb", // » + 0xbc => "\xc2\xbc", // ¼ + 0xbd => "\xc2\xbd", // ½ + 0xbe => "\xc2\xbe", // ¾ + 0xbf => "\xc2\xbf", // ¿ + 0xc0 => "\xc3\x80", // À + 0xc1 => "\xc3\x81", // Á + 0xc2 => "\xc3\x82", //  + 0xc3 => "\xc3\x83", // à + 0xc4 => "\xc3\x84", // Ä + 0xc5 => "\xc3\x85", // Å + 0xc6 => "\xc3\x86", // Æ + 0xc7 => "\xc3\x87", // Ç + 0xc8 => "\xc3\x88", // È + 0xc9 => "\xc3\x89", // É + 0xca => "\xc3\x8a", // Ê + 0xcb => "\xc3\x8b", // Ë + 0xcc => "\xc3\x8c", // Ì + 0xcd => "\xc3\x8d", // Í + 0xce => "\xc3\x8e", // Î + 0xcf => "\xc3\x8f", // Ï + 0xd0 => "\xc3\x90", // Ð + 0xd1 => "\xc3\x91", // Ñ + 0xd2 => "\xc3\x92", // Ò + 0xd3 => "\xc3\x93", // Ó + 0xd4 => "\xc3\x94", // Ô + 0xd5 => "\xc3\x95", // Õ + 0xd6 => "\xc3\x96", // Ö + 0xd7 => "\xc3\x97", // × + 0xd8 => "\xc3\x98", // Ø + 0xd9 => "\xc3\x99", // Ù + 0xda => "\xc3\x9a", // Ú + 0xdb => "\xc3\x9b", // Û + 0xdc => "\xc3\x9c", // Ü + 0xdd => "\xc3\x9d", // Ý + 0xde => "\xc3\x9e", // Þ + 0xdf => "\xc3\x9f", // ß + 0xe0 => "\xc3\xa0", // à + 0xe1 => "\xc3\xa1", // á + 0xe2 => "\xc3\xa2", // â + 0xe3 => "\xc3\xa3", // ã + 0xe4 => "\xc3\xa4", // ä + 0xe5 => "\xc3\xa5", // å + 0xe6 => "\xc3\xa6", // æ + 0xe7 => "\xc3\xa7", // ç + 0xe8 => "\xc3\xa8", // è + 0xe9 => "\xc3\xa9", // é + 0xea => "\xc3\xaa", // ê + 0xeb => "\xc3\xab", // ë + 0xec => "\xc3\xac", // ì + 0xed => "\xc3\xad", // í + 0xee => "\xc3\xae", // î + 0xef => "\xc3\xaf", // ï + 0xf0 => "\xc3\xb0", // ð + 0xf1 => "\xc3\xb1", // ñ + 0xf2 => "\xc3\xb2", // ò + 0xf3 => "\xc3\xb3", // ó + 0xf4 => "\xc3\xb4", // ô + 0xf5 => "\xc3\xb5", // õ + 0xf6 => "\xc3\xb6", // ö + 0xf7 => "\xc3\xb7", // ÷ + 0xf8 => "\xc3\xb8", // ø + 0xf9 => "\xc3\xb9", // ù + 0xfa => "\xc3\xba", // ú + 0xfb => "\xc3\xbb", // û + 0xfc => "\xc3\xbc", // ü + 0xfd => "\xc3\xbd", // ý + 0xfe => "\xc3\xbe", // þ +]; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/x000.php b/includes/libraries/anti-xss-master/src/voku/helper/data/x000.php new file mode 100644 index 000000000..6c9d81f9d --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/x000.php @@ -0,0 +1,16 @@ +', '?', '@', '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', '[', '\\', ']', '^', '_', '`', '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', '{', '|', '}', '~', '', 'EUR', // "\xc2\x80" => "\xe2\x82\xac" => EURO SIGN + '', ',', 'f', ',,', // "\xc2\x84" => "\xe2\x80\x9e" => DOUBLE LOW-9 QUOTATION MARK + '...', // "\xc2\x85" => "\xe2\x80\xa6" => HORIZONTAL ELLIPSIS + '+', '++', // "\xc2\x87" => "\xe2\x80\xa1" => DOUBLE DAGGER + '^', '%0', // "\xc2\x89" => "\xe2\x80\xb0" => PER MILLE SIGN + 'S', '<', 'OE', // "\xc2\x8c" => "\xc5\x92" => LATIN CAPITAL LIGATURE OE + '', 'Z', '', '', '\'', // "\xc2\x91" => "\xe2\x80\x98" => LEFT SINGLE QUOTATION MARK + '\'', // "\xc2\x92" => "\xe2\x80\x99" => RIGHT SINGLE QUOTATION MARK + '"', '"', '*', '-', '--', // "\xc2\x97" => "\xe2\x80\x94" => EM DASH + '~', 'tm', 's', '>', 'oe', '', 'z', 'Y', ' ', '!', 'C/', 'PS', '$?', 'Y=', '|', 'SS', '"', '(c)', 'a', '<<', '!', '', '(r)', '-', 'deg', '+-', '2', '3', '\'', 'u', 'P', '*', ',', '1', 'o', '>>', '1/4', '1/2', '3/4', '?', 'A', 'A', 'A', 'A', // Not "AE" - used in languages other than German + 'A', 'A', 'AE', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I', 'I', 'D', 'N', 'O', 'O', 'O', 'O', // Not "OE" - used in languages other than German + 'O', 'x', 'O', 'U', 'U', 'U', // Not "UE" - used in languages other than German + 'U', 'Y', 'Th', 'ss', 'a', 'a', 'a', 'a', // Not "ae" - used in languages other than German + 'a', 'a', 'ae', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', 'd', 'n', 'o', 'o', 'o', 'o', // Not "oe" - used in languages other than German + 'o', '/', 'o', 'u', 'u', 'u', // Not "ue" - used in languages other than German + 'u', 'y', 'th', 'y', ]; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/x001.php b/includes/libraries/anti-xss-master/src/voku/helper/data/x001.php new file mode 100644 index 000000000..87fb12fb9 --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/x001.php @@ -0,0 +1 @@ +', '^', 'V', '^', 'V', '\'', '-', '/', '\\', ',', '_', '\\', '/', ':', '.', '`', '\'', '^', 'V', '+', '-', 'V', '.', '@', ',', '~', '"', 'R', 'X', 'G', 'l', 's', 'x', '?', '', '', '', '', '', '', '', 'V', '=', '"', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]']; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/x003.php b/includes/libraries/anti-xss-master/src/voku/helper/data/x003.php new file mode 100644 index 000000000..3d02b86e2 --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/x003.php @@ -0,0 +1 @@ +', '[?]', '[?]', '[?]', 'f', 'v', 'u', 'yr', 'y', 'w', 'th', 'th', 'a', 'o', 'ac', 'ae', 'o', 'o', 'o', 'oe', 'on', 'r', 'k', 'c', 'k', 'g', 'ng', 'g', 'g', 'w', 'h', 'h', 'h', 'h', 'n', 'n', 'n', 'i', 'e', 'j', 'g', 'ae', 'a', 'eo', 'p', 'z', 's', 's', 's', 'c', 'z', 't', 't', 'd', 'b', 'b', 'p', 'p', 'e', 'm', 'm', 'm', 'l', 'l', 'ng', 'ng', 'd', 'o', 'ear', 'ior', 'qu', 'qu', 'qu', 's', 'yr', 'yr', 'yr', 'q', 'x', '.', ':', '+', '17', '18', '19', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]']; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/x017.php b/includes/libraries/anti-xss-master/src/voku/helper/data/x017.php new file mode 100644 index 000000000..8f2a7cac1 --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/x017.php @@ -0,0 +1 @@ +', '.', '..', '...', '.', "\n", + "\n\n", + '', '', '', '', '', ' ', '%0', '%00', '\'', '\'\'', '\'\'\'', '`', '``', '```', '^', '<', '>', '*', '!!', '!?', '-', '_', '-', '^', '***', '--', '/', '-[', ']-', '??', '?!', '!?', '7', 'PP', '(]', '[)', '*', '[?]', '[?]', '[?]', '%', '~', '[?]', '[?]', '[?]', "''''", // 0x57 + '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', ' ', '', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '', '', '', '', '', '', '0', 'i', '', '', '4', '5', '6', '7', '8', '9', '+', '-', '=', '(', ')', 'n', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '-', '=', '(', ')', '[?]', 'a', 'e', 'o', 'x', '[?]', 'h', 'k', 'l', 'm', 'n', 'p', 's', 't', '[?]', '[?]', '[?]', 'ECU', 'CL', 'Cr', 'Fr.', 'L.', 'mil', 'N', 'Pts', 'Rs', 'W', 'NS', 'D', 'EUR', 'K', 'T', 'Dr', 'Pf', 'P', 'G', 'A', 'UAH', 'C|', 'L', 'Sm', 'T', 'Rs', 'L', 'M', 'm', 'R', 'l', 'BTC', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '[?]', '', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', ]; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/x021.php b/includes/libraries/anti-xss-master/src/voku/helper/data/x021.php new file mode 100644 index 000000000..1643d67dc --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/x021.php @@ -0,0 +1 @@ +=', '<=', '>=', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]']; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/x023.php b/includes/libraries/anti-xss-master/src/voku/helper/data/x023.php new file mode 100644 index 000000000..b8f4ca0d2 --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/x023.php @@ -0,0 +1 @@ + ', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]']; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/x024.php b/includes/libraries/anti-xss-master/src/voku/helper/data/x024.php new file mode 100644 index 000000000..26abcc69a --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/x024.php @@ -0,0 +1 @@ +', '>', '>', '>', '>', '>', 'V', 'V', 'V', 'V', '<', '<', '<', '<', '<', '<', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '#', '#', '#', '#', '#', '^', '^', '^', 'O', '#', '#', '#', '#', 'O', 'O', 'O', 'O', '/', '\\\\', '\\\\', '#', '#', '#', '#', '/']; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/x026.php b/includes/libraries/anti-xss-master/src/voku/helper/data/x026.php new file mode 100644 index 000000000..0c97de3f8 --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/x026.php @@ -0,0 +1 @@ + ', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]']; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/x028.php b/includes/libraries/anti-xss-master/src/voku/helper/data/x028.php new file mode 100644 index 000000000..9585d9149 --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/x028.php @@ -0,0 +1 @@ +', 'n', 't', 'q', ',', '*', '5', '<', '-', 'u', '8', 'v', '.', '%', '[', '$', '+', 'x', '!', '&', ';', ':', '4', '\\', '0', 'z', '7', '(', '_', '?', 'w', ']', '#', 'y', ')', '=', '[d7]', '[d17]', '[d27]', '[d127]', '[d37]', '[d137]', '[d237]', '[d1237]', '[d47]', '[d147]', '[d247]', '[d1247]', '[d347]', '[d1347]', '[d2347]', '[d12347]', '[d57]', '[d157]', '[d257]', '[d1257]', '[d357]', '[d1357]', '[d2357]', '[d12357]', '[d457]', '[d1457]', '[d2457]', '[d12457]', '[d3457]', '[d13457]', '[d23457]', '[d123457]', '[d67]', '[d167]', '[d267]', '[d1267]', '[d367]', '[d1367]', '[d2367]', '[d12367]', '[d467]', '[d1467]', '[d2467]', '[d12467]', '[d3467]', '[d13467]', '[d23467]', '[d123467]', '[d567]', '[d1567]', '[d2567]', '[d12567]', '[d3567]', '[d13567]', '[d23567]', '[d123567]', '[d4567]', '[d14567]', '[d24567]', '[d124567]', '[d34567]', '[d134567]', '[d234567]', '[d1234567]', '[d8]', '[d18]', '[d28]', '[d128]', '[d38]', '[d138]', '[d238]', '[d1238]', '[d48]', '[d148]', '[d248]', '[d1248]', '[d348]', '[d1348]', '[d2348]', '[d12348]', '[d58]', '[d158]', '[d258]', '[d1258]', '[d358]', '[d1358]', '[d2358]', '[d12358]', '[d458]', '[d1458]', '[d2458]', '[d12458]', '[d3458]', '[d13458]', '[d23458]', '[d123458]', '[d68]', '[d168]', '[d268]', '[d1268]', '[d368]', '[d1368]', '[d2368]', '[d12368]', '[d468]', '[d1468]', '[d2468]', '[d12468]', '[d3468]', '[d13468]', '[d23468]', '[d123468]', '[d568]', '[d1568]', '[d2568]', '[d12568]', '[d3568]', '[d13568]', '[d23568]', '[d123568]', '[d4568]', '[d14568]', '[d24568]', '[d124568]', '[d34568]', '[d134568]', '[d234568]', '[d1234568]', '[d78]', '[d178]', '[d278]', '[d1278]', '[d378]', '[d1378]', '[d2378]', '[d12378]', '[d478]', '[d1478]', '[d2478]', '[d12478]', '[d3478]', '[d13478]', '[d23478]', '[d123478]', '[d578]', '[d1578]', '[d2578]', '[d12578]', '[d3578]', '[d13578]', '[d23578]', '[d123578]', '[d4578]', '[d14578]', '[d24578]', '[d124578]', '[d34578]', '[d134578]', '[d234578]', '[d1234578]', '[d678]', '[d1678]', '[d2678]', '[d12678]', '[d3678]', '[d13678]', '[d23678]', '[d123678]', '[d4678]', '[d14678]', '[d24678]', '[d124678]', '[d34678]', '[d134678]', '[d234678]', '[d1234678]', '[d5678]', '[d15678]', '[d25678]', '[d125678]', '[d35678]', '[d135678]', '[d235678]', '[d1235678]', '[d45678]', '[d145678]', '[d245678]', '[d1245678]', '[d345678]', '[d1345678]', '[d2345678]', '[d12345678]']; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/x029.php b/includes/libraries/anti-xss-master/src/voku/helper/data/x029.php new file mode 100644 index 000000000..5162de386 --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/x029.php @@ -0,0 +1 @@ +', '%', '[?]', '[?]', '>', '=', '[?]', '/', '-', '~', '\\', '/', '~', '~', '|-', '-|', '[?]', '[?]', '[?]', '[?]', '<=', '=>', '((', '))', '[?]', '[?]', '::', '[?]', '?', '\'', 'o', '.', ',', '.', ',', ';', '[?]', '[?]', '[?]', '[?]', '----', '------', 'x', '|', '[?]', '[?]', '=', ',', '"', '`--', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?]', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?] ', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]']; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/x02f.php b/includes/libraries/anti-xss-master/src/voku/helper/data/x02f.php new file mode 100644 index 000000000..5147b5740 --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/x02f.php @@ -0,0 +1 @@ + ', '<<', '>> ', '[', '] ', '{', '} ', '[(', ')] ', '@', 'X ', '[', '] ', '[[', ']] ', '((', ')) ', '[[', ']] ', '~ ', '``', '\'\'', ',,', '@', '1', '2', '3', '4', '5', '6', '7', '8', '9', '', '', '', '', '', '', '~', '+', '+', '+', '+', '', '@', ' // ', '+10+', '+20+', '+30+', '[?]', '[?]', '[?]', '', '', '[?]', 'a', 'a', 'i', 'i', 'u', 'u', 'e', 'e', 'o', 'o', 'ka', 'ga', 'ki', 'gi', 'ku', 'gu', 'ke', 'ge', 'ko', 'go', 'sa', 'za', 'shi', // 0x57 + 'zi', 'su', 'zu', 'se', 'ze', 'so', 'zo', 'ta', 'da', 'chi', // 0x61 + 'di', 'tsu', // 0x63 + 'tsu', // 0x64 + 'du', 'te', 'de', 'to', 'do', 'na', 'ni', 'nu', 'ne', 'no', 'ha', 'ba', 'pa', 'hi', 'bi', 'pi', 'hu', 'bu', 'pu', 'he', 'be', 'pe', 'ho', 'bo', 'po', 'ma', 'mi', 'mu', 'me', 'mo', 'ya', 'ya', 'yu', 'yu', 'yo', 'yo', 'ra', 'ri', 'ru', 're', 'ro', 'wa', 'wa', 'wi', 'we', 'wo', 'n', 'vu', '[?]', '[?]', '[?]', '[?]', '', '', '', '', '"', '"', '[?]', '[?]', 'a', 'a', 'i', 'i', 'u', 'u', 'e', 'e', 'o', 'o', 'ka', 'ga', 'ki', 'gi', 'ku', 'gu', 'ke', 'ge', 'ko', 'go', 'sa', 'za', 'shi', // 0xb7 + 'zi', 'su', 'zu', 'se', 'ze', 'so', 'zo', 'ta', 'da', 'chi', // 0xc1 + 'di', 'tsu', // 0xc3 + 'tsu', // 0xc4 + 'du', 'te', 'de', 'to', 'do', 'na', 'ni', 'nu', 'ne', 'no', 'ha', 'ba', 'pa', 'hi', 'bi', 'pi', 'hu', 'bu', 'pu', 'he', 'be', 'pe', 'ho', 'bo', 'po', 'ma', 'mi', 'mu', 'me', 'mo', 'ya', 'ya', 'yu', 'yu', 'yo', 'yo', 'ra', 'ri', 'ru', 're', 'ro', 'wa', 'wa', 'wi', 'we', 'wo', 'n', 'vu', 'ka', 'ke', 'va', 'vi', 've', 'vo', '', '', '"', '"', ]; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/x031.php b/includes/libraries/anti-xss-master/src/voku/helper/data/x031.php new file mode 100644 index 000000000..72c0260cf --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/x031.php @@ -0,0 +1 @@ +>', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '(g)', '(n)', '(d)', '(r)', '(m)', '(b)', '(s)', '()', '(j)', '(c)', '(k)', '(t)', '(p)', '(h)', '(ga)', '(na)', '(da)', '(ra)', '(ma)', '(ba)', '(sa)', '(a)', '(ja)', '(ca)', '(ka)', '(ta)', '(pa)', '(ha)', '[?]', '[?]', '[?]', 'KIS ', '(1) ', '(2) ', '(3) ', '(4) ', '(5) ', '(6) ', '(7) ', '(8) ', '(9) ', '(10) ', '(Yue) ', '(Huo) ', '(Shui) ', '(Mu) ', '(Jin) ', '(Tu) ', '(Ri) ', '(Zhu) ', '(You) ', '(She) ', '(Ming) ', '(Te) ', '(Cai) ', '(Zhu) ', '(Lao) ', '(Mi) ', '(Nan) ', '(Nu) ', '(Shi) ', '(You) ', '(Yin) ', '(Zhu) ', '(Xiang) ', '(Xiu) ', '(Xie) ', '(Zheng) ', '(Shang) ', '(Zhong) ', '(Xia) ', '(Zuo) ', '(You) ', '(Yi) ', '(Zong) ', '(Xue) ', '(Jian) ', '(Qi) ', '(Zi) ', '(Xie) ', '(Ye) ', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '1M', '2M', '3M', '4M', '5M', '6M', '7M', '8M', '9M', '10M', '11M', '12M', 'Hg', 'erg', 'eV', 'LTD', 'a', 'i', 'u', 'u', 'o', 'ka', 'ki', 'ku', 'ke', 'ko', 'sa', 'si', 'su', 'se', 'so', 'ta', 'ti', 'tu', 'te', 'to', 'na', 'ni', 'nu', 'ne', 'no', 'ha', 'hi', 'hu', 'he', 'ho', 'ma', 'mi', 'mu', 'me', 'mo', 'ya', 'yu', 'yo', 'ra', 'ri', 'ru', 're', 'ro', 'wa', 'wi', 'we', 'wo']; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/x033.php b/includes/libraries/anti-xss-master/src/voku/helper/data/x033.php new file mode 100644 index 000000000..8505337e3 --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/x033.php @@ -0,0 +1 @@ +> ', '<', '> ', '[', '] ', '{', '}', '[?]', '[?]', '[?]', '[?]', '', '', '', '', '', '', '', ',', ',', '.', '', ';', ':', '?', '!', '-', '(', ')', '{', '}', '{', '}', '#', '&', '*', '+', '-', '<', '>', '=', '', '\\', '$', '%', '@', '[?]', '[?]', '[?]', '[?]', '', '', '', '[?]', '', '[?]', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '[?]', '[?]', '']; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/x0ff.php b/includes/libraries/anti-xss-master/src/voku/helper/data/x0ff.php new file mode 100644 index 000000000..b3a15398c --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/x0ff.php @@ -0,0 +1 @@ +', '?', '@', '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', '[', '\\', ']', '^', '_', '`', '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', '{', '|', '}', '~', '[?]', '[?]', '.', '[', ']', ',', '*', 'wo', 'a', 'i', 'u', 'e', 'o', 'ya', 'yu', 'yo', 'tu', '+', 'a', 'i', 'u', 'e', 'o', 'ka', 'ki', 'ku', 'ke', 'ko', 'sa', 'si', 'su', 'se', 'so', 'ta', 'ti', 'tu', 'te', 'to', 'na', 'ni', 'nu', 'ne', 'no', 'ha', 'hi', 'hu', 'he', 'ho', 'ma', 'mi', 'mu', 'me', 'mo', 'ya', 'yu', 'yo', 'ra', 'ri', 'ru', 're', 'ro', 'wa', 'n', ':', ';', '', 'g', 'gg', 'gs', 'n', 'nj', 'nh', 'd', 'dd', 'r', 'lg', 'lm', 'lb', 'ls', 'lt', 'lp', 'rh', 'm', 'b', 'bb', 'bs', 's', 'ss', '', 'j', 'jj', 'c', 'k', 't', 'p', 'h', '[?]', '[?]', '[?]', 'a', 'ae', 'ya', 'yae', 'eo', 'e', '[?]', '[?]', 'yeo', 'ye', 'o', 'wa', 'wae', 'oe', '[?]', '[?]', 'yo', 'u', 'weo', 'we', 'wi', 'yu', '[?]', '[?]', 'eu', 'yi', 'i', '[?]', '[?]', '[?]', '/C', 'PS', '!', '-', '|', 'Y=', 'W=', '[?]', '|', '-', '|', '-', '|', '#', 'O', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '[?]', '{', '|', '}', '', '', '', '']; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/x1d4.php b/includes/libraries/anti-xss-master/src/voku/helper/data/x1d4.php new file mode 100644 index 000000000..ad8d3b257 --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/x1d4.php @@ -0,0 +1 @@ + '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', 52 => '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', 78 => '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', 104 => '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', 130 => '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', 156 => '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', 181 => 'Z', 182 => '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', 208 => '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', 234 => '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']; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/x1d5.php b/includes/libraries/anti-xss-master/src/voku/helper/data/x1d5.php new file mode 100644 index 000000000..a2a9b908d --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/x1d5.php @@ -0,0 +1,4 @@ + 'w', 'x', 'y', 'z', 4 => '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', 30 => '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', 56 => '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', 82 => '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', 108 => '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', 134 => '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', 160 => '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', 186 => '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', 212 => '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', 238 => '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', ]; diff --git a/includes/libraries/anti-xss-master/src/voku/helper/data/x1d6.php b/includes/libraries/anti-xss-master/src/voku/helper/data/x1d6.php new file mode 100644 index 000000000..315ef5e40 --- /dev/null +++ b/includes/libraries/anti-xss-master/src/voku/helper/data/x1d6.php @@ -0,0 +1 @@ + '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', 80 => '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', 112 => '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', 230 => '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', ]; diff --git a/sources/core.php b/sources/core.php index 16e8d5b69..59d7b12ee 100755 --- a/sources/core.php +++ b/sources/core.php @@ -48,6 +48,8 @@ function redirect($url) { // Load AntiXSS + include_once '../includes/libraries/anti-xss-master/src/voku/helper/ASCII.php'; + include_once '../includes/libraries/anti-xss-master/src/voku/helper/UTF8.php'; include_once '../includes/libraries/anti-xss-master/src/voku/helper/AntiXSS.php'; $antiXss = new voku\helper\AntiXSS(); if (! headers_sent()) { //If headers not sent yet... then do php redirect diff --git a/sources/identify.php b/sources/identify.php index e94d1fbe4..3ab6ba711 100755 --- a/sources/identify.php +++ b/sources/identify.php @@ -188,6 +188,8 @@ function identifyUser(string $sentData, array $SETTINGS): bool error_reporting(E_ERROR); // Load AntiXSS + include_once $SETTINGS['cpassman_dir'] . '/includes/libraries/anti-xss-master/src/voku/helper/ASCII.php'; + include_once $SETTINGS['cpassman_dir'] . '/includes/libraries/anti-xss-master/src/voku/helper/UTF8.php'; include_once $SETTINGS['cpassman_dir'] . '/includes/libraries/anti-xss-master/src/voku/helper/AntiXSS.php'; $antiXss = new voku\helper\AntiXSS(); diff --git a/sources/items.queries.php b/sources/items.queries.php index 670c17f24..1a902ed98 100755 --- a/sources/items.queries.php +++ b/sources/items.queries.php @@ -78,6 +78,12 @@ ); } +// Load AntiXSS +include_once $SETTINGS['cpassman_dir'] . '/includes/libraries/anti-xss-master/src/voku/helper/ASCII.php'; +include_once $SETTINGS['cpassman_dir'] . '/includes/libraries/anti-xss-master/src/voku/helper/UTF8.php'; +include_once $SETTINGS['cpassman_dir'] . '/includes/libraries/anti-xss-master/src/voku/helper/AntiXSS.php'; +$antiXss = new voku\helper\AntiXSS(); + // Connect to mysql server require_once $SETTINGS['cpassman_dir'] . '/includes/libraries/Database/Meekrodb/db.class.php'; if (defined('DB_PASSWD_CLEAR') === false) { @@ -195,7 +201,7 @@ // Prepare variables $post_anyone_can_modify = filter_var($dataReceived['anyone_can_modify'], FILTER_SANITIZE_NUMBER_INT); $post_complexity_level = filter_var($dataReceived['complexity_level'], FILTER_SANITIZE_NUMBER_INT); - $post_description = ($dataReceived['description']); + $post_description = $antiXss->xss_clean($dataReceived['description']); $post_diffusion_list = filter_var( $dataReceived['diffusion_list'], FILTER_SANITIZE_STRING @@ -898,7 +904,7 @@ $dataReceived['fields'], FILTER_SANITIZE_STRING )); - $post_description = ($dataReceived['description']); + $post_description = $antiXss->xss_clean($dataReceived['description']); $post_fa_icon = filter_var(($dataReceived['fa_icon']), FILTER_SANITIZE_STRING); //-> DO A SET OF CHECKS