ÿØÿà JFIF    ÿÛ „  ( %!1"%)+...383-7(-.+  -%%--------+------------/----------------------------ÿÀ  ¶" ÿÄ     ÿÄ @    !1AQaq‘¡"±ÁÑð2’BRráS‚ñ3b¢CT²Ò #cÿÄ    ÿÄ '   1!AQ2a"‘±#ÿÚ   ? ò(/p‘—–¢·,M|¯G»R£üešT. ôŸEoCFñ‡ 4ÔkåóxR|µÁ¨ÓDà!Ç´µ˜‡p ÍQ‹§!þž^õWsŒy  åÁ§$á«%ºq˜™JyyË0y«^Ϗ -3ÃÏËÈ£Æ\P’ä„s&•‹Üs üô'àWt¹pñCp$bÚF`·7.^)¾!)ÒÙ˜–ÅÏš^h¾ø³·ìe±ŒaeÖ—Í,e=B}Jéߦ$$½—šÙÜCC¯¶è8β–Åkèwx LÉngT±æ¹£Ócœ¿Í/©Éÿ ‰ÚCÒ­mq;Tt¶–}0"zÖPcd1š­¤tˆ„ÐÓâqú[™öUCŠ2޿د­É(¸ßúçšmW,Ò ºf‹Ån™ÄLêÁ8üÁkÁ€L¥ÍuJ1œôrÂSŒÓöt!7EUíïb)AËi¬â-ÙHk8òÁiXYwÅ)O^"ÇØriÛô{»wRUKÙÏÚlÓ¬€‚’שT ] ªb—ÊîKC^×M“xùäñz¬zJ× {4[¹M'IÆeH1LCWÕ]œûº WDæà°OÅ‚¹c²ÞuA–rL`HšpCez‡V’— Ž‚Ë„–ñ­'µR0ÕÖ=À:±G»C\nÆÉ5*¢ †3šhQ4ýÒi$Õ1"Ü]¢p-q3zcQ$ªö¨¥æf›‘»´ÝÚHá„e²JÇ–iÊ:·à¬Øc5Åk»Laª*wi [0Ówk ¦a¦0Õ²ÅÅ‚T¸’³q:Æ<¹ú Ò˜Æ}2VE•Ѐp¡Ô3Úº …h³^LJºçì¥Ánó|˜ÖˆÎˆ+« ¦dø‘Mº–d\ªDðÛ„Ì×LÝ——Ð9Ç|•FèçVm™¨€™3õS–9Äå¢<̉Ìm¢±`·º˜&Z²ž Ë®D«¶»6™‰©­HÈ Àá«h­i³04æ’hxœi3ï¨(ÓL·†‹¶ËpŒ ƒÜÒ? :õdsÀ –3æÓ·Üjâ¬9—]8n¼&]I F£¼…ì–—Œ0v°LǐÅfÛ2TÖ’aµ˜N@ÖBSÏ^à´4-±°b×nÈÈœÆD=KdŒø…ÄÈK,›ÖR§fjü$^ÔÎ!„6^ s:Üun\ôkCÞò÷<—Lúl Í›G¹ÀPá¼Nc¡šÒ…ÙWͳœ±vÊáЄ×9‹P‰cEØ‘™›µŸP<×g1 º©Ø¬wiÁ^l5× I/';Ë+´Z‡ÓÄFÕp[Èð’ HÄ ó 9¬Dl4“é±Ï”V=^Hð;žLädÉa‚°Ë,#/Ž~²BÔÛ QãñQtIeórVB,ÏÂf‹4#Μc‹É3ZIÖ Œ¢¥·üxa‡Ãçè„jŠ[5 Ä!U?,3žÎ×…ðdÓ÷háŠA‰ìÄ4÷ÃÜZÃE{‰®+W\ZÍE[‰»µk»MÝ­`¢©†˜ÃV‹-f¢¡†¢a«eŠ%«Y¨©q%jâd,Ôq`) ¤¦…šˆ ¦E>0Ùb²t–Ÿ  ÷jsςҒKÈcø(é›;k(’#ôŒQ ™C> õ³M9óºÆµ¤çâ;uÀ)5>RÔ¸fÓ~Ȧ—’-$fe«"FâUˆÊwµPÏu w+"åÉó¨6s™Û9(À¨ù©hE°½†n`m~“@©›p!Vkhµ Á1šbEqqÊ@ºèl›2 –Yã%‘‚hÛ{a¶‡ÅÞM²¬çL34®Çl]®‹ŽØŒm'RÜe35æöˆ­Á­ cP9šeÁköo´L³Ì=p8]”‡B¶,šº|ɏdzXˆØk*ÇÚ{#ñ‰pã(€¶‡9ý'šÜ³½¯kƒ†Â’ëSOƒ•Å®H6+a¢µˆ‹Y¨b˜b+XˆÖ!°u!¢"µˆˆn2ˆ Å0Ä`Å Ô®c(ÓÜGº•Ä»Œ âWî%q.áÐÄ÷î%umÍ£+ÜQ,Vn¦-GphU¸¢X­&,Gt ·K¢ÅÅ·¥RÄÊÉbKn N­R2g$VµÕó Qr#–ÓZUÏð0ÎtÙÀœz ëöo“Îk¯n„T°"SÞ+³/…€½"ižãO%Í%&Δâ‘ËØ´IˆÓ°Ë‰ÞM3.™yçÁzit›`4C`k¢¼á!álÄï sÂ[×!¤l¾æo"ƒIÔ'@ªu)3›ô®“@Z à¾] üœ'‡4¸PÞkÁ-qÄH‰ÓÍBd´ÿ —¹°ÄA&ÊUC„öz‚‚RæŠtf¬>˜ÑidšEçÑL÷áý¡V±h§­c¿¥¨ƒ@g¼…Ýö^ÞËc.ž„æ“I[ ª+·zÐÒÚ,½Ð»¶€C›7jk$๖€Ž¾ÅÙpp¶ÍþéΤ ½ØÎŒq ñpæžÅ¥#Øâ49ÃÂK^MYV“,¶Éz_òæ:…;Õ«¦I3âJ£¤û5$7Èxün\â]Êe¯(Ÿ&Ž‹¶2<6Ćf× æ¢ƱqWı[(ÙÂŽç‚T7¨@ÈÉÍß‚ïÙ"&3TYlGށ†)†#5ŠA©^T2ÆÁ†)©†©†¤yGXÁ†©"†)©¼ÅV WS†#©]R–r‹q5ÕbâWþBh¯u+ªÅÄ×ü„nÑ^êkªÁj‰jeœWˆÕÕ`µDµ2Ì+Ä µDµµ5Ô{¤Þ0RF’H÷AÛ<ÊÁ§ ƈæ0Ñ£ê4 öÚµ[¬/1²€â<-¬šö²r×0o×w ´xÐÒË„ g01¬„åEM蛇Ã\6µE›‘fÙO k÷CºnÓ1`iîÒ² áÂ!ÑLÄÿ ³¬\õ*:M=Ç»c‹2[‰ØsÕLò\ŒK L^™üÄN\¶#» Ç\……ßïIœÉ$¸ÎñÍ®ÔHÇ Ûí/´>Li”„†g^$ 7NÍÑÑ2M2ªNg=k½Ð}Ÿl6‡ —JWˆ”ÞéT·+µ¦üÂFè¢Vs6ýÆ4»2+2IÝ9ô9®ÇGÙÇ1+Ä8;*Õ§ž½D*îÑWÚçá3Ma¤·ˆ¥t}š²Ü…Q+Æüµ8HíS”üxGéÁˆ¦Ël„éÈ 5 µÄƒ6äÜ(kIš¯S†fÖ&¸®×v|Äyˆ*禌Éù@7-®Ä[]ÎÖ¿ê`º…=:…žJVnݳvðÖKE¼‚ »mà ÷f®:Ë ™–4rð¡4` ܹçž~‹C=œ…¾Ïj|VDtK.ƒ"9 Ï ­–éXá³6WÒïIL-Ї Ç register_handler( $id, $regex, $callback, $priority ); } /** * Unregisters a previously-registered embed handler. * * @since 2.9.0 * * @global WP_Embed $wp_embed WordPress Embed object. * * @param string $id The handler ID that should be removed. * @param int $priority Optional. The priority of the handler to be removed. Default 10. */ function wp_embed_unregister_handler( $id, $priority = 10 ) { global $wp_embed; $wp_embed->unregister_handler( $id, $priority ); } /** * Creates default array of embed parameters. * * The width defaults to the content width as specified by the theme. If the * theme does not specify a content width, then 500px is used. * * The default height is 1.5 times the width, or 1000px, whichever is smaller. * * The {@see 'embed_defaults'} filter can be used to adjust either of these values. * * @since 2.9.0 * * @global int $content_width * * @param string $url Optional. The URL that should be embedded. Default empty. * @return int[] { * Indexed array of the embed width and height in pixels. * * @type int $0 The embed width. * @type int $1 The embed height. * } */ function wp_embed_defaults( $url = '' ) { if ( ! empty( $GLOBALS['content_width'] ) ) { $width = (int) $GLOBALS['content_width']; } if ( empty( $width ) ) { $width = 500; } $height = min( (int) ceil( $width * 1.5 ), 1000 ); /** * Filters the default array of embed dimensions. * * @since 2.9.0 * * @param int[] $size { * Indexed array of the embed width and height in pixels. * * @type int $0 The embed width. * @type int $1 The embed height. * } * @param string $url The URL that should be embedded. */ return apply_filters( 'embed_defaults', compact( 'width', 'height' ), $url ); } /** * Attempts to fetch the embed HTML for a provided URL using oEmbed. * * @since 2.9.0 * * @see WP_oEmbed * * @param string $url The URL that should be embedded. * @param array|string $args { * Optional. Additional arguments for retrieving embed HTML. Default empty. * * @type int|string $width Optional. The `maxwidth` value passed to the provider URL. * @type int|string $height Optional. The `maxheight` value passed to the provider URL. * @type bool $discover Optional. Determines whether to attempt to discover link tags * at the given URL for an oEmbed provider when the provider URL * is not found in the built-in providers list. Default true. * } * @return string|false The embed HTML on success, false on failure. */ function wp_oembed_get( $url, $args = '' ) { $oembed = _wp_oembed_get_object(); return $oembed->get_html( $url, $args ); } /** * Returns the initialized WP_oEmbed object. * * @since 2.9.0 * @access private * * @return WP_oEmbed object. */ function _wp_oembed_get_object() { static $wp_oembed = null; if ( is_null( $wp_oembed ) ) { $wp_oembed = new WP_oEmbed(); } return $wp_oembed; } /** * Adds a URL format and oEmbed provider URL pair. * * @since 2.9.0 * * @see WP_oEmbed * * @param string $format The format of URL that this provider can handle. You can use asterisks * as wildcards. * @param string $provider The URL to the oEmbed provider. * @param bool $regex Optional. Whether the `$format` parameter is in a RegEx format. Default false. */ function wp_oembed_add_provider( $format, $provider, $regex = false ) { if ( did_action( 'plugins_loaded' ) ) { $oembed = _wp_oembed_get_object(); $oembed->providers[ $format ] = array( $provider, $regex ); } else { WP_oEmbed::_add_provider_early( $format, $provider, $regex ); } } /** * Removes an oEmbed provider. * * @since 3.5.0 * * @see WP_oEmbed * * @param string $format The URL format for the oEmbed provider to remove. * @return bool Was the provider removed successfully? */ function wp_oembed_remove_provider( $format ) { if ( did_action( 'plugins_loaded' ) ) { $oembed = _wp_oembed_get_object(); if ( isset( $oembed->providers[ $format ] ) ) { unset( $oembed->providers[ $format ] ); return true; } } else { WP_oEmbed::_remove_provider_early( $format ); } return false; } /** * Determines if default embed handlers should be loaded. * * Checks to make sure that the embeds library hasn't already been loaded. If * it hasn't, then it will load the embeds library. * * @since 2.9.0 * * @see wp_embed_register_handler() */ function wp_maybe_load_embeds() { /** * Filters whether to load the default embed handlers. * * Returning a falsey value will prevent loading the default embed handlers. * * @since 2.9.0 * * @param bool $maybe_load_embeds Whether to load the embeds library. Default true. */ if ( ! apply_filters( 'load_default_embeds', true ) ) { return; } wp_embed_register_handler( 'youtube_embed_url', '#https?://(www\.)?youtube\.com/(?:v|embed)/([^/]+)#i', 'wp_embed_handler_youtube' ); /** * Filters the audio embed handler callback. * * @since 3.6.0 * * @param callable $handler Audio embed handler callback function. */ wp_embed_register_handler( 'audio', '#^https?://.+?\.(' . implode( '|', wp_get_audio_extensions() ) . ')$#i', apply_filters( 'wp_audio_embed_handler', 'wp_embed_handler_audio' ), 9999 ); /** * Filters the video embed handler callback. * * @since 3.6.0 * * @param callable $handler Video embed handler callback function. */ wp_embed_register_handler( 'video', '#^https?://.+?\.(' . implode( '|', wp_get_video_extensions() ) . ')$#i', apply_filters( 'wp_video_embed_handler', 'wp_embed_handler_video' ), 9999 ); } /** * YouTube iframe embed handler callback. * * Catches YouTube iframe embed URLs that are not parsable by oEmbed but can be translated into a URL that is. * * @since 4.0.0 * * @global WP_Embed $wp_embed WordPress Embed object. * * @param array $matches The RegEx matches from the provided regex when calling * wp_embed_register_handler(). * @param array $attr Embed attributes. * @param string $url The original URL that was matched by the regex. * @param array $rawattr The original unmodified attributes. * @return string The embed HTML. */ function wp_embed_handler_youtube( $matches, $attr, $url, $rawattr ) { global $wp_embed; $embed = $wp_embed->autoembed( sprintf( 'https://youtube.com/watch?v=%s', urlencode( $matches[2] ) ) ); /** * Filters the YouTube embed output. * * @since 4.0.0 * * @see wp_embed_handler_youtube() * * @param string $embed YouTube embed output. * @param array $attr An array of embed attributes. * @param string $url The original URL that was matched by the regex. * @param array $rawattr The original unmodified attributes. */ return apply_filters( 'wp_embed_handler_youtube', $embed, $attr, $url, $rawattr ); } /** * Audio embed handler callback. * * @since 3.6.0 * * @param array $matches The RegEx matches from the provided regex when calling wp_embed_register_handler(). * @param array $attr Embed attributes. * @param string $url The original URL that was matched by the regex. * @param array $rawattr The original unmodified attributes. * @return string The embed HTML. */ function wp_embed_handler_audio( $matches, $attr, $url, $rawattr ) { $audio = sprintf( '[audio src="%s" /]', esc_url( $url ) ); /** * Filters the audio embed output. * * @since 3.6.0 * * @param string $audio Audio embed output. * @param array $attr An array of embed attributes. * @param string $url The original URL that was matched by the regex. * @param array $rawattr The original unmodified attributes. */ return apply_filters( 'wp_embed_handler_audio', $audio, $attr, $url, $rawattr ); } /** * Video embed handler callback. * * @since 3.6.0 * * @param array $matches The RegEx matches from the provided regex when calling wp_embed_register_handler(). * @param array $attr Embed attributes. * @param string $url The original URL that was matched by the regex. * @param array $rawattr The original unmodified attributes. * @return string The embed HTML. */ function wp_embed_handler_video( $matches, $attr, $url, $rawattr ) { $dimensions = ''; if ( ! empty( $rawattr['width'] ) && ! empty( $rawattr['height'] ) ) { $dimensions .= sprintf( 'width="%d" ', (int) $rawattr['width'] ); $dimensions .= sprintf( 'height="%d" ', (int) $rawattr['height'] ); } $video = sprintf( '[video %s src="%s" /]', $dimensions, esc_url( $url ) ); /** * Filters the video embed output. * * @since 3.6.0 * * @param string $video Video embed output. * @param array $attr An array of embed attributes. * @param string $url The original URL that was matched by the regex. * @param array $rawattr The original unmodified attributes. */ return apply_filters( 'wp_embed_handler_video', $video, $attr, $url, $rawattr ); } /** * Registers the oEmbed REST API route. * * @since 4.4.0 */ function wp_oembed_register_route() { $controller = new WP_oEmbed_Controller(); $controller->register_routes(); } /** * Adds oEmbed discovery links in the head element of the website. * * @since 4.4.0 * @since 6.8.0 Output was adjusted to only embed if the post supports it. * @since 6.9.0 Now runs first at `wp_head` priority 4, with a fallback to priority 10. This helps ensure the discovery links appear within the first 150KB. */ function wp_oembed_add_discovery_links() { if ( doing_action( 'wp_head' ) ) { // For back-compat, short-circuit if a plugin has removed the action at the original priority. if ( ! has_action( 'wp_head', 'wp_oembed_add_discovery_links', 10 ) ) { return; } // Prevent running again at the original priority. remove_action( 'wp_head', 'wp_oembed_add_discovery_links' ); } $output = ''; if ( is_singular() && is_post_embeddable() ) { $output .= '' . "\n"; if ( class_exists( 'SimpleXMLElement' ) ) { $output .= '' . "\n"; } } /** * Filters the oEmbed discovery links HTML. * * @since 4.4.0 * * @param string $output HTML of the discovery links. */ echo apply_filters( 'oembed_discovery_links', $output ); } /** * Adds the necessary JavaScript to communicate with the embedded iframes. * * This function is no longer used directly. For back-compat it exists exclusively as a way to indicate that the oEmbed * host JS _should_ be added. In `default-filters.php` there remains this code: * * add_action( 'wp_head', 'wp_oembed_add_host_js' ) * * Historically a site has been able to disable adding the oEmbed host script by doing: * * remove_action( 'wp_head', 'wp_oembed_add_host_js' ) * * In order to ensure that such code still works as expected, this function remains. There is now a `has_action()` check * in `wp_maybe_enqueue_oembed_host_js()` to see if `wp_oembed_add_host_js()` has not been unhooked from running at the * `wp_head` action. * * @since 4.4.0 * @deprecated 5.9.0 Use {@see wp_maybe_enqueue_oembed_host_js()} instead. */ function wp_oembed_add_host_js() {} /** * Enqueue the wp-embed script if the provided oEmbed HTML contains a post embed. * * In order to only enqueue the wp-embed script on pages that actually contain post embeds, this function checks if the * provided HTML contains post embed markup and if so enqueues the script so that it will get printed in the footer. * * @since 5.9.0 * * @param string $html Embed markup. * @return string Embed markup (without modifications). */ function wp_maybe_enqueue_oembed_host_js( $html ) { if ( has_action( 'wp_head', 'wp_oembed_add_host_js' ) && preg_match( '/]*?wp-embedded-content/', $html ) ) { wp_enqueue_script( 'wp-embed' ); } return $html; } /** * Retrieves the URL to embed a specific post in an iframe. * * @since 4.4.0 * * @param int|WP_Post|null $post Optional. Post ID or object. Defaults to the current post. * @return string|false The post embed URL on success, false if the post doesn't exist. */ function get_post_embed_url( $post = null ) { $post = get_post( $post ); if ( ! $post ) { return false; } $embed_url = trailingslashit( get_permalink( $post ) ) . user_trailingslashit( 'embed' ); $path_conflict = get_page_by_path( str_replace( home_url(), '', $embed_url ), OBJECT, get_post_types( array( 'public' => true ) ) ); if ( ! get_option( 'permalink_structure' ) || $path_conflict ) { $embed_url = add_query_arg( array( 'embed' => 'true' ), get_permalink( $post ) ); } /** * Filters the URL to embed a specific post. * * @since 4.4.0 * * @param string $embed_url The post embed URL. * @param WP_Post $post The corresponding post object. */ return sanitize_url( apply_filters( 'post_embed_url', $embed_url, $post ) ); } /** * Retrieves the oEmbed endpoint URL for a given permalink. * * Pass an empty string as the first argument to get the endpoint base URL. * * @since 4.4.0 * * @param string $permalink Optional. The permalink used for the `url` query arg. Default empty. * @param string $format Optional. The requested response format. Default 'json'. * @return string The oEmbed endpoint URL. */ function get_oembed_endpoint_url( $permalink = '', $format = 'json' ) { $url = rest_url( 'oembed/1.0/embed' ); if ( '' !== $permalink ) { $url = add_query_arg( array( 'url' => urlencode( $permalink ), 'format' => ( 'json' !== $format ) ? $format : false, ), $url ); } /** * Filters the oEmbed endpoint URL. * * @since 4.4.0 * * @param string $url The URL to the oEmbed endpoint. * @param string $permalink The permalink used for the `url` query arg. * @param string $format The requested response format. */ return apply_filters( 'oembed_endpoint_url', $url, $permalink, $format ); } /** * Retrieves the embed code for a specific post. * * @since 4.4.0 * * @param int $width The width for the response. * @param int $height The height for the response. * @param int|WP_Post|null $post Optional. Post ID or object. Default is global `$post`. * @return string|false Embed code on success, false if post doesn't exist. */ function get_post_embed_html( $width, $height, $post = null ) { $post = get_post( $post ); if ( ! $post ) { return false; } $embed_url = get_post_embed_url( $post ); $secret = wp_generate_password( 10, false ); $embed_url .= "#?secret={$secret}"; $output = sprintf( '
%3$s
', esc_attr( $secret ), esc_url( get_permalink( $post ) ), get_the_title( $post ) ); $output .= sprintf( '', esc_url( $embed_url ), absint( $width ), absint( $height ), esc_attr( sprintf( /* translators: 1: Post title, 2: Site title. */ __( '“%1$s” — %2$s' ), get_the_title( $post ), get_bloginfo( 'name' ) ) ), esc_attr( $secret ) ); /* * Note that the script must be placed after the
and )|ms', $html, $content ); // We require at least the iframe to exist. if ( empty( $content[2] ) ) { return false; } $html = $content[1] . $content[2]; preg_match( '/ src=([\'"])(.*?)\1/', $html, $results ); if ( ! empty( $results ) ) { $secret = wp_generate_password( 10, false ); $url = esc_url( "{$results[2]}#?secret=$secret" ); $q = $results[1]; $html = str_replace( $results[0], ' src=' . $q . $url . $q . ' data-secret=' . $q . $secret . $q, $html ); $html = str_replace( '