Get possible plural forms from MO header

@access private
@return string plural form header
1237
private function get_plural_forms() {
        // lets assume message number 0 is header
        // this is true, right?
        $this->load_tables();

        // cache header field for plural forms
        if (!is_string($this->pluralheader)) {
            if ($this->enable_cache) {
                $header = $this->cache_translations[""];
            }
            else {
                $header = $this->get_translation_string(0);
            }
            if (preg_match("/plural\-forms: ([^\n]*)\n/i", $header, $regs))
                $expr = $regs[1];
            else
                $expr = "nplurals=2; plural=n == 1 ? 0 : 1;";
            $this->pluralheader = $expr;
        }
        return $this->pluralheader;
    }
450644
public function getModifiers()
    {
        $mods = $this->modifiers;
        if ($this->getIgnoreCase()) {
            $mods .= 'i';
        } elseif ($this->getIgnoreCase() === false) {
            $mods = str_replace('i', '', $mods);
        }
        if ($this->getMultiline()) {
            $mods .= 's';
        } elseif ($this->getMultiline() === false) {
            $mods = str_replace('s', '', $mods);
        }
        // filter out duplicates
        $mods = preg_split('//', $mods, -1, PREG_SPLIT_NO_EMPTY);
        $mods = implode('', array_unique($mods));

        return $mods;
    }
468290
public function plural_name()
    {
        if ($name = $this->config()->get('plural_name')) {
            return $name;
        }
        $name = $this->singular_name();
        //if the penultimate character is not a vowel, replace "y" with "ies"
        if (preg_match('/[^aeiou]y$/i', $name)) {
            $name = substr($name, 0, -1) . 'ie';
        }
        return ucfirst($name . 's');
    }
14808
public static function extractPluralsForms($header)
    {
        $headers = explode("\n", $header);
        $expr = 'nplurals=2; plural=n == 1 ? 0 : 1;';
        foreach ($headers as $header) {
            if (stripos($header, 'Plural-Forms:') === 0) {
                $expr = substr($header, 13);
            }
        }

        return $expr;
    }
414488
public function getPluralTitle()
    {
        if (!isset($this->pluralTitle) || !$this->pluralTitle) {
            return Str::plural($this->getTitle());
        }

        return $this->pluralTitle;
    }
1042214
public function getHeaders()
    {
        $headers = [];
        $pattern = '#(.*?): (.*?);#i';
        if (preg_match_all($pattern, $this->header, $match)) {
            foreach ($match[1] as $co => $vo) {
                if (!isset($headers[$vo])) {
                    $headers[$vo] = [];
                }
                $headers[$vo][] = $match[2][$co];
            }
        }
        return $headers;
    }
792127
protected function getUsings()
    {
        $usings = array();

        for ($i=0; $i<count($this->values); $i++) {
            $using = '"-" using 1:2 with '.$this->mode;
            if (isset($this->titles[$i])) {
                $using .= ' title "'.$this->titles[$i].'"';
            }
            $usings[] = $using;
        }

        return implode(', ', $usings);
    }
268970
protected function getPluralIndex(callable $pluralForm, $number)
    {
        $nplurals = 0;
        $plural = 0;

        call_user_func_array($pluralForm, [&$nplurals, &$plural, $number]);

        if (is_bool($plural)) {
            $plural = $plural ? 1 : 0;
        }

        if ($plural < 0) {
            $plural = 0;
        }

        if ($plural > $nplurals - 1) {
            $plural = $nplurals - 1;
        }

        return $plural;
    }
1149961
public function getPlural(): string
    {
        try {
            if (null === $this->plural) {
                $singular     = $this->getSingular();
                $this->plural = Inflector::pluralize($singular);
            }

            return $this->plural;
        } catch (\Exception $e) {
            throw new DoctrineStaticMetaException(
                'Exception in ' . __METHOD__ . ': ' . $e->getMessage(),
                $e->getCode(),
                $e
            );
        }
    }
474360
public function getHeadScripts()
    {
        $output = '';
        foreach ($this->headScripts as $script) {
            $output .= $script . "\n";
        }
        $output = rtrim($output, "\n");
        return $output;
    }
995323
public function pluralize($name)
	{
		$rules=array(
			'/(m)ove$/i' => '\1oves',
			'/(f)oot$/i' => '\1eet',
			'/(c)hild$/i' => '\1hildren',
			'/(h)uman$/i' => '\1umans',
			'/(m)an$/i' => '\1en',
			'/(s)taff$/i' => '\1taff',
			'/(t)ooth$/i' => '\1eeth',
			'/(p)erson$/i' => '\1eople',
			'/([m|l])ouse$/i' => '\1ice',
			'/(x|ch|ss|sh|us|as|is|os)$/i' => '\1es',
			'/([^aeiouy]|qu)y$/i' => '\1ies',
			'/(?:([^f])fe|([lr])f)$/i' => '\1\2ves',
			'/(shea|lea|loa|thie)f$/i' => '\1ves',
			'/([ti])um$/i' => '\1a',
			'/(tomat|potat|ech|her|vet)o$/i' => '\1oes',
			'/(bu)s$/i' => '\1ses',
			'/(ax|test)is$/i' => '\1es',
			'/s$/' => 's',
		);
		foreach($rules as $rule=>$replacement)
		{
			if(preg_match($rule,$name))
				return preg_replace($rule,$replacement,$name);
		}
		return $name.'s';
	}
935067
public static function pluralize( $name )
    {
        /** @noinspection SpellCheckingInspection */
        static $_blacklist = array(
            'Amoyese',
            'bison',
            'Borghese',
            'bream',
            'breeches',
            'britches',
            'buffalo',
            'cantus',
            'carp',
            'chassis',
            'clippers',
            'cod',
            'coitus',
            'Congoese',
            'contretemps',
            'corps',
            'debris',
            'deer',
            'diabetes',
            'djinn',
            'eland',
            'elk',
            'equipment',
            'Faroese',
            'flounder',
            'Foochowese',
            'gallows',
            'Genevese',
            'geese',
            'Genoese',
            'Gilbertese',
            'graffiti',
            'headquarters',
            'herpes',
            'hijinks',
            'Hottentotese',
            'information',
            'innings',
            'jackanapes',
            'Kiplingese',
            'Kongoese',
            'Lucchese',
            'mackerel',
            'Maltese',
            '.*?media',
            'metadata',
            'mews',
            'moose',
            'mumps',
            'Nankingese',
            'news',
            'nexus',
            'Niasese',
            'Pekingese',
            'Piedmontese',
            'pincers',
            'Pistoiese',
            'pliers',
            'Portuguese',
            'proceedings',
            'rabies',
            'rice',
            'rhinoceros',
            'salmon',
            'Sarawakese',
            'scissors',
            'sea[- ]bass',
            'series',
            'Shavese',
            'shears',
            'siemens',
            'species',
            'swine',
            'testes',
            'trousers',
            'trout',
            'tuna',
            'Vermontese',
            'Wenchowese',
            'whiting',
            'wildebeest',
            'Yengeese',
        );
        /** @noinspection SpellCheckingInspection */
        static $_rules = array(
            '/(s)tatus$/i'                                                                 => '\1\2tatuses',
            '/(quiz)$/i'                                                                   => '\1zes',
            '/^(ox)$/i'                                                                    => '\1en',
            '/(matr|vert|ind)(ix|ex)$/i'                                                   => '\1ices',
            '/([m|l])ouse$/i'                                                              => '\1ice',
            '/(x|ch|ss|sh|us|as|is|os)$/i'                                                 => '\1es',
            '/(shea|lea|loa|thie)f$/i'                                                     => '\1ves',
            '/(buffal|tomat|potat|ech|her|vet)o$/i'                                        => '\1oes',
            '/([^aeiouy]|qu)ies$/i'                                                        => '\1y',
            '/([^aeiouy]|qu)y$/i'                                                          => '\1ies',
            '/(?:([^f])fe|([lre])f)$/i'                                                    => '\1\2ves',
            '/([ti])um$/i'                                                                 => '\1a',
            '/sis$/i'                                                                      => 'ses',
            '/move$/i'                                                                     => 'moves',
            '/foot$/i'                                                                     => 'feet',
            '/human$/i'                                                                    => 'humans',
            '/tooth$/i'                                                                    => 'teeth',
            '/(bu)s$/i'                                                                    => '\1ses',
            '/(hive)$/i'                                                                   => '\1s',
            '/(p)erson$/i'                                                                 => '\1eople',
            '/(m)an$/i'                                                                    => '\1en',
            '/(c)hild$/i'                                                                  => '\1hildren',
            '/(alumn|bacill|cact|foc|fung|nucle|octop|radi|stimul|syllab|termin|vir)us$/i' => '\1i',
            '/us$/i'                                                                       => 'uses',
            '/(alias)$/i'                                                                  => '\1es',
            '/(ax|cris|test)is$/i'                                                         => '\1es',
            '/s$/'                                                                         => 's',
            '/$/'                                                                          => 's',
        );

        if ( empty( $name ) || in_array( strtolower( $name ), $_blacklist ) )
        {
            return $name;
        }

        foreach ( $_rules as $_rule => $_replacement )
        {
            if ( preg_match( $_rule, $name ) )
            {
                return preg_replace( $_rule, $_replacement, $name );
            }
        }

        return $name;
    }
407331
static function plural($string) {
		$plural = array(
			array('/(quiz)$/i', "$1zes"),
			array('/^(ox)$/i', "$1en"),
			array('/([m|l])ouse$/i', "$1ice"),
			array('/(matr|vert|ind)ix|ex$/i', "$1ices"),
			array('/(x|ch|ss|sh)$/i', "$1es"),
			array('/([^aeiouy]|qu)y$/i', "$1ies"),
			array('/([^aeiouy]|qu)ies$/i', "$1y"),
			array('/(hive|move)$/i', "$1s"),
			array('/(?:([^f])fe|([lr])f)$/i', "$1$2ves"),
			array('/sis$/i', "ses"),
			array('/([ti])um$/i', "$1a"),
			array('/(buffal|tomat)o$/i', "$1oes"),
			array('/(bu)s$/i', "$1ses"),
			array('/(alias|status|campus)$/i', "$1es"),
			array('/(octop|cact|vir)us$/i', "$1i"),
			array('/(ax|test)is$/i', "$1es"),
			array('/^(m|wom)an$/i', "$1en"),
			array('/(child)$/i', "$1ren"),
			array('/(p)erson$/i', "$1eople"),
			array('/s$/i', "s"),
			array('/$/', "s")
		);

		$words = self::getWords($string);
		$word = array_pop($words);

		// check for matches using regular expressions
		foreach ($plural as &$pattern) {
			if (preg_match($pattern[0], $word)) {
				$prefix = substr($string, 0, strrpos($string, $word));
				return $prefix . preg_replace($pattern[0], $pattern[1], $word);
			}
		}
		return $string . 's';
	}
668872
public function getPluralSuffixes($count)
	{
		if ($this->callbacks['pluralSuffixes'] !== null)
		{
			return call_user_func($this->callbacks['pluralSuffixes'], $count);
		}
		else
		{
			return array((string) $count);
		}
	}
675639
public function getPluralForm($root)
    {
        // save some time in the case that singular and plural are the same
        if (in_array(strtolower($root), $this->uncountable)) {
            return $root;
        }

        // check for irregular singular words
        foreach ($this->irregular as $pattern => $result) {
            $searchPattern = '/' . $pattern . '$/i';
            if (preg_match($searchPattern, $root)) {
                $replacement = preg_replace($searchPattern, $result, $root);
                // look at the first char and see if it's upper case
                // I know it won't handle more than one upper case char here (but I'm OK with that)
                if (preg_match('/^[A-Z]/', $root)) {
                    $replacement = ucfirst($replacement);
                }

                return $replacement;
            }
        }

        // check for irregular singular suffixes
        foreach ($this->plural as $pattern => $result) {
            $searchPattern = '/' . $pattern . '$/i';
            if (preg_match($searchPattern, $root)) {
                return preg_replace($searchPattern, $result, $root);
            }
        }

        // fallback to naive pluralization
        return $root . 's';
    }
367707
public static function pluralize($word)
    {
        if (isset(self::$_cache['pluralize'][$word])) {
            return self::$_cache['pluralize'][$word];
        }

        if (!isset(self::$_plural['merged']['irregular'])) {
            self::$_plural['merged']['irregular'] = self::$_plural['irregular'];
        }

        if (!isset(self::$_plural['merged']['uninflected'])) {
            self::$_plural['merged']['uninflected'] = array_merge(self::$_plural['uninflected'], self::$_uninflected);
        }

        if (!isset(self::$_plural['cacheUninflected']) || !isset(self::$_plural['cacheIrregular'])) {
            self::$_plural['cacheUninflected'] = '(?:' . implode('|', self::$_plural['merged']['uninflected']) . ')';
            self::$_plural['cacheIrregular'] = '(?:' . implode('|', array_keys(self::$_plural['merged']['irregular'])) . ')';
        }

        if (preg_match('/(.*)\\b(' . self::$_plural['cacheIrregular'] . ')$/i', $word, $regs)) {
            self::$_cache['pluralize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$_plural['merged']['irregular'][strtolower($regs[2])], 1);
            return self::$_cache['pluralize'][$word];
        }

        if (preg_match('/^(' . self::$_plural['cacheUninflected'] . ')$/i', $word, $regs)) {
            self::$_cache['pluralize'][$word] = $word;
            return $word;
        }

        foreach (self::$_plural['rules'] as $rule => $replacement) {
            if (preg_match($rule, $word)) {
                self::$_cache['pluralize'][$word] = preg_replace($rule, $replacement, $word);
                return self::$_cache['pluralize'][$word];
            }
        }
    }
74821
public function defaultLabels($plural, $singular, $hierarchical = true)
    {
        $labels = [
            'name' => $plural,
            'singular_name' => $singular,
            'menu_name' => $plural,
            'all_items' => $plural,

            'search_items' => Translate::t('term.labels.search_items'),
            'edit_item' => Translate::t('term.labels.edit_item'),
            'update_item' => Translate::t('term.labels.update_item'),
            'add_new_item' => Translate::t('term.labels.add_new_item'),
            'new_item_name' => Translate::t('term.labels.new_item_name'),
        ];

        if ($hierarchical) {
            $labels = array_merge($labels, [
                'parent_item' => Translate::t('term.labels.parent_item'),
                'parent_item_colon' => Translate::t('term.labels.parent_item_colon'),
            ]);
        } else {
            $labels = array_merge($labels, [
                'parent_item' => null,
                'parent_item_colon' => null,

                'popular_items' => Translate::t('term.labels.popular_items'),
                'separate_items_with_commas' => Translate::t('term.labels.separate_items_with_commas'),
                'choose_from_most_used' => Translate::t('term.labels.choose_from_most_used'),

                'add_or_remove_items' => Translate::t('term.labels.add_or_remove_items'),
                'not_found' => Translate::t('term.labels.not_found'),
            ]);
        }

        return $labels;
    }