changeset 9 | 177826044cd9 |
parent 7 | cf61fcea0001 |
child 16 | a86126ab1dd4 |
8:c7c34916027a | 9:177826044cd9 |
---|---|
48 * @param bool $reset Set to true for unit testing. Translated patterns will reset. |
48 * @param bool $reset Set to true for unit testing. Translated patterns will reset. |
49 * @return string The string replaced with html entities |
49 * @return string The string replaced with html entities |
50 */ |
50 */ |
51 function wptexturize( $text, $reset = false ) { |
51 function wptexturize( $text, $reset = false ) { |
52 global $wp_cockneyreplace, $shortcode_tags; |
52 global $wp_cockneyreplace, $shortcode_tags; |
53 static $static_characters = null, |
53 static $static_characters = null, |
54 $static_replacements = null, |
54 $static_replacements = null, |
55 $dynamic_characters = null, |
55 $dynamic_characters = null, |
56 $dynamic_replacements = null, |
56 $dynamic_replacements = null, |
57 $default_no_texturize_tags = null, |
57 $default_no_texturize_tags = null, |
58 $default_no_texturize_shortcodes = null, |
58 $default_no_texturize_shortcodes = null, |
59 $run_texturize = true, |
59 $run_texturize = true, |
60 $apos = null, |
60 $apos = null, |
61 $prime = null, |
61 $prime = null, |
62 $double_prime = null, |
62 $double_prime = null, |
63 $opening_quote = null, |
63 $opening_quote = null, |
64 $closing_quote = null, |
64 $closing_quote = null, |
65 $opening_single_quote = null, |
65 $opening_single_quote = null, |
66 $closing_single_quote = null, |
66 $closing_single_quote = null, |
67 $open_q_flag = '<!--oq-->', |
67 $open_q_flag = '<!--oq-->', |
68 $open_sq_flag = '<!--osq-->', |
68 $open_sq_flag = '<!--osq-->', |
69 $apos_flag = '<!--apos-->'; |
69 $apos_flag = '<!--apos-->'; |
70 |
70 |
71 // If there's nothing to do, just stop. |
71 // If there's nothing to do, just stop. |
72 if ( empty( $text ) || false === $run_texturize ) { |
72 if ( empty( $text ) || false === $run_texturize ) { |
73 return $text; |
73 return $text; |
74 } |
74 } |
115 /* translators: en dash */ |
115 /* translators: en dash */ |
116 $en_dash = _x( '–', 'en dash' ); |
116 $en_dash = _x( '–', 'en dash' ); |
117 /* translators: em dash */ |
117 /* translators: em dash */ |
118 $em_dash = _x( '—', 'em dash' ); |
118 $em_dash = _x( '—', 'em dash' ); |
119 |
119 |
120 $default_no_texturize_tags = array('pre', 'code', 'kbd', 'style', 'script', 'tt'); |
120 $default_no_texturize_tags = array( 'pre', 'code', 'kbd', 'style', 'script', 'tt' ); |
121 $default_no_texturize_shortcodes = array('code'); |
121 $default_no_texturize_shortcodes = array( 'code' ); |
122 |
122 |
123 // if a plugin has provided an autocorrect array, use it |
123 // if a plugin has provided an autocorrect array, use it |
124 if ( isset($wp_cockneyreplace) ) { |
124 if ( isset( $wp_cockneyreplace ) ) { |
125 $cockney = array_keys( $wp_cockneyreplace ); |
125 $cockney = array_keys( $wp_cockneyreplace ); |
126 $cockneyreplace = array_values( $wp_cockneyreplace ); |
126 $cockneyreplace = array_values( $wp_cockneyreplace ); |
127 } else { |
127 } else { |
128 /* translators: This is a comma-separated list of words that defy the syntax of quotations in normal use, |
128 /* translators: This is a comma-separated list of words that defy the syntax of quotations in normal use, |
129 * for example... 'We do not have enough words yet' ... is a typical quoted phrase. But when we write |
129 * for example... 'We do not have enough words yet' ... is a typical quoted phrase. But when we write |
130 * lines of code 'til we have enough of 'em, then we need to insert apostrophes instead of quotes. |
130 * lines of code 'til we have enough of 'em, then we need to insert apostrophes instead of quotes. |
131 */ |
131 */ |
132 $cockney = explode( ',', _x( "'tain't,'twere,'twas,'tis,'twill,'til,'bout,'nuff,'round,'cause,'em", |
132 $cockney = explode( |
133 'Comma-separated list of words to texturize in your language' ) ); |
133 ',', |
134 |
134 _x( |
135 $cockneyreplace = explode( ',', _x( '’tain’t,’twere,’twas,’tis,’twill,’til,’bout,’nuff,’round,’cause,’em', |
135 "'tain't,'twere,'twas,'tis,'twill,'til,'bout,'nuff,'round,'cause,'em", |
136 'Comma-separated list of replacement words in your language' ) ); |
136 'Comma-separated list of words to texturize in your language' |
137 } |
137 ) |
138 |
138 ); |
139 $static_characters = array_merge( array( '...', '``', '\'\'', ' (tm)' ), $cockney ); |
139 |
140 $cockneyreplace = explode( |
|
141 ',', |
|
142 _x( |
|
143 '’tain’t,’twere,’twas,’tis,’twill,’til,’bout,’nuff,’round,’cause,’em', |
|
144 'Comma-separated list of replacement words in your language' |
|
145 ) |
|
146 ); |
|
147 } |
|
148 |
|
149 $static_characters = array_merge( array( '...', '``', '\'\'', ' (tm)' ), $cockney ); |
|
140 $static_replacements = array_merge( array( '…', $opening_quote, $closing_quote, ' ™' ), $cockneyreplace ); |
150 $static_replacements = array_merge( array( '…', $opening_quote, $closing_quote, ' ™' ), $cockneyreplace ); |
141 |
|
142 |
151 |
143 // Pattern-based replacements of characters. |
152 // Pattern-based replacements of characters. |
144 // Sort the remaining patterns into several arrays for performance tuning. |
153 // Sort the remaining patterns into several arrays for performance tuning. |
145 $dynamic_characters = array( 'apos' => array(), 'quote' => array(), 'dash' => array() ); |
154 $dynamic_characters = array( |
146 $dynamic_replacements = array( 'apos' => array(), 'quote' => array(), 'dash' => array() ); |
155 'apos' => array(), |
147 $dynamic = array(); |
156 'quote' => array(), |
148 $spaces = wp_spaces_regexp(); |
157 'dash' => array(), |
158 ); |
|
159 $dynamic_replacements = array( |
|
160 'apos' => array(), |
|
161 'quote' => array(), |
|
162 'dash' => array(), |
|
163 ); |
|
164 $dynamic = array(); |
|
165 $spaces = wp_spaces_regexp(); |
|
149 |
166 |
150 // '99' and '99" are ambiguous among other patterns; assume it's an abbreviated year at the end of a quotation. |
167 // '99' and '99" are ambiguous among other patterns; assume it's an abbreviated year at the end of a quotation. |
151 if ( "'" !== $apos || "'" !== $closing_single_quote ) { |
168 if ( "'" !== $apos || "'" !== $closing_single_quote ) { |
152 $dynamic[ '/\'(\d\d)\'(?=\Z|[.,:;!?)}\-\]]|>|' . $spaces . ')/' ] = $apos_flag . '$1' . $closing_single_quote; |
169 $dynamic[ '/\'(\d\d)\'(?=\Z|[.,:;!?)}\-\]]|>|' . $spaces . ')/' ] = $apos_flag . '$1' . $closing_single_quote; |
153 } |
170 } |
155 $dynamic[ '/\'(\d\d)"(?=\Z|[.,:;!?)}\-\]]|>|' . $spaces . ')/' ] = $apos_flag . '$1' . $closing_quote; |
172 $dynamic[ '/\'(\d\d)"(?=\Z|[.,:;!?)}\-\]]|>|' . $spaces . ')/' ] = $apos_flag . '$1' . $closing_quote; |
156 } |
173 } |
157 |
174 |
158 // '99 '99s '99's (apostrophe) But never '9 or '99% or '999 or '99.0. |
175 // '99 '99s '99's (apostrophe) But never '9 or '99% or '999 or '99.0. |
159 if ( "'" !== $apos ) { |
176 if ( "'" !== $apos ) { |
160 $dynamic[ '/\'(?=\d\d(?:\Z|(?![%\d]|[.,]\d)))/' ] = $apos_flag; |
177 $dynamic['/\'(?=\d\d(?:\Z|(?![%\d]|[.,]\d)))/'] = $apos_flag; |
161 } |
178 } |
162 |
179 |
163 // Quoted Numbers like '0.42' |
180 // Quoted Numbers like '0.42' |
164 if ( "'" !== $opening_single_quote && "'" !== $closing_single_quote ) { |
181 if ( "'" !== $opening_single_quote && "'" !== $closing_single_quote ) { |
165 $dynamic[ '/(?<=\A|' . $spaces . ')\'(\d[.,\d]*)\'/' ] = $open_sq_flag . '$1' . $closing_single_quote; |
182 $dynamic[ '/(?<=\A|' . $spaces . ')\'(\d[.,\d]*)\'/' ] = $open_sq_flag . '$1' . $closing_single_quote; |
173 // Apostrophe in a word. No spaces, double apostrophes, or other punctuation. |
190 // Apostrophe in a word. No spaces, double apostrophes, or other punctuation. |
174 if ( "'" !== $apos ) { |
191 if ( "'" !== $apos ) { |
175 $dynamic[ '/(?<!' . $spaces . ')\'(?!\Z|[.,:;!?"\'(){}[\]\-]|&[lg]t;|' . $spaces . ')/' ] = $apos_flag; |
192 $dynamic[ '/(?<!' . $spaces . ')\'(?!\Z|[.,:;!?"\'(){}[\]\-]|&[lg]t;|' . $spaces . ')/' ] = $apos_flag; |
176 } |
193 } |
177 |
194 |
178 $dynamic_characters['apos'] = array_keys( $dynamic ); |
195 $dynamic_characters['apos'] = array_keys( $dynamic ); |
179 $dynamic_replacements['apos'] = array_values( $dynamic ); |
196 $dynamic_replacements['apos'] = array_values( $dynamic ); |
180 $dynamic = array(); |
197 $dynamic = array(); |
181 |
198 |
182 // Quoted Numbers like "42" |
199 // Quoted Numbers like "42" |
183 if ( '"' !== $opening_quote && '"' !== $closing_quote ) { |
200 if ( '"' !== $opening_quote && '"' !== $closing_quote ) { |
184 $dynamic[ '/(?<=\A|' . $spaces . ')"(\d[.,\d]*)"/' ] = $open_q_flag . '$1' . $closing_quote; |
201 $dynamic[ '/(?<=\A|' . $spaces . ')"(\d[.,\d]*)"/' ] = $open_q_flag . '$1' . $closing_quote; |
185 } |
202 } |
187 // Double quote at start, or preceded by (, {, <, [, -, or spaces, and not followed by spaces. |
204 // Double quote at start, or preceded by (, {, <, [, -, or spaces, and not followed by spaces. |
188 if ( '"' !== $opening_quote ) { |
205 if ( '"' !== $opening_quote ) { |
189 $dynamic[ '/(?<=\A|[([{\-]|<|' . $spaces . ')"(?!' . $spaces . ')/' ] = $open_q_flag; |
206 $dynamic[ '/(?<=\A|[([{\-]|<|' . $spaces . ')"(?!' . $spaces . ')/' ] = $open_q_flag; |
190 } |
207 } |
191 |
208 |
192 $dynamic_characters['quote'] = array_keys( $dynamic ); |
209 $dynamic_characters['quote'] = array_keys( $dynamic ); |
193 $dynamic_replacements['quote'] = array_values( $dynamic ); |
210 $dynamic_replacements['quote'] = array_values( $dynamic ); |
194 $dynamic = array(); |
211 $dynamic = array(); |
195 |
212 |
196 // Dashes and spaces |
213 // Dashes and spaces |
197 $dynamic[ '/---/' ] = $em_dash; |
214 $dynamic['/---/'] = $em_dash; |
198 $dynamic[ '/(?<=^|' . $spaces . ')--(?=$|' . $spaces . ')/' ] = $em_dash; |
215 $dynamic[ '/(?<=^|' . $spaces . ')--(?=$|' . $spaces . ')/' ] = $em_dash; |
199 $dynamic[ '/(?<!xn)--/' ] = $en_dash; |
216 $dynamic['/(?<!xn)--/'] = $en_dash; |
200 $dynamic[ '/(?<=^|' . $spaces . ')-(?=$|' . $spaces . ')/' ] = $en_dash; |
217 $dynamic[ '/(?<=^|' . $spaces . ')-(?=$|' . $spaces . ')/' ] = $en_dash; |
201 |
218 |
202 $dynamic_characters['dash'] = array_keys( $dynamic ); |
219 $dynamic_characters['dash'] = array_keys( $dynamic ); |
203 $dynamic_replacements['dash'] = array_values( $dynamic ); |
220 $dynamic_replacements['dash'] = array_values( $dynamic ); |
204 } |
221 } |
205 |
222 |
206 // Must do this every time in case plugins use these filters in a context sensitive manner |
223 // Must do this every time in case plugins use these filters in a context sensitive manner |
207 /** |
224 /** |
219 * |
236 * |
220 * @param array $default_no_texturize_shortcodes An array of shortcode names. |
237 * @param array $default_no_texturize_shortcodes An array of shortcode names. |
221 */ |
238 */ |
222 $no_texturize_shortcodes = apply_filters( 'no_texturize_shortcodes', $default_no_texturize_shortcodes ); |
239 $no_texturize_shortcodes = apply_filters( 'no_texturize_shortcodes', $default_no_texturize_shortcodes ); |
223 |
240 |
224 $no_texturize_tags_stack = array(); |
241 $no_texturize_tags_stack = array(); |
225 $no_texturize_shortcodes_stack = array(); |
242 $no_texturize_shortcodes_stack = array(); |
226 |
243 |
227 // Look for shortcodes and HTML elements. |
244 // Look for shortcodes and HTML elements. |
228 |
245 |
229 preg_match_all( '@\[/?([^<>&/\[\]\x00-\x20=]++)@', $text, $matches ); |
246 preg_match_all( '@\[/?([^<>&/\[\]\x00-\x20=]++)@', $text, $matches ); |
230 $tagnames = array_intersect( array_keys( $shortcode_tags ), $matches[1] ); |
247 $tagnames = array_intersect( array_keys( $shortcode_tags ), $matches[1] ); |
231 $found_shortcodes = ! empty( $tagnames ); |
248 $found_shortcodes = ! empty( $tagnames ); |
232 $shortcode_regex = $found_shortcodes ? _get_wptexturize_shortcode_regex( $tagnames ) : ''; |
249 $shortcode_regex = $found_shortcodes ? _get_wptexturize_shortcode_regex( $tagnames ) : ''; |
233 $regex = _get_wptexturize_split_regex( $shortcode_regex ); |
250 $regex = _get_wptexturize_split_regex( $shortcode_regex ); |
234 |
251 |
235 $textarr = preg_split( $regex, $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY ); |
252 $textarr = preg_split( $regex, $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY ); |
236 |
253 |
237 foreach ( $textarr as &$curl ) { |
254 foreach ( $textarr as &$curl ) { |
238 // Only call _wptexturize_pushpop_element if $curl is a delimiter. |
255 // Only call _wptexturize_pushpop_element if $curl is a delimiter. |
247 // Replace each & with & unless it already looks like an entity. |
264 // Replace each & with & unless it already looks like an entity. |
248 $curl = preg_replace( '/&(?!#(?:\d+|x[a-f0-9]+);|[a-z1-4]{1,8};)/i', '&', $curl ); |
265 $curl = preg_replace( '/&(?!#(?:\d+|x[a-f0-9]+);|[a-z1-4]{1,8};)/i', '&', $curl ); |
249 |
266 |
250 _wptexturize_pushpop_element( $curl, $no_texturize_tags_stack, $no_texturize_tags ); |
267 _wptexturize_pushpop_element( $curl, $no_texturize_tags_stack, $no_texturize_tags ); |
251 } |
268 } |
252 |
|
253 } elseif ( '' === trim( $curl ) ) { |
269 } elseif ( '' === trim( $curl ) ) { |
254 // This is a newline between delimiters. Performance improves when we check this. |
270 // This is a newline between delimiters. Performance improves when we check this. |
255 continue; |
271 continue; |
256 |
272 |
257 } elseif ( '[' === $first && $found_shortcodes && 1 === preg_match( '/^' . $shortcode_regex . '$/', $curl ) ) { |
273 } elseif ( '[' === $first && $found_shortcodes && 1 === preg_match( '/^' . $shortcode_regex . '$/', $curl ) ) { |
262 _wptexturize_pushpop_element( $curl, $no_texturize_shortcodes_stack, $no_texturize_shortcodes ); |
278 _wptexturize_pushpop_element( $curl, $no_texturize_shortcodes_stack, $no_texturize_shortcodes ); |
263 } else { |
279 } else { |
264 // Looks like an escaped shortcode. |
280 // Looks like an escaped shortcode. |
265 continue; |
281 continue; |
266 } |
282 } |
267 |
|
268 } elseif ( empty( $no_texturize_shortcodes_stack ) && empty( $no_texturize_tags_stack ) ) { |
283 } elseif ( empty( $no_texturize_shortcodes_stack ) && empty( $no_texturize_tags_stack ) ) { |
269 // This is neither a delimiter, nor is this content inside of no_texturize pairs. Do texturize. |
284 // This is neither a delimiter, nor is this content inside of no_texturize pairs. Do texturize. |
270 |
285 |
271 $curl = str_replace( $static_characters, $static_replacements, $curl ); |
286 $curl = str_replace( $static_characters, $static_replacements, $curl ); |
272 |
287 |
312 * accomplished already. |
327 * accomplished already. |
313 * @param string $close_quote The closing quote char to use for replacement. |
328 * @param string $close_quote The closing quote char to use for replacement. |
314 * @return string The $haystack value after primes and quotes replacements. |
329 * @return string The $haystack value after primes and quotes replacements. |
315 */ |
330 */ |
316 function wptexturize_primes( $haystack, $needle, $prime, $open_quote, $close_quote ) { |
331 function wptexturize_primes( $haystack, $needle, $prime, $open_quote, $close_quote ) { |
317 $spaces = wp_spaces_regexp(); |
332 $spaces = wp_spaces_regexp(); |
318 $flag = '<!--wp-prime-or-quote-->'; |
333 $flag = '<!--wp-prime-or-quote-->'; |
319 $quote_pattern = "/$needle(?=\\Z|[.,:;!?)}\\-\\]]|>|" . $spaces . ")/"; |
334 $quote_pattern = "/$needle(?=\\Z|[.,:;!?)}\\-\\]]|>|" . $spaces . ')/'; |
320 $prime_pattern = "/(?<=\\d)$needle/"; |
335 $prime_pattern = "/(?<=\\d)$needle/"; |
321 $flag_after_digit = "/(?<=\\d)$flag/"; |
336 $flag_after_digit = "/(?<=\\d)$flag/"; |
322 $flag_no_digit = "/(?<!\\d)$flag/"; |
337 $flag_no_digit = "/(?<!\\d)$flag/"; |
323 |
338 |
324 $sentences = explode( $open_quote, $haystack ); |
339 $sentences = explode( $open_quote, $haystack ); |
437 * @return string Text which has been converted into correct paragraph tags. |
452 * @return string Text which has been converted into correct paragraph tags. |
438 */ |
453 */ |
439 function wpautop( $pee, $br = true ) { |
454 function wpautop( $pee, $br = true ) { |
440 $pre_tags = array(); |
455 $pre_tags = array(); |
441 |
456 |
442 if ( trim($pee) === '' ) |
457 if ( trim( $pee ) === '' ) { |
443 return ''; |
458 return ''; |
459 } |
|
444 |
460 |
445 // Just to make things a little easier, pad the end. |
461 // Just to make things a little easier, pad the end. |
446 $pee = $pee . "\n"; |
462 $pee = $pee . "\n"; |
447 |
463 |
448 /* |
464 /* |
449 * Pre tags shouldn't be touched by autop. |
465 * Pre tags shouldn't be touched by autop. |
450 * Replace pre tags with placeholders and bring them back after autop. |
466 * Replace pre tags with placeholders and bring them back after autop. |
451 */ |
467 */ |
452 if ( strpos($pee, '<pre') !== false ) { |
468 if ( strpos( $pee, '<pre' ) !== false ) { |
453 $pee_parts = explode( '</pre>', $pee ); |
469 $pee_parts = explode( '</pre>', $pee ); |
454 $last_pee = array_pop($pee_parts); |
470 $last_pee = array_pop( $pee_parts ); |
455 $pee = ''; |
471 $pee = ''; |
456 $i = 0; |
472 $i = 0; |
457 |
473 |
458 foreach ( $pee_parts as $pee_part ) { |
474 foreach ( $pee_parts as $pee_part ) { |
459 $start = strpos($pee_part, '<pre'); |
475 $start = strpos( $pee_part, '<pre' ); |
460 |
476 |
461 // Malformed html? |
477 // Malformed html? |
462 if ( $start === false ) { |
478 if ( $start === false ) { |
463 $pee .= $pee_part; |
479 $pee .= $pee_part; |
464 continue; |
480 continue; |
465 } |
481 } |
466 |
482 |
467 $name = "<pre wp-pre-tag-$i></pre>"; |
483 $name = "<pre wp-pre-tag-$i></pre>"; |
468 $pre_tags[$name] = substr( $pee_part, $start ) . '</pre>'; |
484 $pre_tags[ $name ] = substr( $pee_part, $start ) . '</pre>'; |
469 |
485 |
470 $pee .= substr( $pee_part, 0, $start ) . $name; |
486 $pee .= substr( $pee_part, 0, $start ) . $name; |
471 $i++; |
487 $i++; |
472 } |
488 } |
473 |
489 |
474 $pee .= $last_pee; |
490 $pee .= $last_pee; |
475 } |
491 } |
476 // Change multiple <br>s into two line breaks, which will turn into paragraphs. |
492 // Change multiple <br>s into two line breaks, which will turn into paragraphs. |
477 $pee = preg_replace('|<br\s*/?>\s*<br\s*/?>|', "\n\n", $pee); |
493 $pee = preg_replace( '|<br\s*/?>\s*<br\s*/?>|', "\n\n", $pee ); |
478 |
494 |
479 $allblocks = '(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|form|map|area|blockquote|address|math|style|p|h[1-6]|hr|fieldset|legend|section|article|aside|hgroup|header|footer|nav|figure|figcaption|details|menu|summary)'; |
495 $allblocks = '(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|form|map|area|blockquote|address|math|style|p|h[1-6]|hr|fieldset|legend|section|article|aside|hgroup|header|footer|nav|figure|figcaption|details|menu|summary)'; |
480 |
496 |
481 // Add a double line break above block-level opening tags. |
497 // Add a double line break above block-level opening tags. |
482 $pee = preg_replace('!(<' . $allblocks . '[\s/>])!', "\n\n$1", $pee); |
498 $pee = preg_replace( '!(<' . $allblocks . '[\s/>])!', "\n\n$1", $pee ); |
483 |
499 |
484 // Add a double line break below block-level closing tags. |
500 // Add a double line break below block-level closing tags. |
485 $pee = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $pee); |
501 $pee = preg_replace( '!(</' . $allblocks . '>)!', "$1\n\n", $pee ); |
486 |
502 |
487 // Standardize newline characters to "\n". |
503 // Standardize newline characters to "\n". |
488 $pee = str_replace(array("\r\n", "\r"), "\n", $pee); |
504 $pee = str_replace( array( "\r\n", "\r" ), "\n", $pee ); |
489 |
505 |
490 // Find newlines in all elements and add placeholders. |
506 // Find newlines in all elements and add placeholders. |
491 $pee = wp_replace_in_html_tags( $pee, array( "\n" => " <!-- wpnl --> " ) ); |
507 $pee = wp_replace_in_html_tags( $pee, array( "\n" => ' <!-- wpnl --> ' ) ); |
492 |
508 |
493 // Collapse line breaks before and after <option> elements so they don't get autop'd. |
509 // Collapse line breaks before and after <option> elements so they don't get autop'd. |
494 if ( strpos( $pee, '<option' ) !== false ) { |
510 if ( strpos( $pee, '<option' ) !== false ) { |
495 $pee = preg_replace( '|\s*<option|', '<option', $pee ); |
511 $pee = preg_replace( '|\s*<option|', '<option', $pee ); |
496 $pee = preg_replace( '|</option>\s*|', '</option>', $pee ); |
512 $pee = preg_replace( '|</option>\s*|', '</option>', $pee ); |
521 $pee = preg_replace( '|\s*(<figcaption[^>]*>)|', '$1', $pee ); |
537 $pee = preg_replace( '|\s*(<figcaption[^>]*>)|', '$1', $pee ); |
522 $pee = preg_replace( '|</figcaption>\s*|', '</figcaption>', $pee ); |
538 $pee = preg_replace( '|</figcaption>\s*|', '</figcaption>', $pee ); |
523 } |
539 } |
524 |
540 |
525 // Remove more than two contiguous line breaks. |
541 // Remove more than two contiguous line breaks. |
526 $pee = preg_replace("/\n\n+/", "\n\n", $pee); |
542 $pee = preg_replace( "/\n\n+/", "\n\n", $pee ); |
527 |
543 |
528 // Split up the contents into an array of strings, separated by double line breaks. |
544 // Split up the contents into an array of strings, separated by double line breaks. |
529 $pees = preg_split('/\n\s*\n/', $pee, -1, PREG_SPLIT_NO_EMPTY); |
545 $pees = preg_split( '/\n\s*\n/', $pee, -1, PREG_SPLIT_NO_EMPTY ); |
530 |
546 |
531 // Reset $pee prior to rebuilding. |
547 // Reset $pee prior to rebuilding. |
532 $pee = ''; |
548 $pee = ''; |
533 |
549 |
534 // Rebuild the content as a string, wrapping every bit with a <p>. |
550 // Rebuild the content as a string, wrapping every bit with a <p>. |
535 foreach ( $pees as $tinkle ) { |
551 foreach ( $pees as $tinkle ) { |
536 $pee .= '<p>' . trim($tinkle, "\n") . "</p>\n"; |
552 $pee .= '<p>' . trim( $tinkle, "\n" ) . "</p>\n"; |
537 } |
553 } |
538 |
554 |
539 // Under certain strange conditions it could create a P of entirely whitespace. |
555 // Under certain strange conditions it could create a P of entirely whitespace. |
540 $pee = preg_replace('|<p>\s*</p>|', '', $pee); |
556 $pee = preg_replace( '|<p>\s*</p>|', '', $pee ); |
541 |
557 |
542 // Add a closing <p> inside <div>, <address>, or <form> tag if missing. |
558 // Add a closing <p> inside <div>, <address>, or <form> tag if missing. |
543 $pee = preg_replace('!<p>([^<]+)</(div|address|form)>!', "<p>$1</p></$2>", $pee); |
559 $pee = preg_replace( '!<p>([^<]+)</(div|address|form)>!', '<p>$1</p></$2>', $pee ); |
544 |
560 |
545 // If an opening or closing block element tag is wrapped in a <p>, unwrap it. |
561 // If an opening or closing block element tag is wrapped in a <p>, unwrap it. |
546 $pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee); |
562 $pee = preg_replace( '!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', '$1', $pee ); |
547 |
563 |
548 // In some cases <li> may get wrapped in <p>, fix them. |
564 // In some cases <li> may get wrapped in <p>, fix them. |
549 $pee = preg_replace("|<p>(<li.+?)</p>|", "$1", $pee); |
565 $pee = preg_replace( '|<p>(<li.+?)</p>|', '$1', $pee ); |
550 |
566 |
551 // If a <blockquote> is wrapped with a <p>, move it inside the <blockquote>. |
567 // If a <blockquote> is wrapped with a <p>, move it inside the <blockquote>. |
552 $pee = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote$1><p>", $pee); |
568 $pee = preg_replace( '|<p><blockquote([^>]*)>|i', '<blockquote$1><p>', $pee ); |
553 $pee = str_replace('</blockquote></p>', '</p></blockquote>', $pee); |
569 $pee = str_replace( '</blockquote></p>', '</p></blockquote>', $pee ); |
554 |
570 |
555 // If an opening or closing block element tag is preceded by an opening <p> tag, remove it. |
571 // If an opening or closing block element tag is preceded by an opening <p> tag, remove it. |
556 $pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)!', "$1", $pee); |
572 $pee = preg_replace( '!<p>\s*(</?' . $allblocks . '[^>]*>)!', '$1', $pee ); |
557 |
573 |
558 // If an opening or closing block element tag is followed by a closing <p> tag, remove it. |
574 // If an opening or closing block element tag is followed by a closing <p> tag, remove it. |
559 $pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee); |
575 $pee = preg_replace( '!(</?' . $allblocks . '[^>]*>)\s*</p>!', '$1', $pee ); |
560 |
576 |
561 // Optionally insert line breaks. |
577 // Optionally insert line breaks. |
562 if ( $br ) { |
578 if ( $br ) { |
563 // Replace newlines that shouldn't be touched with a placeholder. |
579 // Replace newlines that shouldn't be touched with a placeholder. |
564 $pee = preg_replace_callback('/<(script|style).*?<\/\\1>/s', '_autop_newline_preservation_helper', $pee); |
580 $pee = preg_replace_callback( '/<(script|style).*?<\/\\1>/s', '_autop_newline_preservation_helper', $pee ); |
565 |
581 |
566 // Normalize <br> |
582 // Normalize <br> |
567 $pee = str_replace( array( '<br>', '<br/>' ), '<br />', $pee ); |
583 $pee = str_replace( array( '<br>', '<br/>' ), '<br />', $pee ); |
568 |
584 |
569 // Replace any new line characters that aren't preceded by a <br /> with a <br />. |
585 // Replace any new line characters that aren't preceded by a <br /> with a <br />. |
570 $pee = preg_replace('|(?<!<br />)\s*\n|', "<br />\n", $pee); |
586 $pee = preg_replace( '|(?<!<br />)\s*\n|', "<br />\n", $pee ); |
571 |
587 |
572 // Replace newline placeholders with newlines. |
588 // Replace newline placeholders with newlines. |
573 $pee = str_replace('<WPPreserveNewline />', "\n", $pee); |
589 $pee = str_replace( '<WPPreserveNewline />', "\n", $pee ); |
574 } |
590 } |
575 |
591 |
576 // If a <br /> tag is after an opening or closing block tag, remove it. |
592 // If a <br /> tag is after an opening or closing block tag, remove it. |
577 $pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*<br />!', "$1", $pee); |
593 $pee = preg_replace( '!(</?' . $allblocks . '[^>]*>)\s*<br />!', '$1', $pee ); |
578 |
594 |
579 // If a <br /> tag is before a subset of opening or closing block tags, remove it. |
595 // If a <br /> tag is before a subset of opening or closing block tags, remove it. |
580 $pee = preg_replace('!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $pee); |
596 $pee = preg_replace( '!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $pee ); |
581 $pee = preg_replace( "|\n</p>$|", '</p>', $pee ); |
597 $pee = preg_replace( "|\n</p>$|", '</p>', $pee ); |
582 |
598 |
583 // Replace placeholder <pre> tags with their original content. |
599 // Replace placeholder <pre> tags with their original content. |
584 if ( !empty($pre_tags) ) |
600 if ( ! empty( $pre_tags ) ) { |
585 $pee = str_replace(array_keys($pre_tags), array_values($pre_tags), $pee); |
601 $pee = str_replace( array_keys( $pre_tags ), array_values( $pre_tags ), $pee ); |
602 } |
|
586 |
603 |
587 // Restore newlines in all elements. |
604 // Restore newlines in all elements. |
588 if ( false !== strpos( $pee, '<!-- wpnl -->' ) ) { |
605 if ( false !== strpos( $pee, '<!-- wpnl -->' ) ) { |
589 $pee = str_replace( array( ' <!-- wpnl --> ', '<!-- wpnl -->' ), "\n", $pee ); |
606 $pee = str_replace( array( ' <!-- wpnl --> ', '<!-- wpnl -->' ), "\n", $pee ); |
590 } |
607 } |
615 */ |
632 */ |
616 function get_html_split_regex() { |
633 function get_html_split_regex() { |
617 static $regex; |
634 static $regex; |
618 |
635 |
619 if ( ! isset( $regex ) ) { |
636 if ( ! isset( $regex ) ) { |
637 // phpcs:disable Squiz.Strings.ConcatenationSpacing.PaddingFound -- don't remove regex indentation |
|
620 $comments = |
638 $comments = |
621 '!' // Start of comment, after the <. |
639 '!' // Start of comment, after the <. |
622 . '(?:' // Unroll the loop: Consume everything until --> is found. |
640 . '(?:' // Unroll the loop: Consume everything until --> is found. |
623 . '-(?!->)' // Dash not followed by end of comment. |
641 . '-(?!->)' // Dash not followed by end of comment. |
624 . '[^\-]*+' // Consume non-dashes. |
642 . '[^\-]*+' // Consume non-dashes. |
625 . ')*+' // Loop possessively. |
643 . ')*+' // Loop possessively. |
626 . '(?:-->)?'; // End of comment. If not found, match all input. |
644 . '(?:-->)?'; // End of comment. If not found, match all input. |
627 |
645 |
628 $cdata = |
646 $cdata = |
629 '!\[CDATA\[' // Start of comment, after the <. |
647 '!\[CDATA\[' // Start of comment, after the <. |
630 . '[^\]]*+' // Consume non-]. |
648 . '[^\]]*+' // Consume non-]. |
631 . '(?:' // Unroll the loop: Consume everything until ]]> is found. |
649 . '(?:' // Unroll the loop: Consume everything until ]]> is found. |
632 . '](?!]>)' // One ] not followed by end of comment. |
650 . '](?!]>)' // One ] not followed by end of comment. |
633 . '[^\]]*+' // Consume non-]. |
651 . '[^\]]*+' // Consume non-]. |
634 . ')*+' // Loop possessively. |
652 . ')*+' // Loop possessively. |
635 . '(?:]]>)?'; // End of comment. If not found, match all input. |
653 . '(?:]]>)?'; // End of comment. If not found, match all input. |
636 |
654 |
637 $escaped = |
655 $escaped = |
638 '(?=' // Is the element escaped? |
656 '(?=' // Is the element escaped? |
639 . '!--' |
657 . '!--' |
640 . '|' |
658 . '|' |
641 . '!\[CDATA\[' |
659 . '!\[CDATA\[' |
642 . ')' |
660 . ')' |
643 . '(?(?=!-)' // If yes, which type? |
661 . '(?(?=!-)' // If yes, which type? |
645 . '|' |
663 . '|' |
646 . $cdata |
664 . $cdata |
647 . ')'; |
665 . ')'; |
648 |
666 |
649 $regex = |
667 $regex = |
650 '/(' // Capture the entire match. |
668 '/(' // Capture the entire match. |
651 . '<' // Find start of element. |
669 . '<' // Find start of element. |
652 . '(?' // Conditional expression follows. |
670 . '(?' // Conditional expression follows. |
653 . $escaped // Find end of escaped element. |
671 . $escaped // Find end of escaped element. |
654 . '|' // ... else ... |
672 . '|' // ... else ... |
655 . '[^>]*>?' // Find end of normal element. |
673 . '[^>]*>?' // Find end of normal element. |
656 . ')' |
674 . ')' |
657 . ')/'; |
675 . ')/'; |
676 // phpcs:enable |
|
658 } |
677 } |
659 |
678 |
660 return $regex; |
679 return $regex; |
661 } |
680 } |
662 |
681 |
675 */ |
694 */ |
676 function _get_wptexturize_split_regex( $shortcode_regex = '' ) { |
695 function _get_wptexturize_split_regex( $shortcode_regex = '' ) { |
677 static $html_regex; |
696 static $html_regex; |
678 |
697 |
679 if ( ! isset( $html_regex ) ) { |
698 if ( ! isset( $html_regex ) ) { |
699 // phpcs:disable Squiz.Strings.ConcatenationSpacing.PaddingFound -- don't remove regex indentation |
|
680 $comment_regex = |
700 $comment_regex = |
681 '!' // Start of comment, after the <. |
701 '!' // Start of comment, after the <. |
682 . '(?:' // Unroll the loop: Consume everything until --> is found. |
702 . '(?:' // Unroll the loop: Consume everything until --> is found. |
683 . '-(?!->)' // Dash not followed by end of comment. |
703 . '-(?!->)' // Dash not followed by end of comment. |
684 . '[^\-]*+' // Consume non-dashes. |
704 . '[^\-]*+' // Consume non-dashes. |
685 . ')*+' // Loop possessively. |
705 . ')*+' // Loop possessively. |
686 . '(?:-->)?'; // End of comment. If not found, match all input. |
706 . '(?:-->)?'; // End of comment. If not found, match all input. |
687 |
707 |
688 $html_regex = // Needs replaced with wp_html_split() per Shortcode API Roadmap. |
708 $html_regex = // Needs replaced with wp_html_split() per Shortcode API Roadmap. |
689 '<' // Find start of element. |
709 '<' // Find start of element. |
690 . '(?(?=!--)' // Is this a comment? |
710 . '(?(?=!--)' // Is this a comment? |
691 . $comment_regex // Find end of comment. |
711 . $comment_regex // Find end of comment. |
692 . '|' |
712 . '|' |
693 . '[^>]*>?' // Find end of element. If not found, match all input. |
713 . '[^>]*>?' // Find end of element. If not found, match all input. |
694 . ')'; |
714 . ')'; |
715 // phpcs:enable |
|
695 } |
716 } |
696 |
717 |
697 if ( empty( $shortcode_regex ) ) { |
718 if ( empty( $shortcode_regex ) ) { |
698 $regex = '/(' . $html_regex . ')/'; |
719 $regex = '/(' . $html_regex . ')/'; |
699 } else { |
720 } else { |
715 * @return string The regular expression |
736 * @return string The regular expression |
716 */ |
737 */ |
717 function _get_wptexturize_shortcode_regex( $tagnames ) { |
738 function _get_wptexturize_shortcode_regex( $tagnames ) { |
718 $tagregexp = join( '|', array_map( 'preg_quote', $tagnames ) ); |
739 $tagregexp = join( '|', array_map( 'preg_quote', $tagnames ) ); |
719 $tagregexp = "(?:$tagregexp)(?=[\\s\\]\\/])"; // Excerpt of get_shortcode_regex(). |
740 $tagregexp = "(?:$tagregexp)(?=[\\s\\]\\/])"; // Excerpt of get_shortcode_regex(). |
741 // phpcs:disable Squiz.Strings.ConcatenationSpacing.PaddingFound -- don't remove regex indentation |
|
720 $regex = |
742 $regex = |
721 '\[' // Find start of shortcode. |
743 '\[' // Find start of shortcode. |
722 . '[\/\[]?' // Shortcodes may begin with [/ or [[ |
744 . '[\/\[]?' // Shortcodes may begin with [/ or [[ |
723 . $tagregexp // Only match registered shortcodes, because performance. |
745 . $tagregexp // Only match registered shortcodes, because performance. |
724 . '(?:' |
746 . '(?:' |
725 . '[^\[\]<>]+' // Shortcodes do not contain other shortcodes. Quantifier critical. |
747 . '[^\[\]<>]+' // Shortcodes do not contain other shortcodes. Quantifier critical. |
726 . '|' |
748 . '|' |
727 . '<[^\[\]>]*>' // HTML elements permitted. Prevents matching ] before >. |
749 . '<[^\[\]>]*>' // HTML elements permitted. Prevents matching ] before >. |
728 . ')*+' // Possessive critical. |
750 . ')*+' // Possessive critical. |
729 . '\]' // Find end of shortcode. |
751 . '\]' // Find end of shortcode. |
730 . '\]?'; // Shortcodes may end with ]] |
752 . '\]?'; // Shortcodes may end with ]] |
753 // phpcs:enable |
|
731 |
754 |
732 return $regex; |
755 return $regex; |
733 } |
756 } |
734 |
757 |
735 /** |
758 /** |
747 $changed = false; |
770 $changed = false; |
748 |
771 |
749 // Optimize when searching for one item. |
772 // Optimize when searching for one item. |
750 if ( 1 === count( $replace_pairs ) ) { |
773 if ( 1 === count( $replace_pairs ) ) { |
751 // Extract $needle and $replace. |
774 // Extract $needle and $replace. |
752 foreach ( $replace_pairs as $needle => $replace ); |
775 foreach ( $replace_pairs as $needle => $replace ) { |
776 } |
|
753 |
777 |
754 // Loop through delimiters (elements) only. |
778 // Loop through delimiters (elements) only. |
755 for ( $i = 1, $c = count( $textarr ); $i < $c; $i += 2 ) { |
779 for ( $i = 1, $c = count( $textarr ); $i < $c; $i += 2 ) { |
756 if ( false !== strpos( $textarr[$i], $needle ) ) { |
780 if ( false !== strpos( $textarr[ $i ], $needle ) ) { |
757 $textarr[$i] = str_replace( $needle, $replace, $textarr[$i] ); |
781 $textarr[ $i ] = str_replace( $needle, $replace, $textarr[ $i ] ); |
758 $changed = true; |
782 $changed = true; |
759 } |
783 } |
760 } |
784 } |
761 } else { |
785 } else { |
762 // Extract all $needles. |
786 // Extract all $needles. |
763 $needles = array_keys( $replace_pairs ); |
787 $needles = array_keys( $replace_pairs ); |
764 |
788 |
765 // Loop through delimiters (elements) only. |
789 // Loop through delimiters (elements) only. |
766 for ( $i = 1, $c = count( $textarr ); $i < $c; $i += 2 ) { |
790 for ( $i = 1, $c = count( $textarr ); $i < $c; $i += 2 ) { |
767 foreach ( $needles as $needle ) { |
791 foreach ( $needles as $needle ) { |
768 if ( false !== strpos( $textarr[$i], $needle ) ) { |
792 if ( false !== strpos( $textarr[ $i ], $needle ) ) { |
769 $textarr[$i] = strtr( $textarr[$i], $replace_pairs ); |
793 $textarr[ $i ] = strtr( $textarr[ $i ], $replace_pairs ); |
770 $changed = true; |
794 $changed = true; |
771 // After one strtr() break out of the foreach loop and look at next element. |
795 // After one strtr() break out of the foreach loop and look at next element. |
772 break; |
796 break; |
773 } |
797 } |
774 } |
798 } |
775 } |
799 } |
790 * |
814 * |
791 * @param array $matches preg_replace_callback matches array |
815 * @param array $matches preg_replace_callback matches array |
792 * @return string |
816 * @return string |
793 */ |
817 */ |
794 function _autop_newline_preservation_helper( $matches ) { |
818 function _autop_newline_preservation_helper( $matches ) { |
795 return str_replace( "\n", "<WPPreserveNewline />", $matches[0] ); |
819 return str_replace( "\n", '<WPPreserveNewline />', $matches[0] ); |
796 } |
820 } |
797 |
821 |
798 /** |
822 /** |
799 * Don't auto-p wrap shortcodes that stand alone |
823 * Don't auto-p wrap shortcodes that stand alone |
800 * |
824 * |
808 * @return string The filtered content. |
832 * @return string The filtered content. |
809 */ |
833 */ |
810 function shortcode_unautop( $pee ) { |
834 function shortcode_unautop( $pee ) { |
811 global $shortcode_tags; |
835 global $shortcode_tags; |
812 |
836 |
813 if ( empty( $shortcode_tags ) || !is_array( $shortcode_tags ) ) { |
837 if ( empty( $shortcode_tags ) || ! is_array( $shortcode_tags ) ) { |
814 return $pee; |
838 return $pee; |
815 } |
839 } |
816 |
840 |
817 $tagregexp = join( '|', array_map( 'preg_quote', array_keys( $shortcode_tags ) ) ); |
841 $tagregexp = join( '|', array_map( 'preg_quote', array_keys( $shortcode_tags ) ) ); |
818 $spaces = wp_spaces_regexp(); |
842 $spaces = wp_spaces_regexp(); |
819 |
843 |
844 // phpcs:disable Squiz.Strings.ConcatenationSpacing.PaddingFound -- don't remove regex indentation |
|
820 $pattern = |
845 $pattern = |
821 '/' |
846 '/' |
822 . '<p>' // Opening paragraph |
847 . '<p>' // Opening paragraph |
823 . '(?:' . $spaces . ')*+' // Optional leading whitespace |
848 . '(?:' . $spaces . ')*+' // Optional leading whitespace |
824 . '(' // 1: The shortcode |
849 . '(' // 1: The shortcode |
825 . '\\[' // Opening bracket |
850 . '\\[' // Opening bracket |
826 . "($tagregexp)" // 2: Shortcode name |
851 . "($tagregexp)" // 2: Shortcode name |
827 . '(?![\\w-])' // Not followed by word character or hyphen |
852 . '(?![\\w-])' // Not followed by word character or hyphen |
828 // Unroll the loop: Inside the opening shortcode tag |
853 // Unroll the loop: Inside the opening shortcode tag |
829 . '[^\\]\\/]*' // Not a closing bracket or forward slash |
854 . '[^\\]\\/]*' // Not a closing bracket or forward slash |
830 . '(?:' |
855 . '(?:' |
831 . '\\/(?!\\])' // A forward slash not followed by a closing bracket |
856 . '\\/(?!\\])' // A forward slash not followed by a closing bracket |
832 . '[^\\]\\/]*' // Not a closing bracket or forward slash |
857 . '[^\\]\\/]*' // Not a closing bracket or forward slash |
833 . ')*?' |
858 . ')*?' |
846 . ')' |
871 . ')' |
847 . ')' |
872 . ')' |
848 . '(?:' . $spaces . ')*+' // optional trailing whitespace |
873 . '(?:' . $spaces . ')*+' // optional trailing whitespace |
849 . '<\\/p>' // closing paragraph |
874 . '<\\/p>' // closing paragraph |
850 . '/'; |
875 . '/'; |
876 // phpcs:enable |
|
851 |
877 |
852 return preg_replace( $pattern, '$1', $pee ); |
878 return preg_replace( $pattern, '$1', $pee ); |
853 } |
879 } |
854 |
880 |
855 /** |
881 /** |
864 * @param string $str The string to be checked |
890 * @param string $str The string to be checked |
865 * @return bool True if $str fits a UTF-8 model, false otherwise. |
891 * @return bool True if $str fits a UTF-8 model, false otherwise. |
866 */ |
892 */ |
867 function seems_utf8( $str ) { |
893 function seems_utf8( $str ) { |
868 mbstring_binary_safe_encoding(); |
894 mbstring_binary_safe_encoding(); |
869 $length = strlen($str); |
895 $length = strlen( $str ); |
870 reset_mbstring_encoding(); |
896 reset_mbstring_encoding(); |
871 for ($i=0; $i < $length; $i++) { |
897 for ( $i = 0; $i < $length; $i++ ) { |
872 $c = ord($str[$i]); |
898 $c = ord( $str[ $i ] ); |
873 if ($c < 0x80) $n = 0; // 0bbbbbbb |
899 if ( $c < 0x80 ) { |
874 elseif (($c & 0xE0) == 0xC0) $n=1; // 110bbbbb |
900 $n = 0; // 0bbbbbbb |
875 elseif (($c & 0xF0) == 0xE0) $n=2; // 1110bbbb |
901 } elseif ( ( $c & 0xE0 ) == 0xC0 ) { |
876 elseif (($c & 0xF8) == 0xF0) $n=3; // 11110bbb |
902 $n = 1; // 110bbbbb |
877 elseif (($c & 0xFC) == 0xF8) $n=4; // 111110bb |
903 } elseif ( ( $c & 0xF0 ) == 0xE0 ) { |
878 elseif (($c & 0xFE) == 0xFC) $n=5; // 1111110b |
904 $n = 2; // 1110bbbb |
879 else return false; // Does not match any model |
905 } elseif ( ( $c & 0xF8 ) == 0xF0 ) { |
880 for ($j=0; $j<$n; $j++) { // n bytes matching 10bbbbbb follow ? |
906 $n = 3; // 11110bbb |
881 if ((++$i == $length) || ((ord($str[$i]) & 0xC0) != 0x80)) |
907 } elseif ( ( $c & 0xFC ) == 0xF8 ) { |
908 $n = 4; // 111110bb |
|
909 } elseif ( ( $c & 0xFE ) == 0xFC ) { |
|
910 $n = 5; // 1111110b |
|
911 } else { |
|
912 return false; // Does not match any model |
|
913 } |
|
914 for ( $j = 0; $j < $n; $j++ ) { // n bytes matching 10bbbbbb follow ? |
|
915 if ( ( ++$i == $length ) || ( ( ord( $str[ $i ] ) & 0xC0 ) != 0x80 ) ) { |
|
882 return false; |
916 return false; |
917 } |
|
883 } |
918 } |
884 } |
919 } |
885 return true; |
920 return true; |
886 } |
921 } |
887 |
922 |
909 * @return string The encoded text with HTML entities. |
944 * @return string The encoded text with HTML entities. |
910 */ |
945 */ |
911 function _wp_specialchars( $string, $quote_style = ENT_NOQUOTES, $charset = false, $double_encode = false ) { |
946 function _wp_specialchars( $string, $quote_style = ENT_NOQUOTES, $charset = false, $double_encode = false ) { |
912 $string = (string) $string; |
947 $string = (string) $string; |
913 |
948 |
914 if ( 0 === strlen( $string ) ) |
949 if ( 0 === strlen( $string ) ) { |
915 return ''; |
950 return ''; |
951 } |
|
916 |
952 |
917 // Don't bother if there are no specialchars - saves some processing |
953 // Don't bother if there are no specialchars - saves some processing |
918 if ( ! preg_match( '/[&<>"\']/', $string ) ) |
954 if ( ! preg_match( '/[&<>"\']/', $string ) ) { |
919 return $string; |
955 return $string; |
956 } |
|
920 |
957 |
921 // Account for the previous behaviour of the function when the $quote_style is not an accepted value |
958 // Account for the previous behaviour of the function when the $quote_style is not an accepted value |
922 if ( empty( $quote_style ) ) |
959 if ( empty( $quote_style ) ) { |
923 $quote_style = ENT_NOQUOTES; |
960 $quote_style = ENT_NOQUOTES; |
924 elseif ( ! in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) ) |
961 } elseif ( ! in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) ) { |
925 $quote_style = ENT_QUOTES; |
962 $quote_style = ENT_QUOTES; |
963 } |
|
926 |
964 |
927 // Store the site charset as a static to avoid multiple calls to wp_load_alloptions() |
965 // Store the site charset as a static to avoid multiple calls to wp_load_alloptions() |
928 if ( ! $charset ) { |
966 if ( ! $charset ) { |
929 static $_charset = null; |
967 static $_charset = null; |
930 if ( ! isset( $_charset ) ) { |
968 if ( ! isset( $_charset ) ) { |
931 $alloptions = wp_load_alloptions(); |
969 $alloptions = wp_load_alloptions(); |
932 $_charset = isset( $alloptions['blog_charset'] ) ? $alloptions['blog_charset'] : ''; |
970 $_charset = isset( $alloptions['blog_charset'] ) ? $alloptions['blog_charset'] : ''; |
933 } |
971 } |
934 $charset = $_charset; |
972 $charset = $_charset; |
935 } |
973 } |
936 |
974 |
937 if ( in_array( $charset, array( 'utf8', 'utf-8', 'UTF8' ) ) ) |
975 if ( in_array( $charset, array( 'utf8', 'utf-8', 'UTF8' ) ) ) { |
938 $charset = 'UTF-8'; |
976 $charset = 'UTF-8'; |
977 } |
|
939 |
978 |
940 $_quote_style = $quote_style; |
979 $_quote_style = $quote_style; |
941 |
980 |
942 if ( $quote_style === 'double' ) { |
981 if ( $quote_style === 'double' ) { |
943 $quote_style = ENT_COMPAT; |
982 $quote_style = ENT_COMPAT; |
944 $_quote_style = ENT_COMPAT; |
983 $_quote_style = ENT_COMPAT; |
945 } elseif ( $quote_style === 'single' ) { |
984 } elseif ( $quote_style === 'single' ) { |
946 $quote_style = ENT_NOQUOTES; |
985 $quote_style = ENT_NOQUOTES; |
947 } |
986 } |
948 |
987 |
953 } |
992 } |
954 |
993 |
955 $string = @htmlspecialchars( $string, $quote_style, $charset, $double_encode ); |
994 $string = @htmlspecialchars( $string, $quote_style, $charset, $double_encode ); |
956 |
995 |
957 // Back-compat. |
996 // Back-compat. |
958 if ( 'single' === $_quote_style ) |
997 if ( 'single' === $_quote_style ) { |
959 $string = str_replace( "'", ''', $string ); |
998 $string = str_replace( "'", ''', $string ); |
999 } |
|
960 |
1000 |
961 return $string; |
1001 return $string; |
962 } |
1002 } |
963 |
1003 |
964 /** |
1004 /** |
994 } |
1034 } |
995 |
1035 |
996 // Match the previous behaviour of _wp_specialchars() when the $quote_style is not an accepted value |
1036 // Match the previous behaviour of _wp_specialchars() when the $quote_style is not an accepted value |
997 if ( empty( $quote_style ) ) { |
1037 if ( empty( $quote_style ) ) { |
998 $quote_style = ENT_NOQUOTES; |
1038 $quote_style = ENT_NOQUOTES; |
999 } elseif ( !in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) ) { |
1039 } elseif ( ! in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) ) { |
1000 $quote_style = ENT_QUOTES; |
1040 $quote_style = ENT_QUOTES; |
1001 } |
1041 } |
1002 |
1042 |
1003 // More complete than get_html_translation_table( HTML_SPECIALCHARS ) |
1043 // More complete than get_html_translation_table( HTML_SPECIALCHARS ) |
1004 $single = array( ''' => '\'', ''' => '\'' ); |
1044 $single = array( |
1005 $single_preg = array( '/�*39;/' => ''', '/�*27;/i' => ''' ); |
1045 ''' => '\'', |
1006 $double = array( '"' => '"', '"' => '"', '"' => '"' ); |
1046 ''' => '\'', |
1007 $double_preg = array( '/�*34;/' => '"', '/�*22;/i' => '"' ); |
1047 ); |
1008 $others = array( '<' => '<', '<' => '<', '>' => '>', '>' => '>', '&' => '&', '&' => '&', '&' => '&' ); |
1048 $single_preg = array( |
1009 $others_preg = array( '/�*60;/' => '<', '/�*62;/' => '>', '/�*38;/' => '&', '/�*26;/i' => '&' ); |
1049 '/�*39;/' => ''', |
1050 '/�*27;/i' => ''', |
|
1051 ); |
|
1052 $double = array( |
|
1053 '"' => '"', |
|
1054 '"' => '"', |
|
1055 '"' => '"', |
|
1056 ); |
|
1057 $double_preg = array( |
|
1058 '/�*34;/' => '"', |
|
1059 '/�*22;/i' => '"', |
|
1060 ); |
|
1061 $others = array( |
|
1062 '<' => '<', |
|
1063 '<' => '<', |
|
1064 '>' => '>', |
|
1065 '>' => '>', |
|
1066 '&' => '&', |
|
1067 '&' => '&', |
|
1068 '&' => '&', |
|
1069 ); |
|
1070 $others_preg = array( |
|
1071 '/�*60;/' => '<', |
|
1072 '/�*62;/' => '>', |
|
1073 '/�*38;/' => '&', |
|
1074 '/�*26;/i' => '&', |
|
1075 ); |
|
1010 |
1076 |
1011 if ( $quote_style === ENT_QUOTES ) { |
1077 if ( $quote_style === ENT_QUOTES ) { |
1012 $translation = array_merge( $single, $double, $others ); |
1078 $translation = array_merge( $single, $double, $others ); |
1013 $translation_preg = array_merge( $single_preg, $double_preg, $others_preg ); |
1079 $translation_preg = array_merge( $single_preg, $double_preg, $others_preg ); |
1014 } elseif ( $quote_style === ENT_COMPAT || $quote_style === 'double' ) { |
1080 } elseif ( $quote_style === ENT_COMPAT || $quote_style === 'double' ) { |
1015 $translation = array_merge( $double, $others ); |
1081 $translation = array_merge( $double, $others ); |
1016 $translation_preg = array_merge( $double_preg, $others_preg ); |
1082 $translation_preg = array_merge( $double_preg, $others_preg ); |
1017 } elseif ( $quote_style === 'single' ) { |
1083 } elseif ( $quote_style === 'single' ) { |
1018 $translation = array_merge( $single, $others ); |
1084 $translation = array_merge( $single, $others ); |
1019 $translation_preg = array_merge( $single_preg, $others_preg ); |
1085 $translation_preg = array_merge( $single_preg, $others_preg ); |
1020 } elseif ( $quote_style === ENT_NOQUOTES ) { |
1086 } elseif ( $quote_style === ENT_NOQUOTES ) { |
1021 $translation = $others; |
1087 $translation = $others; |
1022 $translation_preg = $others_preg; |
1088 $translation_preg = $others_preg; |
1023 } |
1089 } |
1024 |
1090 |
1025 // Remove zero padding on numeric entities |
1091 // Remove zero padding on numeric entities |
1026 $string = preg_replace( array_keys( $translation_preg ), array_values( $translation_preg ), $string ); |
1092 $string = preg_replace( array_keys( $translation_preg ), array_values( $translation_preg ), $string ); |
1061 static $utf8_pcre = null; |
1127 static $utf8_pcre = null; |
1062 if ( ! isset( $utf8_pcre ) ) { |
1128 if ( ! isset( $utf8_pcre ) ) { |
1063 $utf8_pcre = @preg_match( '/^./u', 'a' ); |
1129 $utf8_pcre = @preg_match( '/^./u', 'a' ); |
1064 } |
1130 } |
1065 // We can't demand utf8 in the PCRE installation, so just return the string in those cases |
1131 // We can't demand utf8 in the PCRE installation, so just return the string in those cases |
1066 if ( !$utf8_pcre ) { |
1132 if ( ! $utf8_pcre ) { |
1067 return $string; |
1133 return $string; |
1068 } |
1134 } |
1069 |
1135 |
1070 // preg_match fails when it encounters invalid UTF8 in $string |
1136 // preg_match fails when it encounters invalid UTF8 in $string |
1071 if ( 1 === @preg_match( '/^./us', $string ) ) { |
1137 if ( 1 === @preg_match( '/^./us', $string ) ) { |
1088 * @param string $utf8_string |
1154 * @param string $utf8_string |
1089 * @param int $length Max length of the string |
1155 * @param int $length Max length of the string |
1090 * @return string String with Unicode encoded for URI. |
1156 * @return string String with Unicode encoded for URI. |
1091 */ |
1157 */ |
1092 function utf8_uri_encode( $utf8_string, $length = 0 ) { |
1158 function utf8_uri_encode( $utf8_string, $length = 0 ) { |
1093 $unicode = ''; |
1159 $unicode = ''; |
1094 $values = array(); |
1160 $values = array(); |
1095 $num_octets = 1; |
1161 $num_octets = 1; |
1096 $unicode_length = 0; |
1162 $unicode_length = 0; |
1097 |
1163 |
1098 mbstring_binary_safe_encoding(); |
1164 mbstring_binary_safe_encoding(); |
1099 $string_length = strlen( $utf8_string ); |
1165 $string_length = strlen( $utf8_string ); |
1100 reset_mbstring_encoding(); |
1166 reset_mbstring_encoding(); |
1101 |
1167 |
1102 for ($i = 0; $i < $string_length; $i++ ) { |
1168 for ( $i = 0; $i < $string_length; $i++ ) { |
1103 |
1169 |
1104 $value = ord( $utf8_string[ $i ] ); |
1170 $value = ord( $utf8_string[ $i ] ); |
1105 |
1171 |
1106 if ( $value < 128 ) { |
1172 if ( $value < 128 ) { |
1107 if ( $length && ( $unicode_length >= $length ) ) |
1173 if ( $length && ( $unicode_length >= $length ) ) { |
1108 break; |
1174 break; |
1109 $unicode .= chr($value); |
1175 } |
1176 $unicode .= chr( $value ); |
|
1110 $unicode_length++; |
1177 $unicode_length++; |
1111 } else { |
1178 } else { |
1112 if ( count( $values ) == 0 ) { |
1179 if ( count( $values ) == 0 ) { |
1113 if ( $value < 224 ) { |
1180 if ( $value < 224 ) { |
1114 $num_octets = 2; |
1181 $num_octets = 2; |
1119 } |
1186 } |
1120 } |
1187 } |
1121 |
1188 |
1122 $values[] = $value; |
1189 $values[] = $value; |
1123 |
1190 |
1124 if ( $length && ( $unicode_length + ($num_octets * 3) ) > $length ) |
1191 if ( $length && ( $unicode_length + ( $num_octets * 3 ) ) > $length ) { |
1125 break; |
1192 break; |
1193 } |
|
1126 if ( count( $values ) == $num_octets ) { |
1194 if ( count( $values ) == $num_octets ) { |
1127 for ( $j = 0; $j < $num_octets; $j++ ) { |
1195 for ( $j = 0; $j < $num_octets; $j++ ) { |
1128 $unicode .= '%' . dechex( $values[ $j ] ); |
1196 $unicode .= '%' . dechex( $values[ $j ] ); |
1129 } |
1197 } |
1130 |
1198 |
1131 $unicode_length += $num_octets * 3; |
1199 $unicode_length += $num_octets * 3; |
1132 |
1200 |
1133 $values = array(); |
1201 $values = array(); |
1134 $num_octets = 1; |
1202 $num_octets = 1; |
1135 } |
1203 } |
1136 } |
1204 } |
1137 } |
1205 } |
1138 |
1206 |
1524 * |
1592 * |
1525 * @param string $string Text that might have accent characters |
1593 * @param string $string Text that might have accent characters |
1526 * @return string Filtered string with replaced "nice" characters. |
1594 * @return string Filtered string with replaced "nice" characters. |
1527 */ |
1595 */ |
1528 function remove_accents( $string ) { |
1596 function remove_accents( $string ) { |
1529 if ( !preg_match('/[\x80-\xff]/', $string) ) |
1597 if ( ! preg_match( '/[\x80-\xff]/', $string ) ) { |
1530 return $string; |
1598 return $string; |
1531 |
1599 } |
1532 if (seems_utf8($string)) { |
1600 |
1601 if ( seems_utf8( $string ) ) { |
|
1533 $chars = array( |
1602 $chars = array( |
1534 // Decompositions for Latin-1 Supplement |
1603 // Decompositions for Latin-1 Supplement |
1535 'ª' => 'a', 'º' => 'o', |
1604 'ª' => 'a', |
1536 'À' => 'A', 'Á' => 'A', |
1605 'º' => 'o', |
1537 'Â' => 'A', 'Ã' => 'A', |
1606 'À' => 'A', |
1538 'Ä' => 'A', 'Å' => 'A', |
1607 'Á' => 'A', |
1539 'Æ' => 'AE','Ç' => 'C', |
1608 'Â' => 'A', |
1540 'È' => 'E', 'É' => 'E', |
1609 'Ã' => 'A', |
1541 'Ê' => 'E', 'Ë' => 'E', |
1610 'Ä' => 'A', |
1542 'Ì' => 'I', 'Í' => 'I', |
1611 'Å' => 'A', |
1543 'Î' => 'I', 'Ï' => 'I', |
1612 'Æ' => 'AE', |
1544 'Ð' => 'D', 'Ñ' => 'N', |
1613 'Ç' => 'C', |
1545 'Ò' => 'O', 'Ó' => 'O', |
1614 'È' => 'E', |
1546 'Ô' => 'O', 'Õ' => 'O', |
1615 'É' => 'E', |
1547 'Ö' => 'O', 'Ù' => 'U', |
1616 'Ê' => 'E', |
1548 'Ú' => 'U', 'Û' => 'U', |
1617 'Ë' => 'E', |
1549 'Ü' => 'U', 'Ý' => 'Y', |
1618 'Ì' => 'I', |
1550 'Þ' => 'TH','ß' => 's', |
1619 'Í' => 'I', |
1551 'à' => 'a', 'á' => 'a', |
1620 'Î' => 'I', |
1552 'â' => 'a', 'ã' => 'a', |
1621 'Ï' => 'I', |
1553 'ä' => 'a', 'å' => 'a', |
1622 'Ð' => 'D', |
1554 'æ' => 'ae','ç' => 'c', |
1623 'Ñ' => 'N', |
1555 'è' => 'e', 'é' => 'e', |
1624 'Ò' => 'O', |
1556 'ê' => 'e', 'ë' => 'e', |
1625 'Ó' => 'O', |
1557 'ì' => 'i', 'í' => 'i', |
1626 'Ô' => 'O', |
1558 'î' => 'i', 'ï' => 'i', |
1627 'Õ' => 'O', |
1559 'ð' => 'd', 'ñ' => 'n', |
1628 'Ö' => 'O', |
1560 'ò' => 'o', 'ó' => 'o', |
1629 'Ù' => 'U', |
1561 'ô' => 'o', 'õ' => 'o', |
1630 'Ú' => 'U', |
1562 'ö' => 'o', 'ø' => 'o', |
1631 'Û' => 'U', |
1563 'ù' => 'u', 'ú' => 'u', |
1632 'Ü' => 'U', |
1564 'û' => 'u', 'ü' => 'u', |
1633 'Ý' => 'Y', |
1565 'ý' => 'y', 'þ' => 'th', |
1634 'Þ' => 'TH', |
1566 'ÿ' => 'y', 'Ø' => 'O', |
1635 'ß' => 's', |
1567 // Decompositions for Latin Extended-A |
1636 'à' => 'a', |
1568 'Ā' => 'A', 'ā' => 'a', |
1637 'á' => 'a', |
1569 'Ă' => 'A', 'ă' => 'a', |
1638 'â' => 'a', |
1570 'Ą' => 'A', 'ą' => 'a', |
1639 'ã' => 'a', |
1571 'Ć' => 'C', 'ć' => 'c', |
1640 'ä' => 'a', |
1572 'Ĉ' => 'C', 'ĉ' => 'c', |
1641 'å' => 'a', |
1573 'Ċ' => 'C', 'ċ' => 'c', |
1642 'æ' => 'ae', |
1574 'Č' => 'C', 'č' => 'c', |
1643 'ç' => 'c', |
1575 'Ď' => 'D', 'ď' => 'd', |
1644 'è' => 'e', |
1576 'Đ' => 'D', 'đ' => 'd', |
1645 'é' => 'e', |
1577 'Ē' => 'E', 'ē' => 'e', |
1646 'ê' => 'e', |
1578 'Ĕ' => 'E', 'ĕ' => 'e', |
1647 'ë' => 'e', |
1579 'Ė' => 'E', 'ė' => 'e', |
1648 'ì' => 'i', |
1580 'Ę' => 'E', 'ę' => 'e', |
1649 'í' => 'i', |
1581 'Ě' => 'E', 'ě' => 'e', |
1650 'î' => 'i', |
1582 'Ĝ' => 'G', 'ĝ' => 'g', |
1651 'ï' => 'i', |
1583 'Ğ' => 'G', 'ğ' => 'g', |
1652 'ð' => 'd', |
1584 'Ġ' => 'G', 'ġ' => 'g', |
1653 'ñ' => 'n', |
1585 'Ģ' => 'G', 'ģ' => 'g', |
1654 'ò' => 'o', |
1586 'Ĥ' => 'H', 'ĥ' => 'h', |
1655 'ó' => 'o', |
1587 'Ħ' => 'H', 'ħ' => 'h', |
1656 'ô' => 'o', |
1588 'Ĩ' => 'I', 'ĩ' => 'i', |
1657 'õ' => 'o', |
1589 'Ī' => 'I', 'ī' => 'i', |
1658 'ö' => 'o', |
1590 'Ĭ' => 'I', 'ĭ' => 'i', |
1659 'ø' => 'o', |
1591 'Į' => 'I', 'į' => 'i', |
1660 'ù' => 'u', |
1592 'İ' => 'I', 'ı' => 'i', |
1661 'ú' => 'u', |
1593 'IJ' => 'IJ','ij' => 'ij', |
1662 'û' => 'u', |
1594 'Ĵ' => 'J', 'ĵ' => 'j', |
1663 'ü' => 'u', |
1595 'Ķ' => 'K', 'ķ' => 'k', |
1664 'ý' => 'y', |
1596 'ĸ' => 'k', 'Ĺ' => 'L', |
1665 'þ' => 'th', |
1597 'ĺ' => 'l', 'Ļ' => 'L', |
1666 'ÿ' => 'y', |
1598 'ļ' => 'l', 'Ľ' => 'L', |
1667 'Ø' => 'O', |
1599 'ľ' => 'l', 'Ŀ' => 'L', |
1668 // Decompositions for Latin Extended-A |
1600 'ŀ' => 'l', 'Ł' => 'L', |
1669 'Ā' => 'A', |
1601 'ł' => 'l', 'Ń' => 'N', |
1670 'ā' => 'a', |
1602 'ń' => 'n', 'Ņ' => 'N', |
1671 'Ă' => 'A', |
1603 'ņ' => 'n', 'Ň' => 'N', |
1672 'ă' => 'a', |
1604 'ň' => 'n', 'ʼn' => 'n', |
1673 'Ą' => 'A', |
1605 'Ŋ' => 'N', 'ŋ' => 'n', |
1674 'ą' => 'a', |
1606 'Ō' => 'O', 'ō' => 'o', |
1675 'Ć' => 'C', |
1607 'Ŏ' => 'O', 'ŏ' => 'o', |
1676 'ć' => 'c', |
1608 'Ő' => 'O', 'ő' => 'o', |
1677 'Ĉ' => 'C', |
1609 'Œ' => 'OE','œ' => 'oe', |
1678 'ĉ' => 'c', |
1610 'Ŕ' => 'R','ŕ' => 'r', |
1679 'Ċ' => 'C', |
1611 'Ŗ' => 'R','ŗ' => 'r', |
1680 'ċ' => 'c', |
1612 'Ř' => 'R','ř' => 'r', |
1681 'Č' => 'C', |
1613 'Ś' => 'S','ś' => 's', |
1682 'č' => 'c', |
1614 'Ŝ' => 'S','ŝ' => 's', |
1683 'Ď' => 'D', |
1615 'Ş' => 'S','ş' => 's', |
1684 'ď' => 'd', |
1616 'Š' => 'S', 'š' => 's', |
1685 'Đ' => 'D', |
1617 'Ţ' => 'T', 'ţ' => 't', |
1686 'đ' => 'd', |
1618 'Ť' => 'T', 'ť' => 't', |
1687 'Ē' => 'E', |
1619 'Ŧ' => 'T', 'ŧ' => 't', |
1688 'ē' => 'e', |
1620 'Ũ' => 'U', 'ũ' => 'u', |
1689 'Ĕ' => 'E', |
1621 'Ū' => 'U', 'ū' => 'u', |
1690 'ĕ' => 'e', |
1622 'Ŭ' => 'U', 'ŭ' => 'u', |
1691 'Ė' => 'E', |
1623 'Ů' => 'U', 'ů' => 'u', |
1692 'ė' => 'e', |
1624 'Ű' => 'U', 'ű' => 'u', |
1693 'Ę' => 'E', |
1625 'Ų' => 'U', 'ų' => 'u', |
1694 'ę' => 'e', |
1626 'Ŵ' => 'W', 'ŵ' => 'w', |
1695 'Ě' => 'E', |
1627 'Ŷ' => 'Y', 'ŷ' => 'y', |
1696 'ě' => 'e', |
1628 'Ÿ' => 'Y', 'Ź' => 'Z', |
1697 'Ĝ' => 'G', |
1629 'ź' => 'z', 'Ż' => 'Z', |
1698 'ĝ' => 'g', |
1630 'ż' => 'z', 'Ž' => 'Z', |
1699 'Ğ' => 'G', |
1631 'ž' => 'z', 'ſ' => 's', |
1700 'ğ' => 'g', |
1632 // Decompositions for Latin Extended-B |
1701 'Ġ' => 'G', |
1633 'Ș' => 'S', 'ș' => 's', |
1702 'ġ' => 'g', |
1634 'Ț' => 'T', 'ț' => 't', |
1703 'Ģ' => 'G', |
1635 // Euro Sign |
1704 'ģ' => 'g', |
1636 '€' => 'E', |
1705 'Ĥ' => 'H', |
1637 // GBP (Pound) Sign |
1706 'ĥ' => 'h', |
1638 '£' => '', |
1707 'Ħ' => 'H', |
1639 // Vowels with diacritic (Vietnamese) |
1708 'ħ' => 'h', |
1640 // unmarked |
1709 'Ĩ' => 'I', |
1641 'Ơ' => 'O', 'ơ' => 'o', |
1710 'ĩ' => 'i', |
1642 'Ư' => 'U', 'ư' => 'u', |
1711 'Ī' => 'I', |
1643 // grave accent |
1712 'ī' => 'i', |
1644 'Ầ' => 'A', 'ầ' => 'a', |
1713 'Ĭ' => 'I', |
1645 'Ằ' => 'A', 'ằ' => 'a', |
1714 'ĭ' => 'i', |
1646 'Ề' => 'E', 'ề' => 'e', |
1715 'Į' => 'I', |
1647 'Ồ' => 'O', 'ồ' => 'o', |
1716 'į' => 'i', |
1648 'Ờ' => 'O', 'ờ' => 'o', |
1717 'İ' => 'I', |
1649 'Ừ' => 'U', 'ừ' => 'u', |
1718 'ı' => 'i', |
1650 'Ỳ' => 'Y', 'ỳ' => 'y', |
1719 'IJ' => 'IJ', |
1651 // hook |
1720 'ij' => 'ij', |
1652 'Ả' => 'A', 'ả' => 'a', |
1721 'Ĵ' => 'J', |
1653 'Ẩ' => 'A', 'ẩ' => 'a', |
1722 'ĵ' => 'j', |
1654 'Ẳ' => 'A', 'ẳ' => 'a', |
1723 'Ķ' => 'K', |
1655 'Ẻ' => 'E', 'ẻ' => 'e', |
1724 'ķ' => 'k', |
1656 'Ể' => 'E', 'ể' => 'e', |
1725 'ĸ' => 'k', |
1657 'Ỉ' => 'I', 'ỉ' => 'i', |
1726 'Ĺ' => 'L', |
1658 'Ỏ' => 'O', 'ỏ' => 'o', |
1727 'ĺ' => 'l', |
1659 'Ổ' => 'O', 'ổ' => 'o', |
1728 'Ļ' => 'L', |
1660 'Ở' => 'O', 'ở' => 'o', |
1729 'ļ' => 'l', |
1661 'Ủ' => 'U', 'ủ' => 'u', |
1730 'Ľ' => 'L', |
1662 'Ử' => 'U', 'ử' => 'u', |
1731 'ľ' => 'l', |
1663 'Ỷ' => 'Y', 'ỷ' => 'y', |
1732 'Ŀ' => 'L', |
1664 // tilde |
1733 'ŀ' => 'l', |
1665 'Ẫ' => 'A', 'ẫ' => 'a', |
1734 'Ł' => 'L', |
1666 'Ẵ' => 'A', 'ẵ' => 'a', |
1735 'ł' => 'l', |
1667 'Ẽ' => 'E', 'ẽ' => 'e', |
1736 'Ń' => 'N', |
1668 'Ễ' => 'E', 'ễ' => 'e', |
1737 'ń' => 'n', |
1669 'Ỗ' => 'O', 'ỗ' => 'o', |
1738 'Ņ' => 'N', |
1670 'Ỡ' => 'O', 'ỡ' => 'o', |
1739 'ņ' => 'n', |
1671 'Ữ' => 'U', 'ữ' => 'u', |
1740 'Ň' => 'N', |
1672 'Ỹ' => 'Y', 'ỹ' => 'y', |
1741 'ň' => 'n', |
1673 // acute accent |
1742 'ʼn' => 'n', |
1674 'Ấ' => 'A', 'ấ' => 'a', |
1743 'Ŋ' => 'N', |
1675 'Ắ' => 'A', 'ắ' => 'a', |
1744 'ŋ' => 'n', |
1676 'Ế' => 'E', 'ế' => 'e', |
1745 'Ō' => 'O', |
1677 'Ố' => 'O', 'ố' => 'o', |
1746 'ō' => 'o', |
1678 'Ớ' => 'O', 'ớ' => 'o', |
1747 'Ŏ' => 'O', |
1679 'Ứ' => 'U', 'ứ' => 'u', |
1748 'ŏ' => 'o', |
1680 // dot below |
1749 'Ő' => 'O', |
1681 'Ạ' => 'A', 'ạ' => 'a', |
1750 'ő' => 'o', |
1682 'Ậ' => 'A', 'ậ' => 'a', |
1751 'Œ' => 'OE', |
1683 'Ặ' => 'A', 'ặ' => 'a', |
1752 'œ' => 'oe', |
1684 'Ẹ' => 'E', 'ẹ' => 'e', |
1753 'Ŕ' => 'R', |
1685 'Ệ' => 'E', 'ệ' => 'e', |
1754 'ŕ' => 'r', |
1686 'Ị' => 'I', 'ị' => 'i', |
1755 'Ŗ' => 'R', |
1687 'Ọ' => 'O', 'ọ' => 'o', |
1756 'ŗ' => 'r', |
1688 'Ộ' => 'O', 'ộ' => 'o', |
1757 'Ř' => 'R', |
1689 'Ợ' => 'O', 'ợ' => 'o', |
1758 'ř' => 'r', |
1690 'Ụ' => 'U', 'ụ' => 'u', |
1759 'Ś' => 'S', |
1691 'Ự' => 'U', 'ự' => 'u', |
1760 'ś' => 's', |
1692 'Ỵ' => 'Y', 'ỵ' => 'y', |
1761 'Ŝ' => 'S', |
1693 // Vowels with diacritic (Chinese, Hanyu Pinyin) |
1762 'ŝ' => 's', |
1694 'ɑ' => 'a', |
1763 'Ş' => 'S', |
1695 // macron |
1764 'ş' => 's', |
1696 'Ǖ' => 'U', 'ǖ' => 'u', |
1765 'Š' => 'S', |
1697 // acute accent |
1766 'š' => 's', |
1698 'Ǘ' => 'U', 'ǘ' => 'u', |
1767 'Ţ' => 'T', |
1699 // caron |
1768 'ţ' => 't', |
1700 'Ǎ' => 'A', 'ǎ' => 'a', |
1769 'Ť' => 'T', |
1701 'Ǐ' => 'I', 'ǐ' => 'i', |
1770 'ť' => 't', |
1702 'Ǒ' => 'O', 'ǒ' => 'o', |
1771 'Ŧ' => 'T', |
1703 'Ǔ' => 'U', 'ǔ' => 'u', |
1772 'ŧ' => 't', |
1704 'Ǚ' => 'U', 'ǚ' => 'u', |
1773 'Ũ' => 'U', |
1705 // grave accent |
1774 'ũ' => 'u', |
1706 'Ǜ' => 'U', 'ǜ' => 'u', |
1775 'Ū' => 'U', |
1776 'ū' => 'u', |
|
1777 'Ŭ' => 'U', |
|
1778 'ŭ' => 'u', |
|
1779 'Ů' => 'U', |
|
1780 'ů' => 'u', |
|
1781 'Ű' => 'U', |
|
1782 'ű' => 'u', |
|
1783 'Ų' => 'U', |
|
1784 'ų' => 'u', |
|
1785 'Ŵ' => 'W', |
|
1786 'ŵ' => 'w', |
|
1787 'Ŷ' => 'Y', |
|
1788 'ŷ' => 'y', |
|
1789 'Ÿ' => 'Y', |
|
1790 'Ź' => 'Z', |
|
1791 'ź' => 'z', |
|
1792 'Ż' => 'Z', |
|
1793 'ż' => 'z', |
|
1794 'Ž' => 'Z', |
|
1795 'ž' => 'z', |
|
1796 'ſ' => 's', |
|
1797 // Decompositions for Latin Extended-B |
|
1798 'Ș' => 'S', |
|
1799 'ș' => 's', |
|
1800 'Ț' => 'T', |
|
1801 'ț' => 't', |
|
1802 // Euro Sign |
|
1803 '€' => 'E', |
|
1804 // GBP (Pound) Sign |
|
1805 '£' => '', |
|
1806 // Vowels with diacritic (Vietnamese) |
|
1807 // unmarked |
|
1808 'Ơ' => 'O', |
|
1809 'ơ' => 'o', |
|
1810 'Ư' => 'U', |
|
1811 'ư' => 'u', |
|
1812 // grave accent |
|
1813 'Ầ' => 'A', |
|
1814 'ầ' => 'a', |
|
1815 'Ằ' => 'A', |
|
1816 'ằ' => 'a', |
|
1817 'Ề' => 'E', |
|
1818 'ề' => 'e', |
|
1819 'Ồ' => 'O', |
|
1820 'ồ' => 'o', |
|
1821 'Ờ' => 'O', |
|
1822 'ờ' => 'o', |
|
1823 'Ừ' => 'U', |
|
1824 'ừ' => 'u', |
|
1825 'Ỳ' => 'Y', |
|
1826 'ỳ' => 'y', |
|
1827 // hook |
|
1828 'Ả' => 'A', |
|
1829 'ả' => 'a', |
|
1830 'Ẩ' => 'A', |
|
1831 'ẩ' => 'a', |
|
1832 'Ẳ' => 'A', |
|
1833 'ẳ' => 'a', |
|
1834 'Ẻ' => 'E', |
|
1835 'ẻ' => 'e', |
|
1836 'Ể' => 'E', |
|
1837 'ể' => 'e', |
|
1838 'Ỉ' => 'I', |
|
1839 'ỉ' => 'i', |
|
1840 'Ỏ' => 'O', |
|
1841 'ỏ' => 'o', |
|
1842 'Ổ' => 'O', |
|
1843 'ổ' => 'o', |
|
1844 'Ở' => 'O', |
|
1845 'ở' => 'o', |
|
1846 'Ủ' => 'U', |
|
1847 'ủ' => 'u', |
|
1848 'Ử' => 'U', |
|
1849 'ử' => 'u', |
|
1850 'Ỷ' => 'Y', |
|
1851 'ỷ' => 'y', |
|
1852 // tilde |
|
1853 'Ẫ' => 'A', |
|
1854 'ẫ' => 'a', |
|
1855 'Ẵ' => 'A', |
|
1856 'ẵ' => 'a', |
|
1857 'Ẽ' => 'E', |
|
1858 'ẽ' => 'e', |
|
1859 'Ễ' => 'E', |
|
1860 'ễ' => 'e', |
|
1861 'Ỗ' => 'O', |
|
1862 'ỗ' => 'o', |
|
1863 'Ỡ' => 'O', |
|
1864 'ỡ' => 'o', |
|
1865 'Ữ' => 'U', |
|
1866 'ữ' => 'u', |
|
1867 'Ỹ' => 'Y', |
|
1868 'ỹ' => 'y', |
|
1869 // acute accent |
|
1870 'Ấ' => 'A', |
|
1871 'ấ' => 'a', |
|
1872 'Ắ' => 'A', |
|
1873 'ắ' => 'a', |
|
1874 'Ế' => 'E', |
|
1875 'ế' => 'e', |
|
1876 'Ố' => 'O', |
|
1877 'ố' => 'o', |
|
1878 'Ớ' => 'O', |
|
1879 'ớ' => 'o', |
|
1880 'Ứ' => 'U', |
|
1881 'ứ' => 'u', |
|
1882 // dot below |
|
1883 'Ạ' => 'A', |
|
1884 'ạ' => 'a', |
|
1885 'Ậ' => 'A', |
|
1886 'ậ' => 'a', |
|
1887 'Ặ' => 'A', |
|
1888 'ặ' => 'a', |
|
1889 'Ẹ' => 'E', |
|
1890 'ẹ' => 'e', |
|
1891 'Ệ' => 'E', |
|
1892 'ệ' => 'e', |
|
1893 'Ị' => 'I', |
|
1894 'ị' => 'i', |
|
1895 'Ọ' => 'O', |
|
1896 'ọ' => 'o', |
|
1897 'Ộ' => 'O', |
|
1898 'ộ' => 'o', |
|
1899 'Ợ' => 'O', |
|
1900 'ợ' => 'o', |
|
1901 'Ụ' => 'U', |
|
1902 'ụ' => 'u', |
|
1903 'Ự' => 'U', |
|
1904 'ự' => 'u', |
|
1905 'Ỵ' => 'Y', |
|
1906 'ỵ' => 'y', |
|
1907 // Vowels with diacritic (Chinese, Hanyu Pinyin) |
|
1908 'ɑ' => 'a', |
|
1909 // macron |
|
1910 'Ǖ' => 'U', |
|
1911 'ǖ' => 'u', |
|
1912 // acute accent |
|
1913 'Ǘ' => 'U', |
|
1914 'ǘ' => 'u', |
|
1915 // caron |
|
1916 'Ǎ' => 'A', |
|
1917 'ǎ' => 'a', |
|
1918 'Ǐ' => 'I', |
|
1919 'ǐ' => 'i', |
|
1920 'Ǒ' => 'O', |
|
1921 'ǒ' => 'o', |
|
1922 'Ǔ' => 'U', |
|
1923 'ǔ' => 'u', |
|
1924 'Ǚ' => 'U', |
|
1925 'ǚ' => 'u', |
|
1926 // grave accent |
|
1927 'Ǜ' => 'U', |
|
1928 'ǜ' => 'u', |
|
1707 ); |
1929 ); |
1708 |
1930 |
1709 // Used for locale-specific rules |
1931 // Used for locale-specific rules |
1710 $locale = get_locale(); |
1932 $locale = get_locale(); |
1711 |
1933 |
1712 if ( 'de_DE' == $locale || 'de_DE_formal' == $locale || 'de_CH' == $locale || 'de_CH_informal' == $locale ) { |
1934 if ( 'de_DE' == $locale || 'de_DE_formal' == $locale || 'de_CH' == $locale || 'de_CH_informal' == $locale ) { |
1713 $chars[ 'Ä' ] = 'Ae'; |
1935 $chars['Ä'] = 'Ae'; |
1714 $chars[ 'ä' ] = 'ae'; |
1936 $chars['ä'] = 'ae'; |
1715 $chars[ 'Ö' ] = 'Oe'; |
1937 $chars['Ö'] = 'Oe'; |
1716 $chars[ 'ö' ] = 'oe'; |
1938 $chars['ö'] = 'oe'; |
1717 $chars[ 'Ü' ] = 'Ue'; |
1939 $chars['Ü'] = 'Ue'; |
1718 $chars[ 'ü' ] = 'ue'; |
1940 $chars['ü'] = 'ue'; |
1719 $chars[ 'ß' ] = 'ss'; |
1941 $chars['ß'] = 'ss'; |
1720 } elseif ( 'da_DK' === $locale ) { |
1942 } elseif ( 'da_DK' === $locale ) { |
1721 $chars[ 'Æ' ] = 'Ae'; |
1943 $chars['Æ'] = 'Ae'; |
1722 $chars[ 'æ' ] = 'ae'; |
1944 $chars['æ'] = 'ae'; |
1723 $chars[ 'Ø' ] = 'Oe'; |
1945 $chars['Ø'] = 'Oe'; |
1724 $chars[ 'ø' ] = 'oe'; |
1946 $chars['ø'] = 'oe'; |
1725 $chars[ 'Å' ] = 'Aa'; |
1947 $chars['Å'] = 'Aa'; |
1726 $chars[ 'å' ] = 'aa'; |
1948 $chars['å'] = 'aa'; |
1727 } elseif ( 'ca' === $locale ) { |
1949 } elseif ( 'ca' === $locale ) { |
1728 $chars[ 'l·l' ] = 'll'; |
1950 $chars['l·l'] = 'll'; |
1729 } elseif ( 'sr_RS' === $locale || 'bs_BA' === $locale ) { |
1951 } elseif ( 'sr_RS' === $locale || 'bs_BA' === $locale ) { |
1730 $chars[ 'Đ' ] = 'DJ'; |
1952 $chars['Đ'] = 'DJ'; |
1731 $chars[ 'đ' ] = 'dj'; |
1953 $chars['đ'] = 'dj'; |
1732 } |
1954 } |
1733 |
1955 |
1734 $string = strtr($string, $chars); |
1956 $string = strtr( $string, $chars ); |
1735 } else { |
1957 } else { |
1736 $chars = array(); |
1958 $chars = array(); |
1737 // Assume ISO-8859-1 if not UTF-8 |
1959 // Assume ISO-8859-1 if not UTF-8 |
1738 $chars['in'] = "\x80\x83\x8a\x8e\x9a\x9e" |
1960 $chars['in'] = "\x80\x83\x8a\x8e\x9a\x9e" |
1739 ."\x9f\xa2\xa5\xb5\xc0\xc1\xc2" |
1961 . "\x9f\xa2\xa5\xb5\xc0\xc1\xc2" |
1740 ."\xc3\xc4\xc5\xc7\xc8\xc9\xca" |
1962 . "\xc3\xc4\xc5\xc7\xc8\xc9\xca" |
1741 ."\xcb\xcc\xcd\xce\xcf\xd1\xd2" |
1963 . "\xcb\xcc\xcd\xce\xcf\xd1\xd2" |
1742 ."\xd3\xd4\xd5\xd6\xd8\xd9\xda" |
1964 . "\xd3\xd4\xd5\xd6\xd8\xd9\xda" |
1743 ."\xdb\xdc\xdd\xe0\xe1\xe2\xe3" |
1965 . "\xdb\xdc\xdd\xe0\xe1\xe2\xe3" |
1744 ."\xe4\xe5\xe7\xe8\xe9\xea\xeb" |
1966 . "\xe4\xe5\xe7\xe8\xe9\xea\xeb" |
1745 ."\xec\xed\xee\xef\xf1\xf2\xf3" |
1967 . "\xec\xed\xee\xef\xf1\xf2\xf3" |
1746 ."\xf4\xf5\xf6\xf8\xf9\xfa\xfb" |
1968 . "\xf4\xf5\xf6\xf8\xf9\xfa\xfb" |
1747 ."\xfc\xfd\xff"; |
1969 . "\xfc\xfd\xff"; |
1748 |
1970 |
1749 $chars['out'] = "EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy"; |
1971 $chars['out'] = 'EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy'; |
1750 |
1972 |
1751 $string = strtr($string, $chars['in'], $chars['out']); |
1973 $string = strtr( $string, $chars['in'], $chars['out'] ); |
1752 $double_chars = array(); |
1974 $double_chars = array(); |
1753 $double_chars['in'] = array("\x8c", "\x9c", "\xc6", "\xd0", "\xde", "\xdf", "\xe6", "\xf0", "\xfe"); |
1975 $double_chars['in'] = array( "\x8c", "\x9c", "\xc6", "\xd0", "\xde", "\xdf", "\xe6", "\xf0", "\xfe" ); |
1754 $double_chars['out'] = array('OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th'); |
1976 $double_chars['out'] = array( 'OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th' ); |
1755 $string = str_replace($double_chars['in'], $double_chars['out'], $string); |
1977 $string = str_replace( $double_chars['in'], $double_chars['out'], $string ); |
1756 } |
1978 } |
1757 |
1979 |
1758 return $string; |
1980 return $string; |
1759 } |
1981 } |
1760 |
1982 |
1772 * |
1994 * |
1773 * @param string $filename The filename to be sanitized |
1995 * @param string $filename The filename to be sanitized |
1774 * @return string The sanitized filename |
1996 * @return string The sanitized filename |
1775 */ |
1997 */ |
1776 function sanitize_file_name( $filename ) { |
1998 function sanitize_file_name( $filename ) { |
1777 $filename_raw = $filename; |
1999 $filename_raw = $filename; |
1778 $special_chars = array("?", "[", "]", "/", "\\", "=", "<", ">", ":", ";", ",", "'", "\"", "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}", "%", "+", chr(0)); |
2000 $special_chars = array( '?', '[', ']', '/', '\\', '=', '<', '>', ':', ';', ',', "'", '"', '&', '$', '#', '*', '(', ')', '|', '~', '`', '!', '{', '}', '%', '+', chr( 0 ) ); |
1779 /** |
2001 /** |
1780 * Filters the list of characters to remove from a filename. |
2002 * Filters the list of characters to remove from a filename. |
1781 * |
2003 * |
1782 * @since 2.8.0 |
2004 * @since 2.8.0 |
1783 * |
2005 * |
1784 * @param array $special_chars Characters to remove. |
2006 * @param array $special_chars Characters to remove. |
1785 * @param string $filename_raw Filename as it was passed into sanitize_file_name(). |
2007 * @param string $filename_raw Filename as it was passed into sanitize_file_name(). |
1786 */ |
2008 */ |
1787 $special_chars = apply_filters( 'sanitize_file_name_chars', $special_chars, $filename_raw ); |
2009 $special_chars = apply_filters( 'sanitize_file_name_chars', $special_chars, $filename_raw ); |
1788 $filename = preg_replace( "#\x{00a0}#siu", ' ', $filename ); |
2010 $filename = preg_replace( "#\x{00a0}#siu", ' ', $filename ); |
1789 $filename = str_replace( $special_chars, '', $filename ); |
2011 $filename = str_replace( $special_chars, '', $filename ); |
1790 $filename = str_replace( array( '%20', '+' ), '-', $filename ); |
2012 $filename = str_replace( array( '%20', '+' ), '-', $filename ); |
1791 $filename = preg_replace( '/[\r\n\t -]+/', '-', $filename ); |
2013 $filename = preg_replace( '/[\r\n\t -]+/', '-', $filename ); |
1792 $filename = trim( $filename, '.-_' ); |
2014 $filename = trim( $filename, '.-_' ); |
1793 |
2015 |
1794 if ( false === strpos( $filename, '.' ) ) { |
2016 if ( false === strpos( $filename, '.' ) ) { |
1795 $mime_types = wp_get_mime_types(); |
2017 $mime_types = wp_get_mime_types(); |
1796 $filetype = wp_check_filetype( 'test.' . $filename, $mime_types ); |
2018 $filetype = wp_check_filetype( 'test.' . $filename, $mime_types ); |
1797 if ( $filetype['ext'] === $filename ) { |
2019 if ( $filetype['ext'] === $filename ) { |
1798 $filename = 'unnamed-file.' . $filetype['ext']; |
2020 $filename = 'unnamed-file.' . $filetype['ext']; |
1799 } |
2021 } |
1800 } |
2022 } |
1801 |
2023 |
1802 // Split the filename into a base and extension[s] |
2024 // Split the filename into a base and extension[s] |
1803 $parts = explode('.', $filename); |
2025 $parts = explode( '.', $filename ); |
1804 |
2026 |
1805 // Return if only one extension |
2027 // Return if only one extension |
1806 if ( count( $parts ) <= 2 ) { |
2028 if ( count( $parts ) <= 2 ) { |
1807 /** |
2029 /** |
1808 * Filters a sanitized filename string. |
2030 * Filters a sanitized filename string. |
1814 */ |
2036 */ |
1815 return apply_filters( 'sanitize_file_name', $filename, $filename_raw ); |
2037 return apply_filters( 'sanitize_file_name', $filename, $filename_raw ); |
1816 } |
2038 } |
1817 |
2039 |
1818 // Process multiple extensions |
2040 // Process multiple extensions |
1819 $filename = array_shift($parts); |
2041 $filename = array_shift( $parts ); |
1820 $extension = array_pop($parts); |
2042 $extension = array_pop( $parts ); |
1821 $mimes = get_allowed_mime_types(); |
2043 $mimes = get_allowed_mime_types(); |
1822 |
2044 |
1823 /* |
2045 /* |
1824 * Loop over any intermediate extensions. Postfix them with a trailing underscore |
2046 * Loop over any intermediate extensions. Postfix them with a trailing underscore |
1825 * if they are a 2 - 5 character long alpha string not in the extension whitelist. |
2047 * if they are a 2 - 5 character long alpha string not in the extension whitelist. |
1826 */ |
2048 */ |
1827 foreach ( (array) $parts as $part) { |
2049 foreach ( (array) $parts as $part ) { |
1828 $filename .= '.' . $part; |
2050 $filename .= '.' . $part; |
1829 |
2051 |
1830 if ( preg_match("/^[a-zA-Z]{2,5}\d?$/", $part) ) { |
2052 if ( preg_match( '/^[a-zA-Z]{2,5}\d?$/', $part ) ) { |
1831 $allowed = false; |
2053 $allowed = false; |
1832 foreach ( $mimes as $ext_preg => $mime_match ) { |
2054 foreach ( $mimes as $ext_preg => $mime_match ) { |
1833 $ext_preg = '!^(' . $ext_preg . ')$!i'; |
2055 $ext_preg = '!^(' . $ext_preg . ')$!i'; |
1834 if ( preg_match( $ext_preg, $part ) ) { |
2056 if ( preg_match( $ext_preg, $part ) ) { |
1835 $allowed = true; |
2057 $allowed = true; |
1836 break; |
2058 break; |
1837 } |
2059 } |
1838 } |
2060 } |
1839 if ( !$allowed ) |
2061 if ( ! $allowed ) { |
1840 $filename .= '_'; |
2062 $filename .= '_'; |
2063 } |
|
1841 } |
2064 } |
1842 } |
2065 } |
1843 $filename .= '.' . $extension; |
2066 $filename .= '.' . $extension; |
1844 /** This filter is documented in wp-includes/formatting.php */ |
2067 /** This filter is documented in wp-includes/formatting.php */ |
1845 return apply_filters('sanitize_file_name', $filename, $filename_raw); |
2068 return apply_filters( 'sanitize_file_name', $filename, $filename_raw ); |
1846 } |
2069 } |
1847 |
2070 |
1848 /** |
2071 /** |
1849 * Sanitizes a username, stripping out unsafe characters. |
2072 * Sanitizes a username, stripping out unsafe characters. |
1850 * |
2073 * |
1859 * @param bool $strict If set limits $username to specific characters. Default false. |
2082 * @param bool $strict If set limits $username to specific characters. Default false. |
1860 * @return string The sanitized username, after passing through filters. |
2083 * @return string The sanitized username, after passing through filters. |
1861 */ |
2084 */ |
1862 function sanitize_user( $username, $strict = false ) { |
2085 function sanitize_user( $username, $strict = false ) { |
1863 $raw_username = $username; |
2086 $raw_username = $username; |
1864 $username = wp_strip_all_tags( $username ); |
2087 $username = wp_strip_all_tags( $username ); |
1865 $username = remove_accents( $username ); |
2088 $username = remove_accents( $username ); |
1866 // Kill octets |
2089 // Kill octets |
1867 $username = preg_replace( '|%([a-fA-F0-9][a-fA-F0-9])|', '', $username ); |
2090 $username = preg_replace( '|%([a-fA-F0-9][a-fA-F0-9])|', '', $username ); |
1868 $username = preg_replace( '/&.+?;/', '', $username ); // Kill entities |
2091 $username = preg_replace( '/&.+?;/', '', $username ); // Kill entities |
1869 |
2092 |
1870 // If strict, reduce to ASCII for max portability. |
2093 // If strict, reduce to ASCII for max portability. |
1871 if ( $strict ) |
2094 if ( $strict ) { |
1872 $username = preg_replace( '|[^a-z0-9 _.\-@]|i', '', $username ); |
2095 $username = preg_replace( '|[^a-z0-9 _.\-@]|i', '', $username ); |
2096 } |
|
1873 |
2097 |
1874 $username = trim( $username ); |
2098 $username = trim( $username ); |
1875 // Consolidate contiguous whitespace |
2099 // Consolidate contiguous whitespace |
1876 $username = preg_replace( '|\s+|', ' ', $username ); |
2100 $username = preg_replace( '|\s+|', ' ', $username ); |
1877 |
2101 |
1897 * @param string $key String key |
2121 * @param string $key String key |
1898 * @return string Sanitized key |
2122 * @return string Sanitized key |
1899 */ |
2123 */ |
1900 function sanitize_key( $key ) { |
2124 function sanitize_key( $key ) { |
1901 $raw_key = $key; |
2125 $raw_key = $key; |
1902 $key = strtolower( $key ); |
2126 $key = strtolower( $key ); |
1903 $key = preg_replace( '/[^a-z0-9_\-]/', '', $key ); |
2127 $key = preg_replace( '/[^a-z0-9_\-]/', '', $key ); |
1904 |
2128 |
1905 /** |
2129 /** |
1906 * Filters a sanitized key string. |
2130 * Filters a sanitized key string. |
1907 * |
2131 * |
1908 * @since 3.0.0 |
2132 * @since 3.0.0 |
1928 * @return string The sanitized string. |
2152 * @return string The sanitized string. |
1929 */ |
2153 */ |
1930 function sanitize_title( $title, $fallback_title = '', $context = 'save' ) { |
2154 function sanitize_title( $title, $fallback_title = '', $context = 'save' ) { |
1931 $raw_title = $title; |
2155 $raw_title = $title; |
1932 |
2156 |
1933 if ( 'save' == $context ) |
2157 if ( 'save' == $context ) { |
1934 $title = remove_accents($title); |
2158 $title = remove_accents( $title ); |
2159 } |
|
1935 |
2160 |
1936 /** |
2161 /** |
1937 * Filters a sanitized title string. |
2162 * Filters a sanitized title string. |
1938 * |
2163 * |
1939 * @since 1.2.0 |
2164 * @since 1.2.0 |
1942 * @param string $raw_title The title prior to sanitization. |
2167 * @param string $raw_title The title prior to sanitization. |
1943 * @param string $context The context for which the title is being sanitized. |
2168 * @param string $context The context for which the title is being sanitized. |
1944 */ |
2169 */ |
1945 $title = apply_filters( 'sanitize_title', $title, $raw_title, $context ); |
2170 $title = apply_filters( 'sanitize_title', $title, $raw_title, $context ); |
1946 |
2171 |
1947 if ( '' === $title || false === $title ) |
2172 if ( '' === $title || false === $title ) { |
1948 $title = $fallback_title; |
2173 $title = $fallback_title; |
2174 } |
|
1949 |
2175 |
1950 return $title; |
2176 return $title; |
1951 } |
2177 } |
1952 |
2178 |
1953 /** |
2179 /** |
1976 * @param string $raw_title Optional. Not used. |
2202 * @param string $raw_title Optional. Not used. |
1977 * @param string $context Optional. The operation for which the string is sanitized. |
2203 * @param string $context Optional. The operation for which the string is sanitized. |
1978 * @return string The sanitized title. |
2204 * @return string The sanitized title. |
1979 */ |
2205 */ |
1980 function sanitize_title_with_dashes( $title, $raw_title = '', $context = 'display' ) { |
2206 function sanitize_title_with_dashes( $title, $raw_title = '', $context = 'display' ) { |
1981 $title = strip_tags($title); |
2207 $title = strip_tags( $title ); |
1982 // Preserve escaped octets. |
2208 // Preserve escaped octets. |
1983 $title = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|', '---$1---', $title); |
2209 $title = preg_replace( '|%([a-fA-F0-9][a-fA-F0-9])|', '---$1---', $title ); |
1984 // Remove percent signs that are not part of an octet. |
2210 // Remove percent signs that are not part of an octet. |
1985 $title = str_replace('%', '', $title); |
2211 $title = str_replace( '%', '', $title ); |
1986 // Restore octets. |
2212 // Restore octets. |
1987 $title = preg_replace('|---([a-fA-F0-9][a-fA-F0-9])---|', '%$1', $title); |
2213 $title = preg_replace( '|---([a-fA-F0-9][a-fA-F0-9])---|', '%$1', $title ); |
1988 |
2214 |
1989 if (seems_utf8($title)) { |
2215 if ( seems_utf8( $title ) ) { |
1990 if (function_exists('mb_strtolower')) { |
2216 if ( function_exists( 'mb_strtolower' ) ) { |
1991 $title = mb_strtolower($title, 'UTF-8'); |
2217 $title = mb_strtolower( $title, 'UTF-8' ); |
1992 } |
2218 } |
1993 $title = utf8_uri_encode($title, 200); |
2219 $title = utf8_uri_encode( $title, 200 ); |
1994 } |
2220 } |
1995 |
2221 |
1996 $title = strtolower($title); |
2222 $title = strtolower( $title ); |
1997 |
2223 |
1998 if ( 'save' == $context ) { |
2224 if ( 'save' == $context ) { |
1999 // Convert nbsp, ndash and mdash to hyphens |
2225 // Convert nbsp, ndash and mdash to hyphens |
2000 $title = str_replace( array( '%c2%a0', '%e2%80%93', '%e2%80%94' ), '-', $title ); |
2226 $title = str_replace( array( '%c2%a0', '%e2%80%93', '%e2%80%94' ), '-', $title ); |
2001 // Convert nbsp, ndash and mdash HTML entities to hyphens |
2227 // Convert nbsp, ndash and mdash HTML entities to hyphens |
2002 $title = str_replace( array( ' ', ' ', '–', '–', '—', '—' ), '-', $title ); |
2228 $title = str_replace( array( ' ', ' ', '–', '–', '—', '—' ), '-', $title ); |
2003 // Convert forward slash to hyphen |
2229 // Convert forward slash to hyphen |
2004 $title = str_replace( '/', '-', $title ); |
2230 $title = str_replace( '/', '-', $title ); |
2005 |
2231 |
2006 // Strip these characters entirely |
2232 // Strip these characters entirely |
2007 $title = str_replace( array( |
2233 $title = str_replace( |
2008 // iexcl and iquest |
2234 array( |
2009 '%c2%a1', '%c2%bf', |
2235 // soft hyphens |
2010 // angle quotes |
2236 '%c2%ad', |
2011 '%c2%ab', '%c2%bb', '%e2%80%b9', '%e2%80%ba', |
2237 // iexcl and iquest |
2012 // curly quotes |
2238 '%c2%a1', |
2013 '%e2%80%98', '%e2%80%99', '%e2%80%9c', '%e2%80%9d', |
2239 '%c2%bf', |
2014 '%e2%80%9a', '%e2%80%9b', '%e2%80%9e', '%e2%80%9f', |
2240 // angle quotes |
2015 // copy, reg, deg, hellip and trade |
2241 '%c2%ab', |
2016 '%c2%a9', '%c2%ae', '%c2%b0', '%e2%80%a6', '%e2%84%a2', |
2242 '%c2%bb', |
2017 // acute accents |
2243 '%e2%80%b9', |
2018 '%c2%b4', '%cb%8a', '%cc%81', '%cd%81', |
2244 '%e2%80%ba', |
2019 // grave accent, macron, caron |
2245 // curly quotes |
2020 '%cc%80', '%cc%84', '%cc%8c', |
2246 '%e2%80%98', |
2021 ), '', $title ); |
2247 '%e2%80%99', |
2248 '%e2%80%9c', |
|
2249 '%e2%80%9d', |
|
2250 '%e2%80%9a', |
|
2251 '%e2%80%9b', |
|
2252 '%e2%80%9e', |
|
2253 '%e2%80%9f', |
|
2254 // copy, reg, deg, hellip and trade |
|
2255 '%c2%a9', |
|
2256 '%c2%ae', |
|
2257 '%c2%b0', |
|
2258 '%e2%80%a6', |
|
2259 '%e2%84%a2', |
|
2260 // acute accents |
|
2261 '%c2%b4', |
|
2262 '%cb%8a', |
|
2263 '%cc%81', |
|
2264 '%cd%81', |
|
2265 // grave accent, macron, caron |
|
2266 '%cc%80', |
|
2267 '%cc%84', |
|
2268 '%cc%8c', |
|
2269 ), |
|
2270 '', |
|
2271 $title |
|
2272 ); |
|
2022 |
2273 |
2023 // Convert times to x |
2274 // Convert times to x |
2024 $title = str_replace( '%c3%97', 'x', $title ); |
2275 $title = str_replace( '%c3%97', 'x', $title ); |
2025 } |
2276 } |
2026 |
2277 |
2027 $title = preg_replace('/&.+?;/', '', $title); // kill entities |
2278 $title = preg_replace( '/&.+?;/', '', $title ); // kill entities |
2028 $title = str_replace('.', '-', $title); |
2279 $title = str_replace( '.', '-', $title ); |
2029 |
2280 |
2030 $title = preg_replace('/[^%a-z0-9 _-]/', '', $title); |
2281 $title = preg_replace( '/[^%a-z0-9 _-]/', '', $title ); |
2031 $title = preg_replace('/\s+/', '-', $title); |
2282 $title = preg_replace( '/\s+/', '-', $title ); |
2032 $title = preg_replace('|-+|', '-', $title); |
2283 $title = preg_replace( '|-+|', '-', $title ); |
2033 $title = trim($title, '-'); |
2284 $title = trim( $title, '-' ); |
2034 |
2285 |
2035 return $title; |
2286 return $title; |
2036 } |
2287 } |
2037 |
2288 |
2038 /** |
2289 /** |
2065 * |
2316 * |
2066 * @since 2.8.0 |
2317 * @since 2.8.0 |
2067 * |
2318 * |
2068 * @param string $class The classname to be sanitized |
2319 * @param string $class The classname to be sanitized |
2069 * @param string $fallback Optional. The value to return if the sanitization ends up as an empty string. |
2320 * @param string $fallback Optional. The value to return if the sanitization ends up as an empty string. |
2070 * Defaults to an empty string. |
2321 * Defaults to an empty string. |
2071 * @return string The sanitized value |
2322 * @return string The sanitized value |
2072 */ |
2323 */ |
2073 function sanitize_html_class( $class, $fallback = '' ) { |
2324 function sanitize_html_class( $class, $fallback = '' ) { |
2074 //Strip out any % encoded octets |
2325 //Strip out any % encoded octets |
2075 $sanitized = preg_replace( '|%[a-fA-F0-9][a-fA-F0-9]|', '', $class ); |
2326 $sanitized = preg_replace( '|%[a-fA-F0-9][a-fA-F0-9]|', '', $class ); |
2152 'š' => 'š', |
2403 'š' => 'š', |
2153 '›' => '›', |
2404 '›' => '›', |
2154 'œ' => 'œ', |
2405 'œ' => 'œ', |
2155 '' => '', |
2406 '' => '', |
2156 'ž' => 'ž', |
2407 'ž' => 'ž', |
2157 'Ÿ' => 'Ÿ' |
2408 'Ÿ' => 'Ÿ', |
2158 ); |
2409 ); |
2159 |
2410 |
2160 if ( strpos( $content, '' ) !== false ) { |
2411 if ( strpos( $content, '' ) !== false ) { |
2161 $content = strtr( $content, $wp_htmltranswinuni ); |
2412 $content = strtr( $content, $wp_htmltranswinuni ); |
2162 } |
2413 } |
2172 * @param string $text Text to be balanced |
2423 * @param string $text Text to be balanced |
2173 * @param bool $force If true, forces balancing, ignoring the value of the option. Default false. |
2424 * @param bool $force If true, forces balancing, ignoring the value of the option. Default false. |
2174 * @return string Balanced text |
2425 * @return string Balanced text |
2175 */ |
2426 */ |
2176 function balanceTags( $text, $force = false ) { |
2427 function balanceTags( $text, $force = false ) { |
2177 if ( $force || get_option('use_balanceTags') == 1 ) { |
2428 if ( $force || get_option( 'use_balanceTags' ) == 1 ) { |
2178 return force_balance_tags( $text ); |
2429 return force_balance_tags( $text ); |
2179 } else { |
2430 } else { |
2180 return $text; |
2431 return $text; |
2181 } |
2432 } |
2182 } |
2433 } |
2190 * @license GPL |
2441 * @license GPL |
2191 * @copyright November 4, 2001 |
2442 * @copyright November 4, 2001 |
2192 * @version 1.1 |
2443 * @version 1.1 |
2193 * @todo Make better - change loop condition to $text in 1.2 |
2444 * @todo Make better - change loop condition to $text in 1.2 |
2194 * @internal Modified by Scott Reilly (coffee2code) 02 Aug 2004 |
2445 * @internal Modified by Scott Reilly (coffee2code) 02 Aug 2004 |
2195 * 1.1 Fixed handling of append/stack pop order of end text |
2446 * 1.1 Fixed handling of append/stack pop order of end text |
2196 * Added Cleaning Hooks |
2447 * Added Cleaning Hooks |
2197 * 1.0 First Version |
2448 * 1.0 First Version |
2198 * |
2449 * |
2199 * @param string $text Text to be balanced. |
2450 * @param string $text Text to be balanced. |
2200 * @return string Balanced text. |
2451 * @return string Balanced text. |
2201 */ |
2452 */ |
2202 function force_balance_tags( $text ) { |
2453 function force_balance_tags( $text ) { |
2203 $tagstack = array(); |
2454 $tagstack = array(); |
2204 $stacksize = 0; |
2455 $stacksize = 0; |
2205 $tagqueue = ''; |
2456 $tagqueue = ''; |
2206 $newtext = ''; |
2457 $newtext = ''; |
2207 // Known single-entity/self-closing tags |
2458 // Known single-entity/self-closing tags |
2208 $single_tags = array( 'area', 'base', 'basefont', 'br', 'col', 'command', 'embed', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param', 'source' ); |
2459 $single_tags = array( 'area', 'base', 'basefont', 'br', 'col', 'command', 'embed', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param', 'source' ); |
2209 // Tags that can be immediately nested within themselves |
2460 // Tags that can be immediately nested within themselves |
2210 $nestable_tags = array( 'blockquote', 'div', 'object', 'q', 'span' ); |
2461 $nestable_tags = array( 'blockquote', 'div', 'object', 'q', 'span' ); |
2211 |
2462 |
2212 // WP bug fix for comments - in case you REALLY meant to type '< !--' |
2463 // WP bug fix for comments - in case you REALLY meant to type '< !--' |
2213 $text = str_replace('< !--', '< !--', $text); |
2464 $text = str_replace( '< !--', '< !--', $text ); |
2214 // WP bug fix for LOVE <3 (and other situations with '<' before a number) |
2465 // WP bug fix for LOVE <3 (and other situations with '<' before a number) |
2215 $text = preg_replace('#<([0-9]{1})#', '<$1', $text); |
2466 $text = preg_replace( '#<([0-9]{1})#', '<$1', $text ); |
2216 |
2467 |
2217 while ( preg_match("/<(\/?[\w:]*)\s*([^>]*)>/", $text, $regex) ) { |
2468 while ( preg_match( '/<(\/?[\w:]*)\s*([^>]*)>/', $text, $regex ) ) { |
2218 $newtext .= $tagqueue; |
2469 $newtext .= $tagqueue; |
2219 |
2470 |
2220 $i = strpos($text, $regex[0]); |
2471 $i = strpos( $text, $regex[0] ); |
2221 $l = strlen($regex[0]); |
2472 $l = strlen( $regex[0] ); |
2222 |
2473 |
2223 // clear the shifter |
2474 // clear the shifter |
2224 $tagqueue = ''; |
2475 $tagqueue = ''; |
2225 // Pop or Push |
2476 // Pop or Push |
2226 if ( isset($regex[1][0]) && '/' == $regex[1][0] ) { // End Tag |
2477 if ( isset( $regex[1][0] ) && '/' == $regex[1][0] ) { // End Tag |
2227 $tag = strtolower(substr($regex[1],1)); |
2478 $tag = strtolower( substr( $regex[1], 1 ) ); |
2228 // if too many closing tags |
2479 // if too many closing tags |
2229 if ( $stacksize <= 0 ) { |
2480 if ( $stacksize <= 0 ) { |
2230 $tag = ''; |
2481 $tag = ''; |
2231 // or close to be safe $tag = '/' . $tag; |
2482 // or close to be safe $tag = '/' . $tag; |
2232 } |
2483 |
2233 // if stacktop value = tag close value then pop |
2484 // if stacktop value = tag close value then pop |
2234 elseif ( $tagstack[$stacksize - 1] == $tag ) { // found closing tag |
2485 } elseif ( $tagstack[ $stacksize - 1 ] == $tag ) { // found closing tag |
2235 $tag = '</' . $tag . '>'; // Close Tag |
2486 $tag = '</' . $tag . '>'; // Close Tag |
2236 // Pop |
2487 // Pop |
2237 array_pop( $tagstack ); |
2488 array_pop( $tagstack ); |
2238 $stacksize--; |
2489 $stacksize--; |
2239 } else { // closing tag not at top, search for it |
2490 } else { // closing tag not at top, search for it |
2240 for ( $j = $stacksize-1; $j >= 0; $j-- ) { |
2491 for ( $j = $stacksize - 1; $j >= 0; $j-- ) { |
2241 if ( $tagstack[$j] == $tag ) { |
2492 if ( $tagstack[ $j ] == $tag ) { |
2242 // add tag to tagqueue |
2493 // add tag to tagqueue |
2243 for ( $k = $stacksize-1; $k >= $j; $k--) { |
2494 for ( $k = $stacksize - 1; $k >= $j; $k-- ) { |
2244 $tagqueue .= '</' . array_pop( $tagstack ) . '>'; |
2495 $tagqueue .= '</' . array_pop( $tagstack ) . '>'; |
2245 $stacksize--; |
2496 $stacksize--; |
2246 } |
2497 } |
2247 break; |
2498 break; |
2248 } |
2499 } |
2249 } |
2500 } |
2250 $tag = ''; |
2501 $tag = ''; |
2251 } |
2502 } |
2252 } else { // Begin Tag |
2503 } else { // Begin Tag |
2253 $tag = strtolower($regex[1]); |
2504 $tag = strtolower( $regex[1] ); |
2254 |
2505 |
2255 // Tag Cleaning |
2506 // Tag Cleaning |
2256 |
2507 |
2257 // If it's an empty tag "< >", do nothing |
2508 // If it's an empty tag "< >", do nothing |
2258 if ( '' == $tag ) { |
2509 if ( '' == $tag ) { |
2259 // do nothing |
2510 // do nothing |
2260 } |
2511 } elseif ( substr( $regex[2], -1 ) == '/' ) { // ElseIf it presents itself as a self-closing tag... |
2261 // ElseIf it presents itself as a self-closing tag... |
|
2262 elseif ( substr( $regex[2], -1 ) == '/' ) { |
|
2263 // ...but it isn't a known single-entity self-closing tag, then don't let it be treated as such and |
2512 // ...but it isn't a known single-entity self-closing tag, then don't let it be treated as such and |
2264 // immediately close it with a closing tag (the tag will encapsulate no text as a result) |
2513 // immediately close it with a closing tag (the tag will encapsulate no text as a result) |
2265 if ( ! in_array( $tag, $single_tags ) ) |
2514 if ( ! in_array( $tag, $single_tags ) ) { |
2266 $regex[2] = trim( substr( $regex[2], 0, -1 ) ) . "></$tag"; |
2515 $regex[2] = trim( substr( $regex[2], 0, -1 ) ) . "></$tag"; |
2267 } |
2516 } |
2268 // ElseIf it's a known single-entity tag but it doesn't close itself, do so |
2517 } elseif ( in_array( $tag, $single_tags ) ) { // ElseIf it's a known single-entity tag but it doesn't close itself, do so |
2269 elseif ( in_array($tag, $single_tags) ) { |
|
2270 $regex[2] .= '/'; |
2518 $regex[2] .= '/'; |
2271 } |
2519 } else { // Else it's not a single-entity tag |
2272 // Else it's not a single-entity tag |
|
2273 else { |
|
2274 // If the top of the stack is the same as the tag we want to push, close previous tag |
2520 // If the top of the stack is the same as the tag we want to push, close previous tag |
2275 if ( $stacksize > 0 && !in_array($tag, $nestable_tags) && $tagstack[$stacksize - 1] == $tag ) { |
2521 if ( $stacksize > 0 && ! in_array( $tag, $nestable_tags ) && $tagstack[ $stacksize - 1 ] == $tag ) { |
2276 $tagqueue = '</' . array_pop( $tagstack ) . '>'; |
2522 $tagqueue = '</' . array_pop( $tagstack ) . '>'; |
2277 $stacksize--; |
2523 $stacksize--; |
2278 } |
2524 } |
2279 $stacksize = array_push( $tagstack, $tag ); |
2525 $stacksize = array_push( $tagstack, $tag ); |
2280 } |
2526 } |
2281 |
2527 |
2282 // Attributes |
2528 // Attributes |
2283 $attributes = $regex[2]; |
2529 $attributes = $regex[2]; |
2284 if ( ! empty( $attributes ) && $attributes[0] != '>' ) |
2530 if ( ! empty( $attributes ) && $attributes[0] != '>' ) { |
2285 $attributes = ' ' . $attributes; |
2531 $attributes = ' ' . $attributes; |
2532 } |
|
2286 |
2533 |
2287 $tag = '<' . $tag . $attributes . '>'; |
2534 $tag = '<' . $tag . $attributes . '>'; |
2288 //If already queuing a close tag, then put this tag on, too |
2535 //If already queuing a close tag, then put this tag on, too |
2289 if ( !empty($tagqueue) ) { |
2536 if ( ! empty( $tagqueue ) ) { |
2290 $tagqueue .= $tag; |
2537 $tagqueue .= $tag; |
2291 $tag = ''; |
2538 $tag = ''; |
2292 } |
2539 } |
2293 } |
2540 } |
2294 $newtext .= substr($text, 0, $i) . $tag; |
2541 $newtext .= substr( $text, 0, $i ) . $tag; |
2295 $text = substr($text, $i + $l); |
2542 $text = substr( $text, $i + $l ); |
2296 } |
2543 } |
2297 |
2544 |
2298 // Clear Tag Queue |
2545 // Clear Tag Queue |
2299 $newtext .= $tagqueue; |
2546 $newtext .= $tagqueue; |
2300 |
2547 |
2301 // Add Remaining text |
2548 // Add Remaining text |
2302 $newtext .= $text; |
2549 $newtext .= $text; |
2303 |
2550 |
2304 // Empty Stack |
2551 // Empty Stack |
2305 while( $x = array_pop($tagstack) ) |
2552 while ( $x = array_pop( $tagstack ) ) { |
2306 $newtext .= '</' . $x . '>'; // Add remaining tags to close |
2553 $newtext .= '</' . $x . '>'; // Add remaining tags to close |
2554 } |
|
2307 |
2555 |
2308 // WP fix for the bug with HTML comments |
2556 // WP fix for the bug with HTML comments |
2309 $newtext = str_replace("< !--","<!--",$newtext); |
2557 $newtext = str_replace( '< !--', '<!--', $newtext ); |
2310 $newtext = str_replace("< !--","< !--",$newtext); |
2558 $newtext = str_replace( '< !--', '< !--', $newtext ); |
2311 |
2559 |
2312 return $newtext; |
2560 return $newtext; |
2313 } |
2561 } |
2314 |
2562 |
2315 /** |
2563 /** |
2335 * @since 1.2.0 |
2583 * @since 1.2.0 |
2336 * |
2584 * |
2337 * @param string $content The text, prior to formatting for editing. |
2585 * @param string $content The text, prior to formatting for editing. |
2338 */ |
2586 */ |
2339 $content = apply_filters( 'format_to_edit', $content ); |
2587 $content = apply_filters( 'format_to_edit', $content ); |
2340 if ( ! $rich_text ) |
2588 if ( ! $rich_text ) { |
2341 $content = esc_textarea( $content ); |
2589 $content = esc_textarea( $content ); |
2590 } |
|
2342 return $content; |
2591 return $content; |
2343 } |
2592 } |
2344 |
2593 |
2345 /** |
2594 /** |
2346 * Add leading zeros when necessary. |
2595 * Add leading zeros when necessary. |
2370 * |
2619 * |
2371 * @param string $string Value to which backslashes will be added. |
2620 * @param string $string Value to which backslashes will be added. |
2372 * @return string String with backslashes inserted. |
2621 * @return string String with backslashes inserted. |
2373 */ |
2622 */ |
2374 function backslashit( $string ) { |
2623 function backslashit( $string ) { |
2375 if ( isset( $string[0] ) && $string[0] >= '0' && $string[0] <= '9' ) |
2624 if ( isset( $string[0] ) && $string[0] >= '0' && $string[0] <= '9' ) { |
2376 $string = '\\\\' . $string; |
2625 $string = '\\\\' . $string; |
2626 } |
|
2377 return addcslashes( $string, 'A..Za..z' ); |
2627 return addcslashes( $string, 'A..Za..z' ); |
2378 } |
2628 } |
2379 |
2629 |
2380 /** |
2630 /** |
2381 * Appends a trailing slash. |
2631 * Appends a trailing slash. |
2419 * @since 0.71 |
2669 * @since 0.71 |
2420 * |
2670 * |
2421 * @param string $gpc The string returned from HTTP request data. |
2671 * @param string $gpc The string returned from HTTP request data. |
2422 * @return string Returns a string escaped with slashes. |
2672 * @return string Returns a string escaped with slashes. |
2423 */ |
2673 */ |
2424 function addslashes_gpc($gpc) { |
2674 function addslashes_gpc( $gpc ) { |
2425 if ( get_magic_quotes_gpc() ) |
2675 if ( get_magic_quotes_gpc() ) { |
2426 $gpc = stripslashes($gpc); |
2676 $gpc = stripslashes( $gpc ); |
2427 |
2677 } |
2428 return wp_slash($gpc); |
2678 |
2679 return wp_slash( $gpc ); |
|
2429 } |
2680 } |
2430 |
2681 |
2431 /** |
2682 /** |
2432 * Navigates through an array, object, or scalar, and removes slashes from the values. |
2683 * Navigates through an array, object, or scalar, and removes slashes from the values. |
2433 * |
2684 * |
2500 function antispambot( $email_address, $hex_encoding = 0 ) { |
2751 function antispambot( $email_address, $hex_encoding = 0 ) { |
2501 $email_no_spam_address = ''; |
2752 $email_no_spam_address = ''; |
2502 for ( $i = 0, $len = strlen( $email_address ); $i < $len; $i++ ) { |
2753 for ( $i = 0, $len = strlen( $email_address ); $i < $len; $i++ ) { |
2503 $j = rand( 0, 1 + $hex_encoding ); |
2754 $j = rand( 0, 1 + $hex_encoding ); |
2504 if ( $j == 0 ) { |
2755 if ( $j == 0 ) { |
2505 $email_no_spam_address .= '&#' . ord( $email_address[$i] ) . ';'; |
2756 $email_no_spam_address .= '&#' . ord( $email_address[ $i ] ) . ';'; |
2506 } elseif ( $j == 1 ) { |
2757 } elseif ( $j == 1 ) { |
2507 $email_no_spam_address .= $email_address[$i]; |
2758 $email_no_spam_address .= $email_address[ $i ]; |
2508 } elseif ( $j == 2 ) { |
2759 } elseif ( $j == 2 ) { |
2509 $email_no_spam_address .= '%' . zeroise( dechex( ord( $email_address[$i] ) ), 2 ); |
2760 $email_no_spam_address .= '%' . zeroise( dechex( ord( $email_address[ $i ] ) ), 2 ); |
2510 } |
2761 } |
2511 } |
2762 } |
2512 |
2763 |
2513 return str_replace( '@', '@', $email_no_spam_address ); |
2764 return str_replace( '@', '@', $email_no_spam_address ); |
2514 } |
2765 } |
2528 $url = $matches[2]; |
2779 $url = $matches[2]; |
2529 |
2780 |
2530 if ( ')' == $matches[3] && strpos( $url, '(' ) ) { |
2781 if ( ')' == $matches[3] && strpos( $url, '(' ) ) { |
2531 // If the trailing character is a closing parethesis, and the URL has an opening parenthesis in it, add the closing parenthesis to the URL. |
2782 // If the trailing character is a closing parethesis, and the URL has an opening parenthesis in it, add the closing parenthesis to the URL. |
2532 // Then we can let the parenthesis balancer do its thing below. |
2783 // Then we can let the parenthesis balancer do its thing below. |
2533 $url .= $matches[3]; |
2784 $url .= $matches[3]; |
2534 $suffix = ''; |
2785 $suffix = ''; |
2535 } else { |
2786 } else { |
2536 $suffix = $matches[3]; |
2787 $suffix = $matches[3]; |
2537 } |
2788 } |
2538 |
2789 |
2539 // Include parentheses in the URL only if paired |
2790 // Include parentheses in the URL only if paired |
2540 while ( substr_count( $url, '(' ) < substr_count( $url, ')' ) ) { |
2791 while ( substr_count( $url, '(' ) < substr_count( $url, ')' ) ) { |
2541 $suffix = strrchr( $url, ')' ) . $suffix; |
2792 $suffix = strrchr( $url, ')' ) . $suffix; |
2542 $url = substr( $url, 0, strrpos( $url, ')' ) ); |
2793 $url = substr( $url, 0, strrpos( $url, ')' ) ); |
2543 } |
2794 } |
2544 |
2795 |
2545 $url = esc_url($url); |
2796 $url = esc_url( $url ); |
2546 if ( empty($url) ) |
2797 if ( empty( $url ) ) { |
2547 return $matches[0]; |
2798 return $matches[0]; |
2799 } |
|
2548 |
2800 |
2549 return $matches[1] . "<a href=\"$url\" rel=\"nofollow\">$url</a>" . $suffix; |
2801 return $matches[1] . "<a href=\"$url\" rel=\"nofollow\">$url</a>" . $suffix; |
2550 } |
2802 } |
2551 |
2803 |
2552 /** |
2804 /** |
2559 * |
2811 * |
2560 * @param array $matches Single Regex Match. |
2812 * @param array $matches Single Regex Match. |
2561 * @return string HTML A element with URL address. |
2813 * @return string HTML A element with URL address. |
2562 */ |
2814 */ |
2563 function _make_web_ftp_clickable_cb( $matches ) { |
2815 function _make_web_ftp_clickable_cb( $matches ) { |
2564 $ret = ''; |
2816 $ret = ''; |
2565 $dest = $matches[2]; |
2817 $dest = $matches[2]; |
2566 $dest = 'http://' . $dest; |
2818 $dest = 'http://' . $dest; |
2567 |
2819 |
2568 // removed trailing [.,;:)] from URL |
2820 // removed trailing [.,;:)] from URL |
2569 if ( in_array( substr($dest, -1), array('.', ',', ';', ':', ')') ) === true ) { |
2821 if ( in_array( substr( $dest, -1 ), array( '.', ',', ';', ':', ')' ) ) === true ) { |
2570 $ret = substr($dest, -1); |
2822 $ret = substr( $dest, -1 ); |
2571 $dest = substr($dest, 0, strlen($dest)-1); |
2823 $dest = substr( $dest, 0, strlen( $dest ) - 1 ); |
2572 } |
2824 } |
2573 |
2825 |
2574 $dest = esc_url($dest); |
2826 $dest = esc_url( $dest ); |
2575 if ( empty($dest) ) |
2827 if ( empty( $dest ) ) { |
2576 return $matches[0]; |
2828 return $matches[0]; |
2829 } |
|
2577 |
2830 |
2578 return $matches[1] . "<a href=\"$dest\" rel=\"nofollow\">$dest</a>$ret"; |
2831 return $matches[1] . "<a href=\"$dest\" rel=\"nofollow\">$dest</a>$ret"; |
2579 } |
2832 } |
2580 |
2833 |
2581 /** |
2834 /** |
2604 * |
2857 * |
2605 * @param string $text Content to convert URIs. |
2858 * @param string $text Content to convert URIs. |
2606 * @return string Content with converted URIs. |
2859 * @return string Content with converted URIs. |
2607 */ |
2860 */ |
2608 function make_clickable( $text ) { |
2861 function make_clickable( $text ) { |
2609 $r = ''; |
2862 $r = ''; |
2610 $textarr = preg_split( '/(<[^<>]+>)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); // split out HTML tags |
2863 $textarr = preg_split( '/(<[^<>]+>)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); // split out HTML tags |
2611 $nested_code_pre = 0; // Keep track of how many levels link is nested inside <pre> or <code> |
2864 $nested_code_pre = 0; // Keep track of how many levels link is nested inside <pre> or <code> |
2612 foreach ( $textarr as $piece ) { |
2865 foreach ( $textarr as $piece ) { |
2613 |
2866 |
2614 if ( preg_match( '|^<code[\s>]|i', $piece ) || preg_match( '|^<pre[\s>]|i', $piece ) || preg_match( '|^<script[\s>]|i', $piece ) || preg_match( '|^<style[\s>]|i', $piece ) ) |
2867 if ( preg_match( '|^<code[\s>]|i', $piece ) || preg_match( '|^<pre[\s>]|i', $piece ) || preg_match( '|^<script[\s>]|i', $piece ) || preg_match( '|^<style[\s>]|i', $piece ) ) { |
2615 $nested_code_pre++; |
2868 $nested_code_pre++; |
2616 elseif ( $nested_code_pre && ( '</code>' === strtolower( $piece ) || '</pre>' === strtolower( $piece ) || '</script>' === strtolower( $piece ) || '</style>' === strtolower( $piece ) ) ) |
2869 } elseif ( $nested_code_pre && ( '</code>' === strtolower( $piece ) || '</pre>' === strtolower( $piece ) || '</script>' === strtolower( $piece ) || '</style>' === strtolower( $piece ) ) ) { |
2617 $nested_code_pre--; |
2870 $nested_code_pre--; |
2871 } |
|
2618 |
2872 |
2619 if ( $nested_code_pre || empty( $piece ) || ( $piece[0] === '<' && ! preg_match( '|^<\s*[\w]{1,20}+://|', $piece ) ) ) { |
2873 if ( $nested_code_pre || empty( $piece ) || ( $piece[0] === '<' && ! preg_match( '|^<\s*[\w]{1,20}+://|', $piece ) ) ) { |
2620 $r .= $piece; |
2874 $r .= $piece; |
2621 continue; |
2875 continue; |
2622 } |
2876 } |
2645 [\\w\\x80-\\xff#%\\~/@\\[\\]*(+=&$-]++ # Non-punctuation URL character |
2899 [\\w\\x80-\\xff#%\\~/@\\[\\]*(+=&$-]++ # Non-punctuation URL character |
2646 )* |
2900 )* |
2647 ) |
2901 ) |
2648 (\)?) # 3: Trailing closing parenthesis (for parethesis balancing post processing) |
2902 (\)?) # 3: Trailing closing parenthesis (for parethesis balancing post processing) |
2649 ~xS'; // The regex is a non-anchored pattern and does not have a single fixed starting character. |
2903 ~xS'; // The regex is a non-anchored pattern and does not have a single fixed starting character. |
2650 // Tell PCRE to spend more time optimizing since, when used on a page load, it will probably be used several times. |
2904 // Tell PCRE to spend more time optimizing since, when used on a page load, it will probably be used several times. |
2651 |
2905 |
2652 $ret = preg_replace_callback( $url_clickable, '_make_url_clickable_cb', $ret ); |
2906 $ret = preg_replace_callback( $url_clickable, '_make_url_clickable_cb', $ret ); |
2653 |
2907 |
2654 $ret = preg_replace_callback( '#([\s>])((www|ftp)\.[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]+)#is', '_make_web_ftp_clickable_cb', $ret ); |
2908 $ret = preg_replace_callback( '#([\s>])((www|ftp)\.[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]+)#is', '_make_web_ftp_clickable_cb', $ret ); |
2655 $ret = preg_replace_callback( '#([\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})#i', '_make_email_clickable_cb', $ret ); |
2909 $ret = preg_replace_callback( '#([\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})#i', '_make_email_clickable_cb', $ret ); |
2656 |
2910 |
2657 $ret = substr( $ret, 1, -1 ); // Remove our whitespace padding. |
2911 $ret = substr( $ret, 1, -1 ); // Remove our whitespace padding. |
2658 $r .= $ret; |
2912 $r .= $ret; |
2659 } |
2913 } |
2660 } |
2914 } |
2661 |
2915 |
2662 // Cleanup of accidental links within links |
2916 // Cleanup of accidental links within links |
2663 return preg_replace( '#(<a([ \r\n\t]+[^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i', "$1$3</a>", $r ); |
2917 return preg_replace( '#(<a([ \r\n\t]+[^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i', '$1$3</a>', $r ); |
2664 } |
2918 } |
2665 |
2919 |
2666 /** |
2920 /** |
2667 * Breaks a string into chunks by splitting at whitespace characters. |
2921 * Breaks a string into chunks by splitting at whitespace characters. |
2668 * The length of each returned chunk is as close to the specified length goal as possible, |
2922 * The length of each returned chunk is as close to the specified length goal as possible, |
2705 if ( false === $pos ) { |
2959 if ( false === $pos ) { |
2706 break; |
2960 break; |
2707 } |
2961 } |
2708 } |
2962 } |
2709 |
2963 |
2710 $chunks[] = substr( $string, 0, $pos + 1 ); |
2964 $chunks[] = substr( $string, 0, $pos + 1 ); |
2711 $string = substr( $string, $pos + 1 ); |
2965 $string = substr( $string, $pos + 1 ); |
2712 $string_nullspace = substr( $string_nullspace, $pos + 1 ); |
2966 $string_nullspace = substr( $string_nullspace, $pos + 1 ); |
2713 } |
2967 } |
2714 |
2968 |
2715 if ( $string ) { |
2969 if ( $string ) { |
2716 $chunks[] = $string; |
2970 $chunks[] = $string; |
2727 * @param string $text Content that may contain HTML A elements. |
2981 * @param string $text Content that may contain HTML A elements. |
2728 * @return string Converted content. |
2982 * @return string Converted content. |
2729 */ |
2983 */ |
2730 function wp_rel_nofollow( $text ) { |
2984 function wp_rel_nofollow( $text ) { |
2731 // This is a pre save filter, so text is already escaped. |
2985 // This is a pre save filter, so text is already escaped. |
2732 $text = stripslashes($text); |
2986 $text = stripslashes( $text ); |
2733 $text = preg_replace_callback('|<a (.+?)>|i', 'wp_rel_nofollow_callback', $text); |
2987 $text = preg_replace_callback( '|<a (.+?)>|i', 'wp_rel_nofollow_callback', $text ); |
2734 return wp_slash( $text ); |
2988 return wp_slash( $text ); |
2735 } |
2989 } |
2736 |
2990 |
2737 /** |
2991 /** |
2738 * Callback to add rel=nofollow string to HTML A element. |
2992 * Callback to add rel=nofollow string to HTML A element. |
2745 * @param array $matches Single Match |
2999 * @param array $matches Single Match |
2746 * @return string HTML A Element with rel nofollow. |
3000 * @return string HTML A Element with rel nofollow. |
2747 */ |
3001 */ |
2748 function wp_rel_nofollow_callback( $matches ) { |
3002 function wp_rel_nofollow_callback( $matches ) { |
2749 $text = $matches[1]; |
3003 $text = $matches[1]; |
2750 $atts = shortcode_parse_atts( $matches[1] ); |
3004 $atts = wp_kses_hair( $matches[1], wp_allowed_protocols() ); |
2751 $rel = 'nofollow'; |
3005 $rel = 'nofollow'; |
2752 |
3006 |
2753 if ( preg_match( '%href=["\'](' . preg_quote( set_url_scheme( home_url(), 'http' ) ) . ')%i', $text ) || |
3007 if ( ! empty( $atts['href'] ) ) { |
2754 preg_match( '%href=["\'](' . preg_quote( set_url_scheme( home_url(), 'https' ) ) . ')%i', $text ) |
3008 if ( in_array( strtolower( wp_parse_url( $atts['href']['value'], PHP_URL_SCHEME ) ), array( 'http', 'https' ), true ) ) { |
2755 ) { |
3009 if ( strtolower( wp_parse_url( $atts['href']['value'], PHP_URL_HOST ) ) === strtolower( wp_parse_url( home_url(), PHP_URL_HOST ) ) ) { |
2756 return "<a $text>"; |
3010 return "<a $text>"; |
3011 } |
|
3012 } |
|
2757 } |
3013 } |
2758 |
3014 |
2759 if ( ! empty( $atts['rel'] ) ) { |
3015 if ( ! empty( $atts['rel'] ) ) { |
2760 $parts = array_map( 'trim', explode( ' ', $atts['rel'] ) ); |
3016 $parts = array_map( 'trim', explode( ' ', $atts['rel']['value'] ) ); |
2761 if ( false === array_search( 'nofollow', $parts ) ) { |
3017 if ( false === array_search( 'nofollow', $parts ) ) { |
2762 $parts[] = 'nofollow'; |
3018 $parts[] = 'nofollow'; |
2763 } |
3019 } |
2764 $rel = implode( ' ', $parts ); |
3020 $rel = implode( ' ', $parts ); |
2765 unset( $atts['rel'] ); |
3021 unset( $atts['rel'] ); |
2766 |
3022 |
2767 $html = ''; |
3023 $html = ''; |
2768 foreach ( $atts as $name => $value ) { |
3024 foreach ( $atts as $name => $value ) { |
2769 $html .= "{$name}=\"$value\" "; |
3025 if ( isset( $value['vless'] ) && 'y' === $value['vless'] ) { |
3026 $html .= $name . ' '; |
|
3027 } else { |
|
3028 $html .= "{$name}=\"" . esc_attr( $value['value'] ) . '" '; |
|
3029 } |
|
2770 } |
3030 } |
2771 $text = trim( $html ); |
3031 $text = trim( $html ); |
2772 } |
3032 } |
2773 return "<a $text rel=\"$rel\">"; |
3033 return "<a $text rel=\"" . esc_attr( $rel ) . '">'; |
3034 } |
|
3035 |
|
3036 /** |
|
3037 * Adds rel noreferrer and noopener to all HTML A elements that have a target. |
|
3038 * |
|
3039 * @since 5.1.0 |
|
3040 * |
|
3041 * @param string $text Content that may contain HTML A elements. |
|
3042 * @return string Converted content. |
|
3043 */ |
|
3044 function wp_targeted_link_rel( $text ) { |
|
3045 // Don't run (more expensive) regex if no links with targets. |
|
3046 if ( stripos( $text, 'target' ) !== false && stripos( $text, '<a ' ) !== false ) { |
|
3047 $text = preg_replace_callback( '|<a\s([^>]*target\s*=[^>]*)>|i', 'wp_targeted_link_rel_callback', $text ); |
|
3048 } |
|
3049 |
|
3050 return $text; |
|
3051 } |
|
3052 |
|
3053 /** |
|
3054 * Callback to add rel="noreferrer noopener" string to HTML A element. |
|
3055 * |
|
3056 * Will not duplicate existing noreferrer and noopener values |
|
3057 * to prevent from invalidating the HTML. |
|
3058 * |
|
3059 * @since 5.1.0 |
|
3060 * |
|
3061 * @param array $matches Single Match |
|
3062 * @return string HTML A Element with rel noreferrer noopener in addition to any existing values |
|
3063 */ |
|
3064 function wp_targeted_link_rel_callback( $matches ) { |
|
3065 $link_html = $matches[1]; |
|
3066 $rel_match = array(); |
|
3067 |
|
3068 /** |
|
3069 * Filters the rel values that are added to links with `target` attribute. |
|
3070 * |
|
3071 * @since 5.1.0 |
|
3072 * |
|
3073 * @param string The rel values. |
|
3074 * @param string $link_html The matched content of the link tag including all HTML attributes. |
|
3075 */ |
|
3076 $rel = apply_filters( 'wp_targeted_link_rel', 'noopener noreferrer', $link_html ); |
|
3077 |
|
3078 // Avoid additional regex if the filter removes rel values. |
|
3079 if ( ! $rel ) { |
|
3080 return "<a $link_html>"; |
|
3081 } |
|
3082 |
|
3083 // Value with delimiters, spaces around are optional. |
|
3084 $attr_regex = '|rel\s*=\s*?(\\\\{0,1}["\'])(.*?)\\1|i'; |
|
3085 preg_match( $attr_regex, $link_html, $rel_match ); |
|
3086 |
|
3087 if ( empty( $rel_match[0] ) ) { |
|
3088 // No delimiters, try with a single value and spaces, because `rel = va"lue` is totally fine... |
|
3089 $attr_regex = '|rel\s*=(\s*)([^\s]*)|i'; |
|
3090 preg_match( $attr_regex, $link_html, $rel_match ); |
|
3091 } |
|
3092 |
|
3093 if ( ! empty( $rel_match[0] ) ) { |
|
3094 $parts = preg_split( '|\s+|', strtolower( $rel_match[2] ) ); |
|
3095 $parts = array_map( 'esc_attr', $parts ); |
|
3096 $needed = explode( ' ', $rel ); |
|
3097 $parts = array_unique( array_merge( $parts, $needed ) ); |
|
3098 $delimiter = trim( $rel_match[1] ) ? $rel_match[1] : '"'; |
|
3099 $rel = 'rel=' . $delimiter . trim( implode( ' ', $parts ) ) . $delimiter; |
|
3100 $link_html = str_replace( $rel_match[0], $rel, $link_html ); |
|
3101 } elseif ( preg_match( '|target\s*=\s*?\\\\"|', $link_html ) ) { |
|
3102 $link_html .= " rel=\\\"$rel\\\""; |
|
3103 } elseif ( preg_match( '#(target|href)\s*=\s*?\'#', $link_html ) ) { |
|
3104 $link_html .= " rel='$rel'"; |
|
3105 } else { |
|
3106 $link_html .= " rel=\"$rel\""; |
|
3107 } |
|
3108 |
|
3109 return "<a $link_html>"; |
|
3110 } |
|
3111 |
|
3112 /** |
|
3113 * Adds all filters modifying the rel attribute of targeted links. |
|
3114 * |
|
3115 * @since 5.1.0 |
|
3116 */ |
|
3117 function wp_init_targeted_link_rel_filters() { |
|
3118 $filters = array( |
|
3119 'title_save_pre', |
|
3120 'content_save_pre', |
|
3121 'excerpt_save_pre', |
|
3122 'content_filtered_save_pre', |
|
3123 'pre_comment_content', |
|
3124 'pre_term_description', |
|
3125 'pre_link_description', |
|
3126 'pre_link_notes', |
|
3127 'pre_user_description', |
|
3128 ); |
|
3129 |
|
3130 foreach ( $filters as $filter ) { |
|
3131 add_filter( $filter, 'wp_targeted_link_rel' ); |
|
3132 }; |
|
3133 } |
|
3134 |
|
3135 /** |
|
3136 * Removes all filters modifying the rel attribute of targeted links. |
|
3137 * |
|
3138 * @since 5.1.0 |
|
3139 */ |
|
3140 function wp_remove_targeted_link_rel_filters() { |
|
3141 $filters = array( |
|
3142 'title_save_pre', |
|
3143 'content_save_pre', |
|
3144 'excerpt_save_pre', |
|
3145 'content_filtered_save_pre', |
|
3146 'pre_comment_content', |
|
3147 'pre_term_description', |
|
3148 'pre_link_description', |
|
3149 'pre_link_notes', |
|
3150 'pre_user_description', |
|
3151 ); |
|
3152 |
|
3153 foreach ( $filters as $filter ) { |
|
3154 remove_filter( $filter, 'wp_targeted_link_rel' ); |
|
3155 }; |
|
2774 } |
3156 } |
2775 |
3157 |
2776 /** |
3158 /** |
2777 * Convert one smiley code to the icon graphic file equivalent. |
3159 * Convert one smiley code to the icon graphic file equivalent. |
2778 * |
3160 * |
2789 * @return string Image string for smiley. |
3171 * @return string Image string for smiley. |
2790 */ |
3172 */ |
2791 function translate_smiley( $matches ) { |
3173 function translate_smiley( $matches ) { |
2792 global $wpsmiliestrans; |
3174 global $wpsmiliestrans; |
2793 |
3175 |
2794 if ( count( $matches ) == 0 ) |
3176 if ( count( $matches ) == 0 ) { |
2795 return ''; |
3177 return ''; |
3178 } |
|
2796 |
3179 |
2797 $smiley = trim( reset( $matches ) ); |
3180 $smiley = trim( reset( $matches ) ); |
2798 $img = $wpsmiliestrans[ $smiley ]; |
3181 $img = $wpsmiliestrans[ $smiley ]; |
2799 |
3182 |
2800 $matches = array(); |
3183 $matches = array(); |
2801 $ext = preg_match( '/\.([^.]+)$/', $img, $matches ) ? strtolower( $matches[1] ) : false; |
3184 $ext = preg_match( '/\.([^.]+)$/', $img, $matches ) ? strtolower( $matches[1] ) : false; |
2802 $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png' ); |
3185 $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png' ); |
2803 |
3186 |
2804 // Don't convert smilies that aren't images - they're probably emoji. |
3187 // Don't convert smilies that aren't images - they're probably emoji. |
2805 if ( ! in_array( $ext, $image_exts ) ) { |
3188 if ( ! in_array( $ext, $image_exts ) ) { |
2806 return $img; |
3189 return $img; |
2837 global $wp_smiliessearch; |
3220 global $wp_smiliessearch; |
2838 $output = ''; |
3221 $output = ''; |
2839 if ( get_option( 'use_smilies' ) && ! empty( $wp_smiliessearch ) ) { |
3222 if ( get_option( 'use_smilies' ) && ! empty( $wp_smiliessearch ) ) { |
2840 // HTML loop taken from texturize function, could possible be consolidated |
3223 // HTML loop taken from texturize function, could possible be consolidated |
2841 $textarr = preg_split( '/(<.*>)/U', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); // capture the tags as well as in between |
3224 $textarr = preg_split( '/(<.*>)/U', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); // capture the tags as well as in between |
2842 $stop = count( $textarr );// loop stuff |
3225 $stop = count( $textarr );// loop stuff |
2843 |
3226 |
2844 // Ignore proessing of specific tags |
3227 // Ignore proessing of specific tags |
2845 $tags_to_ignore = 'code|pre|style|script|textarea'; |
3228 $tags_to_ignore = 'code|pre|style|script|textarea'; |
2846 $ignore_block_element = ''; |
3229 $ignore_block_element = ''; |
2847 |
3230 |
2848 for ( $i = 0; $i < $stop; $i++ ) { |
3231 for ( $i = 0; $i < $stop; $i++ ) { |
2849 $content = $textarr[$i]; |
3232 $content = $textarr[ $i ]; |
2850 |
3233 |
2851 // If we're in an ignore block, wait until we find its closing tag |
3234 // If we're in an ignore block, wait until we find its closing tag |
2852 if ( '' == $ignore_block_element && preg_match( '/^<(' . $tags_to_ignore . ')>/', $content, $matches ) ) { |
3235 if ( '' == $ignore_block_element && preg_match( '/^<(' . $tags_to_ignore . ')[^>]*>/', $content, $matches ) ) { |
2853 $ignore_block_element = $matches[1]; |
3236 $ignore_block_element = $matches[1]; |
2854 } |
3237 } |
2855 |
3238 |
2856 // If it's not a tag and not in ignore block |
3239 // If it's not a tag and not in ignore block |
2857 if ( '' == $ignore_block_element && strlen( $content ) > 0 && '<' != $content[0] ) { |
3240 if ( '' == $ignore_block_element && strlen( $content ) > 0 && '<' != $content[0] ) { |
2858 $content = preg_replace_callback( $wp_smiliessearch, 'translate_smiley', $content ); |
3241 $content = preg_replace_callback( $wp_smiliessearch, 'translate_smiley', $content ); |
2859 } |
3242 } |
2860 |
3243 |
2861 // did we exit ignore block |
3244 // did we exit ignore block |
2862 if ( '' != $ignore_block_element && '</' . $ignore_block_element . '>' == $content ) { |
3245 if ( '' != $ignore_block_element && '</' . $ignore_block_element . '>' == $content ) { |
2863 $ignore_block_element = ''; |
3246 $ignore_block_element = ''; |
2864 } |
3247 } |
2865 |
3248 |
2866 $output .= $content; |
3249 $output .= $content; |
2867 } |
3250 } |
2882 * @param string $email Email address to verify. |
3265 * @param string $email Email address to verify. |
2883 * @param bool $deprecated Deprecated. |
3266 * @param bool $deprecated Deprecated. |
2884 * @return string|bool Either false or the valid email address. |
3267 * @return string|bool Either false or the valid email address. |
2885 */ |
3268 */ |
2886 function is_email( $email, $deprecated = false ) { |
3269 function is_email( $email, $deprecated = false ) { |
2887 if ( ! empty( $deprecated ) ) |
3270 if ( ! empty( $deprecated ) ) { |
2888 _deprecated_argument( __FUNCTION__, '3.0.0' ); |
3271 _deprecated_argument( __FUNCTION__, '3.0.0' ); |
3272 } |
|
2889 |
3273 |
2890 // Test for the minimum length the email can be |
3274 // Test for the minimum length the email can be |
2891 if ( strlen( $email ) < 6 ) { |
3275 if ( strlen( $email ) < 6 ) { |
2892 /** |
3276 /** |
2893 * Filters whether an email address is valid. |
3277 * Filters whether an email address is valid. |
2914 // Split out the local and domain parts |
3298 // Split out the local and domain parts |
2915 list( $local, $domain ) = explode( '@', $email, 2 ); |
3299 list( $local, $domain ) = explode( '@', $email, 2 ); |
2916 |
3300 |
2917 // LOCAL PART |
3301 // LOCAL PART |
2918 // Test for invalid characters |
3302 // Test for invalid characters |
2919 if ( !preg_match( '/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]+$/', $local ) ) { |
3303 if ( ! preg_match( '/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]+$/', $local ) ) { |
2920 /** This filter is documented in wp-includes/formatting.php */ |
3304 /** This filter is documented in wp-includes/formatting.php */ |
2921 return apply_filters( 'is_email', false, $email, 'local_invalid_chars' ); |
3305 return apply_filters( 'is_email', false, $email, 'local_invalid_chars' ); |
2922 } |
3306 } |
2923 |
3307 |
2924 // DOMAIN PART |
3308 // DOMAIN PART |
2950 /** This filter is documented in wp-includes/formatting.php */ |
3334 /** This filter is documented in wp-includes/formatting.php */ |
2951 return apply_filters( 'is_email', false, $email, 'sub_hyphen_limits' ); |
3335 return apply_filters( 'is_email', false, $email, 'sub_hyphen_limits' ); |
2952 } |
3336 } |
2953 |
3337 |
2954 // Test for invalid characters |
3338 // Test for invalid characters |
2955 if ( !preg_match('/^[a-z0-9-]+$/i', $sub ) ) { |
3339 if ( ! preg_match( '/^[a-z0-9-]+$/i', $sub ) ) { |
2956 /** This filter is documented in wp-includes/formatting.php */ |
3340 /** This filter is documented in wp-includes/formatting.php */ |
2957 return apply_filters( 'is_email', false, $email, 'sub_invalid_chars' ); |
3341 return apply_filters( 'is_email', false, $email, 'sub_invalid_chars' ); |
2958 } |
3342 } |
2959 } |
3343 } |
2960 |
3344 |
2971 * @param string $string Subject line |
3355 * @param string $string Subject line |
2972 * @return string Converted string to ASCII |
3356 * @return string Converted string to ASCII |
2973 */ |
3357 */ |
2974 function wp_iso_descrambler( $string ) { |
3358 function wp_iso_descrambler( $string ) { |
2975 /* this may only work with iso-8859-1, I'm afraid */ |
3359 /* this may only work with iso-8859-1, I'm afraid */ |
2976 if (!preg_match('#\=\?(.+)\?Q\?(.+)\?\=#i', $string, $matches)) { |
3360 if ( ! preg_match( '#\=\?(.+)\?Q\?(.+)\?\=#i', $string, $matches ) ) { |
2977 return $string; |
3361 return $string; |
2978 } else { |
3362 } else { |
2979 $subject = str_replace('_', ' ', $matches[2]); |
3363 $subject = str_replace( '_', ' ', $matches[2] ); |
2980 return preg_replace_callback( '#\=([0-9a-f]{2})#i', '_wp_iso_convert', $subject ); |
3364 return preg_replace_callback( '#\=([0-9a-f]{2})#i', '_wp_iso_convert', $subject ); |
2981 } |
3365 } |
2982 } |
3366 } |
2983 |
3367 |
2984 /** |
3368 /** |
3024 return gmdate( $format, 0 ); |
3408 return gmdate( $format, 0 ); |
3025 } |
3409 } |
3026 return gmdate( $format, $datetime ); |
3410 return gmdate( $format, $datetime ); |
3027 } |
3411 } |
3028 $string_time = gmmktime( $matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1] ); |
3412 $string_time = gmmktime( $matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1] ); |
3029 $string_gmt = gmdate( $format, $string_time - get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ); |
3413 $string_gmt = gmdate( $format, $string_time - get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ); |
3030 } |
3414 } |
3031 return $string_gmt; |
3415 return $string_gmt; |
3032 } |
3416 } |
3033 |
3417 |
3034 /** |
3418 /** |
3047 */ |
3431 */ |
3048 function get_date_from_gmt( $string, $format = 'Y-m-d H:i:s' ) { |
3432 function get_date_from_gmt( $string, $format = 'Y-m-d H:i:s' ) { |
3049 $tz = get_option( 'timezone_string' ); |
3433 $tz = get_option( 'timezone_string' ); |
3050 if ( $tz ) { |
3434 if ( $tz ) { |
3051 $datetime = date_create( $string, new DateTimeZone( 'UTC' ) ); |
3435 $datetime = date_create( $string, new DateTimeZone( 'UTC' ) ); |
3052 if ( ! $datetime ) |
3436 if ( ! $datetime ) { |
3053 return date( $format, 0 ); |
3437 return date( $format, 0 ); |
3438 } |
|
3054 $datetime->setTimezone( new DateTimeZone( $tz ) ); |
3439 $datetime->setTimezone( new DateTimeZone( $tz ) ); |
3055 $string_localtime = $datetime->format( $format ); |
3440 $string_localtime = $datetime->format( $format ); |
3056 } else { |
3441 } else { |
3057 if ( ! preg_match('#([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})#', $string, $matches) ) |
3442 if ( ! preg_match( '#([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})#', $string, $matches ) ) { |
3058 return date( $format, 0 ); |
3443 return date( $format, 0 ); |
3059 $string_time = gmmktime( $matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1] ); |
3444 } |
3445 $string_time = gmmktime( $matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1] ); |
|
3060 $string_localtime = gmdate( $format, $string_time + get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ); |
3446 $string_localtime = gmdate( $format, $string_time + get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ); |
3061 } |
3447 } |
3062 return $string_localtime; |
3448 return $string_localtime; |
3063 } |
3449 } |
3064 |
3450 |
3070 * @param string $timezone Either 'Z' for 0 offset or '±hhmm'. |
3456 * @param string $timezone Either 'Z' for 0 offset or '±hhmm'. |
3071 * @return int|float The offset in seconds. |
3457 * @return int|float The offset in seconds. |
3072 */ |
3458 */ |
3073 function iso8601_timezone_to_offset( $timezone ) { |
3459 function iso8601_timezone_to_offset( $timezone ) { |
3074 // $timezone is either 'Z' or '[+|-]hhmm' |
3460 // $timezone is either 'Z' or '[+|-]hhmm' |
3075 if ($timezone == 'Z') { |
3461 if ( $timezone == 'Z' ) { |
3076 $offset = 0; |
3462 $offset = 0; |
3077 } else { |
3463 } else { |
3078 $sign = (substr($timezone, 0, 1) == '+') ? 1 : -1; |
3464 $sign = ( substr( $timezone, 0, 1 ) == '+' ) ? 1 : -1; |
3079 $hours = intval(substr($timezone, 1, 2)); |
3465 $hours = intval( substr( $timezone, 1, 2 ) ); |
3080 $minutes = intval(substr($timezone, 3, 4)) / 60; |
3466 $minutes = intval( substr( $timezone, 3, 4 ) ) / 60; |
3081 $offset = $sign * HOUR_IN_SECONDS * ($hours + $minutes); |
3467 $offset = $sign * HOUR_IN_SECONDS * ( $hours + $minutes ); |
3082 } |
3468 } |
3083 return $offset; |
3469 return $offset; |
3084 } |
3470 } |
3085 |
3471 |
3086 /** |
3472 /** |
3091 * @param string $date_string Date and time in ISO 8601 format {@link https://en.wikipedia.org/wiki/ISO_8601}. |
3477 * @param string $date_string Date and time in ISO 8601 format {@link https://en.wikipedia.org/wiki/ISO_8601}. |
3092 * @param string $timezone Optional. If set to GMT returns the time minus gmt_offset. Default is 'user'. |
3478 * @param string $timezone Optional. If set to GMT returns the time minus gmt_offset. Default is 'user'. |
3093 * @return string The date and time in MySQL DateTime format - Y-m-d H:i:s. |
3479 * @return string The date and time in MySQL DateTime format - Y-m-d H:i:s. |
3094 */ |
3480 */ |
3095 function iso8601_to_datetime( $date_string, $timezone = 'user' ) { |
3481 function iso8601_to_datetime( $date_string, $timezone = 'user' ) { |
3096 $timezone = strtolower($timezone); |
3482 $timezone = strtolower( $timezone ); |
3097 |
3483 |
3098 if ($timezone == 'gmt') { |
3484 if ( $timezone == 'gmt' ) { |
3099 |
3485 |
3100 preg_match('#([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(Z|[\+|\-][0-9]{2,4}){0,1}#', $date_string, $date_bits); |
3486 preg_match( '#([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(Z|[\+|\-][0-9]{2,4}){0,1}#', $date_string, $date_bits ); |
3101 |
3487 |
3102 if (!empty($date_bits[7])) { // we have a timezone, so let's compute an offset |
3488 if ( ! empty( $date_bits[7] ) ) { // we have a timezone, so let's compute an offset |
3103 $offset = iso8601_timezone_to_offset($date_bits[7]); |
3489 $offset = iso8601_timezone_to_offset( $date_bits[7] ); |
3104 } else { // we don't have a timezone, so we assume user local timezone (not server's!) |
3490 } else { // we don't have a timezone, so we assume user local timezone (not server's!) |
3105 $offset = HOUR_IN_SECONDS * get_option('gmt_offset'); |
3491 $offset = HOUR_IN_SECONDS * get_option( 'gmt_offset' ); |
3106 } |
3492 } |
3107 |
3493 |
3108 $timestamp = gmmktime($date_bits[4], $date_bits[5], $date_bits[6], $date_bits[2], $date_bits[3], $date_bits[1]); |
3494 $timestamp = gmmktime( $date_bits[4], $date_bits[5], $date_bits[6], $date_bits[2], $date_bits[3], $date_bits[1] ); |
3109 $timestamp -= $offset; |
3495 $timestamp -= $offset; |
3110 |
3496 |
3111 return gmdate('Y-m-d H:i:s', $timestamp); |
3497 return gmdate( 'Y-m-d H:i:s', $timestamp ); |
3112 |
3498 |
3113 } elseif ($timezone == 'user') { |
3499 } elseif ( $timezone == 'user' ) { |
3114 return preg_replace('#([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(Z|[\+|\-][0-9]{2,4}){0,1}#', '$1-$2-$3 $4:$5:$6', $date_string); |
3500 return preg_replace( '#([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(Z|[\+|\-][0-9]{2,4}){0,1}#', '$1-$2-$3 $4:$5:$6', $date_string ); |
3115 } |
3501 } |
3116 } |
3502 } |
3117 |
3503 |
3118 /** |
3504 /** |
3119 * Strips out all characters that are not allowable in an email. |
3505 * Strips out all characters that are not allowable in an email. |
3133 * 'email_no_at', 'local_invalid_chars', 'domain_period_sequence', 'domain_period_limits', |
3519 * 'email_no_at', 'local_invalid_chars', 'domain_period_sequence', 'domain_period_limits', |
3134 * 'domain_no_periods', 'domain_no_valid_subs', or no context. |
3520 * 'domain_no_periods', 'domain_no_valid_subs', or no context. |
3135 * |
3521 * |
3136 * @since 2.8.0 |
3522 * @since 2.8.0 |
3137 * |
3523 * |
3138 * @param string $email The sanitized email address. |
3524 * @param string $sanitized_email The sanitized email address. |
3139 * @param string $email The email address, as provided to sanitize_email(). |
3525 * @param string $email The email address, as provided to sanitize_email(). |
3140 * @param string $message A message to pass to the user. |
3526 * @param string|null $message A message to pass to the user. null if email is sanitized. |
3141 */ |
3527 */ |
3142 return apply_filters( 'sanitize_email', '', $email, 'email_too_short' ); |
3528 return apply_filters( 'sanitize_email', '', $email, 'email_too_short' ); |
3143 } |
3529 } |
3144 |
3530 |
3145 // Test for an @ character after the first position |
3531 // Test for an @ character after the first position |
3208 |
3594 |
3209 // Join valid subs into the new domain |
3595 // Join valid subs into the new domain |
3210 $domain = join( '.', $new_subs ); |
3596 $domain = join( '.', $new_subs ); |
3211 |
3597 |
3212 // Put the email back together |
3598 // Put the email back together |
3213 $email = $local . '@' . $domain; |
3599 $sanitized_email = $local . '@' . $domain; |
3214 |
3600 |
3215 // Congratulations your email made it! |
3601 // Congratulations your email made it! |
3216 /** This filter is documented in wp-includes/formatting.php */ |
3602 /** This filter is documented in wp-includes/formatting.php */ |
3217 return apply_filters( 'sanitize_email', $email, $email, null ); |
3603 return apply_filters( 'sanitize_email', $sanitized_email, $email, null ); |
3218 } |
3604 } |
3219 |
3605 |
3220 /** |
3606 /** |
3221 * Determines the difference between two timestamps. |
3607 * Determines the difference between two timestamps. |
3222 * |
3608 * |
3236 |
3622 |
3237 $diff = (int) abs( $to - $from ); |
3623 $diff = (int) abs( $to - $from ); |
3238 |
3624 |
3239 if ( $diff < HOUR_IN_SECONDS ) { |
3625 if ( $diff < HOUR_IN_SECONDS ) { |
3240 $mins = round( $diff / MINUTE_IN_SECONDS ); |
3626 $mins = round( $diff / MINUTE_IN_SECONDS ); |
3241 if ( $mins <= 1 ) |
3627 if ( $mins <= 1 ) { |
3242 $mins = 1; |
3628 $mins = 1; |
3243 /* translators: Time difference between two dates, in minutes (min=minute). 1: Number of minutes */ |
3629 } |
3630 /* translators: Time difference between two dates, in minutes (min=minute). %s: Number of minutes */ |
|
3244 $since = sprintf( _n( '%s min', '%s mins', $mins ), $mins ); |
3631 $since = sprintf( _n( '%s min', '%s mins', $mins ), $mins ); |
3245 } elseif ( $diff < DAY_IN_SECONDS && $diff >= HOUR_IN_SECONDS ) { |
3632 } elseif ( $diff < DAY_IN_SECONDS && $diff >= HOUR_IN_SECONDS ) { |
3246 $hours = round( $diff / HOUR_IN_SECONDS ); |
3633 $hours = round( $diff / HOUR_IN_SECONDS ); |
3247 if ( $hours <= 1 ) |
3634 if ( $hours <= 1 ) { |
3248 $hours = 1; |
3635 $hours = 1; |
3249 /* translators: Time difference between two dates, in hours. 1: Number of hours */ |
3636 } |
3637 /* translators: Time difference between two dates, in hours. %s: Number of hours */ |
|
3250 $since = sprintf( _n( '%s hour', '%s hours', $hours ), $hours ); |
3638 $since = sprintf( _n( '%s hour', '%s hours', $hours ), $hours ); |
3251 } elseif ( $diff < WEEK_IN_SECONDS && $diff >= DAY_IN_SECONDS ) { |
3639 } elseif ( $diff < WEEK_IN_SECONDS && $diff >= DAY_IN_SECONDS ) { |
3252 $days = round( $diff / DAY_IN_SECONDS ); |
3640 $days = round( $diff / DAY_IN_SECONDS ); |
3253 if ( $days <= 1 ) |
3641 if ( $days <= 1 ) { |
3254 $days = 1; |
3642 $days = 1; |
3255 /* translators: Time difference between two dates, in days. 1: Number of days */ |
3643 } |
3644 /* translators: Time difference between two dates, in days. %s: Number of days */ |
|
3256 $since = sprintf( _n( '%s day', '%s days', $days ), $days ); |
3645 $since = sprintf( _n( '%s day', '%s days', $days ), $days ); |
3257 } elseif ( $diff < MONTH_IN_SECONDS && $diff >= WEEK_IN_SECONDS ) { |
3646 } elseif ( $diff < MONTH_IN_SECONDS && $diff >= WEEK_IN_SECONDS ) { |
3258 $weeks = round( $diff / WEEK_IN_SECONDS ); |
3647 $weeks = round( $diff / WEEK_IN_SECONDS ); |
3259 if ( $weeks <= 1 ) |
3648 if ( $weeks <= 1 ) { |
3260 $weeks = 1; |
3649 $weeks = 1; |
3261 /* translators: Time difference between two dates, in weeks. 1: Number of weeks */ |
3650 } |
3651 /* translators: Time difference between two dates, in weeks. %s: Number of weeks */ |
|
3262 $since = sprintf( _n( '%s week', '%s weeks', $weeks ), $weeks ); |
3652 $since = sprintf( _n( '%s week', '%s weeks', $weeks ), $weeks ); |
3263 } elseif ( $diff < YEAR_IN_SECONDS && $diff >= MONTH_IN_SECONDS ) { |
3653 } elseif ( $diff < YEAR_IN_SECONDS && $diff >= MONTH_IN_SECONDS ) { |
3264 $months = round( $diff / MONTH_IN_SECONDS ); |
3654 $months = round( $diff / MONTH_IN_SECONDS ); |
3265 if ( $months <= 1 ) |
3655 if ( $months <= 1 ) { |
3266 $months = 1; |
3656 $months = 1; |
3267 /* translators: Time difference between two dates, in months. 1: Number of months */ |
3657 } |
3658 /* translators: Time difference between two dates, in months. %s: Number of months */ |
|
3268 $since = sprintf( _n( '%s month', '%s months', $months ), $months ); |
3659 $since = sprintf( _n( '%s month', '%s months', $months ), $months ); |
3269 } elseif ( $diff >= YEAR_IN_SECONDS ) { |
3660 } elseif ( $diff >= YEAR_IN_SECONDS ) { |
3270 $years = round( $diff / YEAR_IN_SECONDS ); |
3661 $years = round( $diff / YEAR_IN_SECONDS ); |
3271 if ( $years <= 1 ) |
3662 if ( $years <= 1 ) { |
3272 $years = 1; |
3663 $years = 1; |
3273 /* translators: Time difference between two dates, in years. 1: Number of years */ |
3664 } |
3665 /* translators: Time difference between two dates, in years. %s: Number of years */ |
|
3274 $since = sprintf( _n( '%s year', '%s years', $years ), $years ); |
3666 $since = sprintf( _n( '%s year', '%s years', $years ), $years ); |
3275 } |
3667 } |
3276 |
3668 |
3277 /** |
3669 /** |
3278 * Filters the human readable difference between two timestamps. |
3670 * Filters the human readable difference between two timestamps. |
3296 * |
3688 * |
3297 * The 55 word limit can be modified by plugins/themes using the {@see 'excerpt_length'} filter |
3689 * The 55 word limit can be modified by plugins/themes using the {@see 'excerpt_length'} filter |
3298 * The ' […]' string can be modified by plugins/themes using the {@see 'excerpt_more'} filter |
3690 * The ' […]' string can be modified by plugins/themes using the {@see 'excerpt_more'} filter |
3299 * |
3691 * |
3300 * @since 1.5.0 |
3692 * @since 1.5.0 |
3301 * |
3693 * @since 5.2.0 Added the `$post` parameter. |
3302 * @param string $text Optional. The excerpt. If set to empty, an excerpt is generated. |
3694 * |
3695 * @param string $text Optional. The excerpt. If set to empty, an excerpt is generated. |
|
3696 * @param WP_Post|object|int $post Optional. WP_Post instance or Post ID/object. Default is null. |
|
3303 * @return string The excerpt. |
3697 * @return string The excerpt. |
3304 */ |
3698 */ |
3305 function wp_trim_excerpt( $text = '' ) { |
3699 function wp_trim_excerpt( $text = '', $post = null ) { |
3306 $raw_excerpt = $text; |
3700 $raw_excerpt = $text; |
3307 if ( '' == $text ) { |
3701 if ( '' == $text ) { |
3308 $text = get_the_content(''); |
3702 $post = get_post( $post ); |
3703 $text = get_the_content( '', false, $post ); |
|
3309 |
3704 |
3310 $text = strip_shortcodes( $text ); |
3705 $text = strip_shortcodes( $text ); |
3706 $text = excerpt_remove_blocks( $text ); |
|
3311 |
3707 |
3312 /** This filter is documented in wp-includes/post-template.php */ |
3708 /** This filter is documented in wp-includes/post-template.php */ |
3313 $text = apply_filters( 'the_content', $text ); |
3709 $text = apply_filters( 'the_content', $text ); |
3314 $text = str_replace(']]>', ']]>', $text); |
3710 $text = str_replace( ']]>', ']]>', $text ); |
3315 |
3711 |
3316 /** |
3712 /** |
3317 * Filters the number of words in an excerpt. |
3713 * Filters the number of words in an excerpt. |
3318 * |
3714 * |
3319 * @since 2.7.0 |
3715 * @since 2.7.0 |
3327 * @since 2.9.0 |
3723 * @since 2.9.0 |
3328 * |
3724 * |
3329 * @param string $more_string The string shown within the more link. |
3725 * @param string $more_string The string shown within the more link. |
3330 */ |
3726 */ |
3331 $excerpt_more = apply_filters( 'excerpt_more', ' ' . '[…]' ); |
3727 $excerpt_more = apply_filters( 'excerpt_more', ' ' . '[…]' ); |
3332 $text = wp_trim_words( $text, $excerpt_length, $excerpt_more ); |
3728 $text = wp_trim_words( $text, $excerpt_length, $excerpt_more ); |
3333 } |
3729 } |
3334 /** |
3730 /** |
3335 * Filters the trimmed excerpt string. |
3731 * Filters the trimmed excerpt string. |
3336 * |
3732 * |
3337 * @since 2.8.0 |
3733 * @since 2.8.0 |
3360 if ( null === $more ) { |
3756 if ( null === $more ) { |
3361 $more = __( '…' ); |
3757 $more = __( '…' ); |
3362 } |
3758 } |
3363 |
3759 |
3364 $original_text = $text; |
3760 $original_text = $text; |
3365 $text = wp_strip_all_tags( $text ); |
3761 $text = wp_strip_all_tags( $text ); |
3366 |
3762 |
3367 /* |
3763 /* |
3368 * translators: If your word count is based on single characters (e.g. East Asian characters), |
3764 * translators: If your word count is based on single characters (e.g. East Asian characters), |
3369 * enter 'characters_excluding_spaces' or 'characters_including_spaces'. Otherwise, enter 'words'. |
3765 * enter 'characters_excluding_spaces' or 'characters_including_spaces'. Otherwise, enter 'words'. |
3370 * Do not translate into your own language. |
3766 * Do not translate into your own language. |
3371 */ |
3767 */ |
3372 if ( strpos( _x( 'words', 'Word count type. Do not translate!' ), 'characters' ) === 0 && preg_match( '/^utf\-?8$/i', get_option( 'blog_charset' ) ) ) { |
3768 if ( strpos( _x( 'words', 'Word count type. Do not translate!' ), 'characters' ) === 0 && preg_match( '/^utf\-?8$/i', get_option( 'blog_charset' ) ) ) { |
3373 $text = trim( preg_replace( "/[\n\r\t ]+/", ' ', $text ), ' ' ); |
3769 $text = trim( preg_replace( "/[\n\r\t ]+/", ' ', $text ), ' ' ); |
3374 preg_match_all( '/./u', $text, $words_array ); |
3770 preg_match_all( '/./u', $text, $words_array ); |
3375 $words_array = array_slice( $words_array[0], 0, $num_words + 1 ); |
3771 $words_array = array_slice( $words_array[0], 0, $num_words + 1 ); |
3376 $sep = ''; |
3772 $sep = ''; |
3377 } else { |
3773 } else { |
3378 $words_array = preg_split( "/[\n\r\t ]+/", $text, $num_words + 1, PREG_SPLIT_NO_EMPTY ); |
3774 $words_array = preg_split( "/[\n\r\t ]+/", $text, $num_words + 1, PREG_SPLIT_NO_EMPTY ); |
3379 $sep = ' '; |
3775 $sep = ' '; |
3380 } |
3776 } |
3381 |
3777 |
3382 if ( count( $words_array ) > $num_words ) { |
3778 if ( count( $words_array ) > $num_words ) { |
3383 array_pop( $words_array ); |
3779 array_pop( $words_array ); |
3384 $text = implode( $sep, $words_array ); |
3780 $text = implode( $sep, $words_array ); |
3419 * |
3815 * |
3420 * @param null $converted_text The text to be converted. Default null. |
3816 * @param null $converted_text The text to be converted. Default null. |
3421 * @param string $text The text prior to entity conversion. |
3817 * @param string $text The text prior to entity conversion. |
3422 */ |
3818 */ |
3423 $filtered = apply_filters( 'pre_ent2ncr', null, $text ); |
3819 $filtered = apply_filters( 'pre_ent2ncr', null, $text ); |
3424 if ( null !== $filtered ) |
3820 if ( null !== $filtered ) { |
3425 return $filtered; |
3821 return $filtered; |
3822 } |
|
3426 |
3823 |
3427 $to_ncr = array( |
3824 $to_ncr = array( |
3428 '"' => '"', |
3825 '"' => '"', |
3429 '&' => '&', |
3826 '&' => '&', |
3430 '<' => '<', |
3827 '<' => '<', |
3431 '>' => '>', |
3828 '>' => '>', |
3432 '|' => '|', |
3829 '|' => '|', |
3433 ' ' => ' ', |
3830 ' ' => ' ', |
3434 '¡' => '¡', |
3831 '¡' => '¡', |
3435 '¢' => '¢', |
3832 '¢' => '¢', |
3436 '£' => '£', |
3833 '£' => '£', |
3437 '¤' => '¤', |
3834 '¤' => '¤', |
3438 '¥' => '¥', |
3835 '¥' => '¥', |
3439 '¦' => '¦', |
3836 '¦' => '¦', |
3440 '&brkbar;' => '¦', |
3837 '&brkbar;' => '¦', |
3441 '§' => '§', |
3838 '§' => '§', |
3442 '¨' => '¨', |
3839 '¨' => '¨', |
3443 '¨' => '¨', |
3840 '¨' => '¨', |
3444 '©' => '©', |
3841 '©' => '©', |
3445 'ª' => 'ª', |
3842 'ª' => 'ª', |
3446 '«' => '«', |
3843 '«' => '«', |
3447 '¬' => '¬', |
3844 '¬' => '¬', |
3448 '­' => '­', |
3845 '­' => '­', |
3449 '®' => '®', |
3846 '®' => '®', |
3450 '¯' => '¯', |
3847 '¯' => '¯', |
3451 '&hibar;' => '¯', |
3848 '&hibar;' => '¯', |
3452 '°' => '°', |
3849 '°' => '°', |
3453 '±' => '±', |
3850 '±' => '±', |
3454 '²' => '²', |
3851 '²' => '²', |
3455 '³' => '³', |
3852 '³' => '³', |
3456 '´' => '´', |
3853 '´' => '´', |
3457 'µ' => 'µ', |
3854 'µ' => 'µ', |
3458 '¶' => '¶', |
3855 '¶' => '¶', |
3459 '·' => '·', |
3856 '·' => '·', |
3460 '¸' => '¸', |
3857 '¸' => '¸', |
3461 '¹' => '¹', |
3858 '¹' => '¹', |
3462 'º' => 'º', |
3859 'º' => 'º', |
3463 '»' => '»', |
3860 '»' => '»', |
3464 '¼' => '¼', |
3861 '¼' => '¼', |
3465 '½' => '½', |
3862 '½' => '½', |
3466 '¾' => '¾', |
3863 '¾' => '¾', |
3467 '¿' => '¿', |
3864 '¿' => '¿', |
3468 'À' => 'À', |
3865 'À' => 'À', |
3469 'Á' => 'Á', |
3866 'Á' => 'Á', |
3470 'Â' => 'Â', |
3867 'Â' => 'Â', |
3471 'Ã' => 'Ã', |
3868 'Ã' => 'Ã', |
3472 'Ä' => 'Ä', |
3869 'Ä' => 'Ä', |
3473 'Å' => 'Å', |
3870 'Å' => 'Å', |
3474 'Æ' => 'Æ', |
3871 'Æ' => 'Æ', |
3475 'Ç' => 'Ç', |
3872 'Ç' => 'Ç', |
3476 'È' => 'È', |
3873 'È' => 'È', |
3477 'É' => 'É', |
3874 'É' => 'É', |
3478 'Ê' => 'Ê', |
3875 'Ê' => 'Ê', |
3479 'Ë' => 'Ë', |
3876 'Ë' => 'Ë', |
3480 'Ì' => 'Ì', |
3877 'Ì' => 'Ì', |
3481 'Í' => 'Í', |
3878 'Í' => 'Í', |
3482 'Î' => 'Î', |
3879 'Î' => 'Î', |
3483 'Ï' => 'Ï', |
3880 'Ï' => 'Ï', |
3484 'Ð' => 'Ð', |
3881 'Ð' => 'Ð', |
3485 'Ñ' => 'Ñ', |
3882 'Ñ' => 'Ñ', |
3486 'Ò' => 'Ò', |
3883 'Ò' => 'Ò', |
3487 'Ó' => 'Ó', |
3884 'Ó' => 'Ó', |
3488 'Ô' => 'Ô', |
3885 'Ô' => 'Ô', |
3489 'Õ' => 'Õ', |
3886 'Õ' => 'Õ', |
3490 'Ö' => 'Ö', |
3887 'Ö' => 'Ö', |
3491 '×' => '×', |
3888 '×' => '×', |
3492 'Ø' => 'Ø', |
3889 'Ø' => 'Ø', |
3493 'Ù' => 'Ù', |
3890 'Ù' => 'Ù', |
3494 'Ú' => 'Ú', |
3891 'Ú' => 'Ú', |
3495 'Û' => 'Û', |
3892 'Û' => 'Û', |
3496 'Ü' => 'Ü', |
3893 'Ü' => 'Ü', |
3497 'Ý' => 'Ý', |
3894 'Ý' => 'Ý', |
3498 'Þ' => 'Þ', |
3895 'Þ' => 'Þ', |
3499 'ß' => 'ß', |
3896 'ß' => 'ß', |
3500 'à' => 'à', |
3897 'à' => 'à', |
3501 'á' => 'á', |
3898 'á' => 'á', |
3502 'â' => 'â', |
3899 'â' => 'â', |
3503 'ã' => 'ã', |
3900 'ã' => 'ã', |
3504 'ä' => 'ä', |
3901 'ä' => 'ä', |
3505 'å' => 'å', |
3902 'å' => 'å', |
3506 'æ' => 'æ', |
3903 'æ' => 'æ', |
3507 'ç' => 'ç', |
3904 'ç' => 'ç', |
3508 'è' => 'è', |
3905 'è' => 'è', |
3509 'é' => 'é', |
3906 'é' => 'é', |
3510 'ê' => 'ê', |
3907 'ê' => 'ê', |
3511 'ë' => 'ë', |
3908 'ë' => 'ë', |
3512 'ì' => 'ì', |
3909 'ì' => 'ì', |
3513 'í' => 'í', |
3910 'í' => 'í', |
3514 'î' => 'î', |
3911 'î' => 'î', |
3515 'ï' => 'ï', |
3912 'ï' => 'ï', |
3516 'ð' => 'ð', |
3913 'ð' => 'ð', |
3517 'ñ' => 'ñ', |
3914 'ñ' => 'ñ', |
3518 'ò' => 'ò', |
3915 'ò' => 'ò', |
3519 'ó' => 'ó', |
3916 'ó' => 'ó', |
3520 'ô' => 'ô', |
3917 'ô' => 'ô', |
3521 'õ' => 'õ', |
3918 'õ' => 'õ', |
3522 'ö' => 'ö', |
3919 'ö' => 'ö', |
3523 '÷' => '÷', |
3920 '÷' => '÷', |
3524 'ø' => 'ø', |
3921 'ø' => 'ø', |
3525 'ù' => 'ù', |
3922 'ù' => 'ù', |
3526 'ú' => 'ú', |
3923 'ú' => 'ú', |
3527 'û' => 'û', |
3924 'û' => 'û', |
3528 'ü' => 'ü', |
3925 'ü' => 'ü', |
3529 'ý' => 'ý', |
3926 'ý' => 'ý', |
3530 'þ' => 'þ', |
3927 'þ' => 'þ', |
3531 'ÿ' => 'ÿ', |
3928 'ÿ' => 'ÿ', |
3532 'Œ' => 'Œ', |
3929 'Œ' => 'Œ', |
3533 'œ' => 'œ', |
3930 'œ' => 'œ', |
3534 'Š' => 'Š', |
3931 'Š' => 'Š', |
3535 'š' => 'š', |
3932 'š' => 'š', |
3536 'Ÿ' => 'Ÿ', |
3933 'Ÿ' => 'Ÿ', |
3537 'ƒ' => 'ƒ', |
3934 'ƒ' => 'ƒ', |
3538 'ˆ' => 'ˆ', |
3935 'ˆ' => 'ˆ', |
3539 '˜' => '˜', |
3936 '˜' => '˜', |
3540 'Α' => 'Α', |
3937 'Α' => 'Α', |
3541 'Β' => 'Β', |
3938 'Β' => 'Β', |
3542 'Γ' => 'Γ', |
3939 'Γ' => 'Γ', |
3543 'Δ' => 'Δ', |
3940 'Δ' => 'Δ', |
3544 'Ε' => 'Ε', |
3941 'Ε' => 'Ε', |
3545 'Ζ' => 'Ζ', |
3942 'Ζ' => 'Ζ', |
3546 'Η' => 'Η', |
3943 'Η' => 'Η', |
3547 'Θ' => 'Θ', |
3944 'Θ' => 'Θ', |
3548 'Ι' => 'Ι', |
3945 'Ι' => 'Ι', |
3549 'Κ' => 'Κ', |
3946 'Κ' => 'Κ', |
3550 'Λ' => 'Λ', |
3947 'Λ' => 'Λ', |
3551 'Μ' => 'Μ', |
3948 'Μ' => 'Μ', |
3552 'Ν' => 'Ν', |
3949 'Ν' => 'Ν', |
3553 'Ξ' => 'Ξ', |
3950 'Ξ' => 'Ξ', |
3554 'Ο' => 'Ο', |
3951 'Ο' => 'Ο', |
3555 'Π' => 'Π', |
3952 'Π' => 'Π', |
3556 'Ρ' => 'Ρ', |
3953 'Ρ' => 'Ρ', |
3557 'Σ' => 'Σ', |
3954 'Σ' => 'Σ', |
3558 'Τ' => 'Τ', |
3955 'Τ' => 'Τ', |
3559 'Υ' => 'Υ', |
3956 'Υ' => 'Υ', |
3560 'Φ' => 'Φ', |
3957 'Φ' => 'Φ', |
3561 'Χ' => 'Χ', |
3958 'Χ' => 'Χ', |
3562 'Ψ' => 'Ψ', |
3959 'Ψ' => 'Ψ', |
3563 'Ω' => 'Ω', |
3960 'Ω' => 'Ω', |
3564 'α' => 'α', |
3961 'α' => 'α', |
3565 'β' => 'β', |
3962 'β' => 'β', |
3566 'γ' => 'γ', |
3963 'γ' => 'γ', |
3567 'δ' => 'δ', |
3964 'δ' => 'δ', |
3568 'ε' => 'ε', |
3965 'ε' => 'ε', |
3569 'ζ' => 'ζ', |
3966 'ζ' => 'ζ', |
3570 'η' => 'η', |
3967 'η' => 'η', |
3571 'θ' => 'θ', |
3968 'θ' => 'θ', |
3572 'ι' => 'ι', |
3969 'ι' => 'ι', |
3573 'κ' => 'κ', |
3970 'κ' => 'κ', |
3574 'λ' => 'λ', |
3971 'λ' => 'λ', |
3575 'μ' => 'μ', |
3972 'μ' => 'μ', |
3576 'ν' => 'ν', |
3973 'ν' => 'ν', |
3577 'ξ' => 'ξ', |
3974 'ξ' => 'ξ', |
3578 'ο' => 'ο', |
3975 'ο' => 'ο', |
3579 'π' => 'π', |
3976 'π' => 'π', |
3580 'ρ' => 'ρ', |
3977 'ρ' => 'ρ', |
3581 'ς' => 'ς', |
3978 'ς' => 'ς', |
3582 'σ' => 'σ', |
3979 'σ' => 'σ', |
3583 'τ' => 'τ', |
3980 'τ' => 'τ', |
3584 'υ' => 'υ', |
3981 'υ' => 'υ', |
3585 'φ' => 'φ', |
3982 'φ' => 'φ', |
3586 'χ' => 'χ', |
3983 'χ' => 'χ', |
3587 'ψ' => 'ψ', |
3984 'ψ' => 'ψ', |
3588 'ω' => 'ω', |
3985 'ω' => 'ω', |
3589 'ϑ' => 'ϑ', |
3986 'ϑ' => 'ϑ', |
3590 'ϒ' => 'ϒ', |
3987 'ϒ' => 'ϒ', |
3591 'ϖ' => 'ϖ', |
3988 'ϖ' => 'ϖ', |
3592 ' ' => ' ', |
3989 ' ' => ' ', |
3593 ' ' => ' ', |
3990 ' ' => ' ', |
3594 ' ' => ' ', |
3991 ' ' => ' ', |
3595 '‌' => '‌', |
3992 '‌' => '‌', |
3596 '‍' => '‍', |
3993 '‍' => '‍', |
3597 '‎' => '‎', |
3994 '‎' => '‎', |
3598 '‏' => '‏', |
3995 '‏' => '‏', |
3599 '–' => '–', |
3996 '–' => '–', |
3600 '—' => '—', |
3997 '—' => '—', |
3601 '‘' => '‘', |
3998 '‘' => '‘', |
3602 '’' => '’', |
3999 '’' => '’', |
3603 '‚' => '‚', |
4000 '‚' => '‚', |
3604 '“' => '“', |
4001 '“' => '“', |
3605 '”' => '”', |
4002 '”' => '”', |
3606 '„' => '„', |
4003 '„' => '„', |
3607 '†' => '†', |
4004 '†' => '†', |
3608 '‡' => '‡', |
4005 '‡' => '‡', |
3609 '•' => '•', |
4006 '•' => '•', |
3610 '…' => '…', |
4007 '…' => '…', |
3611 '‰' => '‰', |
4008 '‰' => '‰', |
3612 '′' => '′', |
4009 '′' => '′', |
3613 '″' => '″', |
4010 '″' => '″', |
3614 '‹' => '‹', |
4011 '‹' => '‹', |
3615 '›' => '›', |
4012 '›' => '›', |
3616 '‾' => '‾', |
4013 '‾' => '‾', |
3617 '⁄' => '⁄', |
4014 '⁄' => '⁄', |
3618 '€' => '€', |
4015 '€' => '€', |
3619 'ℑ' => 'ℑ', |
4016 'ℑ' => 'ℑ', |
3620 '℘' => '℘', |
4017 '℘' => '℘', |
3621 'ℜ' => 'ℜ', |
4018 'ℜ' => 'ℜ', |
3622 '™' => '™', |
4019 '™' => '™', |
3623 'ℵ' => 'ℵ', |
4020 'ℵ' => 'ℵ', |
3624 '↵' => '↵', |
4021 '↵' => '↵', |
3625 '⇐' => '⇐', |
4022 '⇐' => '⇐', |
3626 '⇑' => '⇑', |
4023 '⇑' => '⇑', |
3627 '⇒' => '⇒', |
4024 '⇒' => '⇒', |
3628 '⇓' => '⇓', |
4025 '⇓' => '⇓', |
3629 '⇔' => '⇔', |
4026 '⇔' => '⇔', |
3630 '∀' => '∀', |
4027 '∀' => '∀', |
3631 '∂' => '∂', |
4028 '∂' => '∂', |
3632 '∃' => '∃', |
4029 '∃' => '∃', |
3633 '∅' => '∅', |
4030 '∅' => '∅', |
3634 '∇' => '∇', |
4031 '∇' => '∇', |
3635 '∈' => '∈', |
4032 '∈' => '∈', |
3636 '∉' => '∉', |
4033 '∉' => '∉', |
3637 '∋' => '∋', |
4034 '∋' => '∋', |
3638 '∏' => '∏', |
4035 '∏' => '∏', |
3639 '∑' => '∑', |
4036 '∑' => '∑', |
3640 '−' => '−', |
4037 '−' => '−', |
3641 '∗' => '∗', |
4038 '∗' => '∗', |
3642 '√' => '√', |
4039 '√' => '√', |
3643 '∝' => '∝', |
4040 '∝' => '∝', |
3644 '∞' => '∞', |
4041 '∞' => '∞', |
3645 '∠' => '∠', |
4042 '∠' => '∠', |
3646 '∧' => '∧', |
4043 '∧' => '∧', |
3647 '∨' => '∨', |
4044 '∨' => '∨', |
3648 '∩' => '∩', |
4045 '∩' => '∩', |
3649 '∪' => '∪', |
4046 '∪' => '∪', |
3650 '∫' => '∫', |
4047 '∫' => '∫', |
3651 '∴' => '∴', |
4048 '∴' => '∴', |
3652 '∼' => '∼', |
4049 '∼' => '∼', |
3653 '≅' => '≅', |
4050 '≅' => '≅', |
3654 '≈' => '≈', |
4051 '≈' => '≈', |
3655 '≠' => '≠', |
4052 '≠' => '≠', |
3656 '≡' => '≡', |
4053 '≡' => '≡', |
3657 '≤' => '≤', |
4054 '≤' => '≤', |
3658 '≥' => '≥', |
4055 '≥' => '≥', |
3659 '⊂' => '⊂', |
4056 '⊂' => '⊂', |
3660 '⊃' => '⊃', |
4057 '⊃' => '⊃', |
3661 '⊄' => '⊄', |
4058 '⊄' => '⊄', |
3662 '⊆' => '⊆', |
4059 '⊆' => '⊆', |
3663 '⊇' => '⊇', |
4060 '⊇' => '⊇', |
3664 '⊕' => '⊕', |
4061 '⊕' => '⊕', |
3665 '⊗' => '⊗', |
4062 '⊗' => '⊗', |
3666 '⊥' => '⊥', |
4063 '⊥' => '⊥', |
3667 '⋅' => '⋅', |
4064 '⋅' => '⋅', |
3668 '⌈' => '⌈', |
4065 '⌈' => '⌈', |
3669 '⌉' => '⌉', |
4066 '⌉' => '⌉', |
3670 '⌊' => '⌊', |
4067 '⌊' => '⌊', |
3671 '⌋' => '⌋', |
4068 '⌋' => '⌋', |
3672 '⟨' => '〈', |
4069 '⟨' => '〈', |
3673 '⟩' => '〉', |
4070 '⟩' => '〉', |
3674 '←' => '←', |
4071 '←' => '←', |
3675 '↑' => '↑', |
4072 '↑' => '↑', |
3676 '→' => '→', |
4073 '→' => '→', |
3677 '↓' => '↓', |
4074 '↓' => '↓', |
3678 '↔' => '↔', |
4075 '↔' => '↔', |
3679 '◊' => '◊', |
4076 '◊' => '◊', |
3680 '♠' => '♠', |
4077 '♠' => '♠', |
3681 '♣' => '♣', |
4078 '♣' => '♣', |
3682 '♥' => '♥', |
4079 '♥' => '♥', |
3683 '♦' => '♦' |
4080 '♦' => '♦', |
3684 ); |
4081 ); |
3685 |
4082 |
3686 return str_replace( array_keys($to_ncr), array_values($to_ncr), $text ); |
4083 return str_replace( array_keys( $to_ncr ), array_values( $to_ncr ), $text ); |
3687 } |
4084 } |
3688 |
4085 |
3689 /** |
4086 /** |
3690 * Formats text for the editor. |
4087 * Formats text for the editor. |
3691 * |
4088 * |
3732 * @access private |
4129 * @access private |
3733 * |
4130 * |
3734 * @param string|array $search The value being searched for, otherwise known as the needle. |
4131 * @param string|array $search The value being searched for, otherwise known as the needle. |
3735 * An array may be used to designate multiple needles. |
4132 * An array may be used to designate multiple needles. |
3736 * @param string $subject The string being searched and replaced on, otherwise known as the haystack. |
4133 * @param string $subject The string being searched and replaced on, otherwise known as the haystack. |
3737 * @return string The string with the replaced svalues. |
4134 * @return string The string with the replaced values. |
3738 */ |
4135 */ |
3739 function _deep_replace( $search, $subject ) { |
4136 function _deep_replace( $search, $subject ) { |
3740 $subject = (string) $subject; |
4137 $subject = (string) $subject; |
3741 |
4138 |
3742 $count = 1; |
4139 $count = 1; |
3780 * |
4177 * |
3781 * @since 2.8.0 |
4178 * @since 2.8.0 |
3782 * |
4179 * |
3783 * @param string $url The URL to be cleaned. |
4180 * @param string $url The URL to be cleaned. |
3784 * @param array $protocols Optional. An array of acceptable protocols. |
4181 * @param array $protocols Optional. An array of acceptable protocols. |
3785 * Defaults to return value of wp_allowed_protocols() |
4182 * Defaults to return value of wp_allowed_protocols() |
3786 * @param string $_context Private. Use esc_url_raw() for database usage. |
4183 * @param string $_context Private. Use esc_url_raw() for database usage. |
3787 * @return string The cleaned $url after the {@see 'clean_url'} filter is applied. |
4184 * @return string The cleaned $url after the {@see 'clean_url'} filter is applied. |
3788 */ |
4185 */ |
3789 function esc_url( $url, $protocols = null, $_context = 'display' ) { |
4186 function esc_url( $url, $protocols = null, $_context = 'display' ) { |
3790 $original_url = $url; |
4187 $original_url = $url; |
3791 |
4188 |
3792 if ( '' == $url ) |
4189 if ( '' == $url ) { |
3793 return $url; |
4190 return $url; |
4191 } |
|
3794 |
4192 |
3795 $url = str_replace( ' ', '%20', $url ); |
4193 $url = str_replace( ' ', '%20', $url ); |
3796 $url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\[\]\\x80-\\xff]|i', '', $url); |
4194 $url = preg_replace( '|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\[\]\\x80-\\xff]|i', '', $url ); |
3797 |
4195 |
3798 if ( '' === $url ) { |
4196 if ( '' === $url ) { |
3799 return $url; |
4197 return $url; |
3800 } |
4198 } |
3801 |
4199 |
3802 if ( 0 !== stripos( $url, 'mailto:' ) ) { |
4200 if ( 0 !== stripos( $url, 'mailto:' ) ) { |
3803 $strip = array('%0d', '%0a', '%0D', '%0A'); |
4201 $strip = array( '%0d', '%0a', '%0D', '%0A' ); |
3804 $url = _deep_replace($strip, $url); |
4202 $url = _deep_replace( $strip, $url ); |
3805 } |
4203 } |
3806 |
4204 |
3807 $url = str_replace(';//', '://', $url); |
4205 $url = str_replace( ';//', '://', $url ); |
3808 /* If the URL doesn't appear to contain a scheme, we |
4206 /* If the URL doesn't appear to contain a scheme, we |
3809 * presume it needs http:// prepended (unless a relative |
4207 * presume it needs http:// prepended (unless a relative |
3810 * link starting with /, # or ? or a php file). |
4208 * link starting with /, # or ? or a php file). |
3811 */ |
4209 */ |
3812 if ( strpos($url, ':') === false && ! in_array( $url[0], array( '/', '#', '?' ) ) && |
4210 if ( strpos( $url, ':' ) === false && ! in_array( $url[0], array( '/', '#', '?' ) ) && |
3813 ! preg_match('/^[a-z0-9-]+?\.php/i', $url) ) |
4211 ! preg_match( '/^[a-z0-9-]+?\.php/i', $url ) ) { |
3814 $url = 'http://' . $url; |
4212 $url = 'http://' . $url; |
4213 } |
|
3815 |
4214 |
3816 // Replace ampersands and single quotes only when displaying. |
4215 // Replace ampersands and single quotes only when displaying. |
3817 if ( 'display' == $_context ) { |
4216 if ( 'display' == $_context ) { |
3818 $url = wp_kses_normalize_entities( $url ); |
4217 $url = wp_kses_normalize_entities( $url ); |
3819 $url = str_replace( '&', '&', $url ); |
4218 $url = str_replace( '&', '&', $url ); |
3858 } |
4257 } |
3859 |
4258 |
3860 if ( '/' === $url[0] ) { |
4259 if ( '/' === $url[0] ) { |
3861 $good_protocol_url = $url; |
4260 $good_protocol_url = $url; |
3862 } else { |
4261 } else { |
3863 if ( ! is_array( $protocols ) ) |
4262 if ( ! is_array( $protocols ) ) { |
3864 $protocols = wp_allowed_protocols(); |
4263 $protocols = wp_allowed_protocols(); |
4264 } |
|
3865 $good_protocol_url = wp_kses_bad_protocol( $url, $protocols ); |
4265 $good_protocol_url = wp_kses_bad_protocol( $url, $protocols ); |
3866 if ( strtolower( $good_protocol_url ) != strtolower( $url ) ) |
4266 if ( strtolower( $good_protocol_url ) != strtolower( $url ) ) { |
3867 return ''; |
4267 return ''; |
4268 } |
|
3868 } |
4269 } |
3869 |
4270 |
3870 /** |
4271 /** |
3871 * Filters a string cleaned and escaped for output as a URL. |
4272 * Filters a string cleaned and escaped for output as a URL. |
3872 * |
4273 * |
3901 * |
4302 * |
3902 * @param string $myHTML The text to be converted. |
4303 * @param string $myHTML The text to be converted. |
3903 * @return string Converted text. |
4304 * @return string Converted text. |
3904 */ |
4305 */ |
3905 function htmlentities2( $myHTML ) { |
4306 function htmlentities2( $myHTML ) { |
3906 $translation_table = get_html_translation_table( HTML_ENTITIES, ENT_QUOTES ); |
4307 $translation_table = get_html_translation_table( HTML_ENTITIES, ENT_QUOTES ); |
3907 $translation_table[chr(38)] = '&'; |
4308 $translation_table[ chr( 38 ) ] = '&'; |
3908 return preg_replace( "/&(?![A-Za-z]{0,4}\w{2,3};|#[0-9]{2,3};)/", "&", strtr($myHTML, $translation_table) ); |
4309 return preg_replace( '/&(?![A-Za-z]{0,4}\w{2,3};|#[0-9]{2,3};)/', '&', strtr( $myHTML, $translation_table ) ); |
3909 } |
4310 } |
3910 |
4311 |
3911 /** |
4312 /** |
3912 * Escape single quotes, htmlspecialchar " < > &, and fix line endings. |
4313 * Escape single quotes, htmlspecialchar " < > &, and fix line endings. |
3913 * |
4314 * |
3933 * and properly slashed for output. |
4334 * and properly slashed for output. |
3934 * |
4335 * |
3935 * @since 2.0.6 |
4336 * @since 2.0.6 |
3936 * |
4337 * |
3937 * @param string $safe_text The text after it has been escaped. |
4338 * @param string $safe_text The text after it has been escaped. |
3938 * @param string $text The text prior to being escaped. |
4339 * @param string $text The text prior to being escaped. |
3939 */ |
4340 */ |
3940 return apply_filters( 'js_escape', $safe_text, $text ); |
4341 return apply_filters( 'js_escape', $safe_text, $text ); |
3941 } |
4342 } |
3942 |
4343 |
3943 /** |
4344 /** |
3958 * before output. |
4359 * before output. |
3959 * |
4360 * |
3960 * @since 2.8.0 |
4361 * @since 2.8.0 |
3961 * |
4362 * |
3962 * @param string $safe_text The text after it has been escaped. |
4363 * @param string $safe_text The text after it has been escaped. |
3963 * @param string $text The text prior to being escaped. |
4364 * @param string $text The text prior to being escaped. |
3964 */ |
4365 */ |
3965 return apply_filters( 'esc_html', $safe_text, $text ); |
4366 return apply_filters( 'esc_html', $safe_text, $text ); |
3966 } |
4367 } |
3967 |
4368 |
3968 /** |
4369 /** |
3983 * before output. |
4384 * before output. |
3984 * |
4385 * |
3985 * @since 2.0.6 |
4386 * @since 2.0.6 |
3986 * |
4387 * |
3987 * @param string $safe_text The text after it has been escaped. |
4388 * @param string $safe_text The text after it has been escaped. |
3988 * @param string $text The text prior to being escaped. |
4389 * @param string $text The text prior to being escaped. |
3989 */ |
4390 */ |
3990 return apply_filters( 'attribute_escape', $safe_text, $text ); |
4391 return apply_filters( 'attribute_escape', $safe_text, $text ); |
3991 } |
4392 } |
3992 |
4393 |
3993 /** |
4394 /** |
4004 * Filters a string cleaned and escaped for output in a textarea element. |
4405 * Filters a string cleaned and escaped for output in a textarea element. |
4005 * |
4406 * |
4006 * @since 3.1.0 |
4407 * @since 3.1.0 |
4007 * |
4408 * |
4008 * @param string $safe_text The text after it has been escaped. |
4409 * @param string $safe_text The text after it has been escaped. |
4009 * @param string $text The text prior to being escaped. |
4410 * @param string $text The text prior to being escaped. |
4010 */ |
4411 */ |
4011 return apply_filters( 'esc_textarea', $safe_text, $text ); |
4412 return apply_filters( 'esc_textarea', $safe_text, $text ); |
4012 } |
4413 } |
4013 |
4414 |
4014 /** |
4415 /** |
4018 * |
4419 * |
4019 * @param string $tag_name |
4420 * @param string $tag_name |
4020 * @return string |
4421 * @return string |
4021 */ |
4422 */ |
4022 function tag_escape( $tag_name ) { |
4423 function tag_escape( $tag_name ) { |
4023 $safe_tag = strtolower( preg_replace('/[^a-zA-Z0-9_:]/', '', $tag_name) ); |
4424 $safe_tag = strtolower( preg_replace( '/[^a-zA-Z0-9_:]/', '', $tag_name ) ); |
4024 /** |
4425 /** |
4025 * Filters a string cleaned and escaped for output as an HTML tag. |
4426 * Filters a string cleaned and escaped for output as an HTML tag. |
4026 * |
4427 * |
4027 * @since 2.8.0 |
4428 * @since 2.8.0 |
4028 * |
4429 * |
4029 * @param string $safe_tag The tag name after it has been escaped. |
4430 * @param string $safe_tag The tag name after it has been escaped. |
4030 * @param string $tag_name The text before it was escaped. |
4431 * @param string $tag_name The text before it was escaped. |
4031 */ |
4432 */ |
4032 return apply_filters( 'tag_escape', $safe_tag, $tag_name ); |
4433 return apply_filters( 'tag_escape', $safe_tag, $tag_name ); |
4033 } |
4434 } |
4034 |
4435 |
4035 /** |
4436 /** |
4064 */ |
4465 */ |
4065 function sanitize_option( $option, $value ) { |
4466 function sanitize_option( $option, $value ) { |
4066 global $wpdb; |
4467 global $wpdb; |
4067 |
4468 |
4068 $original_value = $value; |
4469 $original_value = $value; |
4069 $error = ''; |
4470 $error = ''; |
4070 |
4471 |
4071 switch ( $option ) { |
4472 switch ( $option ) { |
4072 case 'admin_email' : |
4473 case 'admin_email': |
4073 case 'new_admin_email' : |
4474 case 'new_admin_email': |
4074 $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value ); |
4475 $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value ); |
4075 if ( is_wp_error( $value ) ) { |
4476 if ( is_wp_error( $value ) ) { |
4076 $error = $value->get_error_message(); |
4477 $error = $value->get_error_message(); |
4077 } else { |
4478 } else { |
4078 $value = sanitize_email( $value ); |
4479 $value = sanitize_email( $value ); |
4108 break; |
4509 break; |
4109 |
4510 |
4110 case 'posts_per_page': |
4511 case 'posts_per_page': |
4111 case 'posts_per_rss': |
4512 case 'posts_per_rss': |
4112 $value = (int) $value; |
4513 $value = (int) $value; |
4113 if ( empty($value) ) |
4514 if ( empty( $value ) ) { |
4114 $value = 1; |
4515 $value = 1; |
4115 if ( $value < -1 ) |
4516 } |
4116 $value = abs($value); |
4517 if ( $value < -1 ) { |
4518 $value = abs( $value ); |
|
4519 } |
|
4117 break; |
4520 break; |
4118 |
4521 |
4119 case 'default_ping_status': |
4522 case 'default_ping_status': |
4120 case 'default_comment_status': |
4523 case 'default_comment_status': |
4121 // Options that if not there have 0 value but need to be something like "closed" |
4524 // Options that if not there have 0 value but need to be something like "closed" |
4122 if ( $value == '0' || $value == '') |
4525 if ( $value == '0' || $value == '' ) { |
4123 $value = 'closed'; |
4526 $value = 'closed'; |
4527 } |
|
4124 break; |
4528 break; |
4125 |
4529 |
4126 case 'blogdescription': |
4530 case 'blogdescription': |
4127 case 'blogname': |
4531 case 'blogname': |
4128 $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value ); |
4532 $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value ); |
4136 $value = esc_html( $value ); |
4540 $value = esc_html( $value ); |
4137 } |
4541 } |
4138 break; |
4542 break; |
4139 |
4543 |
4140 case 'blog_charset': |
4544 case 'blog_charset': |
4141 $value = preg_replace('/[^a-zA-Z0-9_-]/', '', $value); // strips slashes |
4545 $value = preg_replace( '/[^a-zA-Z0-9_-]/', '', $value ); // strips slashes |
4142 break; |
4546 break; |
4143 |
4547 |
4144 case 'blog_public': |
4548 case 'blog_public': |
4145 // This is the value if the settings checkbox is not checked on POST. Don't rely on this. |
4549 // This is the value if the settings checkbox is not checked on POST. Don't rely on this. |
4146 if ( null === $value ) |
4550 if ( null === $value ) { |
4147 $value = 1; |
4551 $value = 1; |
4148 else |
4552 } else { |
4149 $value = intval( $value ); |
4553 $value = intval( $value ); |
4554 } |
|
4150 break; |
4555 break; |
4151 |
4556 |
4152 case 'date_format': |
4557 case 'date_format': |
4153 case 'time_format': |
4558 case 'time_format': |
4154 case 'mailserver_url': |
4559 case 'mailserver_url': |
4170 $value = array_filter( array_map( 'esc_url_raw', $value ) ); |
4575 $value = array_filter( array_map( 'esc_url_raw', $value ) ); |
4171 $value = implode( "\n", $value ); |
4576 $value = implode( "\n", $value ); |
4172 break; |
4577 break; |
4173 |
4578 |
4174 case 'gmt_offset': |
4579 case 'gmt_offset': |
4175 $value = preg_replace('/[^0-9:.-]/', '', $value); // strips slashes |
4580 $value = preg_replace( '/[^0-9:.-]/', '', $value ); // strips slashes |
4176 break; |
4581 break; |
4177 |
4582 |
4178 case 'siteurl': |
4583 case 'siteurl': |
4179 $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value ); |
4584 $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value ); |
4180 if ( is_wp_error( $value ) ) { |
4585 if ( is_wp_error( $value ) ) { |
4214 case 'illegal_names': |
4619 case 'illegal_names': |
4215 $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value ); |
4620 $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value ); |
4216 if ( is_wp_error( $value ) ) { |
4621 if ( is_wp_error( $value ) ) { |
4217 $error = $value->get_error_message(); |
4622 $error = $value->get_error_message(); |
4218 } else { |
4623 } else { |
4219 if ( ! is_array( $value ) ) |
4624 if ( ! is_array( $value ) ) { |
4220 $value = explode( ' ', $value ); |
4625 $value = explode( ' ', $value ); |
4626 } |
|
4221 |
4627 |
4222 $value = array_values( array_filter( array_map( 'trim', $value ) ) ); |
4628 $value = array_values( array_filter( array_map( 'trim', $value ) ) ); |
4223 |
4629 |
4224 if ( ! $value ) |
4630 if ( ! $value ) { |
4225 $value = ''; |
4631 $value = ''; |
4632 } |
|
4226 } |
4633 } |
4227 break; |
4634 break; |
4228 |
4635 |
4229 case 'limited_email_domains': |
4636 case 'limited_email_domains': |
4230 case 'banned_email_domains': |
4637 case 'banned_email_domains': |
4231 $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value ); |
4638 $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value ); |
4232 if ( is_wp_error( $value ) ) { |
4639 if ( is_wp_error( $value ) ) { |
4233 $error = $value->get_error_message(); |
4640 $error = $value->get_error_message(); |
4234 } else { |
4641 } else { |
4235 if ( ! is_array( $value ) ) |
4642 if ( ! is_array( $value ) ) { |
4236 $value = explode( "\n", $value ); |
4643 $value = explode( "\n", $value ); |
4644 } |
|
4237 |
4645 |
4238 $domains = array_values( array_filter( array_map( 'trim', $value ) ) ); |
4646 $domains = array_values( array_filter( array_map( 'trim', $value ) ) ); |
4239 $value = array(); |
4647 $value = array(); |
4240 |
4648 |
4241 foreach ( $domains as $domain ) { |
4649 foreach ( $domains as $domain ) { |
4242 if ( ! preg_match( '/(--|\.\.)/', $domain ) && preg_match( '|^([a-zA-Z0-9-\.])+$|', $domain ) ) { |
4650 if ( ! preg_match( '/(--|\.\.)/', $domain ) && preg_match( '|^([a-zA-Z0-9-\.])+$|', $domain ) ) { |
4243 $value[] = $domain; |
4651 $value[] = $domain; |
4244 } |
4652 } |
4245 } |
4653 } |
4246 if ( ! $value ) |
4654 if ( ! $value ) { |
4247 $value = ''; |
4655 $value = ''; |
4656 } |
|
4248 } |
4657 } |
4249 break; |
4658 break; |
4250 |
4659 |
4251 case 'timezone_string': |
4660 case 'timezone_string': |
4252 $allowed_zones = timezone_identifiers_list(); |
4661 $allowed_zones = timezone_identifiers_list(); |
4273 __( 'https://codex.wordpress.org/Using_Permalinks#Choosing_your_permalink_structure' ) |
4682 __( 'https://codex.wordpress.org/Using_Permalinks#Choosing_your_permalink_structure' ) |
4274 ); |
4683 ); |
4275 } |
4684 } |
4276 break; |
4685 break; |
4277 |
4686 |
4278 case 'default_role' : |
4687 case 'default_role': |
4279 if ( ! get_role( $value ) && get_role( 'subscriber' ) ) |
4688 if ( ! get_role( $value ) && get_role( 'subscriber' ) ) { |
4280 $value = 'subscriber'; |
4689 $value = 'subscriber'; |
4690 } |
|
4281 break; |
4691 break; |
4282 |
4692 |
4283 case 'moderation_keys': |
4693 case 'moderation_keys': |
4284 case 'blacklist_keys': |
4694 case 'blacklist_keys': |
4285 $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value ); |
4695 $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value ); |
4353 * @param string $string The string to be parsed. |
4763 * @param string $string The string to be parsed. |
4354 * @param array $array Variables will be stored in this array. |
4764 * @param array $array Variables will be stored in this array. |
4355 */ |
4765 */ |
4356 function wp_parse_str( $string, &$array ) { |
4766 function wp_parse_str( $string, &$array ) { |
4357 parse_str( $string, $array ); |
4767 parse_str( $string, $array ); |
4358 if ( get_magic_quotes_gpc() ) |
4768 if ( get_magic_quotes_gpc() ) { |
4359 $array = stripslashes_deep( $array ); |
4769 $array = stripslashes_deep( $array ); |
4770 } |
|
4360 /** |
4771 /** |
4361 * Filters the array of variables derived from a parsed string. |
4772 * Filters the array of variables derived from a parsed string. |
4362 * |
4773 * |
4363 * @since 2.3.0 |
4774 * @since 2.3.0 |
4364 * |
4775 * |
4376 * |
4787 * |
4377 * @param string $text Text to be converted. |
4788 * @param string $text Text to be converted. |
4378 * @return string Converted text. |
4789 * @return string Converted text. |
4379 */ |
4790 */ |
4380 function wp_pre_kses_less_than( $text ) { |
4791 function wp_pre_kses_less_than( $text ) { |
4381 return preg_replace_callback('%<[^>]*?((?=<)|>|$)%', 'wp_pre_kses_less_than_callback', $text); |
4792 return preg_replace_callback( '%<[^>]*?((?=<)|>|$)%', 'wp_pre_kses_less_than_callback', $text ); |
4382 } |
4793 } |
4383 |
4794 |
4384 /** |
4795 /** |
4385 * Callback function used by preg_replace. |
4796 * Callback function used by preg_replace. |
4386 * |
4797 * |
4388 * |
4799 * |
4389 * @param array $matches Populated by matches to preg_replace. |
4800 * @param array $matches Populated by matches to preg_replace. |
4390 * @return string The text returned after esc_html if needed. |
4801 * @return string The text returned after esc_html if needed. |
4391 */ |
4802 */ |
4392 function wp_pre_kses_less_than_callback( $matches ) { |
4803 function wp_pre_kses_less_than_callback( $matches ) { |
4393 if ( false === strpos($matches[0], '>') ) |
4804 if ( false === strpos( $matches[0], '>' ) ) { |
4394 return esc_html($matches[0]); |
4805 return esc_html( $matches[0] ); |
4806 } |
|
4395 return $matches[0]; |
4807 return $matches[0]; |
4396 } |
4808 } |
4397 |
4809 |
4398 /** |
4810 /** |
4399 * WordPress implementation of PHP sprintf() with filters. |
4811 * WordPress implementation of PHP sprintf() with filters. |
4404 * @param string $pattern The string which formatted args are inserted. |
4816 * @param string $pattern The string which formatted args are inserted. |
4405 * @param mixed $args ,... Arguments to be formatted into the $pattern string. |
4817 * @param mixed $args ,... Arguments to be formatted into the $pattern string. |
4406 * @return string The formatted string. |
4818 * @return string The formatted string. |
4407 */ |
4819 */ |
4408 function wp_sprintf( $pattern ) { |
4820 function wp_sprintf( $pattern ) { |
4409 $args = func_get_args(); |
4821 $args = func_get_args(); |
4410 $len = strlen($pattern); |
4822 $len = strlen( $pattern ); |
4411 $start = 0; |
4823 $start = 0; |
4412 $result = ''; |
4824 $result = ''; |
4413 $arg_index = 0; |
4825 $arg_index = 0; |
4414 while ( $len > $start ) { |
4826 while ( $len > $start ) { |
4415 // Last character: append and break |
4827 // Last character: append and break |
4416 if ( strlen($pattern) - 1 == $start ) { |
4828 if ( strlen( $pattern ) - 1 == $start ) { |
4417 $result .= substr($pattern, -1); |
4829 $result .= substr( $pattern, -1 ); |
4418 break; |
4830 break; |
4419 } |
4831 } |
4420 |
4832 |
4421 // Literal %: append and continue |
4833 // Literal %: append and continue |
4422 if ( substr($pattern, $start, 2) == '%%' ) { |
4834 if ( substr( $pattern, $start, 2 ) == '%%' ) { |
4423 $start += 2; |
4835 $start += 2; |
4424 $result .= '%'; |
4836 $result .= '%'; |
4425 continue; |
4837 continue; |
4426 } |
4838 } |
4427 |
4839 |
4428 // Get fragment before next % |
4840 // Get fragment before next % |
4429 $end = strpos($pattern, '%', $start + 1); |
4841 $end = strpos( $pattern, '%', $start + 1 ); |
4430 if ( false === $end ) |
4842 if ( false === $end ) { |
4431 $end = $len; |
4843 $end = $len; |
4432 $fragment = substr($pattern, $start, $end - $start); |
4844 } |
4845 $fragment = substr( $pattern, $start, $end - $start ); |
|
4433 |
4846 |
4434 // Fragment has a specifier |
4847 // Fragment has a specifier |
4435 if ( $pattern[$start] == '%' ) { |
4848 if ( $pattern[ $start ] == '%' ) { |
4436 // Find numbered arguments or take the next one in order |
4849 // Find numbered arguments or take the next one in order |
4437 if ( preg_match('/^%(\d+)\$/', $fragment, $matches) ) { |
4850 if ( preg_match( '/^%(\d+)\$/', $fragment, $matches ) ) { |
4438 $arg = isset($args[$matches[1]]) ? $args[$matches[1]] : ''; |
4851 $arg = isset( $args[ $matches[1] ] ) ? $args[ $matches[1] ] : ''; |
4439 $fragment = str_replace("%{$matches[1]}$", '%', $fragment); |
4852 $fragment = str_replace( "%{$matches[1]}$", '%', $fragment ); |
4440 } else { |
4853 } else { |
4441 ++$arg_index; |
4854 ++$arg_index; |
4442 $arg = isset($args[$arg_index]) ? $args[$arg_index] : ''; |
4855 $arg = isset( $args[ $arg_index ] ) ? $args[ $arg_index ] : ''; |
4443 } |
4856 } |
4444 |
4857 |
4445 /** |
4858 /** |
4446 * Filters a fragment from the pattern passed to wp_sprintf(). |
4859 * Filters a fragment from the pattern passed to wp_sprintf(). |
4447 * |
4860 * |
4451 * |
4864 * |
4452 * @param string $fragment A fragment from the pattern. |
4865 * @param string $fragment A fragment from the pattern. |
4453 * @param string $arg The argument. |
4866 * @param string $arg The argument. |
4454 */ |
4867 */ |
4455 $_fragment = apply_filters( 'wp_sprintf', $fragment, $arg ); |
4868 $_fragment = apply_filters( 'wp_sprintf', $fragment, $arg ); |
4456 if ( $_fragment != $fragment ) |
4869 if ( $_fragment != $fragment ) { |
4457 $fragment = $_fragment; |
4870 $fragment = $_fragment; |
4458 else |
4871 } else { |
4459 $fragment = sprintf($fragment, strval($arg) ); |
4872 $fragment = sprintf( $fragment, strval( $arg ) ); |
4873 } |
|
4460 } |
4874 } |
4461 |
4875 |
4462 // Append to result and move to next fragment |
4876 // Append to result and move to next fragment |
4463 $result .= $fragment; |
4877 $result .= $fragment; |
4464 $start = $end; |
4878 $start = $end; |
4465 } |
4879 } |
4466 return $result; |
4880 return $result; |
4467 } |
4881 } |
4468 |
4882 |
4469 /** |
4883 /** |
4479 * @param array $args List items to prepend to the content and replace '%l'. |
4893 * @param array $args List items to prepend to the content and replace '%l'. |
4480 * @return string Localized list items and rest of the content. |
4894 * @return string Localized list items and rest of the content. |
4481 */ |
4895 */ |
4482 function wp_sprintf_l( $pattern, $args ) { |
4896 function wp_sprintf_l( $pattern, $args ) { |
4483 // Not a match |
4897 // Not a match |
4484 if ( substr($pattern, 0, 2) != '%l' ) |
4898 if ( substr( $pattern, 0, 2 ) != '%l' ) { |
4485 return $pattern; |
4899 return $pattern; |
4900 } |
|
4486 |
4901 |
4487 // Nothing to work with |
4902 // Nothing to work with |
4488 if ( empty($args) ) |
4903 if ( empty( $args ) ) { |
4489 return ''; |
4904 return ''; |
4905 } |
|
4490 |
4906 |
4491 /** |
4907 /** |
4492 * Filters the translated delimiters used by wp_sprintf_l(). |
4908 * Filters the translated delimiters used by wp_sprintf_l(). |
4493 * Placeholders (%s) are included to assist translators and then |
4909 * Placeholders (%s) are included to assist translators and then |
4494 * removed before the array of strings reaches the filter. |
4910 * removed before the array of strings reaches the filter. |
4497 * |
4913 * |
4498 * @since 2.5.0 |
4914 * @since 2.5.0 |
4499 * |
4915 * |
4500 * @param array $delimiters An array of translated delimiters. |
4916 * @param array $delimiters An array of translated delimiters. |
4501 */ |
4917 */ |
4502 $l = apply_filters( 'wp_sprintf_l', array( |
4918 $l = apply_filters( |
4503 /* translators: used to join items in a list with more than 2 items */ |
4919 'wp_sprintf_l', |
4504 'between' => sprintf( __('%s, %s'), '', '' ), |
4920 array( |
4505 /* translators: used to join last two items in a list with more than 2 times */ |
4921 /* translators: used to join items in a list with more than 2 items */ |
4506 'between_last_two' => sprintf( __('%s, and %s'), '', '' ), |
4922 'between' => sprintf( __( '%1$s, %2$s' ), '', '' ), |
4507 /* translators: used to join items in a list with only 2 items */ |
4923 /* translators: used to join last two items in a list with more than 2 times */ |
4508 'between_only_two' => sprintf( __('%s and %s'), '', '' ), |
4924 'between_last_two' => sprintf( __( '%1$s, and %2$s' ), '', '' ), |
4509 ) ); |
4925 /* translators: used to join items in a list with only 2 items */ |
4510 |
4926 'between_only_two' => sprintf( __( '%1$s and %2$s' ), '', '' ), |
4511 $args = (array) $args; |
4927 ) |
4512 $result = array_shift($args); |
4928 ); |
4513 if ( count($args) == 1 ) |
4929 |
4514 $result .= $l['between_only_two'] . array_shift($args); |
4930 $args = (array) $args; |
4931 $result = array_shift( $args ); |
|
4932 if ( count( $args ) == 1 ) { |
|
4933 $result .= $l['between_only_two'] . array_shift( $args ); |
|
4934 } |
|
4515 // Loop when more than two args |
4935 // Loop when more than two args |
4516 $i = count($args); |
4936 $i = count( $args ); |
4517 while ( $i ) { |
4937 while ( $i ) { |
4518 $arg = array_shift($args); |
4938 $arg = array_shift( $args ); |
4519 $i--; |
4939 $i--; |
4520 if ( 0 == $i ) |
4940 if ( 0 == $i ) { |
4521 $result .= $l['between_last_two'] . $arg; |
4941 $result .= $l['between_last_two'] . $arg; |
4522 else |
4942 } else { |
4523 $result .= $l['between'] . $arg; |
4943 $result .= $l['between'] . $arg; |
4524 } |
4944 } |
4525 return $result . substr($pattern, 2); |
4945 } |
4946 return $result . substr( $pattern, 2 ); |
|
4526 } |
4947 } |
4527 |
4948 |
4528 /** |
4949 /** |
4529 * Safely extracts not more than the first $count characters from html string. |
4950 * Safely extracts not more than the first $count characters from html string. |
4530 * |
4951 * |
4538 * @param int $count Maximum number of characters to take. |
4959 * @param int $count Maximum number of characters to take. |
4539 * @param string $more Optional. What to append if $str needs to be trimmed. Defaults to empty string. |
4960 * @param string $more Optional. What to append if $str needs to be trimmed. Defaults to empty string. |
4540 * @return string The excerpt. |
4961 * @return string The excerpt. |
4541 */ |
4962 */ |
4542 function wp_html_excerpt( $str, $count, $more = null ) { |
4963 function wp_html_excerpt( $str, $count, $more = null ) { |
4543 if ( null === $more ) |
4964 if ( null === $more ) { |
4544 $more = ''; |
4965 $more = ''; |
4545 $str = wp_strip_all_tags( $str, true ); |
4966 } |
4967 $str = wp_strip_all_tags( $str, true ); |
|
4546 $excerpt = mb_substr( $str, 0, $count ); |
4968 $excerpt = mb_substr( $str, 0, $count ); |
4547 // remove part of an entity at the end |
4969 // remove part of an entity at the end |
4548 $excerpt = preg_replace( '/&[^;\s]{0,6}$/', '', $excerpt ); |
4970 $excerpt = preg_replace( '/&[^;\s]{0,6}$/', '', $excerpt ); |
4549 if ( $str != $excerpt ) |
4971 if ( $str != $excerpt ) { |
4550 $excerpt = trim( $excerpt ) . $more; |
4972 $excerpt = trim( $excerpt ) . $more; |
4973 } |
|
4551 return $excerpt; |
4974 return $excerpt; |
4552 } |
4975 } |
4553 |
4976 |
4554 /** |
4977 /** |
4555 * Add a Base url to relative links in passed content. |
4978 * Add a Base url to relative links in passed content. |
4564 * @param string $content String to search for links in. |
4987 * @param string $content String to search for links in. |
4565 * @param string $base The base URL to prefix to links. |
4988 * @param string $base The base URL to prefix to links. |
4566 * @param array $attrs The attributes which should be processed. |
4989 * @param array $attrs The attributes which should be processed. |
4567 * @return string The processed content. |
4990 * @return string The processed content. |
4568 */ |
4991 */ |
4569 function links_add_base_url( $content, $base, $attrs = array('src', 'href') ) { |
4992 function links_add_base_url( $content, $base, $attrs = array( 'src', 'href' ) ) { |
4570 global $_links_add_base; |
4993 global $_links_add_base; |
4571 $_links_add_base = $base; |
4994 $_links_add_base = $base; |
4572 $attrs = implode('|', (array)$attrs); |
4995 $attrs = implode( '|', (array) $attrs ); |
4573 return preg_replace_callback( "!($attrs)=(['\"])(.+?)\\2!i", '_links_add_base', $content ); |
4996 return preg_replace_callback( "!($attrs)=(['\"])(.+?)\\2!i", '_links_add_base', $content ); |
4574 } |
4997 } |
4575 |
4998 |
4576 /** |
4999 /** |
4577 * Callback to add a base url to relative links in passed content. |
5000 * Callback to add a base url to relative links in passed content. |
4610 * @param string $content String to search for links in. |
5033 * @param string $content String to search for links in. |
4611 * @param string $target The Target to add to the links. |
5034 * @param string $target The Target to add to the links. |
4612 * @param array $tags An array of tags to apply to. |
5035 * @param array $tags An array of tags to apply to. |
4613 * @return string The processed content. |
5036 * @return string The processed content. |
4614 */ |
5037 */ |
4615 function links_add_target( $content, $target = '_blank', $tags = array('a') ) { |
5038 function links_add_target( $content, $target = '_blank', $tags = array( 'a' ) ) { |
4616 global $_links_add_target; |
5039 global $_links_add_target; |
4617 $_links_add_target = $target; |
5040 $_links_add_target = $target; |
4618 $tags = implode('|', (array)$tags); |
5041 $tags = implode( '|', (array) $tags ); |
4619 return preg_replace_callback( "!<($tags)([^>]*)>!i", '_links_add_target', $content ); |
5042 return preg_replace_callback( "!<($tags)([^>]*)>!i", '_links_add_target', $content ); |
4620 } |
5043 } |
4621 |
5044 |
4622 /** |
5045 /** |
4623 * Callback to add a target attribute to all links in passed content. |
5046 * Callback to add a target attribute to all links in passed content. |
4630 * @param string $m The matched link. |
5053 * @param string $m The matched link. |
4631 * @return string The processed link. |
5054 * @return string The processed link. |
4632 */ |
5055 */ |
4633 function _links_add_target( $m ) { |
5056 function _links_add_target( $m ) { |
4634 global $_links_add_target; |
5057 global $_links_add_target; |
4635 $tag = $m[1]; |
5058 $tag = $m[1]; |
4636 $link = preg_replace('|( target=([\'"])(.*?)\2)|i', '', $m[2]); |
5059 $link = preg_replace( '|( target=([\'"])(.*?)\2)|i', '', $m[2] ); |
4637 return '<' . $tag . $link . ' target="' . esc_attr( $_links_add_target ) . '">'; |
5060 return '<' . $tag . $link . ' target="' . esc_attr( $_links_add_target ) . '">'; |
4638 } |
5061 } |
4639 |
5062 |
4640 /** |
5063 /** |
4641 * Normalize EOL characters and strip duplicate whitespace. |
5064 * Normalize EOL characters and strip duplicate whitespace. |
4644 * |
5067 * |
4645 * @param string $str The string to normalize. |
5068 * @param string $str The string to normalize. |
4646 * @return string The normalized string. |
5069 * @return string The normalized string. |
4647 */ |
5070 */ |
4648 function normalize_whitespace( $str ) { |
5071 function normalize_whitespace( $str ) { |
4649 $str = trim( $str ); |
5072 $str = trim( $str ); |
4650 $str = str_replace( "\r", "\n", $str ); |
5073 $str = str_replace( "\r", "\n", $str ); |
4651 $str = preg_replace( array( '/\n+/', '/[ \t]+/' ), array( "\n", ' ' ), $str ); |
5074 $str = preg_replace( array( '/\n+/', '/[ \t]+/' ), array( "\n", ' ' ), $str ); |
4652 return $str; |
5075 return $str; |
4653 } |
5076 } |
4654 |
5077 |
4655 /** |
5078 /** |
4656 * Properly strip all HTML tags including script and style |
5079 * Properly strip all HTML tags including script and style |
4663 * |
5086 * |
4664 * @param string $string String containing HTML tags |
5087 * @param string $string String containing HTML tags |
4665 * @param bool $remove_breaks Optional. Whether to remove left over line breaks and white space chars |
5088 * @param bool $remove_breaks Optional. Whether to remove left over line breaks and white space chars |
4666 * @return string The processed string. |
5089 * @return string The processed string. |
4667 */ |
5090 */ |
4668 function wp_strip_all_tags($string, $remove_breaks = false) { |
5091 function wp_strip_all_tags( $string, $remove_breaks = false ) { |
4669 $string = preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $string ); |
5092 $string = preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $string ); |
4670 $string = strip_tags($string); |
5093 $string = strip_tags( $string ); |
4671 |
5094 |
4672 if ( $remove_breaks ) |
5095 if ( $remove_breaks ) { |
4673 $string = preg_replace('/[\r\n\t ]+/', ' ', $string); |
5096 $string = preg_replace( '/[\r\n\t ]+/', ' ', $string ); |
5097 } |
|
4674 |
5098 |
4675 return trim( $string ); |
5099 return trim( $string ); |
4676 } |
5100 } |
4677 |
5101 |
4678 /** |
5102 /** |
4744 * @param string $str String to sanitize. |
5168 * @param string $str String to sanitize. |
4745 * @param bool $keep_newlines optional Whether to keep newlines. Default: false. |
5169 * @param bool $keep_newlines optional Whether to keep newlines. Default: false. |
4746 * @return string Sanitized string. |
5170 * @return string Sanitized string. |
4747 */ |
5171 */ |
4748 function _sanitize_text_fields( $str, $keep_newlines = false ) { |
5172 function _sanitize_text_fields( $str, $keep_newlines = false ) { |
5173 if ( is_object( $str ) || is_array( $str ) ) { |
|
5174 return ''; |
|
5175 } |
|
5176 |
|
5177 $str = (string) $str; |
|
5178 |
|
4749 $filtered = wp_check_invalid_utf8( $str ); |
5179 $filtered = wp_check_invalid_utf8( $str ); |
4750 |
5180 |
4751 if ( strpos($filtered, '<') !== false ) { |
5181 if ( strpos( $filtered, '<' ) !== false ) { |
4752 $filtered = wp_pre_kses_less_than( $filtered ); |
5182 $filtered = wp_pre_kses_less_than( $filtered ); |
4753 // This will strip extra whitespace for us. |
5183 // This will strip extra whitespace for us. |
4754 $filtered = wp_strip_all_tags( $filtered, false ); |
5184 $filtered = wp_strip_all_tags( $filtered, false ); |
4755 |
5185 |
4756 // Use html entities in a special case to make sure no later |
5186 // Use html entities in a special case to make sure no later |
4757 // newline stripping stage could lead to a functional tag |
5187 // newline stripping stage could lead to a functional tag |
4758 $filtered = str_replace("<\n", "<\n", $filtered); |
5188 $filtered = str_replace( "<\n", "<\n", $filtered ); |
4759 } |
5189 } |
4760 |
5190 |
4761 if ( ! $keep_newlines ) { |
5191 if ( ! $keep_newlines ) { |
4762 $filtered = preg_replace( '/[\r\n\t ]+/', ' ', $filtered ); |
5192 $filtered = preg_replace( '/[\r\n\t ]+/', ' ', $filtered ); |
4763 } |
5193 } |
4764 $filtered = trim( $filtered ); |
5194 $filtered = trim( $filtered ); |
4765 |
5195 |
4766 $found = false; |
5196 $found = false; |
4767 while ( preg_match('/%[a-f0-9]{2}/i', $filtered, $match) ) { |
5197 while ( preg_match( '/%[a-f0-9]{2}/i', $filtered, $match ) ) { |
4768 $filtered = str_replace($match[0], '', $filtered); |
5198 $filtered = str_replace( $match[0], '', $filtered ); |
4769 $found = true; |
5199 $found = true; |
4770 } |
5200 } |
4771 |
5201 |
4772 if ( $found ) { |
5202 if ( $found ) { |
4773 // Strip out the whitespace that may now exist after removing the octets. |
5203 // Strip out the whitespace that may now exist after removing the octets. |
4774 $filtered = trim( preg_replace('/ +/', ' ', $filtered) ); |
5204 $filtered = trim( preg_replace( '/ +/', ' ', $filtered ) ); |
4775 } |
5205 } |
4776 |
5206 |
4777 return $filtered; |
5207 return $filtered; |
4778 } |
5208 } |
4779 |
5209 |
4788 */ |
5218 */ |
4789 function wp_basename( $path, $suffix = '' ) { |
5219 function wp_basename( $path, $suffix = '' ) { |
4790 return urldecode( basename( str_replace( array( '%2F', '%5C' ), '/', urlencode( $path ) ), $suffix ) ); |
5220 return urldecode( basename( str_replace( array( '%2F', '%5C' ), '/', urlencode( $path ) ), $suffix ) ); |
4791 } |
5221 } |
4792 |
5222 |
5223 // phpcs:disable WordPress.WP.CapitalPDangit.Misspelled, WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid -- 8-) |
|
4793 /** |
5224 /** |
4794 * Forever eliminate "Wordpress" from the planet (or at least the little bit we can influence). |
5225 * Forever eliminate "Wordpress" from the planet (or at least the little bit we can influence). |
4795 * |
5226 * |
4796 * Violating our coding standards for a good function name. |
5227 * Violating our coding standards for a good function name. |
4797 * |
5228 * |
4803 * @return string The modified text. |
5234 * @return string The modified text. |
4804 */ |
5235 */ |
4805 function capital_P_dangit( $text ) { |
5236 function capital_P_dangit( $text ) { |
4806 // Simple replacement for titles |
5237 // Simple replacement for titles |
4807 $current_filter = current_filter(); |
5238 $current_filter = current_filter(); |
4808 if ( 'the_title' === $current_filter || 'wp_title' === $current_filter ) |
5239 if ( 'the_title' === $current_filter || 'wp_title' === $current_filter ) { |
4809 return str_replace( 'Wordpress', 'WordPress', $text ); |
5240 return str_replace( 'Wordpress', 'WordPress', $text ); |
5241 } |
|
4810 // Still here? Use the more judicious replacement |
5242 // Still here? Use the more judicious replacement |
4811 static $dblq = false; |
5243 static $dblq = false; |
4812 if ( false === $dblq ) { |
5244 if ( false === $dblq ) { |
4813 $dblq = _x( '“', 'opening curly double quote' ); |
5245 $dblq = _x( '“', 'opening curly double quote' ); |
4814 } |
5246 } |
4815 return str_replace( |
5247 return str_replace( |
4816 array( ' Wordpress', '‘Wordpress', $dblq . 'Wordpress', '>Wordpress', '(Wordpress' ), |
5248 array( ' Wordpress', '‘Wordpress', $dblq . 'Wordpress', '>Wordpress', '(Wordpress' ), |
4817 array( ' WordPress', '‘WordPress', $dblq . 'WordPress', '>WordPress', '(WordPress' ), |
5249 array( ' WordPress', '‘WordPress', $dblq . 'WordPress', '>WordPress', '(WordPress' ), |
4818 $text ); |
5250 $text |
4819 } |
5251 ); |
5252 } |
|
5253 // phpcs:enable |
|
4820 |
5254 |
4821 /** |
5255 /** |
4822 * Sanitize a mime type |
5256 * Sanitize a mime type |
4823 * |
5257 * |
4824 * @since 3.1.3 |
5258 * @since 3.1.3 |
4848 * @return string URLs starting with the http or https protocol, separated by a carriage return. |
5282 * @return string URLs starting with the http or https protocol, separated by a carriage return. |
4849 */ |
5283 */ |
4850 function sanitize_trackback_urls( $to_ping ) { |
5284 function sanitize_trackback_urls( $to_ping ) { |
4851 $urls_to_ping = preg_split( '/[\r\n\t ]/', trim( $to_ping ), -1, PREG_SPLIT_NO_EMPTY ); |
5285 $urls_to_ping = preg_split( '/[\r\n\t ]/', trim( $to_ping ), -1, PREG_SPLIT_NO_EMPTY ); |
4852 foreach ( $urls_to_ping as $k => $url ) { |
5286 foreach ( $urls_to_ping as $k => $url ) { |
4853 if ( !preg_match( '#^https?://.#i', $url ) ) |
5287 if ( ! preg_match( '#^https?://.#i', $url ) ) { |
4854 unset( $urls_to_ping[$k] ); |
5288 unset( $urls_to_ping[ $k ] ); |
5289 } |
|
4855 } |
5290 } |
4856 $urls_to_ping = array_map( 'esc_url_raw', $urls_to_ping ); |
5291 $urls_to_ping = array_map( 'esc_url_raw', $urls_to_ping ); |
4857 $urls_to_ping = implode( "\n", $urls_to_ping ); |
5292 $urls_to_ping = implode( "\n", $urls_to_ping ); |
4858 /** |
5293 /** |
4859 * Filters a list of trackback URLs following sanitization. |
5294 * Filters a list of trackback URLs following sanitization. |
4882 */ |
5317 */ |
4883 function wp_slash( $value ) { |
5318 function wp_slash( $value ) { |
4884 if ( is_array( $value ) ) { |
5319 if ( is_array( $value ) ) { |
4885 foreach ( $value as $k => $v ) { |
5320 foreach ( $value as $k => $v ) { |
4886 if ( is_array( $v ) ) { |
5321 if ( is_array( $v ) ) { |
4887 $value[$k] = wp_slash( $v ); |
5322 $value[ $k ] = wp_slash( $v ); |
4888 } else { |
5323 } else { |
4889 $value[$k] = addslashes( $v ); |
5324 $value[ $k ] = addslashes( $v ); |
4890 } |
5325 } |
4891 } |
5326 } |
4892 } else { |
5327 } else { |
4893 $value = addslashes( $value ); |
5328 $value = addslashes( $value ); |
4894 } |
5329 } |
4979 if ( $printed ) { |
5414 if ( $printed ) { |
4980 return; |
5415 return; |
4981 } |
5416 } |
4982 |
5417 |
4983 $printed = true; |
5418 $printed = true; |
4984 ?> |
5419 ?> |
4985 <style type="text/css"> |
5420 <style type="text/css"> |
4986 img.wp-smiley, |
5421 img.wp-smiley, |
4987 img.emoji { |
5422 img.emoji { |
4988 display: inline !important; |
5423 display: inline !important; |
4989 border: none !important; |
5424 border: none !important; |
4994 vertical-align: -0.1em !important; |
5429 vertical-align: -0.1em !important; |
4995 background: none !important; |
5430 background: none !important; |
4996 padding: 0 !important; |
5431 padding: 0 !important; |
4997 } |
5432 } |
4998 </style> |
5433 </style> |
4999 <?php |
5434 <?php |
5000 } |
5435 } |
5001 |
5436 |
5002 /** |
5437 /** |
5003 * Print the inline Emoji detection script if it is not already printed. |
5438 * Print the inline Emoji detection script if it is not already printed. |
5004 * |
5439 * |
5031 * |
5466 * |
5032 * @since 4.2.0 |
5467 * @since 4.2.0 |
5033 * |
5468 * |
5034 * @param string The emoji base URL for png images. |
5469 * @param string The emoji base URL for png images. |
5035 */ |
5470 */ |
5036 'baseUrl' => apply_filters( 'emoji_url', 'https://s.w.org/images/core/emoji/11/72x72/' ), |
5471 'baseUrl' => apply_filters( 'emoji_url', 'https://s.w.org/images/core/emoji/12.0.0-1/72x72/' ), |
5037 |
5472 |
5038 /** |
5473 /** |
5039 * Filters the extension of the emoji png files. |
5474 * Filters the extension of the emoji png files. |
5040 * |
5475 * |
5041 * @since 4.2.0 |
5476 * @since 4.2.0 |
5042 * |
5477 * |
5043 * @param string The emoji extension for png files. Default .png. |
5478 * @param string The emoji extension for png files. Default .png. |
5044 */ |
5479 */ |
5045 'ext' => apply_filters( 'emoji_ext', '.png' ), |
5480 'ext' => apply_filters( 'emoji_ext', '.png' ), |
5046 |
5481 |
5047 /** |
5482 /** |
5048 * Filters the URL where emoji SVG images are hosted. |
5483 * Filters the URL where emoji SVG images are hosted. |
5049 * |
5484 * |
5050 * @since 4.6.0 |
5485 * @since 4.6.0 |
5051 * |
5486 * |
5052 * @param string The emoji base URL for svg images. |
5487 * @param string The emoji base URL for svg images. |
5053 */ |
5488 */ |
5054 'svgUrl' => apply_filters( 'emoji_svg_url', 'https://s.w.org/images/core/emoji/11/svg/' ), |
5489 'svgUrl' => apply_filters( 'emoji_svg_url', 'https://s.w.org/images/core/emoji/12.0.0-1/svg/' ), |
5055 |
5490 |
5056 /** |
5491 /** |
5057 * Filters the extension of the emoji SVG files. |
5492 * Filters the extension of the emoji SVG files. |
5058 * |
5493 * |
5059 * @since 4.6.0 |
5494 * @since 4.6.0 |
5060 * |
5495 * |
5061 * @param string The emoji extension for svg files. Default .svg. |
5496 * @param string The emoji extension for svg files. Default .svg. |
5062 */ |
5497 */ |
5063 'svgExt' => apply_filters( 'emoji_svg_ext', '.svg' ), |
5498 'svgExt' => apply_filters( 'emoji_svg_ext', '.svg' ), |
5064 ); |
5499 ); |
5065 |
5500 |
5066 $version = 'ver=' . get_bloginfo( 'version' ); |
5501 $version = 'ver=' . get_bloginfo( 'version' ); |
5067 |
5502 |
5068 if ( SCRIPT_DEBUG ) { |
5503 if ( SCRIPT_DEBUG ) { |
5074 ); |
5509 ); |
5075 |
5510 |
5076 ?> |
5511 ?> |
5077 <script type="text/javascript"> |
5512 <script type="text/javascript"> |
5078 window._wpemojiSettings = <?php echo wp_json_encode( $settings ); ?>; |
5513 window._wpemojiSettings = <?php echo wp_json_encode( $settings ); ?>; |
5079 <?php readfile( ABSPATH . WPINC . "/js/wp-emoji-loader.js" ); ?> |
5514 <?php readfile( ABSPATH . WPINC . '/js/wp-emoji-loader.js' ); ?> |
5080 </script> |
5515 </script> |
5081 <?php |
5516 <?php |
5082 } else { |
5517 } else { |
5083 $settings['source'] = array( |
5518 $settings['source'] = array( |
5084 /** This filter is documented in wp-includes/class.wp-scripts.php */ |
5519 /** This filter is documented in wp-includes/class.wp-scripts.php */ |
5096 * and edit wp-emoji-loader.js directly. |
5531 * and edit wp-emoji-loader.js directly. |
5097 */ |
5532 */ |
5098 ?> |
5533 ?> |
5099 <script type="text/javascript"> |
5534 <script type="text/javascript"> |
5100 window._wpemojiSettings = <?php echo wp_json_encode( $settings ); ?>; |
5535 window._wpemojiSettings = <?php echo wp_json_encode( $settings ); ?>; |
5101 !function(a,b,c){function d(a,b){var c=String.fromCharCode;l.clearRect(0,0,k.width,k.height),l.fillText(c.apply(this,a),0,0);var d=k.toDataURL();l.clearRect(0,0,k.width,k.height),l.fillText(c.apply(this,b),0,0);var e=k.toDataURL();return d===e}function e(a){var b;if(!l||!l.fillText)return!1;switch(l.textBaseline="top",l.font="600 32px Arial",a){case"flag":return!(b=d([55356,56826,55356,56819],[55356,56826,8203,55356,56819]))&&(b=d([55356,57332,56128,56423,56128,56418,56128,56421,56128,56430,56128,56423,56128,56447],[55356,57332,8203,56128,56423,8203,56128,56418,8203,56128,56421,8203,56128,56430,8203,56128,56423,8203,56128,56447]),!b);case"emoji":return b=d([55358,56760,9792,65039],[55358,56760,8203,9792,65039]),!b}return!1}function f(a){var c=b.createElement("script");c.src=a,c.defer=c.type="text/javascript",b.getElementsByTagName("head")[0].appendChild(c)}var g,h,i,j,k=b.createElement("canvas"),l=k.getContext&&k.getContext("2d");for(j=Array("flag","emoji"),c.supports={everything:!0,everythingExceptFlag:!0},i=0;i<j.length;i++)c.supports[j[i]]=e(j[i]),c.supports.everything=c.supports.everything&&c.supports[j[i]],"flag"!==j[i]&&(c.supports.everythingExceptFlag=c.supports.everythingExceptFlag&&c.supports[j[i]]);c.supports.everythingExceptFlag=c.supports.everythingExceptFlag&&!c.supports.flag,c.DOMReady=!1,c.readyCallback=function(){c.DOMReady=!0},c.supports.everything||(h=function(){c.readyCallback()},b.addEventListener?(b.addEventListener("DOMContentLoaded",h,!1),a.addEventListener("load",h,!1)):(a.attachEvent("onload",h),b.attachEvent("onreadystatechange",function(){"complete"===b.readyState&&c.readyCallback()})),g=c.source||{},g.concatemoji?f(g.concatemoji):g.wpemoji&&g.twemoji&&(f(g.twemoji),f(g.wpemoji)))}(window,document,window._wpemojiSettings); |
5536 !function(a,b,c){function d(a,b){var c=String.fromCharCode;l.clearRect(0,0,k.width,k.height),l.fillText(c.apply(this,a),0,0);var d=k.toDataURL();l.clearRect(0,0,k.width,k.height),l.fillText(c.apply(this,b),0,0);var e=k.toDataURL();return d===e}function e(a){var b;if(!l||!l.fillText)return!1;switch(l.textBaseline="top",l.font="600 32px Arial",a){case"flag":return!(b=d([55356,56826,55356,56819],[55356,56826,8203,55356,56819]))&&(b=d([55356,57332,56128,56423,56128,56418,56128,56421,56128,56430,56128,56423,56128,56447],[55356,57332,8203,56128,56423,8203,56128,56418,8203,56128,56421,8203,56128,56430,8203,56128,56423,8203,56128,56447]),!b);case"emoji":return b=d([55357,56424,55356,57342,8205,55358,56605,8205,55357,56424,55356,57340],[55357,56424,55356,57342,8203,55358,56605,8203,55357,56424,55356,57340]),!b}return!1}function f(a){var c=b.createElement("script");c.src=a,c.defer=c.type="text/javascript",b.getElementsByTagName("head")[0].appendChild(c)}var g,h,i,j,k=b.createElement("canvas"),l=k.getContext&&k.getContext("2d");for(j=Array("flag","emoji"),c.supports={everything:!0,everythingExceptFlag:!0},i=0;i<j.length;i++)c.supports[j[i]]=e(j[i]),c.supports.everything=c.supports.everything&&c.supports[j[i]],"flag"!==j[i]&&(c.supports.everythingExceptFlag=c.supports.everythingExceptFlag&&c.supports[j[i]]);c.supports.everythingExceptFlag=c.supports.everythingExceptFlag&&!c.supports.flag,c.DOMReady=!1,c.readyCallback=function(){c.DOMReady=!0},c.supports.everything||(h=function(){c.readyCallback()},b.addEventListener?(b.addEventListener("DOMContentLoaded",h,!1),a.addEventListener("load",h,!1)):(a.attachEvent("onload",h),b.attachEvent("onreadystatechange",function(){"complete"===b.readyState&&c.readyCallback()})),g=c.source||{},g.concatemoji?f(g.concatemoji):g.wpemoji&&g.twemoji&&(f(g.twemoji),f(g.wpemoji)))}(window,document,window._wpemojiSettings); |
5102 </script> |
5537 </script> |
5103 <?php |
5538 <?php |
5104 } |
5539 } |
5105 } |
5540 } |
5106 |
5541 |
5113 * |
5548 * |
5114 * @param string $content The content to encode. |
5549 * @param string $content The content to encode. |
5115 * @return string The encoded content. |
5550 * @return string The encoded content. |
5116 */ |
5551 */ |
5117 function wp_encode_emoji( $content ) { |
5552 function wp_encode_emoji( $content ) { |
5118 $emoji = _wp_emoji_list( 'partials' ); |
5553 $emoji = _wp_emoji_list( 'partials' ); |
5554 $compat = version_compare( phpversion(), '5.4', '<' ); |
|
5119 |
5555 |
5120 foreach ( $emoji as $emojum ) { |
5556 foreach ( $emoji as $emojum ) { |
5121 if ( version_compare( phpversion(), '5.4', '<' ) ) { |
5557 if ( $compat ) { |
5122 $emoji_char = html_entity_decode( $emojum, ENT_COMPAT, 'UTF-8' ); |
5558 $emoji_char = html_entity_decode( $emojum, ENT_COMPAT, 'UTF-8' ); |
5123 } else { |
5559 } else { |
5124 $emoji_char = html_entity_decode( $emojum ); |
5560 $emoji_char = html_entity_decode( $emojum ); |
5125 } |
5561 } |
5126 if ( false !== strpos( $content, $emoji_char ) ) { |
5562 if ( false !== strpos( $content, $emoji_char ) ) { |
5156 |
5592 |
5157 $emoji = _wp_emoji_list( 'entities' ); |
5593 $emoji = _wp_emoji_list( 'entities' ); |
5158 |
5594 |
5159 // Quickly narrow down the list of emoji that might be in the text and need replacing. |
5595 // Quickly narrow down the list of emoji that might be in the text and need replacing. |
5160 $possible_emoji = array(); |
5596 $possible_emoji = array(); |
5161 foreach( $emoji as $emojum ) { |
5597 $compat = version_compare( phpversion(), '5.4', '<' ); |
5598 foreach ( $emoji as $emojum ) { |
|
5162 if ( false !== strpos( $text, $emojum ) ) { |
5599 if ( false !== strpos( $text, $emojum ) ) { |
5163 if ( version_compare( phpversion(), '5.4', '<' ) ) { |
5600 if ( $compat ) { |
5164 $possible_emoji[ $emojum ] = html_entity_decode( $emojum, ENT_COMPAT, 'UTF-8' ); |
5601 $possible_emoji[ $emojum ] = html_entity_decode( $emojum, ENT_COMPAT, 'UTF-8' ); |
5165 } else { |
5602 } else { |
5166 $possible_emoji[ $emojum ] = html_entity_decode( $emojum ); |
5603 $possible_emoji[ $emojum ] = html_entity_decode( $emojum ); |
5167 } |
5604 } |
5168 } |
5605 } |
5171 if ( ! $possible_emoji ) { |
5608 if ( ! $possible_emoji ) { |
5172 return $text; |
5609 return $text; |
5173 } |
5610 } |
5174 |
5611 |
5175 /** This filter is documented in wp-includes/formatting.php */ |
5612 /** This filter is documented in wp-includes/formatting.php */ |
5176 $cdn_url = apply_filters( 'emoji_url', 'https://s.w.org/images/core/emoji/11/72x72/' ); |
5613 $cdn_url = apply_filters( 'emoji_url', 'https://s.w.org/images/core/emoji/12.0.0-1/72x72/' ); |
5177 |
5614 |
5178 /** This filter is documented in wp-includes/formatting.php */ |
5615 /** This filter is documented in wp-includes/formatting.php */ |
5179 $ext = apply_filters( 'emoji_ext', '.png' ); |
5616 $ext = apply_filters( 'emoji_ext', '.png' ); |
5180 |
5617 |
5181 $output = ''; |
5618 $output = ''; |
5184 * It'll never be consolidated. |
5621 * It'll never be consolidated. |
5185 * |
5622 * |
5186 * First, capture the tags as well as in between. |
5623 * First, capture the tags as well as in between. |
5187 */ |
5624 */ |
5188 $textarr = preg_split( '/(<.*>)/U', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); |
5625 $textarr = preg_split( '/(<.*>)/U', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); |
5189 $stop = count( $textarr ); |
5626 $stop = count( $textarr ); |
5190 |
5627 |
5191 // Ignore processing of specific tags. |
5628 // Ignore processing of specific tags. |
5192 $tags_to_ignore = 'code|pre|style|script|textarea'; |
5629 $tags_to_ignore = 'code|pre|style|script|textarea'; |
5193 $ignore_block_element = ''; |
5630 $ignore_block_element = ''; |
5194 |
5631 |
5195 for ( $i = 0; $i < $stop; $i++ ) { |
5632 for ( $i = 0; $i < $stop; $i++ ) { |
5196 $content = $textarr[$i]; |
5633 $content = $textarr[ $i ]; |
5197 |
5634 |
5198 // If we're in an ignore block, wait until we find its closing tag. |
5635 // If we're in an ignore block, wait until we find its closing tag. |
5199 if ( '' == $ignore_block_element && preg_match( '/^<(' . $tags_to_ignore . ')>/', $content, $matches ) ) { |
5636 if ( '' == $ignore_block_element && preg_match( '/^<(' . $tags_to_ignore . ')>/', $content, $matches ) ) { |
5200 $ignore_block_element = $matches[1]; |
5637 $ignore_block_element = $matches[1]; |
5201 } |
5638 } |
5202 |
5639 |
5203 // If it's not a tag and not in ignore block. |
5640 // If it's not a tag and not in ignore block. |
5204 if ( '' == $ignore_block_element && strlen( $content ) > 0 && '<' != $content[0] && false !== strpos( $content, '&#x' ) ) { |
5641 if ( '' == $ignore_block_element && strlen( $content ) > 0 && '<' != $content[0] && false !== strpos( $content, '&#x' ) ) { |
5205 foreach ( $possible_emoji as $emojum => $emoji_char ) { |
5642 foreach ( $possible_emoji as $emojum => $emoji_char ) { |
5206 if ( false === strpos( $content, $emojum ) ) { |
5643 if ( false === strpos( $content, $emojum ) ) { |
5207 continue; |
5644 continue; |
5208 } |
5645 } |
5209 |
5646 |
5210 $file = str_replace( ';&#x', '-', $emojum ); |
5647 $file = str_replace( ';&#x', '-', $emojum ); |
5211 $file = str_replace( array( '&#x', ';'), '', $file ); |
5648 $file = str_replace( array( '&#x', ';' ), '', $file ); |
5212 |
5649 |
5213 $entity = sprintf( '<img src="%s" alt="%s" class="wp-smiley" style="height: 1em; max-height: 1em;" />', $cdn_url . $file . $ext, $emoji_char ); |
5650 $entity = sprintf( '<img src="%s" alt="%s" class="wp-smiley" style="height: 1em; max-height: 1em;" />', $cdn_url . $file . $ext, $emoji_char ); |
5214 |
5651 |
5215 $content = str_replace( $emojum, $entity, $content ); |
5652 $content = str_replace( $emojum, $entity, $content ); |
5216 } |
5653 } |
5217 } |
5654 } |
5218 |
5655 |
5219 // Did we exit ignore block. |
5656 // Did we exit ignore block. |
5220 if ( '' != $ignore_block_element && '</' . $ignore_block_element . '>' == $content ) { |
5657 if ( '' != $ignore_block_element && '</' . $ignore_block_element . '>' == $content ) { |
5221 $ignore_block_element = ''; |
5658 $ignore_block_element = ''; |
5222 } |
5659 } |
5223 |
5660 |
5224 $output .= $content; |
5661 $output .= $content; |
5225 } |
5662 } |
5258 $headers = explode( "\n", str_replace( "\r\n", "\n", $mail['headers'] ) ); |
5695 $headers = explode( "\n", str_replace( "\r\n", "\n", $mail['headers'] ) ); |
5259 } |
5696 } |
5260 } |
5697 } |
5261 |
5698 |
5262 foreach ( $headers as $header ) { |
5699 foreach ( $headers as $header ) { |
5263 if ( strpos($header, ':') === false ) { |
5700 if ( strpos( $header, ':' ) === false ) { |
5264 continue; |
5701 continue; |
5265 } |
5702 } |
5266 |
5703 |
5267 // Explode them out. |
5704 // Explode them out. |
5268 list( $name, $content ) = explode( ':', trim( $header ), 2 ); |
5705 list( $name, $content ) = explode( ':', trim( $header ), 2 ); |
5269 |
5706 |
5270 // Cleanup crew. |
5707 // Cleanup crew. |
5271 $name = trim( $name ); |
5708 $name = trim( $name ); |
5272 $content = trim( $content ); |
5709 $content = trim( $content ); |
5273 |
5710 |
5274 if ( 'content-type' === strtolower( $name ) ) { |
5711 if ( 'content-type' === strtolower( $name ) ) { |
5275 if ( strpos( $content, ';' ) !== false ) { |
5712 if ( strpos( $content, ';' ) !== false ) { |
5276 list( $type, $charset ) = explode( ';', $content ); |
5713 list( $type, $charset ) = explode( ';', $content ); |
5277 $content_type = trim( $type ); |
5714 $content_type = trim( $type ); |
5278 } else { |
5715 } else { |
5279 $content_type = trim( $content ); |
5716 $content_type = trim( $content ); |
5280 } |
5717 } |
5281 break; |
5718 break; |
5282 } |
5719 } |
5296 |
5733 |
5297 return $mail; |
5734 return $mail; |
5298 } |
5735 } |
5299 |
5736 |
5300 /** |
5737 /** |
5301 * Returns a arrays of emoji data. |
5738 * Returns arrays of emoji data. |
5302 * |
5739 * |
5303 * These arrays automatically built from the regex in twemoji.js - if they need to be updated, |
5740 * These arrays are automatically built from the regex in twemoji.js - if they need to be updated, |
5304 * you should update the regex there, then run the `grunt precommit:emoji` job. |
5741 * you should update the regex there, then run the `grunt precommit:emoji` job. |
5305 * |
5742 * |
5306 * @since 4.9.0 |
5743 * @since 4.9.0 |
5307 * @access private |
5744 * @access private |
5308 * |
5745 * |
5311 */ |
5748 */ |
5312 function _wp_emoji_list( $type = 'entities' ) { |
5749 function _wp_emoji_list( $type = 'entities' ) { |
5313 // Do not remove the START/END comments - they're used to find where to insert the arrays. |
5750 // Do not remove the START/END comments - they're used to find where to insert the arrays. |
5314 |
5751 |
5315 // START: emoji arrays |
5752 // START: emoji arrays |
5316 $entities = array('👩‍❤️‍💋‍👩','👩‍❤️‍💋‍👨','👨‍❤️‍💋‍👨','🏴󠁧󠁢󠁳󠁣󠁴󠁿','🏴󠁧󠁢󠁷󠁬󠁳󠁿','🏴󠁧󠁢󠁥󠁮󠁧󠁿','👩‍👩‍👧‍👦','👨‍👨‍👦‍👦','👩‍👩‍👦‍👦','👨‍👨‍👧‍👦','👨‍👨‍👧‍👧','👨‍👩‍👧‍👧','👨‍👩‍👦‍👦','👩‍👩‍👧‍👧','👨‍👩‍👧‍👦','👨‍❤️‍👨','👩‍❤️‍👨','👩‍❤️‍👩','👩‍👩‍👦','👩‍👦‍👦','👩‍👧‍👦','👩‍👧‍👧','👨‍👨‍👦','👨‍👩‍👧','👨‍👧‍👧','👨‍👧‍👦','👩‍👩‍👧','👨‍👩‍👦','👨‍👨‍👧','👨‍👦‍👦','🤵🏿‍♀️','🏋🏻‍♂️','🏋🏼‍♀️','🏋🏼‍♂️','🏋🏽‍♀️','🏋🏽‍♂️','🏋🏾‍♀️','🏋🏾‍♂️','🏋🏿‍♀️','🏋🏿‍♂️','🏌🏻‍♀️','🏌🏻‍♂️','🏌🏼‍♀️','🏌🏼‍♂️','🏌🏽‍♀️','🏌🏽‍♂️','🏌🏾‍♀️','🏌🏾‍♂️','🏌🏿‍♀️','🏌🏿‍♂️','💂🏻‍♀️','🏃🏼‍♀️','🏃🏼‍♂️','🧝🏿‍♂️','🧝🏿‍♀️','🧝🏾‍♂️','🧝🏾‍♀️','🧝🏽‍♂️','🧝🏽‍♀️','🧝🏼‍♂️','🧝🏼‍♀️','🧝🏻‍♂️','🧝🏻‍♀️','🧜🏿‍♂️','🧜🏿‍♀️','🧜🏾‍♂️','🧜🏾‍♀️','🧜🏽‍♂️','🧜🏽‍♀️','🧜🏼‍♂️','🧜🏼‍♀️','👨🏻‍⚕️','👨🏻‍⚖️','👨🏻‍✈️','🧜🏻‍♂️','🧜🏻‍♀️','🧛🏿‍♂️','🧛🏿‍♀️','🧛🏾‍♂️','🧛🏾‍♀️','🧛🏽‍♂️','🧛🏽‍♀️','🧛🏼‍♂️','🧛🏼‍♀️','🧛🏻‍♂️','🧛🏻‍♀️','🧚🏿‍♂️','🧚🏿‍♀️','🧚🏾‍♂️','🧚🏾‍♀️','🧚🏽‍♂️','👨🏼‍⚕️','👨🏼‍⚖️','👨🏼‍✈️','🧚🏽‍♀️','🧚🏼‍♂️','🧚🏼‍♀️','🧚🏻‍♂️','🧚🏻‍♀️','🧙🏿‍♂️','🧙🏿‍♀️','🧙🏾‍♂️','🧙🏾‍♀️','🧙🏽‍♂️','🧙🏽‍♀️','🧙🏼‍♂️','🧙🏼‍♀️','🧙🏻‍♂️','🧙🏻‍♀️','🧘🏿‍♂️','🧘🏿‍♀️','👨🏽‍⚕️','👨🏽‍⚖️','👨🏽‍✈️','🧘🏾‍♂️','🧘🏾‍♀️','🧘🏽‍♂️','🧘🏽‍♀️','🧘🏼‍♂️','🧘🏼‍♀️','🧘🏻‍♂️','🧘🏻‍♀️','🧗🏿‍♂️','🧗🏿‍♀️','🧗🏾‍♂️','🧗🏾‍♀️','🧗🏽‍♂️','🧗🏽‍♀️','🧗🏼‍♂️','🧗🏼‍♀️','🧗🏻‍♂️','👨🏾‍⚕️','👨🏾‍⚖️','👨🏾‍✈️','🧗🏻‍♀️','🧖🏿‍♂️','🧖🏿‍♀️','🧖🏾‍♂️','🧖🏾‍♀️','🧖🏽‍♂️','🧖🏽‍♀️','🧖🏼‍♂️','🧖🏼‍♀️','🧖🏻‍♂️','🧖🏻‍♀️','🦹🏿‍♂️','🦹🏿‍♀️','🦹🏾‍♂️','🦹🏾‍♀️','🦹🏽‍♂️','🦹🏽‍♀️','👨🏿‍⚕️','👨🏿‍⚖️','👨🏿‍✈️','🦹🏼‍♂️','🦹🏼‍♀️','🦹🏻‍♂️','🦹🏻‍♀️','🦸🏿‍♂️','🦸🏿‍♀️','🦸🏾‍♂️','🏃🏽‍♀️','🦸🏾‍♀️','🏃🏽‍♂️','🏃🏾‍♀️','🦸🏽‍♂️','🏃🏾‍♂️','🏃🏿‍♀️','🏃🏿‍♂️','🏄🏻‍♀️','🏄🏻‍♂️','🏄🏼‍♀️','🏄🏼‍♂️','🏄🏽‍♀️','🏄🏽‍♂️','🏄🏾‍♀️','🦸🏽‍♀️','🦸🏼‍♂️','🦸🏼‍♀️','🦸🏻‍♂️','🦸🏻‍♀️','🤾🏿‍♂️','🤾🏿‍♀️','🤾🏾‍♂️','🤾🏾‍♀️','🤾🏽‍♂️','🤾🏽‍♀️','🤾🏼‍♂️','🤾🏼‍♀️','🏄🏾‍♂️','🏄🏿‍♀️','🤾🏻‍♂️','🤾🏻‍♀️','🤽🏿‍♂️','🤽🏿‍♀️','🤽🏾‍♂️','🤽🏾‍♀️','🤽🏽‍♂️','🤽🏽‍♀️','🤽🏼‍♂️','🤽🏼‍♀️','🤽🏻‍♂️','🤽🏻‍♀️','🤹🏿‍♂️','🤹🏿‍♀️','🤹🏾‍♂️','🤹🏾‍♀️','🤹🏽‍♂️','👩🏻‍⚕️','👩🏻‍⚖️','👩🏻‍✈️','🤹🏽‍♀️','🤹🏼‍♂️','🤹🏼‍♀️','🤹🏻‍♂️','🤹🏻‍♀️','🤸🏿‍♂️','🤸🏿‍♀️','🤸🏾‍♂️','🤸🏾‍♀️','🤸🏽‍♂️','🤸🏽‍♀️','🤸🏼‍♂️','🤸🏼‍♀️','🤸🏻‍♂️','🤸🏻‍♀️','🤷🏿‍♂️','🤷🏿‍♀️','👩🏼‍⚕️','👩🏼‍⚖️','👩🏼‍✈️','🤷🏾‍♂️','🤷🏾‍♀️','🤷🏽‍♂️','🤷🏽‍♀️','🤷🏼‍♂️','🤷🏼‍♀️','🤷🏻‍♂️','🤷🏻‍♀️','🤵🏿‍♂️','🏃🏻‍♂️','🤵🏾‍♂️','🤵🏾‍♀️','🤵🏽‍♂️','🤵🏽‍♀️','🤵🏼‍♂️','🤵🏼‍♀️','🤵🏻‍♂️','👩🏽‍⚕️','👩🏽‍⚖️','👩🏽‍✈️','🤵🏻‍♀️','🤦🏿‍♂️','🤦🏿‍♀️','🤦🏾‍♂️','🤦🏾‍♀️','🤦🏽‍♂️','🤦🏽‍♀️','🤦🏼‍♂️','🤦🏼‍♀️','🤦🏻‍♂️','🤦🏻‍♀️','🚶🏿‍♂️','🚶🏿‍♀️','🚶🏾‍♂️','🚶🏾‍♀️','🚶🏽‍♂️','🚶🏽‍♀️','👩🏾‍⚕️','👩🏾‍⚖️','👩🏾‍✈️','🚶🏼‍♂️','🚶🏼‍♀️','🚶🏻‍♂️','🚶🏻‍♀️','🚵🏿‍♂️','🚵🏿‍♀️','🚵🏾‍♂️','🚵🏾‍♀️','🚵🏽‍♂️','🚵🏽‍♀️','🚵🏼‍♂️','🚵🏼‍♀️','🚵🏻‍♂️','🚵🏻‍♀️','🚴🏿‍♂️','🚴🏿‍♀️','🚴🏾‍♂️','👩🏿‍⚕️','👩🏿‍⚖️','👩🏿‍✈️','🚴🏾‍♀️','🚴🏽‍♂️','🚴🏽‍♀️','🚴🏼‍♂️','🚴🏼‍♀️','🚴🏻‍♂️','🚴🏻‍♀️','🏄🏿‍♂️','🚣🏿‍♂️','🏊🏻‍♀️','🏊🏻‍♂️','🚣🏿‍♀️','🏊🏼‍♀️','🏊🏼‍♂️','🏊🏽‍♀️','🏊🏽‍♂️','🏊🏾‍♀️','🚣🏾‍♂️','🚣🏾‍♀️','🚣🏽‍♂️','🚣🏽‍♀️','🚣🏼‍♂️','🚣🏼‍♀️','🚣🏻‍♂️','🚣🏻‍♀️','🙎🏿‍♂️','🙎🏿‍♀️','🙎🏾‍♂️','🙎🏾‍♀️','🙎🏽‍♂️','🏊🏾‍♂️','🏊🏿‍♀️','🏊🏿‍♂️','🏋🏻‍♀️','👮🏻‍♀️','👮🏻‍♂️','👮🏼‍♀️','👮🏼‍♂️','👮🏽‍♀️','👮🏽‍♂️','👮🏾‍♀️','👮🏾‍♂️','👮🏿‍♀️','👮🏿‍♂️','🙎🏽‍♀️','🙎🏼‍♂️','🙎🏼‍♀️','🙎🏻‍♂️','👱🏻‍♀️','👱🏻‍♂️','👱🏼‍♀️','👱🏼‍♂️','👱🏽‍♀️','👱🏽‍♂️','👱🏾‍♀️','👱🏾‍♂️','👱🏿‍♀️','👱🏿‍♂️','🙎🏻‍♀️','🙍🏿‍♂️','👳🏻‍♀️','👳🏻‍♂️','👳🏼‍♀️','👳🏼‍♂️','👳🏽‍♀️','👳🏽‍♂️','👳🏾‍♀️','👳🏾‍♂️','👳🏿‍♀️','👳🏿‍♂️','🙍🏿‍♀️','🙍🏾‍♂️','👷🏻‍♀️','👷🏻‍♂️','👷🏼‍♀️','👷🏼‍♂️','👷🏽‍♀️','👷🏽‍♂️','👷🏾‍♀️','👷🏾‍♂️','👷🏿‍♀️','👷🏿‍♂️','🙍🏾‍♀️','🙍🏽‍♂️','💁🏻‍♀️','💁🏻‍♂️','💁🏼‍♀️','💁🏼‍♂️','💁🏽‍♀️','💁🏽‍♂️','💁🏾‍♀️','💁🏾‍♂️','💁🏿‍♀️','💁🏿‍♂️','🙍🏽‍♀️','🙍🏼‍♂️','🏃🏻‍♀️','💂🏻‍♂️','💂🏼‍♀️','💂🏼‍♂️','💂🏽‍♀️','💂🏽‍♂️','💂🏾‍♀️','💂🏾‍♂️','💂🏿‍♀️','💂🏿‍♂️','🙍🏼‍♀️','🙍🏻‍♂️','💆🏻‍♀️','💆🏻‍♂️','💆🏼‍♀️','💆🏼‍♂️','💆🏽‍♀️','💆🏽‍♂️','💆🏾‍♀️','💆🏾‍♂️','💆🏿‍♀️','💆🏿‍♂️','🙍🏻‍♀️','🙋🏿‍♂️','💇🏻‍♀️','💇🏻‍♂️','💇🏼‍♀️','💇🏼‍♂️','💇🏽‍♀️','💇🏽‍♂️','💇🏾‍♀️','💇🏾‍♂️','💇🏿‍♀️','💇🏿‍♂️','🙋🏿‍♀️','🙋🏾‍♂️','🕴🏻‍♀️','🕴🏻‍♂️','🕴🏼‍♀️','🕴🏼‍♂️','🕴🏽‍♀️','🕴🏽‍♂️','🕴🏾‍♀️','🕴🏾‍♂️','🕴🏿‍♀️','🕴🏿‍♂️','🕵🏻‍♀️','🕵🏻‍♂️','🕵🏼‍♀️','🕵🏼‍♂️','🕵🏽‍♀️','🕵🏽‍♂️','🕵🏾‍♀️','🕵🏾‍♂️','🕵🏿‍♀️','🕵🏿‍♂️','🙅🏻‍♀️','🙅🏻‍♂️','🙅🏼‍♀️','🙅🏼‍♂️','🙅🏽‍♀️','🙅🏽‍♂️','🙅🏾‍♀️','🙅🏾‍♂️','🙅🏿‍♀️','🙅🏿‍♂️','🙋🏾‍♀️','🙋🏽‍♂️','🙆🏻‍♀️','🙆🏻‍♂️','🙆🏼‍♀️','🙆🏼‍♂️','🙆🏽‍♀️','🙆🏽‍♂️','🙆🏾‍♀️','🙆🏾‍♂️','🙆🏿‍♀️','🙆🏿‍♂️','🙋🏽‍♀️','🙋🏼‍♂️','🙇🏻‍♀️','🙇🏻‍♂️','🙇🏼‍♀️','🙇🏼‍♂️','🙇🏽‍♀️','🙇🏽‍♂️','🙇🏾‍♀️','🙇🏾‍♂️','🙇🏿‍♀️','🙇🏿‍♂️','🙋🏼‍♀️','🙋🏻‍♂️','🙋🏻‍♀️','🕴️‍♀️','🕴️‍♂️','🏋️‍♀️','🏋️‍♂️','⛹🏾‍♀️','🏌️‍♀️','🏌️‍♂️','⛹🏻‍♂️','⛹🏻‍♀️','⛹🏾‍♂️','⛹🏿‍♀️','⛹🏿‍♂️','🕵️‍♀️','🕵️‍♂️','⛹🏽‍♀️','⛹🏽‍♂️','⛹🏼‍♀️','⛹🏼‍♂️','⛹️‍♀️','⛹️‍♂️','👩🏻‍🎨','👨🏻‍🌾','👨🏻‍🍳','👨🏻‍🎓','👨🏻‍🎤','👨🏻‍🎨','👨🏻‍🏫','👨🏻‍🏭','👨🏻‍💻','👨🏻‍💼','👨🏻‍🔧','👨🏻‍🔬','👨🏻‍🚀','👨🏻‍🚒','👨🏻‍🦰','👨🏻‍🦱','👨🏻‍🦲','👨🏻‍🦳','👨🏼‍🌾','👨🏼‍🍳','👨🏼‍🎓','👨🏼‍🎤','👨🏼‍🎨','👨🏼‍🏫','👨🏼‍🏭','👨🏼‍💻','👨🏼‍💼','👨🏼‍🔧','👨🏼‍🔬','👨🏼‍🚀','👨🏼‍🚒','👨🏼‍🦰','👨🏼‍🦱','👨🏼‍🦲','👨🏼‍🦳','👨🏽‍🌾','👨🏽‍🍳','👨🏽‍🎓','👨🏽‍🎤','👨🏽‍🎨','👨🏽‍🏫','👨🏽‍🏭','👨🏽‍💻','👨🏽‍💼','👨🏽‍🔧','👨🏽‍🔬','👨🏽‍🚀','👨🏽‍🚒','👨🏽‍🦰','👨🏽‍🦱','👨🏽‍🦲','👩🏿‍🦳','👩🏿‍🦲','👩🏿‍🦱','👨🏽‍🦳','👨🏾‍🌾','👩🏿‍🦰','👩🏿‍🚒','👩🏿‍🚀','👩🏿‍🔬','👩🏿‍🔧','👩🏿‍💼','👩🏿‍💻','👩🏿‍🏭','👩🏿‍🏫','👩🏿‍🎨','👨🏾‍🍳','👨🏾‍🎓','👩🏿‍🎤','👩🏿‍🎓','👩🏿‍🍳','👩🏿‍🌾','👩🏾‍🦳','👩🏾‍🦲','👩🏾‍🦱','👩🏾‍🦰','👩🏾‍🚒','👩🏾‍🚀','👨🏾‍🎤','👨🏾‍🎨','👩🏾‍🔬','👩🏾‍🔧','👩🏾‍💼','👩🏾‍💻','👩🏾‍🏭','👩🏾‍🏫','👩🏾‍🎨','👩🏾‍🎤','👩🏾‍🎓','👩🏾‍🍳','👨🏾‍🏫','👨🏾‍🏭','👩🏾‍🌾','👩🏽‍🦳','👩🏽‍🦲','👩🏽‍🦱','👩🏽‍🦰','👩🏽‍🚒','👩🏽‍🚀','👩🏽‍🔬','👩🏽‍🔧','👩🏽‍💼','👨🏾‍💻','👨🏾‍💼','👩🏽‍💻','👩🏽‍🏭','👩🏽‍🏫','👩🏽‍🎨','👩🏽‍🎤','👩🏽‍🎓','👩🏽‍🍳','👩🏽‍🌾','👩🏼‍🦳','👩🏼‍🦲','👨🏾‍🔧','👨🏾‍🔬','👩🏼‍🦱','👩🏼‍🦰','👩🏼‍🚒','👩🏼‍🚀','👩🏼‍🔬','👩🏼‍🔧','👩🏼‍💼','👩🏼‍💻','👩🏼‍🏭','👩🏼‍🏫','👨🏾‍🚀','👨🏾‍🚒','👩🏼‍🎨','👩🏼‍🎤','👩🏼‍🎓','👩🏼‍🍳','👩🏼‍🌾','👩🏻‍🦳','👩🏻‍🦲','👩🏻‍🦱','👩🏻‍🦰','👩🏻‍🚒','👨🏾‍🦰','👨🏾‍🦱','👨🏾‍🦲','👨🏾‍🦳','👩🏻‍🚀','👩🏻‍🔬','👩🏻‍🔧','👩🏻‍💼','👩🏻‍💻','👩🏻‍🏭','👩🏻‍🏫','👨🏿‍🌾','👩🏻‍🎤','👩🏻‍🎓','👨🏿‍🍳','👨🏿‍🎓','👩🏻‍🍳','👩🏻‍🌾','👨🏿‍🎤','👨🏿‍🎨','👨🏿‍🏫','👨🏿‍🏭','👨🏿‍💻','👨🏿‍💼','👨🏿‍🔧','👨🏿‍🔬','👨🏿‍🚀','👨🏿‍🚒','👨🏿‍🦰','👨🏿‍🦱','👨🏿‍🦲','👨🏿‍🦳','🏳️‍🌈','👩‍⚖️','🦸‍♂️','🤾‍♂️','🤾‍♀️','🦹‍♀️','🦹‍♂️','👨‍⚕️','👨‍⚖️','👨‍✈️','🤽‍♂️','🤽‍♀️','🧖‍♀️','🧖‍♂️','🙇‍♀️','🤼‍♂️','🤼‍♀️','🤹‍♂️','🤹‍♀️','🤸‍♂️','🤸‍♀️','🤷‍♂️','🤷‍♀️','🤵‍♂️','🧗‍♀️','🧗‍♂️','🤵‍♀️','🤦‍♂️','🤦‍♀️','🚶‍♂️','🚶‍♀️','🚵‍♂️','🚵‍♀️','🚴‍♂️','🚴‍♀️','🧘‍♀️','🧘‍♂️','🚣‍♂️','🚣‍♀️','🧙‍♀️','🧙‍♂️','🙎‍♂️','🙎‍♀️','🧚‍♀️','🧚‍♂️','👩‍⚕️','🦸‍♀️','👩‍✈️','👮‍♀️','👮‍♂️','👯‍♀️','👯‍♂️','👱‍♀️','🧛‍♀️','🧛‍♂️','🙍‍♂️','🙍‍♀️','👱‍♂️','👳‍♀️','👳‍♂️','👷‍♀️','👷‍♂️','💁‍♀️','💁‍♂️','💂‍♀️','🧜‍♀️','🧜‍♂️','💂‍♂️','💆‍♀️','🙋‍♂️','🙋‍♀️','💆‍♂️','💇‍♀️','💇‍♂️','🙅‍♀️','🙅‍♂️','🧝‍♀️','🧝‍♂️','🧞‍♀️','🧞‍♂️','🧟‍♀️','🧟‍♂️','🏴‍☠️','🙇‍♂️','🙆‍♀️','🙆‍♂️','🏊‍♂️','🏊‍♀️','🏄‍♂️','🏄‍♀️','🏃‍♂️','🏃‍♀️','👨‍🎨','👩‍🍳','👩‍🎓','👩‍🎤','👩‍🎨','👩‍🏫','👩‍🏭','👨‍💻','👨‍🚒','👩‍👦','👨‍👧','👨‍🦰','👨‍🦱','👩‍💻','👩‍💼','👩‍🔧','👩‍🔬','👩‍🚀','👩‍🚒','👩‍🦰','👩‍🦱','👁‍🗨','👨‍🦲','👨‍🦳','👨‍👦','👨‍🎤','👩‍🦲','👩‍🦳','👨‍🎓','👨‍🍳','👨‍🌾','👨‍💼','👨‍🔧','👨‍🔬','👨‍🚀','👨‍🏭','👩‍🌾','👨‍🏫','👩‍👧','👆🏿','👇🏻','👷🏼','👇🏼','👇🏽','👷🏽','👇🏾','👇🏿','👷🏾','👈🏻','👈🏼','👷🏿','👈🏽','👈🏾','👸🏻','👸🏼','👸🏽','👸🏾','👸🏿','👼🏻','👼🏼','👼🏽','👼🏾','👼🏿','👈🏿','👉🏻','💁🏻','👉🏼','👉🏽','💁🏼','👉🏾','👉🏿','💁🏽','👊🏻','👊🏼','💁🏾','👊🏽','👊🏾','💁🏿','👊🏿','👋🏻','👋🏼','👋🏽','💂🏻','👋🏾','👋🏿','💂🏼','👌🏻','👌🏼','💂🏽','👌🏽','👌🏾','💂🏾','👌🏿','👍🏻','💂🏿','👍🏼','👍🏽','💃🏻','💃🏼','💃🏽','💃🏾','💃🏿','💅🏻','💅🏼','💅🏽','💅🏾','💅🏿','👍🏾','👍🏿','💆🏻','👎🏻','👎🏼','💆🏼','👎🏽','👎🏾','💆🏽','👎🏿','👏🏻','💆🏾','👏🏼','👏🏽','💆🏿','👏🏾','👏🏿','👐🏻','👐🏼','💇🏻','👐🏽','👐🏾','💇🏼','👐🏿','👦🏻','💇🏽','👦🏼','👦🏽','💇🏾','👦🏾','👦🏿','💇🏿','👧🏻','👧🏼','💪🏻','💪🏼','💪🏽','💪🏾','💪🏿','👧🏽','👧🏾','🕴🏻','👧🏿','🇪🇪','🕴🏼','🇪🇬','🇪🇭','🕴🏽','🇪🇷','🇪🇸','🕴🏾','🇪🇹','🇪🇺','🕴🏿','🇫🇮','🇫🇯','🇫🇰','🇫🇲','🕵🏻','🇫🇴','🇫🇷','🕵🏼','🇬🇦','🇬🇧','🕵🏽','🇬🇩','🇬🇪','🕵🏾','🇬🇫','🇬🇬','🕵🏿','🇬🇭','👨🏻','🕺🏻','🕺🏼','🕺🏽','🕺🏾','🕺🏿','🖐🏻','🖐🏼','🖐🏽','🖐🏾','🖐🏿','🖕🏻','🖕🏼','🖕🏽','🖕🏾','🖕🏿','🖖🏻','🖖🏼','🖖🏽','🖖🏾','🖖🏿','🇬🇮','🇬🇱','🙅🏻','🇬🇲','🇬🇳','🙅🏼','🇬🇵','🇬🇶','🙅🏽','🇬🇷','🇬🇸','🙅🏾','🇬🇹','🇬🇺','🙅🏿','🇬🇼','🇬🇾','🇭🇰','🇭🇲','🙆🏻','🇭🇳','🇭🇷','🙆🏼','🇭🇹','🇭🇺','🙆🏽','🇮🇨','🇮🇩','🙆🏾','👨🏼','🇮🇪','🙆🏿','🇮🇱','🇮🇲','🇮🇳','🇮🇴','🙇🏻','🇮🇶','🇮🇷','🙇🏼','🇮🇸','🇮🇹','🙇🏽','🇯🇪','🇯🇲','🙇🏾','🇯🇴','🇯🇵','🙇🏿','🇰🇪','🇰🇬','🇰🇭','🇰🇮','🙋🏻','🇰🇲','🇰🇳','🙋🏼','🇰🇵','👨🏽','🙋🏽','🇰🇷','🇰🇼','🙋🏾','🇰🇾','🇰🇿','🙋🏿','🇱🇦','🇱🇧','🙌🏻','🙌🏼','🙌🏽','🙌🏾','🙌🏿','🇱🇨','🇱🇮','🙍🏻','🇱🇰','🇱🇷','🙍🏼','🇱🇸','🇱🇹','🙍🏽','🇱🇺','🇱🇻','🙍🏾','🇱🇾','🇲🇦','🙍🏿','🇲🇨','🇲🇩','🇲🇪','🇲🇫','🙎🏻','👨🏾','🇲🇬','🙎🏼','🇲🇭','🇲🇰','🙎🏽','🇲🇱','🇲🇲','🙎🏾','🇲🇳','🇲🇴','🙎🏿','🇲🇵','🇲🇶','🙏🏻','🙏🏼','🙏🏽','🙏🏾','🙏🏿','🇲🇷','🇲🇸','🚣🏻','🇲🇹','🇲🇺','🚣🏼','🇲🇻','🇲🇼','🚣🏽','🇲🇽','🇲🇾','🚣🏾','🇲🇿','🇳🇦','🚣🏿','🇳🇨','👨🏿','🇳🇪','🇳🇫','🚴🏻','🇳🇬','🇳🇮','🚴🏼','🇳🇱','🇳🇴','🚴🏽','🇳🇵','🇳🇷','🚴🏾','🇳🇺','🇳🇿','🚴🏿','🇴🇲','🇵🇦','🇵🇪','🇵🇫','🚵🏻','🇵🇬','🇵🇭','🚵🏼','🇵🇰','🇵🇱','🚵🏽','🇵🇲','🇵🇳','🚵🏾','🇵🇷','🇵🇸','🚵🏿','🇵🇹','🇵🇼','🇵🇾','🇶🇦','🚶🏻','🇷🇪','🇷🇴','🚶🏼','🇷🇸','🇷🇺','🚶🏽','🇷🇼','🇸🇦','🚶🏾','🇸🇧','🇸🇨','🚶🏿','🇸🇩','🇸🇪','🛀🏻','🛀🏼','🛀🏽','🛀🏾','🛀🏿','🛌🏻','🛌🏼','🛌🏽','🛌🏾','🛌🏿','🤘🏻','🤘🏼','🤘🏽','🤘🏾','🤘🏿','🤙🏻','🤙🏼','🤙🏽','🤙🏾','🤙🏿','🤚🏻','🤚🏼','🤚🏽','🤚🏾','🤚🏿','🤛🏻','🤛🏼','🤛🏽','🤛🏾','🤛🏿','🤜🏻','🤜🏼','🤜🏽','🤜🏾','🤜🏿','🤞🏻','🤞🏼','🤞🏽','🤞🏾','🤞🏿','🤟🏻','🤟🏼','🤟🏽','🤟🏾','🤟🏿','🇸🇬','🇸🇭','🤦🏻','🇸🇮','🇸🇯','🤦🏼','🇸🇰','🇦🇩','🤦🏽','🇸🇲','🇸🇳','🤦🏾','🇸🇴','🇸🇷','🤦🏿','🇸🇸','🇸🇹','🤰🏻','🤰🏼','🤰🏽','🤰🏾','🤰🏿','🤱🏻','🤱🏼','🤱🏽','🤱🏾','🤱🏿','🤲🏻','🤲🏼','🤲🏽','🤲🏾','🤲🏿','🤳🏻','🤳🏼','🤳🏽','🤳🏾','🤳🏿','🤴🏻','🤴🏼','🤴🏽','🤴🏾','🤴🏿','🇸🇻','🇸🇽','🤵🏻','🇸🇾','🇸🇿','🤵🏼','🇹🇦','🇹🇨','🤵🏽','🇹🇩','🇹🇫','🤵🏾','🇹🇬','👩🏻','🤵🏿','🇹🇭','🇹🇯','🤶🏻','🤶🏼','🤶🏽','🤶🏾','🤶🏿','🇹🇰','🇹🇱','🤷🏻','🇹🇲','🇹🇳','🤷🏼','🇹🇴','🇹🇷','🤷🏽','🇹🇹','🇹🇻','🤷🏾','🇹🇼','🇹🇿','🤷🏿','🇺🇦','🇺🇬','🇺🇲','🇺🇳','🤸🏻','🇺🇸','🇺🇾','🤸🏼','🇺🇿','🇻🇦','🤸🏽','👩🏼','🇻🇨','🤸🏾','🇻🇪','🇻🇬','🤸🏿','🇻🇮','🇻🇳','🇻🇺','🇼🇫','🤹🏻','🇼🇸','🇽🇰','🤹🏼','🇾🇪','🇾🇹','🤹🏽','🇿🇦','🇿🇲','🤹🏾','🇿🇼','🎅🏻','🤹🏿','🎅🏼','🎅🏽','🎅🏾','🎅🏿','🏂🏻','👩🏽','🤽🏻','🏂🏼','🏂🏽','🤽🏼','🏂🏾','🏂🏿','🤽🏽','🇦🇨','🇦🇪','🤽🏾','🏃🏻','🇦🇫','🤽🏿','🇦🇬','🏃🏼','🇦🇮','🇦🇱','🤾🏻','🏃🏽','🇦🇲','🤾🏼','🇦🇴','🏃🏾','🤾🏽','🇦🇶','🇦🇷','🤾🏾','🏃🏿','🇦🇸','🤾🏿','👩🏾','🇦🇹','🦵🏻','🦵🏼','🦵🏽','🦵🏾','🦵🏿','🦶🏻','🦶🏼','🦶🏽','🦶🏾','🦶🏿','🇦🇺','🇦🇼','🦸🏻','🏄🏻','🇦🇽','🦸🏼','🇦🇿','🏄🏼','🦸🏽','🇧🇦','🇧🇧','🦸🏾','🏄🏽','🇧🇩','🦸🏿','🇧🇪','🏄🏾','🇧🇫','🇧🇬','🦹🏻','🏄🏿','🇧🇭','🦹🏼','🇧🇮','🏇🏻','🦹🏽','🏇🏼','👩🏿','🦹🏾','🏇🏽','🏇🏾','🦹🏿','🏇🏿','🇧🇯','🧑🏻','🧑🏼','🧑🏽','🧑🏾','🧑🏿','🧒🏻','🧒🏼','🧒🏽','🧒🏾','🧒🏿','🧓🏻','🧓🏼','🧓🏽','🧓🏾','🧓🏿','🧔🏻','🧔🏼','🧔🏽','🧔🏾','🧔🏿','🧕🏻','🧕🏼','🧕🏽','🧕🏾','🧕🏿','🇧🇱','🏊🏻','🧖🏻','🇧🇲','🇧🇳','🧖🏼','🏊🏼','🇧🇴','🧖🏽','🇧🇶','🏊🏽','🧖🏾','🇧🇷','🇧🇸','🧖🏿','🏊🏾','🇧🇹','🇧🇻','🏊🏿','🧗🏻','🇧🇼','🇧🇾','🧗🏼','🇧🇿','🇨🇦','🧗🏽','🏋🏻','🇨🇨','🧗🏾','🇨🇩','🏋🏼','🧗🏿','🇨🇫','🇨🇬','🏋🏽','🇨🇭','🧘🏻','🇨🇮','🏋🏾','🧘🏼','🇨🇰','🇨🇱','🧘🏽','🏋🏿','🇨🇲','🧘🏾','👮🏻','🇨🇳','🧘🏿','🇨🇴','👮🏼','🇨🇵','🏌🏻','🧙🏻','👮🏽','🇨🇷','🧙🏼','🇨🇺','👮🏾','🧙🏽','🏌🏼','🇨🇻','🧙🏾','👮🏿','🇨🇼','🧙🏿','🏌🏽','🇨🇽','🇨🇾','👰🏻','🧚🏻','👰🏼','👰🏽','🧚🏼','👰🏾','👰🏿','🧚🏽','🏌🏾','🇨🇿','🧚🏾','👱🏻','🇩🇪','🧚🏿','🏌🏿','👱🏼','🇩🇬','🇩🇯','🧛🏻','👱🏽','🇩🇰','🧛🏼','🇩🇲','👱🏾','🧛🏽','🇩🇴','🇩🇿','🧛🏾','👱🏿','🇪🇦','🧛🏿','🇪🇨','👲🏻','👲🏼','👲🏽','🧜🏻','👲🏾','👲🏿','🧜🏼','👂🏻','👂🏼','🧜🏽','👳🏻','👂🏽','🧜🏾','👂🏾','👳🏼','🧜🏿','👂🏿','👃🏻','👳🏽','👃🏼','🧝🏻','👃🏽','👳🏾','🧝🏼','👃🏾','👃🏿','🧝🏽','👳🏿','👆🏻','🧝🏾','👆🏼','👴🏻','🧝🏿','👴🏼','👴🏽','👴🏾','👴🏿','👵🏻','👵🏼','👵🏽','👵🏾','👵🏿','👶🏻','👶🏼','👶🏽','👶🏾','👶🏿','👆🏽','👆🏾','👷🏻','🇸🇱','✍🏿','⛹🏻','✍🏾','✍🏽','✍🏼','✍🏻','✌🏿','✌🏾','✌🏽','✌🏼','✌🏻','✋🏿','✋🏾','✋🏽','✋🏼','✋🏻','✊🏿','✊🏾','✊🏽','✊🏼','✊🏻','⛷🏽','⛷🏾','⛹🏿','☝🏿','☝🏾','⛹🏾','☝🏽','☝🏼','⛹🏽','☝🏻','⛷🏿','⛹🏼','⛷🏻','⛷🏼','4⃣','#⃣','0⃣','1⃣','2⃣','3⃣','*⃣','5⃣','6⃣','7⃣','8⃣','9⃣','🃏','🕺','🖇','🖊','🖋','🖌','🖍','🀄','🇾','🇦','🅰','🅱','🖐','🇿','🈁','🈂','🏄','🏅','🖕','🏆','🈚','🈯','🈲','🈳','🖖','🖤','🖥','🖨','🖱','🖲','🖼','🗂','🗃','🗄','🗑','🗒','🗓','🗜','🗝','🗞','🗡','🗣','🗨','🗯','🗳','🗺','🗻','🗼','🗽','🗾','🗿','😀','😁','😂','😃','😄','😅','😆','😇','😈','😉','😊','😋','😌','😍','😎','😏','😐','😑','😒','😓','😔','😕','😖','😗','😘','😙','😚','😛','😜','😝','😞','😟','😠','😡','😢','😣','😤','😥','😦','😧','😨','😩','😪','😫','😬','😭','😮','😯','😰','😱','😲','😳','😴','😵','😶','😷','😸','😹','😺','😻','😼','😽','😾','😿','🙀','🙁','🙂','🙃','🙄','🈴','🏇','🏈','🏉','🈵','🈶','🈷','🈸','🈹','🈺','🉐','🉑','🌀','🌁','🌂','🌃','🌄','🙅','🌅','🌆','🌇','🌈','🏊','🌉','🌊','🌋','🌌','👨','🌍','🌎','🌏','🌐','🌑','🌒','🌓','🙆','🌔','🌕','🌖','🌗','🌘','🌙','🏋','🌚','🌛','🌜','🌝','🌞','🌟','🌠','🌡','🌤','🌥','🙇','🙈','🙉','🙊','🌦','🌧','🌨','🌩','🌪','🌫','🌬','🏌','🏍','🏎','🏏','🏐','🏑','🏒','🏓','🏔','🏕','🙋','🏖','🏗','🏘','🏙','🏚','🙌','🏛','🏜','🏝','🏞','🏟','🏠','🏡','🏢','🏣','🏤','🏥','🏦','🏧','🏨','🏩','🏪','🏫','🙍','🏬','🏭','🏮','🏯','🏰','🌭','🏳','🌮','🌯','🌰','🌱','🏴','🏵','🏷','🏸','🏹','🏺','🙎','🏻','🏼','🏽','🏾','🏿','🙏','🚀','🚁','🚂','🚃','🚄','🚅','🚆','🚇','🚈','🚉','🚊','🚋','🚌','🚍','🚎','🚏','🚐','🚑','🚒','🚓','🚔','🚕','🚖','🚗','🚘','🚙','🚚','🚛','🚜','🚝','🚞','🚟','🚠','🚡','🚢','🐀','🐁','🐂','🐃','🐄','🐅','🐆','🐇','🐈','🐉','🐊','🐋','🐌','🐍','🐎','🐏','🐐','🚣','🚤','🚥','🚦','🚧','🚨','🚩','🚪','🚫','🚬','🚭','🚮','🚯','🚰','🚱','🚲','🚳','🐑','🐒','🐓','🐔','🐕','🐖','🐗','🐘','🐙','🐚','🐛','🐜','🐝','🐞','🐟','🐠','🐡','🚴','🐢','🐣','🐤','🐥','🐦','🐧','🐨','🐩','🐪','🐫','🐬','🐭','🐮','🐯','🐰','🐱','🐲','🚵','🐳','🐴','🐵','👩','👪','👫','👬','👭','🐶','🐷','🐸','🐹','🐺','🐻','🐼','🐽','🐾','🚶','🚷','🚸','🚹','🚺','🚻','🚼','🚽','🚾','🚿','🐿','👀','🌲','👁','🌳','🛀','🛁','🛂','🛃','🛄','🛅','🛋','🌴','🌵','🌶','👮','🌷','🛌','🛍','🛎','🛏','🛐','🛑','🛒','🛠','🛡','🛢','🛣','🛤','🛥','🛩','🛫','🛬','🛰','🛳','🛴','🛵','🛶','🛷','🛸','🛹','🤐','🤑','🤒','🤓','🤔','🤕','🤖','🤗','👂','👯','🌸','🌹','🌺','🤘','🌻','🌼','👰','👃','👄','🤙','👅','🌽','🌾','🌿','🍀','🤚','🍁','👆','🍂','🍃','🍄','🤛','🍅','🍆','👇','🍇','🍈','🤜','🤝','👱','🍉','🍊','🍋','👈','🤞','🍌','👲','🍍','🍎','🍏','🤟','🤠','🤡','🤢','🤣','🤤','🤥','🍐','👉','🍑','🍒','🍓','🍔','🍕','👊','🍖','🍗','🍘','🍙','🍚','👋','👳','🍛','🍜','🤦','🤧','🤨','🤩','🤪','🤫','🤬','🤭','🤮','🤯','🍝','🍞','🍟','👴','👌','🤰','🍠','🍡','🍢','🍣','👵','🤱','🍤','👍','🍥','🍦','🍧','🤲','👶','🍨','🍩','👎','🍪','🤳','🍫','🍬','🍭','🍮','👏','🤴','🍯','🍰','🍱','🍲','🍳','👐','👑','👒','👷','👓','👔','👕','👖','👗','👸','👹','👺','🤵','👻','👘','👙','👚','👛','🤶','👜','👼','👽','👾','👿','💀','👝','👞','👟','👠','👡','👢','👣','👤','👥','🍴','🍵','🤷','🍶','🍷','🍸','👦','🍹','🍺','💁','🍻','🍼','🍽','👧','🍾','🍿','🎀','🎁','🎂','🎃','🤸','🎄','🇵','🅾','🇶','🇲','🅿','🎅','💂','🎆','🎇','🎈','🎉','🎊','💃','💄','🎋','🎌','🤹','🤺','🎍','🎎','🤼','🎏','💅','🎐','🎑','🎒','🎓','🎖','🎗','🎙','🎚','🎛','🎞','🎟','🎠','🎡','🎢','🎣','🤽','🎤','🎥','💆','🎦','🎧','🎨','🎩','🎪','🎫','🎬','🎭','🎮','🎯','🎰','🎱','🎲','🎳','🤾','🥀','🥁','🥂','🥃','🥄','🥅','🥇','🥈','🥉','🥊','🥋','🥌','🥍','🥎','🥏','🥐','🥑','🥒','🥓','🥔','🥕','🥖','🥗','🥘','🥙','🥚','🥛','🥜','🥝','🥞','🥟','🥠','🥡','🥢','🥣','🥤','🥥','🥦','🥧','🥨','🥩','🥪','🥫','🥬','🥭','🥮','🥯','🥰','🥳','🥴','🥵','🥶','🥺','🥼','🥽','🥾','🥿','🦀','🦁','🦂','🦃','🦄','🦅','🦆','🦇','🦈','🦉','🦊','🦋','🦌','🦍','🦎','🦏','🦐','🦑','🦒','🦓','🦔','🦕','🦖','🦗','🦘','🦙','🦚','🦛','🦜','🦝','🦞','🦟','🦠','🦡','🦢','🦴','🎴','🎵','🎶','💇','💈','🦵','💉','💊','💋','💌','💍','🦶','🦷','💎','💏','💐','💑','💒','💓','💔','💕','💖','💗','💘','💙','💚','💛','💜','💝','💞','🦸','💟','💠','💡','💢','💣','💤','💥','💦','💧','💨','💩','🎷','🎸','🎹','🎺','🎻','💪','🦹','🧀','🧁','🧂','🧐','💫','💬','💭','💮','💯','🧑','💰','💱','💲','💳','💴','🧒','💵','💶','💷','💸','💹','🧓','💺','💻','💼','💽','💾','🧔','💿','📀','📁','📂','📃','🧕','📄','📅','📆','📇','📈','📉','📊','📋','📌','📍','📎','📏','📐','📑','📒','📓','📔','🧖','📕','📖','📗','📘','📙','📚','📛','📜','📝','📞','📟','📠','📡','📢','📣','📤','📥','🧗','📦','📧','📨','📩','📪','📫','📬','📭','📮','📯','📰','📱','📲','📳','📴','📵','📶','🧘','📷','📸','📹','📺','📻','📼','📽','📿','🔀','🔁','🔂','🔃','🔄','🔅','🔆','🔇','🔈','🧙','🔉','🔊','🔋','🔌','🔍','🔎','🔏','🔐','🔑','🔒','🔓','🔔','🔕','🔖','🔗','🔘','🔙','🧚','🔚','🔛','🔜','🔝','🔞','🔟','🔠','🔡','🔢','🔣','🔤','🔥','🔦','🔧','🔨','🔩','🔪','🧛','🔫','🔬','🔭','🔮','🔯','🔰','🔱','🔲','🔳','🔴','🔵','🔶','🔷','🔸','🔹','🔺','🔻','🧜','🔼','🔽','🕉','🕊','🕋','🕌','🕍','🕎','🕐','🕑','🕒','🕓','🕔','🕕','🕖','🕗','🕘','🧝','🕙','🕚','🧞','🕛','🕜','🧟','🧠','🧡','🧢','🧣','🧤','🧥','🧦','🧧','🧨','🧩','🧪','🧫','🧬','🧭','🧮','🧯','🧰','🧱','🧲','🧳','🧴','🧵','🧶','🧷','🧸','🧹','🧺','🧻','🧼','🧽','🧾','🧿','🕝','🕞','🕟','🕠','🕡','🕢','🕣','🕤','🕥','🕦','🕧','🕯','🕰','🕳','🎼','🎽','🎾','🎿','🏀','🏁','🇧','🇮','🇪','🇷','🇱','🏂','🆎','🆑','🇨','🇹','🇯','🕴','🆒','🇬','🆓','🇳','🆔','🇴','🇺','🇫','🆕','🆖','🆗','🇭','🏃','🆘','🇩','🇻','🇰','🕵','🕶','🕷','🕸','🕹','🆙','🇼','🆚','🇽','🇸','▫','☦','☮','☯','☸','☹','☺','♀','♂','♈','♉','♊','♋','♌','♍','♎','♏','♐','♑','♒','♓','♟','♠','♣','♥','♦','♨','♻','♾','♿','⚒','⚓','⚔','⚕','⚖','⚗','⚙','⚛','⚜','⚠','⚡','⚪','⚫','⚰','⚱','⚽','⚾','⛄','⛅','⛈','⛎','⛏','⛑','⛓','⛔','⛩','⛪','⛰','⛱','⛲','⛳','⛴','⛵','☣','☢','☠','☝','☘','⛷','⛸','☕','☔','☑','☎','☄','☃','☂','☁','☀','◾','◽','◼','◻','◀','▶','☪','▪','⛹','⛺','⛽','✂','✅','✈','✉','Ⓜ','⏺','⏹','⏸','⏳','✊','⏲','⏱','⏰','⏯','⏮','✋','⏭','⏬','⏫','⏪','⏩','✌','⏏','⌨','⌛','⌚','↪','✍','✏','✒','✔','✖','✝','✡','✨','✳','✴','❄','❇','❌','❎','❓','❔','❕','❗','❣','❤','➕','➖','➗','➡','➰','➿','⤴','⤵','↩','⬅','⬆','⬇','⬛','⬜','⭐','⭕','↙','〰','〽','↘','↗','㊗','㊙','↖','↕','↔','ℹ','™','⁉','‼',''); |
5753 $entities = array( '👨‍❤️‍💋‍👨', '👩‍❤️‍💋‍👩', '👩‍❤️‍💋‍👨', '🏴󠁧󠁢󠁥󠁮󠁧󠁿', '🏴󠁧󠁢󠁳󠁣󠁴󠁿', '🏴󠁧󠁢󠁷󠁬󠁳󠁿', '🧑🏿‍🤝‍🧑🏻', '🧑🏾‍🤝‍🧑🏾', '🧑🏾‍🤝‍🧑🏽', '🧑🏾‍🤝‍🧑🏼', '🧑🏾‍🤝‍🧑🏻', '🧑🏽‍🤝‍🧑🏽', '🧑🏽‍🤝‍🧑🏼', '🧑🏽‍🤝‍🧑🏻', '🧑🏼‍🤝‍🧑🏼', '🧑🏼‍🤝‍🧑🏻', '🧑🏻‍🤝‍🧑🏻', '👩🏾‍🤝‍👩🏽', '🧑🏿‍🤝‍🧑🏿', '🧑🏿‍🤝‍🧑🏾', '👨🏼‍🤝‍👨🏻', '🧑🏿‍🤝‍🧑🏽', '🧑🏿‍🤝‍🧑🏼', '👩🏻‍🤝‍👨🏼', '👩🏻‍🤝‍👨🏽', '👩🏻‍🤝‍👨🏾', '👩🏻‍🤝‍👨🏿', '👨🏿‍🤝‍👨🏾', '👨🏿‍🤝‍👨🏽', '👨🏿‍🤝‍👨🏼', '👨🏿‍🤝‍👨🏻', '👩🏼‍🤝‍👨🏻', '👩🏼‍🤝‍👨🏽', '👨🏽‍🤝‍👨🏻', '👨🏽‍🤝‍👨🏼', '👩🏿‍🤝‍👩🏾', '👩🏿‍🤝‍👩🏽', '👩🏿‍🤝‍👩🏼', '👩🏿‍🤝‍👩🏻', '👩🏿‍🤝‍👨🏾', '👩🏿‍🤝‍👨🏽', '👩🏿‍🤝‍👨🏼', '👩🏿‍🤝‍👨🏻', '👩🏼‍🤝‍👨🏾', '👩🏾‍🤝‍👩🏼', '👩🏾‍🤝‍👩🏻', '👩🏾‍🤝‍👨🏿', '👩🏾‍🤝‍👨🏽', '👩🏾‍🤝‍👨🏼', '👨🏾‍🤝‍👨🏻', '👨🏾‍🤝‍👨🏼', '👨🏾‍🤝‍👨🏽', '👩🏾‍🤝‍👨🏻', '👩🏽‍🤝‍👩🏼', '👩🏽‍🤝‍👩🏻', '👩🏽‍🤝‍👨🏿', '👩🏽‍🤝‍👨🏾', '👩🏽‍🤝‍👨🏼', '👩🏽‍🤝‍👨🏻', '👩🏼‍🤝‍👩🏻', '👩🏼‍🤝‍👨🏿', '👨‍👨‍👧‍👦', '👩‍👩‍👧‍👦', '👩‍👩‍👧‍👧', '👨‍👨‍👦‍👦', '👩‍👩‍👦‍👦', '👨‍👨‍👧‍👧', '👨‍👩‍👦‍👦', '👨‍👩‍👧‍👦', '👨‍👩‍👧‍👧', '👨‍❤️‍👨', '👩‍❤️‍👨', '👩‍❤️‍👩', '👩‍👦‍👦', '👩‍👩‍👦', '👨‍👨‍👦', '👩‍👧‍👦', '👩‍👧‍👧', '👨‍👨‍👧', '👩‍👩‍👧', '👨‍👩‍👦', '🧑‍🤝‍🧑', '👨‍👦‍👦', '👨‍👩‍👧', '👨‍👧‍👦', '👨‍👧‍👧', '🧗🏽‍♀️', '🧗🏼‍♂️', '🧗🏼‍♀️', '🧗🏻‍♂️', '🧗🏻‍♀️', '👷🏿‍♀️', '💆🏻‍♀️', '🧖🏿‍♂️', '🧖🏿‍♀️', '🧖🏾‍♂️', '🧖🏾‍♀️', '🧖🏽‍♂️', '🧖🏽‍♀️', '🧖🏼‍♂️', '🧖🏼‍♀️', '🧖🏻‍♂️', '🧖🏻‍♀️', '💁🏿‍♀️', '💁🏾‍♂️', '💁🏾‍♀️', '💁🏽‍♂️', '💁🏽‍♀️', '💁🏼‍♂️', '💁🏼‍♀️', '💂🏻‍♀️', '🧝🏿‍♂️', '🧝🏿‍♀️', '🧝🏾‍♂️', '🧝🏾‍♀️', '🧝🏽‍♂️', '🧝🏽‍♀️', '🧝🏼‍♂️', '🧝🏼‍♀️', '👷🏾‍♂️', '👷🏾‍♀️', '🧏🏿‍♂️', '🧏🏿‍♀️', '🧏🏾‍♂️', '🧏🏾‍♀️', '🧏🏽‍♂️', '🧏🏽‍♀️', '🧏🏼‍♂️', '🧏🏼‍♀️', '🧏🏻‍♂️', '🧏🏻‍♀️', '💆🏻‍♂️', '👷🏽‍♂️', '🧎🏿‍♂️', '🧎🏿‍♀️', '🧎🏾‍♂️', '🧎🏾‍♀️', '🧎🏽‍♂️', '🧎🏽‍♀️', '🧎🏼‍♂️', '🧎🏼‍♀️', '🧎🏻‍♂️', '🧎🏻‍♀️', '👷🏽‍♀️', '💆🏼‍♀️', '🧍🏿‍♂️', '🧍🏿‍♀️', '🧍🏾‍♂️', '🧍🏾‍♀️', '🧍🏽‍♂️', '🧍🏽‍♀️', '🧍🏼‍♂️', '🧍🏼‍♀️', '🧍🏻‍♂️', '🧍🏻‍♀️', '👷🏼‍♂️', '👷🏼‍♀️', '🦹🏿‍♂️', '🦹🏿‍♀️', '🦹🏾‍♂️', '🦹🏾‍♀️', '🦹🏽‍♂️', '🦹🏽‍♀️', '🦹🏼‍♂️', '🦹🏼‍♀️', '🦹🏻‍♂️', '🦹🏻‍♀️', '💆🏼‍♂️', '👷🏻‍♂️', '🦸🏿‍♂️', '🦸🏿‍♀️', '🦸🏾‍♂️', '🦸🏾‍♀️', '🦸🏽‍♂️', '🦸🏽‍♀️', '🦸🏼‍♂️', '🦸🏼‍♀️', '🦸🏻‍♂️', '🦸🏻‍♀️', '👷🏻‍♀️', '💆🏽‍♀️', '🤾🏿‍♂️', '🤾🏿‍♀️', '🤾🏾‍♂️', '🤾🏾‍♀️', '🤾🏽‍♂️', '🤾🏽‍♀️', '🤾🏼‍♂️', '🤾🏼‍♀️', '🤾🏻‍♂️', '🤾🏻‍♀️', '💆🏽‍♂️', '💆🏾‍♀️', '🤽🏿‍♂️', '🤽🏿‍♀️', '🤽🏾‍♂️', '🤽🏾‍♀️', '🤽🏽‍♂️', '🤽🏽‍♀️', '🤽🏼‍♂️', '🤽🏼‍♀️', '🤽🏻‍♂️', '🤽🏻‍♀️', '💆🏾‍♂️', '💆🏿‍♀️', '💆🏿‍♂️', '💇🏻‍♀️', '🤹🏿‍♂️', '🤹🏿‍♀️', '🤹🏾‍♂️', '🤹🏾‍♀️', '🤹🏽‍♂️', '🤹🏽‍♀️', '🤹🏼‍♂️', '🤹🏼‍♀️', '🤹🏻‍♂️', '🤹🏻‍♀️', '💇🏻‍♂️', '💇🏼‍♀️', '🤸🏿‍♂️', '🤸🏿‍♀️', '🤸🏾‍♂️', '🤸🏾‍♀️', '🤸🏽‍♂️', '🤸🏽‍♀️', '🤸🏼‍♂️', '🤸🏼‍♀️', '🤸🏻‍♂️', '🤸🏻‍♀️', '💇🏼‍♂️', '💇🏽‍♀️', '🤷🏿‍♂️', '🤷🏿‍♀️', '🤷🏾‍♂️', '🤷🏾‍♀️', '🤷🏽‍♂️', '🤷🏽‍♀️', '🤷🏼‍♂️', '🤷🏼‍♀️', '🤷🏻‍♂️', '🤷🏻‍♀️', '💇🏽‍♂️', '💇🏾‍♀️', '🤵🏿‍♂️', '🤵🏿‍♀️', '🤵🏾‍♂️', '🤵🏾‍♀️', '🤵🏽‍♂️', '🤵🏽‍♀️', '🤵🏼‍♂️', '🤵🏼‍♀️', '🤵🏻‍♂️', '🤵🏻‍♀️', '💇🏾‍♂️', '👳🏿‍♂️', '🤦🏿‍♂️', '🤦🏿‍♀️', '🤦🏾‍♂️', '🏃🏻‍♀️', '🏃🏻‍♂️', '🤦🏾‍♀️', '🏃🏼‍♀️', '🏃🏼‍♂️', '🤦🏽‍♂️', '🏃🏽‍♀️', '🏃🏽‍♂️', '🤦🏽‍♀️', '🏃🏾‍♀️', '🏃🏾‍♂️', '🤦🏼‍♂️', '🏃🏿‍♀️', '🏃🏿‍♂️', '🤦🏼‍♀️', '👳🏿‍♀️', '💇🏿‍♀️', '🏄🏻‍♀️', '🏄🏻‍♂️', '🤦🏻‍♂️', '🏄🏼‍♀️', '🏄🏼‍♂️', '🤦🏻‍♀️', '🏄🏽‍♀️', '🏄🏽‍♂️', '💁🏿‍♂️', '🏄🏾‍♀️', '🏄🏾‍♂️', '👳🏾‍♀️', '🏄🏿‍♀️', '🏄🏿‍♂️', '🚶🏿‍♂️', '💇🏿‍♂️', '👳🏽‍♂️', '🚶🏿‍♀️', '🚶🏾‍♂️', '🚶🏾‍♀️', '🚶🏽‍♂️', '🚶🏽‍♀️', '🏊🏻‍♀️', '🏊🏻‍♂️', '🚶🏼‍♂️', '🏊🏼‍♀️', '🏊🏼‍♂️', '🚶🏼‍♀️', '🏊🏽‍♀️', '🏊🏽‍♂️', '🚶🏻‍♂️', '🏊🏾‍♀️', '🏊🏾‍♂️', '🚶🏻‍♀️', '🏊🏿‍♀️', '🏊🏿‍♂️', '👳🏽‍♀️', '👳🏼‍♂️', '👳🏼‍♀️', '🏋🏻‍♀️', '🏋🏻‍♂️', '👳🏻‍♂️', '🏋🏼‍♀️', '🏋🏼‍♂️', '🚵🏿‍♂️', '🏋🏽‍♀️', '🏋🏽‍♂️', '🚵🏿‍♀️', '🏋🏾‍♀️', '🏋🏾‍♂️', '🚵🏾‍♂️', '🏋🏿‍♀️', '🏋🏿‍♂️', '🚵🏾‍♀️', '🏌🏻‍♀️', '🏌🏻‍♂️', '🚵🏽‍♂️', '🏌🏼‍♀️', '🏌🏼‍♂️', '🚵🏽‍♀️', '🏌🏽‍♀️', '🏌🏽‍♂️', '🚵🏼‍♂️', '🏌🏾‍♀️', '🏌🏾‍♂️', '🚵🏼‍♀️', '🏌🏿‍♀️', '🏌🏿‍♂️', '🚵🏻‍♂️', '👳🏻‍♀️', '🕴🏻‍♀️', '🧝🏻‍♂️', '🧝🏻‍♀️', '💁🏻‍♂️', '🚵🏻‍♀️', '🕴🏻‍♂️', '🕴🏼‍♀️', '🚴🏿‍♂️', '🚴🏿‍♀️', '🚴🏾‍♂️', '🚴🏾‍♀️', '🚴🏽‍♂️', '🚴🏽‍♀️', '🚴🏼‍♂️', '🚴🏼‍♀️', '🚴🏻‍♂️', '🚴🏻‍♀️', '🕴🏼‍♂️', '🕴🏽‍♀️', '🚣🏿‍♂️', '🚣🏿‍♀️', '🚣🏾‍♂️', '🚣🏾‍♀️', '🚣🏽‍♂️', '🚣🏽‍♀️', '🚣🏼‍♂️', '🚣🏼‍♀️', '🚣🏻‍♂️', '🚣🏻‍♀️', '🕴🏽‍♂️', '👱🏿‍♂️', '🙎🏿‍♂️', '🙎🏿‍♀️', '🙎🏾‍♂️', '🙎🏾‍♀️', '🙎🏽‍♂️', '🙎🏽‍♀️', '🙎🏼‍♂️', '🙎🏼‍♀️', '🙎🏻‍♂️', '🙎🏻‍♀️', '👱🏿‍♀️', '🕴🏾‍♀️', '🙍🏿‍♂️', '🙍🏿‍♀️', '🙍🏾‍♂️', '🙍🏾‍♀️', '🙍🏽‍♂️', '🙍🏽‍♀️', '🙍🏼‍♂️', '🙍🏼‍♀️', '🙍🏻‍♂️', '🙍🏻‍♀️', '👱🏾‍♂️', '👱🏾‍♀️', '🙋🏿‍♂️', '🙋🏿‍♀️', '🙋🏾‍♂️', '🙋🏾‍♀️', '🙋🏽‍♂️', '🙋🏽‍♀️', '🙋🏼‍♂️', '🙋🏼‍♀️', '🙋🏻‍♂️', '🙋🏻‍♀️', '🕴🏾‍♂️', '👱🏽‍♂️', '🙇🏿‍♂️', '🙇🏿‍♀️', '🙇🏾‍♂️', '🙇🏾‍♀️', '🙇🏽‍♂️', '🙇🏽‍♀️', '🙇🏼‍♂️', '🙇🏼‍♀️', '🙇🏻‍♂️', '🙇🏻‍♀️', '👱🏽‍♀️', '🕴🏿‍♀️', '👱🏼‍♂️', '👱🏼‍♀️', '🕴🏿‍♂️', '👱🏻‍♂️', '👱🏻‍♀️', '🕵🏻‍♀️', '🕵🏻‍♂️', '🕵🏼‍♀️', '🕵🏼‍♂️', '👮🏿‍♂️', '👮🏿‍♀️', '🕵🏽‍♀️', '👮🏾‍♂️', '👮🏾‍♀️', '🕵🏽‍♂️', '👮🏽‍♂️', '👮🏽‍♀️', '👨🏻‍⚕️', '👨🏻‍⚖️', '👨🏻‍✈️', '🙆🏿‍♂️', '🕵🏾‍♀️', '👮🏼‍♂️', '👮🏼‍♀️', '🕵🏾‍♂️', '👮🏻‍♂️', '👮🏻‍♀️', '🕵🏿‍♀️', '🕵🏿‍♂️', '🙅🏻‍♀️', '🙅🏻‍♂️', '🙅🏼‍♀️', '💁🏻‍♀️', '🙅🏼‍♂️', '🙅🏽‍♀️', '🙅🏽‍♂️', '🙅🏾‍♀️', '🙅🏾‍♂️', '🙅🏿‍♀️', '🙅🏿‍♂️', '👨🏼‍⚕️', '👨🏼‍⚖️', '👨🏼‍✈️', '🙆🏿‍♀️', '🧜🏿‍♂️', '🧜🏿‍♀️', '🧜🏾‍♂️', '🧜🏾‍♀️', '🧜🏽‍♂️', '🧜🏽‍♀️', '🧜🏼‍♂️', '🧜🏼‍♀️', '🧜🏻‍♂️', '🧜🏻‍♀️', '💂🏻‍♂️', '💂🏼‍♀️', '👩🏿‍✈️', '🧛🏿‍♂️', '🧛🏿‍♀️', '👩🏿‍⚖️', '👩🏿‍⚕️', '🧛🏾‍♂️', '🧛🏾‍♀️', '🧛🏽‍♂️', '🧛🏽‍♀️', '🧛🏼‍♂️', '👨🏽‍⚕️', '👨🏽‍⚖️', '👨🏽‍✈️', '🙆🏾‍♂️', '🧛🏼‍♀️', '🧛🏻‍♂️', '🧛🏻‍♀️', '🙆🏻‍♀️', '👩🏾‍✈️', '👩🏾‍⚖️', '👩🏾‍⚕️', '💂🏼‍♂️', '💂🏽‍♀️', '🧚🏿‍♂️', '🧚🏿‍♀️', '🧚🏾‍♂️', '🧚🏾‍♀️', '🧚🏽‍♂️', '🧚🏽‍♀️', '🧚🏼‍♂️', '🧚🏼‍♀️', '🙆🏻‍♂️', '👩🏽‍✈️', '👩🏽‍⚖️', '👩🏽‍⚕️', '🧚🏻‍♂️', '🧚🏻‍♀️', '👨🏾‍⚕️', '👨🏾‍⚖️', '👨🏾‍✈️', '🙆🏾‍♀️', '💂🏽‍♂️', '💂🏾‍♀️', '🧙🏿‍♂️', '🧙🏿‍♀️', '🙆🏼‍♀️', '👩🏼‍✈️', '👩🏼‍⚖️', '👩🏼‍⚕️', '🧙🏾‍♂️', '🧙🏾‍♀️', '🧙🏽‍♂️', '🧙🏽‍♀️', '🧙🏼‍♂️', '🧙🏼‍♀️', '🧙🏻‍♂️', '🧙🏻‍♀️', '💂🏾‍♂️', '🙆🏼‍♂️', '👩🏻‍✈️', '👩🏻‍⚖️', '👩🏻‍⚕️', '💂🏿‍♀️', '🧘🏿‍♂️', '🧘🏿‍♀️', '👨🏿‍⚕️', '👨🏿‍⚖️', '👨🏿‍✈️', '🙆🏽‍♂️', '🧘🏾‍♂️', '🧘🏾‍♀️', '🧘🏽‍♂️', '🧘🏽‍♀️', '🧘🏼‍♂️', '🧘🏼‍♀️', '🧘🏻‍♂️', '🧘🏻‍♀️', '💂🏿‍♂️', '👷🏿‍♂️', '🧗🏿‍♂️', '🧗🏿‍♀️', '🧗🏾‍♂️', '🙆🏽‍♀️', '🧗🏾‍♀️', '🧗🏽‍♂️', '👳🏾‍♂️', '⛹🏼‍♂️', '🕴️‍♀️', '🕴️‍♂️', '⛹🏾‍♂️', '⛹🏿‍♀️', '⛹🏿‍♂️', '⛹🏼‍♀️', '🏌️‍♀️', '🏌️‍♂️', '⛹🏽‍♀️', '⛹🏻‍♂️', '🕵️‍♀️', '🕵️‍♂️', '⛹🏻‍♀️', '⛹🏽‍♂️', '⛹🏾‍♀️', '🏋️‍♀️', '🏋️‍♂️', '⛹️‍♀️', '⛹️‍♂️', '👨🏽‍🚒', '👩🏻‍🍳', '👩🏻‍🎓', '👩🏻‍🎤', '👩🏻‍🎨', '👩🏻‍🏫', '👩🏻‍🏭', '👩🏻‍💻', '👩🏻‍💼', '👩🏻‍🔧', '👩🏻‍🔬', '👩🏻‍🚀', '👩🏻‍🚒', '👨🏻‍🏫', '👨🏿‍🦽', '👨🏿‍🦼', '👨🏿‍🦳', '👩🏻‍🦯', '👩🏻‍🦰', '👩🏻‍🦱', '👩🏻‍🦲', '👩🏻‍🦳', '👩🏻‍🦼', '👩🏻‍🦽', '👨🏿‍🦲', '👨🏿‍🦱', '👨🏿‍🦰', '👨🏿‍🦯', '👩🏼‍🌾', '👩🏼‍🍳', '👩🏼‍🎓', '👩🏼‍🎤', '👩🏼‍🎨', '👩🏼‍🏫', '👩🏼‍🏭', '👩🏼‍💻', '👩🏼‍💼', '👩🏼‍🔧', '👩🏼‍🔬', '👩🏼‍🚀', '👩🏼‍🚒', '👨🏿‍🚒', '👨🏿‍🚀', '👨🏿‍🔬', '👨🏿‍🔧', '👨🏿‍💼', '👩🏼‍🦯', '👩🏼‍🦰', '👩🏼‍🦱', '👩🏼‍🦲', '👩🏼‍🦳', '👩🏼‍🦼', '👩🏼‍🦽', '👨🏿‍💻', '👨🏿‍🏭', '👨🏿‍🏫', '👨🏿‍🎨', '👩🏽‍🌾', '👩🏽‍🍳', '👩🏽‍🎓', '👩🏽‍🎤', '👩🏽‍🎨', '👩🏽‍🏫', '👩🏽‍🏭', '👩🏽‍💻', '👩🏽‍💼', '👩🏽‍🔧', '👩🏽‍🔬', '👩🏽‍🚀', '👩🏽‍🚒', '👨🏿‍🎤', '👨🏿‍🎓', '👨🏿‍🍳', '👨🏿‍🌾', '👨🏾‍🦽', '👨🏾‍🦼', '👩🏽‍🦯', '👩🏽‍🦰', '👩🏽‍🦱', '👩🏽‍🦲', '👩🏽‍🦳', '👩🏽‍🦼', '👩🏽‍🦽', '👨🏾‍🦳', '👨🏾‍🦲', '👨🏾‍🦱', '👨🏾‍🦰', '👩🏾‍🌾', '👩🏾‍🍳', '👩🏾‍🎓', '👩🏾‍🎤', '👩🏾‍🎨', '👩🏾‍🏫', '👩🏾‍🏭', '👩🏾‍💻', '👩🏾‍💼', '👩🏾‍🔧', '👩🏾‍🔬', '👩🏾‍🚀', '👩🏾‍🚒', '👨🏾‍🦯', '👨🏾‍🚒', '👨🏾‍🚀', '👨🏾‍🔬', '👨🏾‍🔧', '👨🏾‍💼', '👨🏾‍💻', '👩🏾‍🦯', '👩🏾‍🦰', '👩🏾‍🦱', '👩🏾‍🦲', '👩🏾‍🦳', '👩🏾‍🦼', '👩🏾‍🦽', '👨🏾‍🏭', '👨🏾‍🏫', '👨🏾‍🎨', '👨🏾‍🎤', '👩🏿‍🌾', '👩🏿‍🍳', '👩🏿‍🎓', '👩🏿‍🎤', '👩🏿‍🎨', '👩🏿‍🏫', '👩🏿‍🏭', '👩🏿‍💻', '👩🏿‍💼', '👩🏿‍🔧', '👩🏿‍🔬', '👩🏿‍🚀', '👩🏿‍🚒', '👨🏾‍🎓', '👨🏾‍🍳', '👨🏾‍🌾', '👨🏽‍🦽', '👨🏽‍🦼', '👨🏽‍🦳', '👨🏽‍🦲', '👨🏽‍🦱', '👩🏿‍🦯', '👩🏿‍🦰', '👩🏿‍🦱', '👩🏿‍🦲', '👩🏿‍🦳', '👩🏿‍🦼', '👩🏿‍🦽', '👨🏽‍🦰', '👨🏽‍🦯', '👩🏻‍🌾', '👨🏻‍🌾', '👨🏽‍🚀', '👨🏽‍🔬', '👨🏽‍🔧', '👨🏽‍💼', '👨🏽‍💻', '👨🏽‍🏭', '👨🏽‍🏫', '👨🏽‍🎨', '👨🏻‍🍳', '👨🏻‍🎓', '👨🏻‍🎤', '👨🏽‍🎤', '👨🏽‍🎓', '👨🏽‍🍳', '👨🏽‍🌾', '👨🏻‍🎨', '👨🏼‍🦽', '👨🏼‍🦼', '👨🏼‍🦳', '👨🏼‍🦲', '👨🏼‍🦱', '👨🏼‍🦰', '👨🏼‍🦯', '👨🏼‍🚒', '👨🏼‍🚀', '👨🏼‍🔬', '👨🏼‍🔧', '👨🏼‍💼', '👨🏼‍💻', '👨🏼‍🏭', '👨🏼‍🏫', '👨🏼‍🎨', '👨🏼‍🎤', '👨🏼‍🎓', '👨🏼‍🍳', '👨🏼‍🌾', '👨🏻‍🦽', '👨🏻‍🦼', '👨🏻‍🦳', '👨🏻‍🦲', '👨🏻‍🦱', '👨🏻‍🦰', '👨🏻‍🦯', '👨🏻‍🚒', '👨🏻‍🚀', '👨🏻‍🏭', '👨🏻‍💻', '👨🏻‍💼', '👨🏻‍🔧', '👨🏻‍🔬', '🏳️‍🌈', '🤹‍♀️', '👮‍♂️', '👮‍♀️', '🙅‍♀️', '👩‍✈️', '👩‍⚖️', '👩‍⚕️', '🙅‍♂️', '🙆‍♀️', '🙆‍♂️', '🙇‍♀️', '🙇‍♂️', '🙋‍♀️', '🙋‍♂️', '🙍‍♀️', '🙍‍♂️', '🙎‍♀️', '🙎‍♂️', '👱‍♀️', '👱‍♂️', '🚣‍♀️', '🚣‍♂️', '🚴‍♀️', '🚴‍♂️', '🏴‍☠️', '👯‍♂️', '🚵‍♀️', '💇‍♂️', '🏊‍♂️', '🏊‍♀️', '💇‍♀️', '🚵‍♂️', '🏄‍♂️', '🏄‍♀️', '🚶‍♀️', '🚶‍♂️', '🏃‍♂️', '🏃‍♀️', '🤦‍♀️', '🤦‍♂️', '👳‍♀️', '👳‍♂️', '🤵‍♀️', '🤵‍♂️', '🤷‍♀️', '🤷‍♂️', '🤸‍♀️', '🤸‍♂️', '👯‍♀️', '💆‍♂️', '💆‍♀️', '🤹‍♂️', '🤼‍♀️', '🤼‍♂️', '🤽‍♀️', '🤽‍♂️', '🤾‍♀️', '🤾‍♂️', '🦸‍♀️', '🦸‍♂️', '🦹‍♀️', '🦹‍♂️', '🧍‍♀️', '🧍‍♂️', '🧎‍♀️', '🧎‍♂️', '🧏‍♀️', '🧏‍♂️', '🧖‍♀️', '🧖‍♂️', '🧗‍♀️', '💂‍♂️', '👷‍♀️', '👷‍♂️', '💂‍♀️', '🧗‍♂️', '🧘‍♀️', '🧘‍♂️', '🧙‍♀️', '🧙‍♂️', '🧚‍♀️', '🧚‍♂️', '🧛‍♀️', '🧛‍♂️', '🧜‍♀️', '🧜‍♂️', '🧝‍♀️', '🧝‍♂️', '🧞‍♀️', '💁‍♂️', '🧞‍♂️', '🧟‍♀️', '💁‍♀️', '🧟‍♂️', '👨‍⚖️', '👨‍⚕️', '👨‍✈️', '👨‍🦳', '👨‍🦼', '👨‍🦽', '👨‍👧', '👨‍🌾', '👨‍🍳', '👨‍🎓', '👨‍🎤', '👨‍🎨', '👨‍🏫', '👨‍🏭', '🐕‍🦺', '👨‍👦', '👁‍🗨', '👩‍🌾', '👩‍🍳', '👩‍🎓', '👩‍🎤', '👩‍🎨', '👩‍🏫', '👩‍🏭', '👨‍💻', '👩‍👦', '👨‍💼', '👨‍🔧', '👩‍👧', '👨‍🔬', '👨‍🚀', '👨‍🚒', '👨‍🦯', '👨‍🦰', '👩‍💻', '👩‍💼', '👩‍🔧', '👩‍🔬', '👩‍🚀', '👩‍🚒', '👩‍🦯', '👩‍🦰', '👩‍🦱', '👩‍🦲', '👩‍🦳', '👩‍🦼', '👩‍🦽', '👨‍🦱', '👨‍🦲', '🎅🏽', '💁🏾', '💁🏽', '💁🏼', '💁🏻', '👼🏿', '💂🏻', '👼🏾', '👼🏽', '💂🏼', '👼🏼', '👼🏻', '💂🏽', '👸🏿', '👸🏾', '💂🏾', '👸🏽', '👸🏼', '💂🏿', '👸🏻', '👷🏿', '💃🏻', '💃🏼', '💃🏽', '💃🏾', '💃🏿', '💅🏻', '💅🏼', '💅🏽', '💅🏾', '💅🏿', '👷🏾', '👷🏽', '💆🏻', '👷🏼', '👷🏻', '💆🏼', '👶🏿', '👶🏾', '💆🏽', '👶🏽', '👶🏼', '💆🏾', '👶🏻', '👵🏿', '💆🏿', '👵🏾', '👵🏽', '👵🏼', '👵🏻', '💇🏻', '👴🏿', '👴🏾', '💇🏼', '👴🏽', '👴🏼', '💇🏽', '👴🏻', '👳🏿', '💇🏾', '👳🏾', '👳🏽', '💇🏿', '👳🏼', '👳🏻', '💪🏻', '💪🏼', '💪🏽', '💪🏾', '💪🏿', '👲🏿', '👲🏾', '🕴🏻', '👲🏽', '👲🏼', '🕴🏼', '👲🏻', '👱🏿', '🕴🏽', '👱🏾', '👱🏽', '🕴🏾', '👱🏼', '👱🏻', '🕴🏿', '👰🏿', '👰🏾', '👰🏽', '👰🏼', '🕵🏻', '👰🏻', '👮🏿', '🕵🏼', '👮🏾', '👮🏽', '🕵🏽', '👮🏼', '👮🏻', '🕵🏾', '👭🏿', '👭🏾', '🕵🏿', '👭🏽', '👭🏼', '🕺🏻', '🕺🏼', '🕺🏽', '🕺🏾', '🕺🏿', '🖐🏻', '🖐🏼', '🖐🏽', '🖐🏾', '🖐🏿', '🖕🏻', '🖕🏼', '🖕🏽', '🖕🏾', '🖕🏿', '🖖🏻', '🖖🏼', '🖖🏽', '🖖🏾', '🖖🏿', '👭🏻', '👬🏿', '🙅🏻', '👬🏾', '👬🏽', '🙅🏼', '👬🏼', '👬🏻', '🙅🏽', '👫🏿', '👫🏾', '🙅🏾', '👫🏽', '👫🏼', '🙅🏿', '👫🏻', '👩🏿', '👩🏾', '👩🏽', '🙆🏻', '👩🏼', '👩🏻', '🙆🏼', '🇦🇨', '👨🏿', '🙆🏽', '👨🏾', '👨🏽', '🙆🏾', '👨🏼', '👨🏻', '🙆🏿', '👧🏿', '👧🏾', '👧🏽', '👧🏼', '🙇🏻', '👧🏻', '👦🏿', '🙇🏼', '👦🏾', '👦🏽', '🙇🏽', '👦🏼', '👦🏻', '🙇🏾', '👐🏿', '👐🏾', '🙇🏿', '👐🏽', '👐🏼', '👐🏻', '👏🏿', '🙋🏻', '👏🏾', '👏🏽', '🙋🏼', '👏🏼', '👏🏻', '🙋🏽', '👎🏿', '👎🏾', '🙋🏾', '👎🏽', '👎🏼', '🙋🏿', '👎🏻', '👍🏿', '🙌🏻', '🙌🏼', '🙌🏽', '🙌🏾', '🙌🏿', '👍🏾', '👍🏽', '🙍🏻', '👍🏼', '👍🏻', '🙍🏼', '👌🏿', '👌🏾', '🙍🏽', '👌🏽', '👌🏼', '🙍🏾', '👌🏻', '👋🏿', '🙍🏿', '👋🏾', '👋🏽', '👋🏼', '👋🏻', '🙎🏻', '👊🏿', '👊🏾', '🙎🏼', '👊🏽', '👊🏼', '🙎🏽', '👊🏻', '👉🏿', '🙎🏾', '👉🏾', '👉🏽', '🙎🏿', '👉🏼', '👉🏻', '🙏🏻', '🙏🏼', '🙏🏽', '🙏🏾', '🙏🏿', '👈🏿', '👈🏾', '🚣🏻', '👈🏽', '👈🏼', '🚣🏼', '👈🏻', '👇🏿', '🚣🏽', '👇🏾', '👇🏽', '🚣🏾', '👇🏼', '👇🏻', '🚣🏿', '👆🏿', '👆🏾', '👆🏽', '👆🏼', '🚴🏻', '👆🏻', '👃🏿', '🚴🏼', '👃🏾', '👃🏽', '🚴🏽', '👃🏼', '👃🏻', '🚴🏾', '👂🏿', '👂🏾', '🚴🏿', '👂🏽', '👂🏼', '👂🏻', '🏌🏿', '🚵🏻', '🏌🏾', '🏌🏽', '🚵🏼', '🏌🏼', '🏌🏻', '🚵🏽', '🏋🏿', '🏋🏾', '🚵🏾', '🏋🏽', '🏋🏼', '🚵🏿', '🏋🏻', '🏊🏿', '🏊🏾', '🏊🏽', '🚶🏻', '🏊🏼', '🏊🏻', '🚶🏼', '🏇🏿', '🏇🏾', '🚶🏽', '🏇🏽', '🏇🏼', '🚶🏾', '🏇🏻', '🏄🏿', '🚶🏿', '🏄🏾', '🏄🏽', '🛀🏻', '🛀🏼', '🛀🏽', '🛀🏾', '🛀🏿', '🛌🏻', '🛌🏼', '🛌🏽', '🛌🏾', '🛌🏿', '🤏🏻', '🤏🏼', '🤏🏽', '🤏🏾', '🤏🏿', '🤘🏻', '🤘🏼', '🤘🏽', '🤘🏾', '🤘🏿', '🤙🏻', '🤙🏼', '🤙🏽', '🤙🏾', '🤙🏿', '🤚🏻', '🤚🏼', '🤚🏽', '🤚🏾', '🤚🏿', '🤛🏻', '🤛🏼', '🤛🏽', '🤛🏾', '🤛🏿', '🤜🏻', '🤜🏼', '🤜🏽', '🤜🏾', '🤜🏿', '🤞🏻', '🤞🏼', '🤞🏽', '🤞🏾', '🤞🏿', '🤟🏻', '🤟🏼', '🤟🏽', '🤟🏾', '🤟🏿', '🏄🏼', '🏄🏻', '🤦🏻', '🏃🏿', '🏃🏾', '🤦🏼', '🏃🏽', '🏃🏼', '🤦🏽', '🏃🏻', '🏂🏿', '🤦🏾', '🏂🏾', '🏂🏽', '🤦🏿', '🏂🏼', '🏂🏻', '🤰🏻', '🤰🏼', '🤰🏽', '🤰🏾', '🤰🏿', '🤱🏻', '🤱🏼', '🤱🏽', '🤱🏾', '🤱🏿', '🤲🏻', '🤲🏼', '🤲🏽', '🤲🏾', '🤲🏿', '🤳🏻', '🤳🏼', '🤳🏽', '🤳🏾', '🤳🏿', '🤴🏻', '🤴🏼', '🤴🏽', '🤴🏾', '🤴🏿', '🎅🏿', '🎅🏾', '🤵🏻', '💁🏿', '🎅🏼', '🤵🏼', '🎅🏻', '🇿🇼', '🤵🏽', '🇿🇲', '🇿🇦', '🤵🏾', '🇾🇹', '🇾🇪', '🤵🏿', '🇽🇰', '🇼🇸', '🤶🏻', '🤶🏼', '🤶🏽', '🤶🏾', '🤶🏿', '🇼🇫', '🇻🇺', '🤷🏻', '🇻🇳', '🇻🇮', '🤷🏼', '🇻🇬', '🇻🇪', '🤷🏽', '🇻🇨', '🇻🇦', '🤷🏾', '🇺🇿', '🇺🇾', '🤷🏿', '🇺🇸', '🇺🇳', '🇺🇲', '🇺🇬', '🤸🏻', '🇺🇦', '🇹🇿', '🤸🏼', '🇹🇼', '🇹🇻', '🤸🏽', '🇹🇹', '🇹🇷', '🤸🏾', '🇹🇴', '🇹🇳', '🤸🏿', '🇹🇲', '🇹🇱', '🇹🇰', '🇹🇯', '🤹🏻', '🇹🇭', '🇹🇬', '🤹🏼', '🇹🇫', '🇹🇩', '🤹🏽', '🇹🇨', '🇹🇦', '🤹🏾', '🇸🇿', '🇸🇾', '🤹🏿', '🇸🇽', '🇸🇻', '🇸🇹', '🇸🇸', '🇸🇷', '🇸🇴', '🤽🏻', '🇸🇳', '🇸🇲', '🤽🏼', '🇸🇱', '🇸🇰', '🤽🏽', '🇸🇯', '🇸🇮', '🤽🏾', '🇸🇭', '🇸🇬', '🤽🏿', '🇸🇪', '🇸🇩', '🇸🇨', '🇸🇧', '🤾🏻', '🇸🇦', '🇷🇼', '🤾🏼', '🇷🇺', '🇷🇸', '🤾🏽', '🇷🇴', '🇷🇪', '🤾🏾', '🇶🇦', '🇵🇾', '🤾🏿', '🇵🇼', '🇵🇹', '🦵🏻', '🦵🏼', '🦵🏽', '🦵🏾', '🦵🏿', '🦶🏻', '🦶🏼', '🦶🏽', '🦶🏾', '🦶🏿', '🇵🇸', '🇵🇷', '🦸🏻', '🇵🇳', '🇵🇲', '🦸🏼', '🇵🇱', '🇵🇰', '🦸🏽', '🇵🇭', '🇵🇬', '🦸🏾', '🇵🇫', '🇵🇪', '🦸🏿', '🇵🇦', '🇴🇲', '🇳🇿', '🇳🇺', '🦹🏻', '🇳🇷', '🇳🇵', '🦹🏼', '🇳🇴', '🇳🇱', '🦹🏽', '🇳🇮', '🇳🇬', '🦹🏾', '🇳🇫', '🇳🇪', '🦹🏿', '🇳🇨', '🇳🇦', '🦻🏻', '🦻🏼', '🦻🏽', '🦻🏾', '🦻🏿', '🇲🇿', '🇲🇾', '🧍🏻', '🇲🇽', '🇲🇼', '🧍🏼', '🇲🇻', '🇲🇺', '🧍🏽', '🇲🇹', '🇲🇸', '🧍🏾', '🇲🇷', '🇲🇶', '🧍🏿', '🇲🇵', '🇲🇴', '🇲🇳', '🇲🇲', '🧎🏻', '🇲🇱', '🇲🇰', '🧎🏼', '🇲🇭', '🇲🇬', '🧎🏽', '🇲🇫', '🇲🇪', '🧎🏾', '🇲🇩', '🇲🇨', '🧎🏿', '🇲🇦', '🇱🇾', '🇱🇻', '🇱🇺', '🧏🏻', '🇱🇹', '🇱🇸', '🧏🏼', '🇱🇷', '🇱🇰', '🧏🏽', '🇱🇮', '🇱🇨', '🧏🏾', '🇱🇧', '🇱🇦', '🧏🏿', '🇰🇿', '🇰🇾', '🇰🇼', '🧑🏻', '🇰🇷', '🇰🇵', '🧑🏼', '🇰🇳', '🇰🇲', '🇰🇮', '🧑🏽', '🇰🇭', '🇰🇬', '🇰🇪', '🇯🇵', '🧑🏾', '🇯🇴', '🇯🇲', '🇯🇪', '🇮🇹', '🇮🇸', '🧑🏿', '🇮🇷', '🧒🏻', '🧒🏼', '🧒🏽', '🧒🏾', '🧒🏿', '🧓🏻', '🧓🏼', '🧓🏽', '🧓🏾', '🧓🏿', '🧔🏻', '🧔🏼', '🧔🏽', '🧔🏾', '🧔🏿', '🧕🏻', '🧕🏼', '🧕🏽', '🧕🏾', '🧕🏿', '🇮🇶', '🇮🇴', '🧖🏻', '🇮🇳', '🇮🇲', '🧖🏼', '🇮🇱', '🇮🇪', '🧖🏽', '🇮🇩', '🇮🇨', '🧖🏾', '🇭🇺', '🇭🇹', '🧖🏿', '🇭🇷', '🇭🇳', '🇭🇲', '🇭🇰', '🧗🏻', '🇬🇾', '🇬🇼', '🧗🏼', '🇬🇺', '🇬🇹', '🧗🏽', '🇬🇸', '🇬🇷', '🧗🏾', '🇬🇶', '🇬🇵', '🧗🏿', '🇬🇳', '🇬🇲', '🇬🇱', '🇬🇮', '🧘🏻', '🇬🇭', '🇬🇬', '🧘🏼', '🇬🇫', '🇬🇪', '🧘🏽', '🇬🇩', '🇬🇧', '🧘🏾', '🇬🇦', '🇫🇷', '🧘🏿', '🇫🇴', '🇫🇲', '🇫🇰', '🇫🇯', '🧙🏻', '🇫🇮', '🇪🇺', '🧙🏼', '🇪🇹', '🇪🇸', '🧙🏽', '🇪🇷', '🇪🇭', '🧙🏾', '🇪🇬', '🇪🇪', '🧙🏿', '🇪🇨', '🇪🇦', '🇩🇿', '🇩🇴', '🧚🏻', '🇩🇲', '🇩🇰', '🧚🏼', '🇩🇯', '🇩🇬', '🧚🏽', '🇩🇪', '🇨🇿', '🧚🏾', '🇨🇾', '🇨🇽', '🧚🏿', '🇨🇼', '🇨🇻', '🇨🇺', '🇨🇷', '🧛🏻', '🇨🇵', '🇨🇴', '🧛🏼', '🇨🇳', '🇨🇲', '🧛🏽', '🇨🇱', '🇨🇰', '🧛🏾', '🇨🇮', '🇨🇭', '🧛🏿', '🇨🇬', '🇨🇫', '🇨🇩', '🇨🇨', '🧜🏻', '🇨🇦', '🇧🇿', '🧜🏼', '🇧🇾', '🇧🇼', '🧜🏽', '🇧🇻', '🇧🇹', '🧜🏾', '🇧🇸', '🇧🇷', '🧜🏿', '🇧🇶', '🇧🇴', '🇧🇳', '🇧🇲', '🧝🏻', '🇧🇱', '🇧🇯', '🧝🏼', '🇧🇮', '🇧🇭', '🧝🏽', '🇧🇬', '🇧🇫', '🧝🏾', '🇧🇪', '🇧🇩', '🧝🏿', '🇧🇧', '🇧🇦', '🇦🇿', '🇦🇽', '🇦🇼', '🇦🇺', '🇦🇹', '🇦🇸', '🇦🇷', '🇦🇶', '🇦🇴', '🇦🇲', '🇦🇱', '🇦🇮', '🇦🇬', '🇦🇫', '🇦🇪', '🇦🇩', '✍🏿', '⛹🏻', '✍🏾', '✍🏽', '✍🏼', '✍🏻', '✌🏿', '✌🏾', '✌🏽', '✌🏼', '✌🏻', '✋🏿', '✋🏾', '✋🏽', '✋🏼', '✋🏻', '✊🏿', '✊🏾', '✊🏽', '✊🏼', '✊🏻', '⛷🏽', '⛷🏾', '⛹🏿', '☝🏿', '☝🏾', '⛹🏾', '☝🏽', '☝🏼', '⛹🏽', '☝🏻', '⛷🏿', '⛹🏼', '⛷🏻', '⛷🏼', '4⃣', '#⃣', '0⃣', '1⃣', '2⃣', '3⃣', '*⃣', '5⃣', '6⃣', '7⃣', '8⃣', '9⃣', '🏌', '😛', '😜', '😝', '😞', '😟', '😠', '😡', '😢', '😣', '😤', '😥', '😦', '😧', '😨', '😩', '😪', '😫', '😬', '😭', '😮', '😯', '😰', '😱', '😲', '😳', '😴', '😵', '😶', '😷', '😸', '😹', '😺', '😻', '😼', '😽', '😾', '😿', '🙀', '🙁', '🙂', '🙃', '🙄', '🏮', '🏯', '🏰', '🌭', '🏳', '🌮', '🌯', '🌰', '🌱', '🏴', '🏵', '🏷', '🏸', '🏹', '🏺', '🏻', '🏼', '🙅', '🏽', '🏾', '🏿', '🐀', '🐁', '🐂', '🐃', '🐄', '🐅', '🐆', '🐇', '🐈', '🐉', '🐊', '🐋', '🐌', '🐍', '🙆', '🐎', '🐏', '🐐', '🐑', '🐒', '🐓', '🐔', '🌲', '🐕', '🐖', '🐗', '🐘', '🐙', '🐚', '🐛', '🐜', '🐝', '🙇', '🙈', '🙉', '🙊', '🐞', '🐟', '🐠', '🐡', '🐢', '🐣', '🐤', '🐥', '🐦', '🐧', '🐨', '🐩', '🐪', '🐫', '🐬', '🐭', '🐮', '🙋', '🐯', '🐰', '🐱', '🐲', '🐳', '🙌', '🐴', '🐵', '🐶', '🐷', '🐸', '🐹', '🐺', '🐻', '🐼', '🐽', '🐾', '🐿', '👀', '🌳', '👁', '🌴', '🌵', '🙍', '🌶', '🌷', '🌸', '👂', '🌹', '🌺', '🌻', '🌼', '🌽', '👃', '👄', '👅', '🌾', '🌿', '🍀', '🍁', '🍂', '🙎', '👆', '🍃', '🍄', '🍅', '🍆', '🙏', '🚀', '🚁', '🚂', '🚃', '🚄', '🚅', '🚆', '🚇', '🚈', '🚉', '🚊', '🚋', '🚌', '🚍', '🚎', '🚏', '🚐', '🚑', '🚒', '🚓', '🚔', '🚕', '🚖', '🚗', '🚘', '🚙', '🚚', '🚛', '🚜', '🚝', '🚞', '🚟', '🚠', '🚡', '🚢', '🍇', '👇', '🍈', '🍉', '🍊', '🍋', '🍌', '👈', '🍍', '🍎', '🍏', '🍐', '🍑', '👉', '🍒', '🍓', '🍔', '🚣', '🚤', '🚥', '🚦', '🚧', '🚨', '🚩', '🚪', '🚫', '🚬', '🚭', '🚮', '🚯', '🚰', '🚱', '🚲', '🚳', '🍕', '🍖', '👊', '🍗', '🍘', '🍙', '🍚', '🍛', '👋', '🍜', '🍝', '🍞', '🍟', '🍠', '👌', '🍡', '🍢', '🚴', '🍣', '🍤', '🍥', '👍', '🍦', '👩', '👪', '🍧', '🍨', '🍩', '🍪', '👎', '👫', '🍫', '🍬', '🍭', '🍮', '🚵', '🍯', '👬', '👏', '🍰', '🍱', '🍲', '🍳', '👭', '🍴', '👐', '👑', '👒', '👓', '👔', '👕', '👖', '👗', '🚶', '🚷', '🚸', '🚹', '🚺', '🚻', '🚼', '🚽', '🚾', '🚿', '👘', '👙', '👚', '👛', '👜', '🛀', '🛁', '🛂', '🛃', '🛄', '🛅', '🛋', '👝', '👞', '👟', '👮', '👠', '🛌', '🛍', '🛎', '🛏', '🛐', '🛑', '🛒', '🛕', '🛠', '🛡', '🛢', '🛣', '🛤', '🛥', '🛩', '🛫', '🛬', '🛰', '🛳', '🛴', '🛵', '🛶', '🛷', '🛸', '🛹', '🛺', '🟠', '🟡', '🟢', '🟣', '🟤', '🟥', '🟦', '🟧', '🟨', '🟩', '🟪', '🟫', '🤍', '🤎', '👡', '👯', '👢', '👣', '👤', '🤏', '🤐', '🤑', '🤒', '🤓', '🤔', '🤕', '🤖', '🤗', '👥', '🍵', '👰', '🍶', '🍷', '🤘', '🍸', '🍹', '👦', '🍺', '🍻', '🤙', '🍼', '🍽', '🍾', '👧', '🍿', '🤚', '🎀', '🎁', '🎂', '🎃', '🎄', '🤛', '👱', '🇵', '🅾', '🇶', '🇲', '🤜', '🤝', '🅿', '👲', '🎅', '🎆', '🎇', '🤞', '🎈', '🎉', '🎊', '🎋', '🎌', '🤟', '🤠', '🤡', '🤢', '🤣', '🤤', '🤥', '🎍', '🎎', '🎏', '🎐', '🎑', '🎒', '🎓', '🎖', '🎗', '👳', '🎙', '🎚', '🎛', '🎞', '🎟', '👴', '🎠', '🤦', '🤧', '🤨', '🤩', '🤪', '🤫', '🤬', '🤭', '🤮', '🤯', '🎡', '🎢', '🎣', '🎤', '👵', '🤰', '🎥', '🎦', '🎧', '🎨', '🎩', '🤱', '👶', '🎪', '🎫', '🎬', '🎭', '🤲', '🎮', '🎯', '🎰', '🎱', '🎲', '🤳', '🎳', '🎴', '🎵', '🎶', '🎷', '🤴', '🎸', '🎹', '🎺', '👷', '🎻', '🎼', '🎽', '🎾', '🎿', '👸', '👹', '👺', '👻', '🏀', '🏁', '🇧', '🇮', '🤵', '🇪', '👼', '👽', '👾', '👿', '🤶', '💀', '🇷', '🇱', '🏂', '🆎', '🆑', '🇨', '🇹', '🇯', '🆒', '🇬', '🆓', '🇳', '🆔', '🇴', '🇺', '🇫', '🤷', '🆕', '💁', '🆖', '🆗', '🇭', '🏃', '🆘', '🇩', '🇻', '🇰', '🆙', '🇼', '🆚', '🇽', '🇸', '🀄', '🇾', '🤸', '🇦', '🅰', '💂', '🅱', '🇿', '🈁', '🈂', '🏄', '💃', '💄', '🏅', '🏆', '🈚', '🈯', '🈲', '💅', '🈳', '🤹', '🤺', '🈴', '🏇', '🤼', '🏈', '🏉', '🈵', '🈶', '🈷', '🈸', '🈹', '🈺', '🉐', '🉑', '🌀', '🌁', '🌂', '🌃', '💆', '🌄', '🌅', '🤽', '🌆', '🌇', '🌈', '🏊', '🌉', '🌊', '🌋', '🌌', '🌍', '🌎', '🌏', '🌐', '🌑', '🌒', '🌓', '💇', '💈', '🤾', '🤿', '🥀', '🥁', '🥂', '🥃', '🥄', '🥅', '🥇', '🥈', '🥉', '🥊', '🥋', '🥌', '🥍', '🥎', '🥏', '🥐', '🥑', '🥒', '🥓', '🥔', '🥕', '🥖', '🥗', '🥘', '🥙', '🥚', '🥛', '🥜', '🥝', '🥞', '🥟', '🥠', '🥡', '🥢', '🥣', '🥤', '🥥', '🥦', '🥧', '🥨', '🥩', '🥪', '🥫', '🥬', '🥭', '🥮', '🥯', '🥰', '🥱', '🥳', '🥴', '🥵', '🥶', '🥺', '🥻', '🥼', '🥽', '🥾', '🥿', '🦀', '🦁', '🦂', '🦃', '🦄', '🦅', '🦆', '🦇', '🦈', '🦉', '🦊', '🦋', '🦌', '🦍', '🦎', '🦏', '🦐', '🦑', '🦒', '🦓', '🦔', '🦕', '🦖', '🦗', '🦘', '🦙', '🦚', '🦛', '🦜', '🦝', '🦞', '🦟', '🦠', '🦡', '🦢', '🦥', '🦦', '🦧', '🦨', '🦩', '🦪', '🦮', '🦯', '🦰', '🦱', '🦲', '🦳', '🦴', '💉', '💊', '💋', '💌', '💍', '🦵', '💎', '💏', '💐', '💑', '💒', '🦶', '🦷', '💓', '💔', '💕', '💖', '💗', '💘', '💙', '💚', '💛', '💜', '💝', '💞', '💟', '💠', '💡', '💢', '💣', '🦸', '💤', '💥', '💦', '💧', '💨', '💩', '🌔', '🌕', '🌖', '🌗', '🌘', '💪', '💫', '💬', '💭', '💮', '💯', '🦹', '🦺', '💰', '💱', '💲', '💳', '💴', '🦻', '🦼', '🦽', '🦾', '🦿', '🧀', '🧁', '🧂', '🧃', '🧄', '🧅', '🧆', '🧇', '🧈', '🧉', '🧊', '💵', '💶', '💷', '💸', '💹', '💺', '💻', '💼', '💽', '💾', '💿', '📀', '📁', '📂', '📃', '📄', '📅', '🧍', '📆', '📇', '📈', '📉', '📊', '📋', '📌', '📍', '📎', '📏', '📐', '📑', '📒', '📓', '📔', '📕', '📖', '🧎', '📗', '📘', '📙', '📚', '📛', '📜', '📝', '📞', '📟', '📠', '📡', '📢', '📣', '📤', '📥', '📦', '📧', '🧏', '🧐', '📨', '📩', '📪', '📫', '📬', '📭', '📮', '📯', '📰', '📱', '📲', '📳', '📴', '📵', '📶', '📷', '📸', '📹', '📺', '📻', '📼', '🧑', '📽', '📿', '🔀', '🔁', '🔂', '🧒', '🔃', '🔄', '🔅', '🔆', '🔇', '🧓', '🔈', '🔉', '🔊', '🔋', '🔌', '🧔', '🔍', '🔎', '🔏', '🔐', '🔑', '🧕', '🔒', '🔓', '🔔', '🔕', '🔖', '🔗', '🔘', '🔙', '🔚', '🔛', '🔜', '🔝', '🔞', '🔟', '🔠', '🔡', '🔢', '🧖', '🔣', '🔤', '🔥', '🔦', '🔧', '🔨', '🔩', '🔪', '🔫', '🔬', '🔭', '🔮', '🔯', '🔰', '🔱', '🔲', '🔳', '🧗', '🔴', '🔵', '🔶', '🔷', '🔸', '🔹', '🔺', '🔻', '🔼', '🔽', '🕉', '🕊', '🕋', '🕌', '🕍', '🕎', '🕐', '🧘', '🕑', '🕒', '🕓', '🕔', '🕕', '🕖', '🕗', '🕘', '🕙', '🕚', '🕛', '🕜', '🕝', '🕞', '🕟', '🕠', '🕡', '🧙', '🕢', '🕣', '🕤', '🕥', '🕦', '🕧', '🕯', '🕰', '🕳', '🌙', '🏋', '🌚', '🌛', '🌜', '🌝', '🌞', '🌟', '🧚', '🌠', '🌡', '🌤', '🌥', '🌦', '🌧', '🌨', '🌩', '🌪', '🕴', '👨', '🌫', '🌬', '🃏', '🏍', '🏎', '🏏', '🧛', '🏐', '🏑', '🏒', '🏓', '🏔', '🏕', '🏖', '🏗', '🏘', '🏙', '🕵', '🕶', '🕷', '🕸', '🕹', '🏚', '🏛', '🧜', '🏜', '🏝', '🏞', '🕺', '🖇', '🖊', '🖋', '🖌', '🖍', '🏟', '🏠', '🏡', '🏢', '🏣', '🖐', '🏤', '🏥', '🧝', '🏦', '🏧', '🧞', '🏨', '🖕', '🧟', '🧠', '🧡', '🧢', '🧣', '🧤', '🧥', '🧦', '🧧', '🧨', '🧩', '🧪', '🧫', '🧬', '🧭', '🧮', '🧯', '🧰', '🧱', '🧲', '🧳', '🧴', '🧵', '🧶', '🧷', '🧸', '🧹', '🧺', '🧻', '🧼', '🧽', '🧾', '🧿', '🩰', '🩱', '🩲', '🩳', '🩸', '🩹', '🩺', '🪀', '🪁', '🪂', '🪐', '🪑', '🪒', '🪓', '🪔', '🪕', '🏩', '🏪', '🏫', '🏬', '🏭', '🖖', '🖤', '🖥', '🖨', '🖱', '🖲', '🖼', '🗂', '🗃', '🗄', '🗑', '🗒', '🗓', '🗜', '🗝', '🗞', '🗡', '🗣', '🗨', '🗯', '🗳', '🗺', '🗻', '🗼', '🗽', '🗾', '🗿', '😀', '😁', '😂', '😃', '😄', '😅', '😆', '😇', '😈', '😉', '😊', '😋', '😌', '😍', '😎', '😏', '😐', '😑', '😒', '😓', '😔', '😕', '😖', '😗', '😘', '😙', '😚', '▫', '☦', '☮', '☯', '☸', '☹', '☺', '♀', '♂', '♈', '♉', '♊', '♋', '♌', '♍', '♎', '♏', '♐', '♑', '♒', '♓', '♟', '♠', '♣', '♥', '♦', '♨', '♻', '♾', '♿', '⚒', '⚓', '⚔', '⚕', '⚖', '⚗', '⚙', '⚛', '⚜', '⚠', '⚡', '⚪', '⚫', '⚰', '⚱', '⚽', '⚾', '⛄', '⛅', '⛈', '⛎', '⛏', '⛑', '⛓', '⛔', '⛩', '⛪', '⛰', '⛱', '⛲', '⛳', '⛴', '⛵', '☣', '☢', '☠', '☝', '☘', '⛷', '⛸', '☕', '☔', '☑', '☎', '☄', '☃', '☂', '☁', '☀', '◾', '◽', '◼', '◻', '◀', '▶', '☪', '▪', '⛹', '⛺', '⛽', '✂', '✅', '✈', '✉', 'Ⓜ', '⏺', '⏹', '⏸', '⏳', '✊', '⏲', '⏱', '⏰', '⏯', '⏮', '✋', '⏭', '⏬', '⏫', '⏪', '⏩', '✌', '⏏', '⌨', '⌛', '⌚', '↪', '✍', '✏', '✒', '✔', '✖', '✝', '✡', '✨', '✳', '✴', '❄', '❇', '❌', '❎', '❓', '❔', '❕', '❗', '❣', '❤', '➕', '➖', '➗', '➡', '➰', '➿', '⤴', '⤵', '↩', '⬅', '⬆', '⬇', '⬛', '⬜', '⭐', '⭕', '↙', '〰', '〽', '↘', '↗', '㊗', '㊙', '↖', '↕', '↔', 'ℹ', '™', '⁉', '‼', '' ); |
5317 $partials = array('🀄','🃏','🅰','🅱','🅾','🅿','🆎','🆑','🆒','🆓','🆔','🆕','🆖','🆗','🆘','🆙','🆚','🇦','🇨','🇩','🇪','🇫','🇬','🇮','🇱','🇲','🇴','🇶','🇷','🇸','🇹','🇺','🇼','🇽','🇿','🇧','🇭','🇯','🇳','🇻','🇾','🇰','🇵','🈁','🈂','🈚','🈯','🈲','🈳','🈴','🈵','🈶','🈷','🈸','🈹','🈺','🉐','🉑','🌀','🌁','🌂','🌃','🌄','🌅','🌆','🌇','🌈','🌉','🌊','🌋','🌌','🌍','🌎','🌏','🌐','🌑','🌒','🌓','🌔','🌕','🌖','🌗','🌘','🌙','🌚','🌛','🌜','🌝','🌞','🌟','🌠','🌡','🌤','🌥','🌦','🌧','🌨','🌩','🌪','🌫','🌬','🌭','🌮','🌯','🌰','🌱','🌲','🌳','🌴','🌵','🌶','🌷','🌸','🌹','🌺','🌻','🌼','🌽','🌾','🌿','🍀','🍁','🍂','🍃','🍄','🍅','🍆','🍇','🍈','🍉','🍊','🍋','🍌','🍍','🍎','🍏','🍐','🍑','🍒','🍓','🍔','🍕','🍖','🍗','🍘','🍙','🍚','🍛','🍜','🍝','🍞','🍟','🍠','🍡','🍢','🍣','🍤','🍥','🍦','🍧','🍨','🍩','🍪','🍫','🍬','🍭','🍮','🍯','🍰','🍱','🍲','🍳','🍴','🍵','🍶','🍷','🍸','🍹','🍺','🍻','🍼','🍽','🍾','🍿','🎀','🎁','🎂','🎃','🎄','🎅','🏻','🏼','🏽','🏾','🏿','🎆','🎇','🎈','🎉','🎊','🎋','🎌','🎍','🎎','🎏','🎐','🎑','🎒','🎓','🎖','🎗','🎙','🎚','🎛','🎞','🎟','🎠','🎡','🎢','🎣','🎤','🎥','🎦','🎧','🎨','🎩','🎪','🎫','🎬','🎭','🎮','🎯','🎰','🎱','🎲','🎳','🎴','🎵','🎶','🎷','🎸','🎹','🎺','🎻','🎼','🎽','🎾','🎿','🏀','🏁','🏂','🏃','‍','♀','️','♂','🏄','🏅','🏆','🏇','🏈','🏉','🏊','🏋','🏌','🏍','🏎','🏏','🏐','🏑','🏒','🏓','🏔','🏕','🏖','🏗','🏘','🏙','🏚','🏛','🏜','🏝','🏞','🏟','🏠','🏡','🏢','🏣','🏤','🏥','🏦','🏧','🏨','🏩','🏪','🏫','🏬','🏭','🏮','🏯','🏰','🏳','🏴','☠','󠁧','󠁢','󠁥','󠁮','󠁿','󠁳','󠁣','󠁴','󠁷','󠁬','🏵','🏷','🏸','🏹','🏺','🐀','🐁','🐂','🐃','🐄','🐅','🐆','🐇','🐈','🐉','🐊','🐋','🐌','🐍','🐎','🐏','🐐','🐑','🐒','🐓','🐔','🐕','🐖','🐗','🐘','🐙','🐚','🐛','🐜','🐝','🐞','🐟','🐠','🐡','🐢','🐣','🐤','🐥','🐦','🐧','🐨','🐩','🐪','🐫','🐬','🐭','🐮','🐯','🐰','🐱','🐲','🐳','🐴','🐵','🐶','🐷','🐸','🐹','🐺','🐻','🐼','🐽','🐾','🐿','👀','👁','🗨','👂','👃','👄','👅','👆','👇','👈','👉','👊','👋','👌','👍','👎','👏','👐','👑','👒','👓','👔','👕','👖','👗','👘','👙','👚','👛','👜','👝','👞','👟','👠','👡','👢','👣','👤','👥','👦','👧','👨','💻','💼','🔧','🔬','🚀','🚒','🦰','🦱','🦲','🦳','⚕','⚖','✈','👩','❤','💋','👪','👫','👬','👭','👮','👯','👰','👱','👲','👳','👴','👵','👶','👷','👸','👹','👺','👻','👼','👽','👾','👿','💀','💁','💂','💃','💄','💅','💆','💇','💈','💉','💊','💌','💍','💎','💏','💐','💑','💒','💓','💔','💕','💖','💗','💘','💙','💚','💛','💜','💝','💞','💟','💠','💡','💢','💣','💤','💥','💦','💧','💨','💩','💪','💫','💬','💭','💮','💯','💰','💱','💲','💳','💴','💵','💶','💷','💸','💹','💺','💽','💾','💿','📀','📁','📂','📃','📄','📅','📆','📇','📈','📉','📊','📋','📌','📍','📎','📏','📐','📑','📒','📓','📔','📕','📖','📗','📘','📙','📚','📛','📜','📝','📞','📟','📠','📡','📢','📣','📤','📥','📦','📧','📨','📩','📪','📫','📬','📭','📮','📯','📰','📱','📲','📳','📴','📵','📶','📷','📸','📹','📺','📻','📼','📽','📿','🔀','🔁','🔂','🔃','🔄','🔅','🔆','🔇','🔈','🔉','🔊','🔋','🔌','🔍','🔎','🔏','🔐','🔑','🔒','🔓','🔔','🔕','🔖','🔗','🔘','🔙','🔚','🔛','🔜','🔝','🔞','🔟','🔠','🔡','🔢','🔣','🔤','🔥','🔦','🔨','🔩','🔪','🔫','🔭','🔮','🔯','🔰','🔱','🔲','🔳','🔴','🔵','🔶','🔷','🔸','🔹','🔺','🔻','🔼','🔽','🕉','🕊','🕋','🕌','🕍','🕎','🕐','🕑','🕒','🕓','🕔','🕕','🕖','🕗','🕘','🕙','🕚','🕛','🕜','🕝','🕞','🕟','🕠','🕡','🕢','🕣','🕤','🕥','🕦','🕧','🕯','🕰','🕳','🕴','🕵','🕶','🕷','🕸','🕹','🕺','🖇','🖊','🖋','🖌','🖍','🖐','🖕','🖖','🖤','🖥','🖨','🖱','🖲','🖼','🗂','🗃','🗄','🗑','🗒','🗓','🗜','🗝','🗞','🗡','🗣','🗯','🗳','🗺','🗻','🗼','🗽','🗾','🗿','😀','😁','😂','😃','😄','😅','😆','😇','😈','😉','😊','😋','😌','😍','😎','😏','😐','😑','😒','😓','😔','😕','😖','😗','😘','😙','😚','😛','😜','😝','😞','😟','😠','😡','😢','😣','😤','😥','😦','😧','😨','😩','😪','😫','😬','😭','😮','😯','😰','😱','😲','😳','😴','😵','😶','😷','😸','😹','😺','😻','😼','😽','😾','😿','🙀','🙁','🙂','🙃','🙄','🙅','🙆','🙇','🙈','🙉','🙊','🙋','🙌','🙍','🙎','🙏','🚁','🚂','🚃','🚄','🚅','🚆','🚇','🚈','🚉','🚊','🚋','🚌','🚍','🚎','🚏','🚐','🚑','🚓','🚔','🚕','🚖','🚗','🚘','🚙','🚚','🚛','🚜','🚝','🚞','🚟','🚠','🚡','🚢','🚣','🚤','🚥','🚦','🚧','🚨','🚩','🚪','🚫','🚬','🚭','🚮','🚯','🚰','🚱','🚲','🚳','🚴','🚵','🚶','🚷','🚸','🚹','🚺','🚻','🚼','🚽','🚾','🚿','🛀','🛁','🛂','🛃','🛄','🛅','🛋','🛌','🛍','🛎','🛏','🛐','🛑','🛒','🛠','🛡','🛢','🛣','🛤','🛥','🛩','🛫','🛬','🛰','🛳','🛴','🛵','🛶','🛷','🛸','🛹','🤐','🤑','🤒','🤓','🤔','🤕','🤖','🤗','🤘','🤙','🤚','🤛','🤜','🤝','🤞','🤟','🤠','🤡','🤢','🤣','🤤','🤥','🤦','🤧','🤨','🤩','🤪','🤫','🤬','🤭','🤮','🤯','🤰','🤱','🤲','🤳','🤴','🤵','🤶','🤷','🤸','🤹','🤺','🤼','🤽','🤾','🥀','🥁','🥂','🥃','🥄','🥅','🥇','🥈','🥉','🥊','🥋','🥌','🥍','🥎','🥏','🥐','🥑','🥒','🥓','🥔','🥕','🥖','🥗','🥘','🥙','🥚','🥛','🥜','🥝','🥞','🥟','🥠','🥡','🥢','🥣','🥤','🥥','🥦','🥧','🥨','🥩','🥪','🥫','🥬','🥭','🥮','🥯','🥰','🥳','🥴','🥵','🥶','🥺','🥼','🥽','🥾','🥿','🦀','🦁','🦂','🦃','🦄','🦅','🦆','🦇','🦈','🦉','🦊','🦋','🦌','🦍','🦎','🦏','🦐','🦑','🦒','🦓','🦔','🦕','🦖','🦗','🦘','🦙','🦚','🦛','🦜','🦝','🦞','🦟','🦠','🦡','🦢','🦴','🦵','🦶','🦷','🦸','🦹','🧀','🧁','🧂','🧐','🧑','🧒','🧓','🧔','🧕','🧖','🧗','🧘','🧙','🧚','🧛','🧜','🧝','🧞','🧟','🧠','🧡','🧢','🧣','🧤','🧥','🧦','🧧','🧨','🧩','🧪','🧫','🧬','🧭','🧮','🧯','🧰','🧱','🧲','🧳','🧴','🧵','🧶','🧷','🧸','🧹','🧺','🧻','🧼','🧽','🧾','🧿','‼','⁉','™','ℹ','↔','↕','↖','↗','↘','↙','↩','↪','⃣','⌚','⌛','⌨','⏏','⏩','⏪','⏫','⏬','⏭','⏮','⏯','⏰','⏱','⏲','⏳','⏸','⏹','⏺','Ⓜ','▪','▫','▶','◀','◻','◼','◽','◾','☀','☁','☂','☃','☄','☎','☑','☔','☕','☘','☝','☢','☣','☦','☪','☮','☯','☸','☹','☺','♈','♉','♊','♋','♌','♍','♎','♏','♐','♑','♒','♓','♟','♠','♣','♥','♦','♨','♻','♾','♿','⚒','⚓','⚔','⚗','⚙','⚛','⚜','⚠','⚡','⚪','⚫','⚰','⚱','⚽','⚾','⛄','⛅','⛈','⛎','⛏','⛑','⛓','⛔','⛩','⛪','⛰','⛱','⛲','⛳','⛴','⛵','⛷','⛸','⛹','⛺','⛽','✂','✅','✉','✊','✋','✌','✍','✏','✒','✔','✖','✝','✡','✨','✳','✴','❄','❇','❌','❎','❓','❔','❕','❗','❣','➕','➖','➗','➡','➰','➿','⤴','⤵','⬅','⬆','⬇','⬛','⬜','⭐','⭕','〰','〽','㊗','㊙',''); |
5754 $partials = array( '🀄', '🃏', '🅰', '🅱', '🅾', '🅿', '🆎', '🆑', '🆒', '🆓', '🆔', '🆕', '🆖', '🆗', '🆘', '🆙', '🆚', '🇦', '🇨', '🇩', '🇪', '🇫', '🇬', '🇮', '🇱', '🇲', '🇴', '🇶', '🇷', '🇸', '🇹', '🇺', '🇼', '🇽', '🇿', '🇧', '🇭', '🇯', '🇳', '🇻', '🇾', '🇰', '🇵', '🈁', '🈂', '🈚', '🈯', '🈲', '🈳', '🈴', '🈵', '🈶', '🈷', '🈸', '🈹', '🈺', '🉐', '🉑', '🌀', '🌁', '🌂', '🌃', '🌄', '🌅', '🌆', '🌇', '🌈', '🌉', '🌊', '🌋', '🌌', '🌍', '🌎', '🌏', '🌐', '🌑', '🌒', '🌓', '🌔', '🌕', '🌖', '🌗', '🌘', '🌙', '🌚', '🌛', '🌜', '🌝', '🌞', '🌟', '🌠', '🌡', '🌤', '🌥', '🌦', '🌧', '🌨', '🌩', '🌪', '🌫', '🌬', '🌭', '🌮', '🌯', '🌰', '🌱', '🌲', '🌳', '🌴', '🌵', '🌶', '🌷', '🌸', '🌹', '🌺', '🌻', '🌼', '🌽', '🌾', '🌿', '🍀', '🍁', '🍂', '🍃', '🍄', '🍅', '🍆', '🍇', '🍈', '🍉', '🍊', '🍋', '🍌', '🍍', '🍎', '🍏', '🍐', '🍑', '🍒', '🍓', '🍔', '🍕', '🍖', '🍗', '🍘', '🍙', '🍚', '🍛', '🍜', '🍝', '🍞', '🍟', '🍠', '🍡', '🍢', '🍣', '🍤', '🍥', '🍦', '🍧', '🍨', '🍩', '🍪', '🍫', '🍬', '🍭', '🍮', '🍯', '🍰', '🍱', '🍲', '🍳', '🍴', '🍵', '🍶', '🍷', '🍸', '🍹', '🍺', '🍻', '🍼', '🍽', '🍾', '🍿', '🎀', '🎁', '🎂', '🎃', '🎄', '🎅', '🏻', '🏼', '🏽', '🏾', '🏿', '🎆', '🎇', '🎈', '🎉', '🎊', '🎋', '🎌', '🎍', '🎎', '🎏', '🎐', '🎑', '🎒', '🎓', '🎖', '🎗', '🎙', '🎚', '🎛', '🎞', '🎟', '🎠', '🎡', '🎢', '🎣', '🎤', '🎥', '🎦', '🎧', '🎨', '🎩', '🎪', '🎫', '🎬', '🎭', '🎮', '🎯', '🎰', '🎱', '🎲', '🎳', '🎴', '🎵', '🎶', '🎷', '🎸', '🎹', '🎺', '🎻', '🎼', '🎽', '🎾', '🎿', '🏀', '🏁', '🏂', '🏃', '‍', '♀', '️', '♂', '🏄', '🏅', '🏆', '🏇', '🏈', '🏉', '🏊', '🏋', '🏌', '🏍', '🏎', '🏏', '🏐', '🏑', '🏒', '🏓', '🏔', '🏕', '🏖', '🏗', '🏘', '🏙', '🏚', '🏛', '🏜', '🏝', '🏞', '🏟', '🏠', '🏡', '🏢', '🏣', '🏤', '🏥', '🏦', '🏧', '🏨', '🏩', '🏪', '🏫', '🏬', '🏭', '🏮', '🏯', '🏰', '🏳', '🏴', '☠', '󠁧', '󠁢', '󠁥', '󠁮', '󠁿', '󠁳', '󠁣', '󠁴', '󠁷', '󠁬', '🏵', '🏷', '🏸', '🏹', '🏺', '🐀', '🐁', '🐂', '🐃', '🐄', '🐅', '🐆', '🐇', '🐈', '🐉', '🐊', '🐋', '🐌', '🐍', '🐎', '🐏', '🐐', '🐑', '🐒', '🐓', '🐔', '🐕', '🦺', '🐖', '🐗', '🐘', '🐙', '🐚', '🐛', '🐜', '🐝', '🐞', '🐟', '🐠', '🐡', '🐢', '🐣', '🐤', '🐥', '🐦', '🐧', '🐨', '🐩', '🐪', '🐫', '🐬', '🐭', '🐮', '🐯', '🐰', '🐱', '🐲', '🐳', '🐴', '🐵', '🐶', '🐷', '🐸', '🐹', '🐺', '🐻', '🐼', '🐽', '🐾', '🐿', '👀', '👁', '🗨', '👂', '👃', '👄', '👅', '👆', '👇', '👈', '👉', '👊', '👋', '👌', '👍', '👎', '👏', '👐', '👑', '👒', '👓', '👔', '👕', '👖', '👗', '👘', '👙', '👚', '👛', '👜', '👝', '👞', '👟', '👠', '👡', '👢', '👣', '👤', '👥', '👦', '👧', '👨', '💻', '💼', '🔧', '🔬', '🚀', '🚒', '🦯', '🦰', '🦱', '🦲', '🦳', '🦼', '🦽', '⚕', '⚖', '✈', '🤝', '👩', '❤', '💋', '👪', '👫', '👬', '👭', '👮', '👯', '👰', '👱', '👲', '👳', '👴', '👵', '👶', '👷', '👸', '👹', '👺', '👻', '👼', '👽', '👾', '👿', '💀', '💁', '💂', '💃', '💄', '💅', '💆', '💇', '💈', '💉', '💊', '💌', '💍', '💎', '💏', '💐', '💑', '💒', '💓', '💔', '💕', '💖', '💗', '💘', '💙', '💚', '💛', '💜', '💝', '💞', '💟', '💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩', '💪', '💫', '💬', '💭', '💮', '💯', '💰', '💱', '💲', '💳', '💴', '💵', '💶', '💷', '💸', '💹', '💺', '💽', '💾', '💿', '📀', '📁', '📂', '📃', '📄', '📅', '📆', '📇', '📈', '📉', '📊', '📋', '📌', '📍', '📎', '📏', '📐', '📑', '📒', '📓', '📔', '📕', '📖', '📗', '📘', '📙', '📚', '📛', '📜', '📝', '📞', '📟', '📠', '📡', '📢', '📣', '📤', '📥', '📦', '📧', '📨', '📩', '📪', '📫', '📬', '📭', '📮', '📯', '📰', '📱', '📲', '📳', '📴', '📵', '📶', '📷', '📸', '📹', '📺', '📻', '📼', '📽', '📿', '🔀', '🔁', '🔂', '🔃', '🔄', '🔅', '🔆', '🔇', '🔈', '🔉', '🔊', '🔋', '🔌', '🔍', '🔎', '🔏', '🔐', '🔑', '🔒', '🔓', '🔔', '🔕', '🔖', '🔗', '🔘', '🔙', '🔚', '🔛', '🔜', '🔝', '🔞', '🔟', '🔠', '🔡', '🔢', '🔣', '🔤', '🔥', '🔦', '🔨', '🔩', '🔪', '🔫', '🔭', '🔮', '🔯', '🔰', '🔱', '🔲', '🔳', '🔴', '🔵', '🔶', '🔷', '🔸', '🔹', '🔺', '🔻', '🔼', '🔽', '🕉', '🕊', '🕋', '🕌', '🕍', '🕎', '🕐', '🕑', '🕒', '🕓', '🕔', '🕕', '🕖', '🕗', '🕘', '🕙', '🕚', '🕛', '🕜', '🕝', '🕞', '🕟', '🕠', '🕡', '🕢', '🕣', '🕤', '🕥', '🕦', '🕧', '🕯', '🕰', '🕳', '🕴', '🕵', '🕶', '🕷', '🕸', '🕹', '🕺', '🖇', '🖊', '🖋', '🖌', '🖍', '🖐', '🖕', '🖖', '🖤', '🖥', '🖨', '🖱', '🖲', '🖼', '🗂', '🗃', '🗄', '🗑', '🗒', '🗓', '🗜', '🗝', '🗞', '🗡', '🗣', '🗯', '🗳', '🗺', '🗻', '🗼', '🗽', '🗾', '🗿', '😀', '😁', '😂', '😃', '😄', '😅', '😆', '😇', '😈', '😉', '😊', '😋', '😌', '😍', '😎', '😏', '😐', '😑', '😒', '😓', '😔', '😕', '😖', '😗', '😘', '😙', '😚', '😛', '😜', '😝', '😞', '😟', '😠', '😡', '😢', '😣', '😤', '😥', '😦', '😧', '😨', '😩', '😪', '😫', '😬', '😭', '😮', '😯', '😰', '😱', '😲', '😳', '😴', '😵', '😶', '😷', '😸', '😹', '😺', '😻', '😼', '😽', '😾', '😿', '🙀', '🙁', '🙂', '🙃', '🙄', '🙅', '🙆', '🙇', '🙈', '🙉', '🙊', '🙋', '🙌', '🙍', '🙎', '🙏', '🚁', '🚂', '🚃', '🚄', '🚅', '🚆', '🚇', '🚈', '🚉', '🚊', '🚋', '🚌', '🚍', '🚎', '🚏', '🚐', '🚑', '🚓', '🚔', '🚕', '🚖', '🚗', '🚘', '🚙', '🚚', '🚛', '🚜', '🚝', '🚞', '🚟', '🚠', '🚡', '🚢', '🚣', '🚤', '🚥', '🚦', '🚧', '🚨', '🚩', '🚪', '🚫', '🚬', '🚭', '🚮', '🚯', '🚰', '🚱', '🚲', '🚳', '🚴', '🚵', '🚶', '🚷', '🚸', '🚹', '🚺', '🚻', '🚼', '🚽', '🚾', '🚿', '🛀', '🛁', '🛂', '🛃', '🛄', '🛅', '🛋', '🛌', '🛍', '🛎', '🛏', '🛐', '🛑', '🛒', '🛕', '🛠', '🛡', '🛢', '🛣', '🛤', '🛥', '🛩', '🛫', '🛬', '🛰', '🛳', '🛴', '🛵', '🛶', '🛷', '🛸', '🛹', '🛺', '🟠', '🟡', '🟢', '🟣', '🟤', '🟥', '🟦', '🟧', '🟨', '🟩', '🟪', '🟫', '🤍', '🤎', '🤏', '🤐', '🤑', '🤒', '🤓', '🤔', '🤕', '🤖', '🤗', '🤘', '🤙', '🤚', '🤛', '🤜', '🤞', '🤟', '🤠', '🤡', '🤢', '🤣', '🤤', '🤥', '🤦', '🤧', '🤨', '🤩', '🤪', '🤫', '🤬', '🤭', '🤮', '🤯', '🤰', '🤱', '🤲', '🤳', '🤴', '🤵', '🤶', '🤷', '🤸', '🤹', '🤺', '🤼', '🤽', '🤾', '🤿', '🥀', '🥁', '🥂', '🥃', '🥄', '🥅', '🥇', '🥈', '🥉', '🥊', '🥋', '🥌', '🥍', '🥎', '🥏', '🥐', '🥑', '🥒', '🥓', '🥔', '🥕', '🥖', '🥗', '🥘', '🥙', '🥚', '🥛', '🥜', '🥝', '🥞', '🥟', '🥠', '🥡', '🥢', '🥣', '🥤', '🥥', '🥦', '🥧', '🥨', '🥩', '🥪', '🥫', '🥬', '🥭', '🥮', '🥯', '🥰', '🥱', '🥳', '🥴', '🥵', '🥶', '🥺', '🥻', '🥼', '🥽', '🥾', '🥿', '🦀', '🦁', '🦂', '🦃', '🦄', '🦅', '🦆', '🦇', '🦈', '🦉', '🦊', '🦋', '🦌', '🦍', '🦎', '🦏', '🦐', '🦑', '🦒', '🦓', '🦔', '🦕', '🦖', '🦗', '🦘', '🦙', '🦚', '🦛', '🦜', '🦝', '🦞', '🦟', '🦠', '🦡', '🦢', '🦥', '🦦', '🦧', '🦨', '🦩', '🦪', '🦮', '🦴', '🦵', '🦶', '🦷', '🦸', '🦹', '🦻', '🦾', '🦿', '🧀', '🧁', '🧂', '🧃', '🧄', '🧅', '🧆', '🧇', '🧈', '🧉', '🧊', '🧍', '🧎', '🧏', '🧐', '🧑', '🧒', '🧓', '🧔', '🧕', '🧖', '🧗', '🧘', '🧙', '🧚', '🧛', '🧜', '🧝', '🧞', '🧟', '🧠', '🧡', '🧢', '🧣', '🧤', '🧥', '🧦', '🧧', '🧨', '🧩', '🧪', '🧫', '🧬', '🧭', '🧮', '🧯', '🧰', '🧱', '🧲', '🧳', '🧴', '🧵', '🧶', '🧷', '🧸', '🧹', '🧺', '🧻', '🧼', '🧽', '🧾', '🧿', '🩰', '🩱', '🩲', '🩳', '🩸', '🩹', '🩺', '🪀', '🪁', '🪂', '🪐', '🪑', '🪒', '🪓', '🪔', '🪕', '‼', '⁉', '™', 'ℹ', '↔', '↕', '↖', '↗', '↘', '↙', '↩', '↪', '⃣', '⌚', '⌛', '⌨', '⏏', '⏩', '⏪', '⏫', '⏬', '⏭', '⏮', '⏯', '⏰', '⏱', '⏲', '⏳', '⏸', '⏹', '⏺', 'Ⓜ', '▪', '▫', '▶', '◀', '◻', '◼', '◽', '◾', '☀', '☁', '☂', '☃', '☄', '☎', '☑', '☔', '☕', '☘', '☝', '☢', '☣', '☦', '☪', '☮', '☯', '☸', '☹', '☺', '♈', '♉', '♊', '♋', '♌', '♍', '♎', '♏', '♐', '♑', '♒', '♓', '♟', '♠', '♣', '♥', '♦', '♨', '♻', '♾', '♿', '⚒', '⚓', '⚔', '⚗', '⚙', '⚛', '⚜', '⚠', '⚡', '⚪', '⚫', '⚰', '⚱', '⚽', '⚾', '⛄', '⛅', '⛈', '⛎', '⛏', '⛑', '⛓', '⛔', '⛩', '⛪', '⛰', '⛱', '⛲', '⛳', '⛴', '⛵', '⛷', '⛸', '⛹', '⛺', '⛽', '✂', '✅', '✉', '✊', '✋', '✌', '✍', '✏', '✒', '✔', '✖', '✝', '✡', '✨', '✳', '✴', '❄', '❇', '❌', '❎', '❓', '❔', '❕', '❗', '❣', '➕', '➖', '➗', '➡', '➰', '➿', '⤴', '⤵', '⬅', '⬆', '⬇', '⬛', '⬜', '⭐', '⭕', '〰', '〽', '㊗', '㊙', '' ); |
5318 // END: emoji arrays |
5755 // END: emoji arrays |
5319 |
5756 |
5320 if ( 'entities' === $type ) { |
5757 if ( 'entities' === $type ) { |
5321 return $entities; |
5758 return $entities; |
5322 } |
5759 } |
5333 * @param string $url URL to shorten. |
5770 * @param string $url URL to shorten. |
5334 * @param int $length Optional. Maximum length of the shortened URL. Default 35 characters. |
5771 * @param int $length Optional. Maximum length of the shortened URL. Default 35 characters. |
5335 * @return string Shortened URL. |
5772 * @return string Shortened URL. |
5336 */ |
5773 */ |
5337 function url_shorten( $url, $length = 35 ) { |
5774 function url_shorten( $url, $length = 35 ) { |
5338 $stripped = str_replace( array( 'https://', 'http://', 'www.' ), '', $url ); |
5775 $stripped = str_replace( array( 'https://', 'http://', 'www.' ), '', $url ); |
5339 $short_url = untrailingslashit( $stripped ); |
5776 $short_url = untrailingslashit( $stripped ); |
5340 |
5777 |
5341 if ( strlen( $short_url ) > $length ) { |
5778 if ( strlen( $short_url ) > $length ) { |
5342 $short_url = substr( $short_url, 0, $length - 3 ) . '…'; |
5779 $short_url = substr( $short_url, 0, $length - 3 ) . '…'; |
5343 } |
5780 } |
5359 if ( '' === $color ) { |
5796 if ( '' === $color ) { |
5360 return ''; |
5797 return ''; |
5361 } |
5798 } |
5362 |
5799 |
5363 // 3 or 6 hex digits, or the empty string. |
5800 // 3 or 6 hex digits, or the empty string. |
5364 if ( preg_match('|^#([A-Fa-f0-9]{3}){1,2}$|', $color ) ) { |
5801 if ( preg_match( '|^#([A-Fa-f0-9]{3}){1,2}$|', $color ) ) { |
5365 return $color; |
5802 return $color; |
5366 } |
5803 } |
5367 } |
5804 } |
5368 |
5805 |
5369 /** |
5806 /** |