Determine if the user's operating system is OS X.

@param Os $os
@param UserAgent $userAgent

@return bool
172676
private static function checkOSX(Os $os, UserAgent $userAgent)
    {
        if (stripos($userAgent->getUserAgentString(), 'OS X') !== false) {
            $os->setName($os::OSX);
            if (preg_match('/OS X ([\d\._]*)/i', $userAgent->getUserAgentString(), $matches)) {
                if (isset($matches[1])) {
                    $os->setVersion(str_replace('_', '.', $matches[1]));
                }
            }

            return true;
        }

        return false;
    }
127303
public function platform($userAgent = null)
    {
        // Get platform rules
        $rules = $this->mergeRules(
            static::$operatingSystems,
            static::$additionalOperatingSystems // NEW
        );

        return $this->findDetectionRulesAgainstUA($rules, $userAgent);
    }
640099
private static function checkBlackBerry(Os $os, UserAgent $userAgent)
    {
        if (stripos($userAgent->getUserAgentString(), 'BlackBerry') !== false) {
            if (stripos($userAgent->getUserAgentString(), 'Version/') !== false) {
                $aresult = explode('Version/', $userAgent->getUserAgentString());
                if (isset($aresult[1])) {
                    $aversion = explode(' ', $aresult[1]);
                    $os->setVersion($aversion[0]);
                }
            } else {
                $os->setVersion($os::VERSION_UNKNOWN);
            }
            $os->setName($os::BLACKBERRY);
            $os->setIsMobile(true);

            return true;
        } elseif (stripos($userAgent->getUserAgentString(), 'BB10') !== false) {
            $aresult = explode('Version/10.', $userAgent->getUserAgentString());
            if (isset($aresult[1])) {
                $aversion = explode(' ', $aresult[1]);
                $os->setVersion('10.' . $aversion[0]);
            } else {
                $os->setVersion('10');
            }
            $os->setName($os::BLACKBERRY);
            $os->setIsMobile(true);

            return true;
        }

        return false;
    }
114121
private static function checkWindows(Os $os, UserAgent $userAgent)
    {
        if (stripos($userAgent->getUserAgentString(), 'Windows NT') !== false) {
            $os->setName($os::WINDOWS);
            // Windows version
            if (preg_match('/Windows NT ([\d\.]*)/i', $userAgent->getUserAgentString(), $matches)) {
                if (isset($matches[1])) {
                    switch (str_replace('_', '.', $matches[1])) {
                        case '6.3':
                            $os->setVersion('8.1');
                            break;
                        case '6.2':
                            $os->setVersion('8');
                            break;
                        case '6.1':
                            $os->setVersion('7');
                            break;
                        case '6.0':
                            $os->setVersion('Vista');
                            break;
                        case '5.2':
                        case '5.1':
                            $os->setVersion('XP');
                            break;
                        case '5.01':
                        case '5.0':
                            $os->setVersion('2000');
                            break;
                        case '4.0':
                            $os->setVersion('NT 4.0');
                            break;
                        default:
                            if ((float)$matches[1] >= 10.0) {
                                $os->setVersion($matches[1]);
                            }
                            break;
                    }
                }
            }

            return true;
        } // Windows Me, Windows 98, Windows 95, Windows CE
        elseif (preg_match(
            '/(Windows 98; Win 9x 4\.90|Windows 98|Windows 95|Windows CE)/i',
            $userAgent->getUserAgentString(),
            $matches
        )) {
            $os->setName($os::WINDOWS);
            switch (strtolower($matches[0])) {
                case 'windows 98; win 9x 4.90':
                    $os->setVersion('Me');
                    break;
                case 'windows 98':
                    $os->setVersion('98');
                    break;
                case 'windows 95':
                    $os->setVersion('95');
                    break;
                case 'windows ce':
                    $os->setVersion('CE');
                    break;
            }

            return true;
        }

        return false;
    }
626817
public function detectVersion(string $useragent): VersionInterface
    {
        if (preg_match('/(?:Puffin%20Free|Puffin)\/([\d\.]+)/', $useragent, $matches)) {
            return (new VersionFactory())->set($matches[1]);
        }

        return (new VersionFactory())->set('0');
    }
1328688
public static function isMobileBrowser($userAgent)
    {
        $userAgent_lower = strtolower($userAgent);
        if (self::$isMobileBrowser === null) {
            if (self::isDesktopBrowser($userAgent)) {
                self::$isMobileBrowser = false;
            } elseif (self::checkIfContainsAnyOf($userAgent_lower, self::$mobileBrowsers)) {
                self::$isMobileBrowser = true;
            } elseif (self::regexContains($userAgent, '/[^\d]\d{3}x\d{3}/')) {
                self::$isMobileBrowser = true;
            } else {
                self::$isMobileBrowser = false;
            }
        }

        return self::$isMobileBrowser;
    }
953583
public function detectVersion(string $useragent): VersionInterface
    {
        $version = (new Trident())->detectVersion($useragent);

        $versions = [
            '8' => '11.0',
            '7' => '11.0',
            '6' => '10.0',
            '5' => '9.0',
            '4' => '8.0',
        ];

        foreach ($versions as $engineVersion => $ieVersion) {
            if (version_compare($version->getMajor(), (string) $engineVersion, '>=')) {
                return (new VersionFactory())->set($ieVersion);
            }
        }

        $doMatch = preg_match('/MSIE ([\d\.]+)/', $useragent, $matches);

        if ($doMatch) {
            return (new VersionFactory())->set($matches[1]);
        }

        return (new VersionFactory())->set('0');
    }
607793
private static function checkSymbOS(Os $os, UserAgent $userAgent)
    {
        if (stripos($userAgent->getUserAgentString(), 'SymbOS') !== false) {
            $os->setName($os::SYMBOS);

            return true;
        }

        return false;
    }
942970
public static function isRobot($userAgent)
    {
        self::$isRobot = false;
        $userAgent     = strtolower($userAgent);

        foreach (self::$robots as $key) {
            if (strpos($userAgent, $key) !== false) {
                self::$isRobot = true;
                break;
            }
        }

        return self::$isRobot;
    }
74508
private function chromeWithMajorVersion($userAgent) {
		$start_idx = strpos($userAgent, 'Chrome');
		$end_idx = strpos($userAgent, '.', $start_idx);
		if ($end_idx === false) {
			return substr($userAgent, $start_idx);
		} else {
			return substr($userAgent, $start_idx, ($end_idx - $start_idx));
		}
	}
745099
public static function isSmartTV($userAgent) {
		if (self::$_is_smarttv !== null) return self::$_is_smarttv;
		self::$_is_smarttv = false;
		$userAgent = strtolower($userAgent);
		foreach (self::$smartTVBrowsers as $key) {
			if (strpos($userAgent, $key) !== false) {
				self::$_is_smarttv = true;
				break;
			}
		}
		return self::$_is_smarttv;
	}
533594
private static function checkAndroid(Os $os, UserAgent $userAgent)
    {
        if (stripos($userAgent->getUserAgentString(), 'Android') !== false) {
            if (preg_match('/Android ([\d\.]*)/i', $userAgent->getUserAgentString(), $matches)) {
                if (isset($matches[1])) {
                    $os->setVersion($matches[1]);
                }
            } else {
                $os->setVersion($os::VERSION_UNKNOWN);
            }
            $os->setName($os::ANDROID);
            $os->setIsMobile(true);

            return true;
        }

        return false;
    }
129172
public function canHandle($userAgent)
    {
        if (Utils::isMobileBrowser($userAgent)) {
            return false;
        }

        return Utils::checkIfContains($userAgent, 'Safari')
            && Utils::checkIfStartsWithAnyOf($userAgent, array('Mozilla/5.0 (Macintosh', 'Mozilla/5.0 (Windows'));
    }
915881
private static function checkWindowsPhone(Os $os, UserAgent $userAgent)
    {
        if (stripos($userAgent->getUserAgentString(), 'Windows Phone') !== false) {
            $os->setIsMobile(true);
            $os->setName($os::WINDOWS_PHONE);
            // Windows version
            if (preg_match('/Windows Phone ([\d\.]*)/i', $userAgent->getUserAgentString(), $matches)) {
                if (isset($matches[1])) {
                    $os->setVersion((float)$matches[1]);
                }
            }
    
            return true;
        }
        return false;
    }
1188632
public function detectVersion(string $useragent): VersionInterface
    {
        if (!preg_match('/rv:(\d+\.\d+)/', $useragent, $matches)) {
            return new Version('0');
        }

        $versions = [
            '44.0' => '2.5',
            '37.0' => '2.2',
            '34.0' => '2.1',
            '32.0' => '2.0',
            '30.0' => '1.4',
            '28.0' => '1.3',
            '26.0' => '1.2',
            '18.1' => '1.1',
            '18.0' => '1.0',
        ];

        foreach ($versions as $engineVersion => $osVersion) {
            if (version_compare($matches[1], $engineVersion, '>=')) {
                return (new VersionFactory())->set($osVersion);
            }
        }

        return new Version('0');
    }
665251
private static function checkOpenSolaris(Os $os, UserAgent $userAgent)
    {
        if (stripos($userAgent->getUserAgentString(), 'OpenSolaris') !== false) {
            $os->setVersion($os::VERSION_UNKNOWN);
            $os->setName($os::OPENSOLARIS);

            return true;
        }

        return false;
    }
1123001
public function isMobile(string $useragent): bool
    {
        if (preg_match('/xbox|googletv|eeepc|smart-?tv|sonydtv|hbbtv|gxt_dongle_3188|apple tv|mxl661l32|nettv|crkey|lenovog780|windows iot|netcast|raspbian|bravia|tablet pc [12]\.|automobile|netgem|wordpress/i', $useragent)) {
            return false;
        }

        if (preg_match('/iphone.*windows nt.*micromessenger/i', $useragent)) {
            return true;
        }

        if (preg_match('/windows nt.*arm;/i', $useragent)) {
            return true;
        }

        // ignore mobile safari token if windows nt token is available
        if (preg_match('/windows nt.*(mobile safari|opera mobi|iphone)/i', $useragent)) {
            return false;
        }

        if (preg_match('/Puffin\/[\d\.]+WD/', $useragent)) {
            return false;
        }

        if (preg_match('/UCWEB|Puffin\/[\d\.]+[AIWM][TP]?|TBD\d{4}|TBD[BCG]\d{3,4}/', $useragent)) {
            return true;
        }

        if (preg_match('/fbid\/desktop/i', $useragent)) {
            return false;
        }

        if (preg_match('/mobile;|mobileok|-mobile|office mobile|tablet|(?<!a)phone|wireless|wpdesktop|zunewp7|xblwp7|(?<!ninesky-)android|adr |iphone|ip[ao]d|samsung(?!browser|-agent)|j2me|micromax|htc|karbonn|hisense|docomo|siemens(?! ?(a\/s|testmanager|lms|ag))|ktouch|portalmmm|rim tablet|jolla|iball|windows mobile|windows ce|symbos|symbian|remixos|webos|velocitymicro|samsung-(gt|sph)|lenovo|lumia|surftab|padfone|xda_diamond_2|transformer tf|touchpad|toshiba_ac_and_az|hpwos|silk|wap-browser|sailfish|crowsnest|folio_and_a|steelcore|m2 note|spice qt-75|spark284|lemon b556|terra_101|dino762|wetab|dataaccessd|lenovotablet|qtcarbrowser|onebrowser|stitcher|rss_?radio|antennapod|antenna\/|podcruncher|captivenetworksupport|(?<!c)ios;|audioboom.com\/boos|beyondpod|st80208|\[fban|wap2|up\.link|up\.browser|series ?[46]0|pocket ?pc|playstation|palm(?!a)|opera mobi|opera mini|openwave|obigo|nokia|nintendo|netfront|mqqbrowser|midp|meego|maemo|look-alike|linux armv|like mac os x|kindle|juc ?\(linux; ?u;|j2me|iuc\(u;ios|iris|hp-tablet|hd_mini_t|gingerbread|folio100|foma|firefox or ie|embider|danger hiptop|cldc|blazer|dalvik|bolt|blackberry|\b(bb10|bada|brew|mtk)\b|\btcl\b(?! http client)|aspen simulator|arm; touch|wap browser|kyy21|ebrd1101|ebrd1201|huawei-u8651|tizen/i', $useragent)) {
            return true;
        }

        return false;
    }