source on its own array key, without adding either
 * the `width` or `height` attributes, since these are added dynamically,
 * before rendering the SVG code.
 *
 * All icons are assumed to have equal width and height, hence the option
 * to only specify a `$size` parameter in the svg methods.
 *
 * @since Twenty Twenty-One 1.0
 */
class Twenty_Twenty_One_SVG_Icons {
	/**
	 * User Interface icons – svg sources.
	 *
	 * @since Twenty Twenty-One 1.0
	 *
	 * @var array
	 */
	protected static $icons = array(
		'arrow_right' => '',
		'arrow_left'  => '',
		'close'       => '',
		'menu'        => '',
		'plus'        => '',
		'minus'       => '',
	);
	/**
	 * Social Icons – svg sources.
	 *
	 * @since Twenty Twenty-One 1.0
	 *
	 * @var array
	 */
	protected static $social_icons = array(
		'500px'      => '',
		'amazon'     => '',
		'bandcamp'   => '',
		'behance'    => '',
		'codepen'    => '',
		'deviantart' => '',
		'dribbble'   => '',
		'dropbox'    => '',
		'etsy'       => '',
		'facebook'   => '',
		'feed'       => '',
		'flickr'     => '',
		'foursquare' => '',
		'goodreads'  => '',
		'google'     => '',
		'github'     => '',
		'instagram'  => '',
		'lastfm'     => '',
		'linkedin'   => '',
		'mail'       => '',
		'mastodon'   => '',
		'medium'     => '',
		'meetup'     => '',
		'pinterest'  => '',
		'pocket'     => '',
		'reddit'     => '',
		'skype'      => '',
		'snapchat'   => '',
		'soundcloud' => '',
		'spotify'    => '',
		'tumblr'     => '',
		'twitch'     => '',
		'twitter'    => '',
		'vimeo'      => '',
		'vk'         => '',
		'wordpress'  => '',
		'yelp'       => '',
		'youtube'    => '',
	);
	/**
	 * Social Icons – domain mappings.
	 *
	 * By default, each Icon ID is matched against a .com TLD. To override this behavior,
	 * specify all the domains it covers (including the .com TLD too, if applicable).
	 *
	 * @since Twenty Twenty-One 1.0
	 *
	 * @var array
	 */
	protected static $social_icons_map = array(
		'amazon'    => array(
			'amazon.com',
			'amazon.cn',
			'amazon.in',
			'amazon.fr',
			'amazon.de',
			'amazon.it',
			'amazon.nl',
			'amazon.es',
			'amazon.co',
			'amazon.ca',
		),
		'behance'   => array(
			'behance.net',
		),
		'codepen'   => array(
			'codepen.io',
		),
		'facebook'  => array(
			'facebook.com',
			'fb.me',
		),
		'feed'      => array(
			'feed',
		),
		'lastfm'    => array(
			'last.fm',
		),
		'mail'      => array(
			'mailto:',
		),
		'pocket'    => array(
			'getpocket.com',
		),
		'twitch'    => array(
			'twitch.tv',
		),
		'wordpress' => array(
			'wordpress.com',
			'wordpress.org',
		),
	);
	/**
	 * Gets the SVG code for a given icon.
	 *
	 * @static
	 *
	 * @since Twenty Twenty-One 1.0
	 *
	 * @param string $group The icon group.
	 * @param string $icon  The icon.
	 * @param int    $size  The icon-size in pixels.
	 * @return string
	 */
	public static function get_svg( $group, $icon, $size ) {
		if ( 'ui' === $group ) {
			$arr = self::$icons;
		} elseif ( 'social' === $group ) {
			$arr = self::$social_icons;
		} else {
			$arr = array();
		}
		/**
		 * Filters Twenty Twenty-Ones's array of icons.
		 *
		 * The dynamic portion of the hook name, `$group`, refers to
		 * the name of the group of icons, either "ui" or "social".
		 *
		 * @since Twenty Twenty-One 1.0
		 *
		 * @param array $arr Array of icons.
		 */
		$arr = apply_filters( "twenty_twenty_one_svg_icons_{$group}", $arr );
		$svg = '';
		if ( array_key_exists( $icon, $arr ) ) {
			$repl = sprintf( '