<commit_before>/* eslint-disable require-jsdoc */
/* eslint-disable no-useless-escape */

const Family = require('../../../model/Family');
const Version = require('../../../model/Version');
const Constants = require('../../../constants');
const Darwin = require('../../../data/Darwin');
const CFNetwork = require('../../../data/CFNetwork');
const DeviceModels = require('../../../data/DeviceModels');
const BuildIds = require('../../../data/BuildIds');
const Manufacturers = require('../../../data/Manufacturers');

class Os {
  static detectOperatingSystem(ua) {
    Os.detectUnix.call(this, ua);
    Os.detectLinux.call(this, ua);
    Os.detectBsd.call(this, ua);
    Os.detectDarwin.call(this, ua);
    Os.detectWindows.call(this, ua);
    Os.detectAndroid.call(this, ua);
    Os.detectChromeos.call(this, ua);
    Os.detectBlackberry.call(this, ua);
    Os.detectWebos.call(this, ua);
    Os.detectSymbian.call(this, ua);
    Os.detectNokiaOs.call(this, ua);
    Os.detectTizen.call(this, ua);
    Os.detectSailfish.call(this, ua);
    Os.detectBada.call(this, ua);
    Os.detectBrew.call(this, ua);
    Os.detectQtopia.call(this, ua);
    Os.detectOpenTV.call(this, ua);
    Os.detectRemainingOperatingSystems.call(this, ua);

    return this;
  }

  static refineOperatingSystem(ua) {
    Os.determineAndroidVersionBasedOnBuild.call(this, ua);

    return this;
  }

  /* Darwin */

  static detectDarwin(ua) {
    let match;
    let device;
    let version;
    /* iOS */

    if (/\(iOS;/u.test(ua)) {
      this.data.os.name = 'iOS';
      this.data.device.type = Constants.deviceType.MOBILE;
    }

    if (/(iPhone|iPad|iPod)/u.test(ua) && !/like iPhone/u.test(ua)) {
      this.data.os.name = 'iOS';

      if (/CPU like Mac OS X/u.test(ua)) {
        this.data.os.version = new Version({value: '1.0'});
      }

      if ((match = /OS (.*) like Mac OS X/u.exec(ua))) {
        this.data.os.version = new Version({value: match[1].replace(/_/g, '.')});
      }

      if ((match = /iPhone OS ([0-9._]*);/u.exec(ua))) {
        this.data.os.version = new Version({value: match[1].replace(/_/g, '.')});
      }

      if (/iPhone Simulator;/u.test(ua)) {
        this.data.device.type = Constants.deviceType.EMULATOR;
      } else {
        if ((match = /(iPad|iPhone( 3GS| 3G| 4S| 4| 5)?|iPod( touch)?)/u.exec(ua))) {
          device = DeviceModels.identify('ios', match[0]);

          if (device) {
            this.data.device = device;
          }
        }

        if ((match = /(iPad|iPhone|iPod)[0-9],[0-9]/u.exec(ua))) {
          device = DeviceModels.identify('ios', match[0]);

          if (device) {
            this.data.device = device;
          }
        }
      }
    } else if (/Mac OS X/u.test(ua) || /;os=Mac/u.test(ua)) {
      /* OS X */

      this.data.os.name = 'OS X';

      if ((match = /Mac OS X (10[0-9\._]*)/u.exec(ua))) {
        this.data.os.version = new Version({value: match[1].replace(/_/g, '.'), details: 2});
      }

      if ((match = /;os=Mac (10[0-9[\.,]*)/u.exec(ua))) {
        this.data.os.version = new Version({value: match[1].replace(/_/g, '.'), details: 2});
      }

      this.data.device.type = Constants.deviceType.DESKTOP;
    }

    /* Darwin */

    if ((match = /Darwin(?:\/([0-9]+).[0-9]+)?/u.exec(ua))) {
      if (/\(X11;/u.test(ua)) {
        /* Darwin */
        this.data.os.name = 'Darwin';
        this.data.device.type = Constants.deviceType.DESKTOP;
      } else if (/\((?:x86_64|i386|Power%20Macintosh)\)/u.test(ua)) {
        /* OS X */
        this.data.os.name = 'OS X';
        this.data.device.type = Constants.deviceType.DESKTOP;

        if (match[1]) {
          version = Darwin.getVersion('osx', match[1]);
          if (version) {
            this.data.os.version = new Version(version);
          }

          if ((match = /CFNetwork\/([0-9\.]+)/u.exec(ua))) {
            version = CFNetwork.getVersion('osx', match[1]);
            if (version) {
              this.data.os.version = new Version(version);
            }
          }
        }
      } else {
        /* iOS */
        this.data.os.name = 'iOS';
        this.data.device.type = Constants.deviceType.MOBILE;

        if (match[1]) {
          version = Darwin.getVersion('ios', match[1]);
          if (version) {
            this.data.os.version = new Version(version);
          }

          if ((match = /CFNetwork\/([0-9\.]+)/u.exec(ua))) {
            version = CFNetwork.getVersion('ios', match[1]);
            if (version) {
              this.data.os.version = new Version(version);
            }
          }
        }
      }
    }

    /* Mac OS */

    if (/\(Macintosh;/u.test(ua) && !/OS X/u.test(ua)) {
      this.data.os.name = 'Mac OS';
      this.data.device.type = Constants.deviceType.DESKTOP;
    }
  }

  /* Android */

  static detectAndroid(ua) {
    /* Android */
    let falsepositive;
    let match;
    let device;
    if (/Andr[0o]id/iu.test(ua)) {
      falsepositive = false;

      /* Prevent the Mobile IE 11 Franken-UA from matching Android */
      if (/IEMobile\/1/u.test(ua)) {
        falsepositive = true;
      }
      if (/Windows Phone 10/u.test(ua)) {
        falsepositive = true;
      }

      /* Prevent from OSes that claim to be 'like' Android from matching */
      if (/like Android/u.test(ua)) {
        falsepositive = true;
      }
      if (/COS like Android/u.test(ua)) {
        falsepositive = false;
      }

      if (!falsepositive) {
        this.data.os.name = 'Android';
        this.data.os.version = new Version();

        if (
          (match = /Andr[0o]id(?: )?(?:AllPhone_|CyanogenMod_|OUYA )?(?:\/)?v?([0-9.]+)/iu.test(
            ua.replace('-update', ',')
          ))
        ) {
          this.data.os.version = new Version({value: match[1], details: 3});
        }

        if ((match = /Android [0-9][0-9].[0-9][0-9].[0-9][0-9]\(([^)]+)\);/u.test(ua.replace('-update', ',')))) {
          this.data.os.version = new Version({value: match[1], details: 3});
        }

        if (/Android Eclair/u.test(ua)) {
          this.data.os.version = new Version({value: '2.0', details: 3});
        }

        if (/Android KeyLimePie/u.test(ua)) {
          this.data.os.version = new Version({value: '4.4', details: 3});
        }<commit_msg>Fix for Android Number<commit_after>/* eslint-disable require-jsdoc */
/* eslint-disable no-useless-escape */

const Family = require('../../../model/Family');
const Version = require('../../../model/Version');
const Constants = require('../../../constants');
const Darwin = require('../../../data/Darwin');
const CFNetwork = require('../../../data/CFNetwork');
const DeviceModels = require('../../../data/DeviceModels');
const BuildIds = require('../../../data/BuildIds');
const Manufacturers = require('../../../data/Manufacturers');

class Os {
  static detectOperatingSystem(ua) {
    Os.detectUnix.call(this, ua);
    Os.detectLinux.call(this, ua);
    Os.detectBsd.call(this, ua);
    Os.detectDarwin.call(this, ua);
    Os.detectWindows.call(this, ua);
    Os.detectAndroid.call(this, ua);
    Os.detectChromeos.call(this, ua);
    Os.detectBlackberry.call(this, ua);
    Os.detectWebos.call(this, ua);
    Os.detectSymbian.call(this, ua);
    Os.detectNokiaOs.call(this, ua);
    Os.detectTizen.call(this, ua);
    Os.detectSailfish.call(this, ua);
    Os.detectBada.call(this, ua);
    Os.detectBrew.call(this, ua);
    Os.detectQtopia.call(this, ua);
    Os.detectOpenTV.call(this, ua);
    Os.detectRemainingOperatingSystems.call(this, ua);

    return this;
  }

  static refineOperatingSystem(ua) {
    Os.determineAndroidVersionBasedOnBuild.call(this, ua);

    return this;
  }

  /* Darwin */

  static detectDarwin(ua) {
    let match;
    let device;
    let version;
    /* iOS */

    if (/\(iOS;/u.test(ua)) {
      this.data.os.name = 'iOS';
      this.data.device.type = Constants.deviceType.MOBILE;
    }

    if (/(iPhone|iPad|iPod)/u.test(ua) && !/like iPhone/u.test(ua)) {
      this.data.os.name = 'iOS';

      if (/CPU like Mac OS X/u.test(ua)) {
        this.data.os.version = new Version({value: '1.0'});
      }

      if ((match = /OS (.*) like Mac OS X/u.exec(ua))) {
        this.data.os.version = new Version({value: match[1].replace(/_/g, '.')});
      }

      if ((match = /iPhone OS ([0-9._]*);/u.exec(ua))) {
        this.data.os.version = new Version({value: match[1].replace(/_/g, '.')});
      }

      if (/iPhone Simulator;/u.test(ua)) {
        this.data.device.type = Constants.deviceType.EMULATOR;
      } else {
        if ((match = /(iPad|iPhone( 3GS| 3G| 4S| 4| 5)?|iPod( touch)?)/u.exec(ua))) {
          device = DeviceModels.identify('ios', match[0]);

          if (device) {
            this.data.device = device;
          }
        }

        if ((match = /(iPad|iPhone|iPod)[0-9],[0-9]/u.exec(ua))) {
          device = DeviceModels.identify('ios', match[0]);

          if (device) {
            this.data.device = device;
          }
        }
      }
    } else if (/Mac OS X/u.test(ua) || /;os=Mac/u.test(ua)) {
      /* OS X */

      this.data.os.name = 'OS X';

      if ((match = /Mac OS X (10[0-9\._]*)/u.exec(ua))) {
        this.data.os.version = new Version({value: match[1].replace(/_/g, '.'), details: 2});
      }

      if ((match = /;os=Mac (10[0-9[\.,]*)/u.exec(ua))) {
        this.data.os.version = new Version({value: match[1].replace(/_/g, '.'), details: 2});
      }

      this.data.device.type = Constants.deviceType.DESKTOP;
    }

    /* Darwin */

    if ((match = /Darwin(?:\/([0-9]+).[0-9]+)?/u.exec(ua))) {
      if (/\(X11;/u.test(ua)) {
        /* Darwin */
        this.data.os.name = 'Darwin';
        this.data.device.type = Constants.deviceType.DESKTOP;
      } else if (/\((?:x86_64|i386|Power%20Macintosh)\)/u.test(ua)) {
        /* OS X */
        this.data.os.name = 'OS X';
        this.data.device.type = Constants.deviceType.DESKTOP;

        if (match[1]) {
          version = Darwin.getVersion('osx', match[1]);
          if (version) {
            this.data.os.version = new Version(version);
          }

          if ((match = /CFNetwork\/([0-9\.]+)/u.exec(ua))) {
            version = CFNetwork.getVersion('osx', match[1]);
            if (version) {
              this.data.os.version = new Version(version);
            }
          }
        }
      } else {
        /* iOS */
        this.data.os.name = 'iOS';
        this.data.device.type = Constants.deviceType.MOBILE;

        if (match[1]) {
          version = Darwin.getVersion('ios', match[1]);
          if (version) {
            this.data.os.version = new Version(version);
          }

          if ((match = /CFNetwork\/([0-9\.]+)/u.exec(ua))) {
            version = CFNetwork.getVersion('ios', match[1]);
            if (version) {
              this.data.os.version = new Version(version);
            }
          }
        }
      }
    }

    /* Mac OS */

    if (/\(Macintosh;/u.test(ua) && !/OS X/u.test(ua)) {
      this.data.os.name = 'Mac OS';
      this.data.device.type = Constants.deviceType.DESKTOP;
    }
  }

  /* Android */

  static detectAndroid(ua) {
    /* Android */
    let falsepositive;
    let match;
    let device;
    if (/Andr[0o]id/iu.test(ua)) {
      falsepositive = false;

      /* Prevent the Mobile IE 11 Franken-UA from matching Android */
      if (/IEMobile\/1/u.test(ua)) {
        falsepositive = true;
      }
      if (/Windows Phone 10/u.test(ua)) {
        falsepositive = true;
      }

      /* Prevent from OSes that claim to be 'like' Android from matching */
      if (/like Android/u.test(ua)) {
        falsepositive = true;
      }
      if (/COS like Android/u.test(ua)) {
        falsepositive = false;
      }

      if (!falsepositive) {
        this.data.os.name = 'Android';
        this.data.os.version = new Version();

        if (
          (match = /Andr[0o]id(?: )?(?:AllPhone_|CyanogenMod_|OUYA )?(?:\/)?v?([0-9.]+)/iu.exec(
            ua.replace('-update', ',')
          ))
        ) {
          this.data.os.version = new Version({value: match[1], details: 3});
        }

        if ((match = /Android [0-9][0-9].[0-9][0-9].[0-9][0-9]\(([^)]+)\);/u.exec(ua.replace('-update', ',')))) {
          this.data.os.version = new Version({value: match[1], details: 3});
        }

        if (/Android Eclair/u.test(ua)) {
          this.data.os.version = new Version({value: '2.0', details: 3});
        }

        if (/Android KeyLimePie/u.test(ua)) {
          this.data.os.version = new Version({value: '4.4', details: 3});
        }
{'fraction_non_alphanumeric': 0.19896455595380327, 'fraction_numerical': 0.013540422142572681, 'mean_word_length': 1.9838403041825095, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4920635', 'n_tokens_mistral': 4552, 'n_tokens_neox': 4354, 'n_words': 759}