<?php
defined('_SITEGUARDING_WAP') or die;

class FUNC_WAP2_general
{
    public static $SITEGUARDING_SERVER = 'http://www.siteguarding.com/ext/antivirus/index.php';
    public static $LINKS = array(
        'upgrade_to_premium' => 'https://www.siteguarding.com/en/buy-service/antivirus-complete-website-protection',
        'clean_website' => 'https://www.siteguarding.com/en/services/malware-removal-service',
        'blacklist_removal' => 'https://www.siteguarding.com/en/website-blacklist-removal-service',
        'contact_support' => 'https://www.siteguarding.com/en/contacts',
        'free_website_check' => 'https://www.siteguarding.com/en/sitecheck',
        'protect_your_website' => 'https://www.siteguarding.com/en/protect-your-website',
        'learn_bruteforce' => 'https://www.siteguarding.com/en/bruteforce-attack',
        'backup_service' => 'https://www.siteguarding.com/en/importance-of-website-backup',
    );
    public static $MAX_LOG_FILE = 5;    // Mb

	public static function get_url_response($url) {
		if (function_exists('curl_init')) {
			$curl = curl_init();
			curl_setopt($curl, CURLOPT_HEADER, 0);
			curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0'); 
			curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
			curl_setopt($curl, CURLOPT_URL, $url); 
			curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
			curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
			curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
			$code = curl_exec($curl); 
			curl_close($curl); 
			if (!$code) {
				return false;
			}
		} elseif (function_exists('file_get_contents')) {
			$code = @file_get_contents($url);
		} else {
			$code = false;
		}
			return $code;
	}
    
    public static function Init()  
    {
		if (!defined('JPATH_ROOT') || strlen(JPATH_ROOT) < 8) 
		{
			$scan_path = dirname(dirname(dirname(dirname(dirname(__FILE__)))));
		}
        else $scan_path = JPATH_ROOT;
        
        if (!defined('SG_SITE_ROOT')) define('SG_SITE_ROOT', $scan_path.DIRSEP);

        
        $plugin_dir = dirname(dirname(__FILE__)).DIRSEP;
        
        if (!class_exists('EasyRequest')) require_once($plugin_dir.'classes'.DIRSEP.'EasyRequest.min.php');
        include_once($plugin_dir.'classes'.DIRSEP.'page_dashboard.php');
        include_once($plugin_dir.'classes'.DIRSEP.'page_antivirus.php');
        include_once($plugin_dir.'classes'.DIRSEP.'page_blacklists.php');
        include_once($plugin_dir.'classes'.DIRSEP.'page_firewall.php');
        include_once($plugin_dir.'classes'.DIRSEP.'page_settings.php');
        include_once($plugin_dir.'classes'.DIRSEP.'page_extensions.php');
        include_once($plugin_dir.'classes'.DIRSEP.'page_help.php');
        

        
        if (!file_exists($plugin_dir.'tmp')) mkdir($plugin_dir.'tmp');
        if (!file_exists($plugin_dir.'tmp'.DIRSEP.'.htaccess')) self::CreateFile($plugin_dir.'tmp'.DIRSEP.'.htaccess', "<Limit GET POST>\norder deny,allow\ndeny from all\n</Limit>");
        
        
        if (!file_exists(SG_SITE_ROOT.'webanalyze')) 
        {
            mkdir(SG_SITE_ROOT.'webanalyze');
            self::CreateFile(SG_SITE_ROOT.'webanalyze'.DIRSEP.'index.html', '<html><body bgcolor="#FFFFFF"></body></html>');
        }
        
        // Get license
        if (session_status() == PHP_SESSION_NONE) 
        {
            session_start();
        }

        if ( !isset($_SESSION['session_plgwap2_params']) || trim($_SESSION['session_plgwap2_params']['access_key']) == '' || !file_exists(SG_SITE_ROOT.'webanalyze'.DIRSEP.'antivirus_config.php'))
        {
            $params = self::Get_SQL_Params(array('access_key', 'email_for_notifications', 'show_protectedby'));
            if (trim($params['email_for_notifications']) == '') 
            {
				$config = new JConfig();
                $params['email_for_notifications'] = $config->mailfrom;
                self::Set_SQL_Params( array('email_for_notifications' => $params['email_for_notifications'], 'send_notifications' => 1) );
            }
            $_SESSION['session_plgwap2_params'] = $params;
            
            if (!isset($params['access_key']) || trim($params['access_key']) == '')
            {
                // Auto registration
                $server_answer = self::Antivirus_AutoRegistration();
                if (strlen($server_answer) == 32 && strpos($server_answer, " ") === false) 
                {
                    $params['access_key'] = $server_answer;
                    $_SESSION['session_plgwap2_params'] = $params;
                    
                    // Store access_key
                    self::Set_SQL_Params( array('access_key' => $params['access_key']) );
                }
                else {
                    $_SESSION['session_plgwap2_alert_message'] = $server_answer;
                }
            }
        }
        else $params = $_SESSION['session_plgwap2_params'];
        

        
        if (!file_exists(SG_SITE_ROOT.'webanalyze'.DIRSEP.'antivirus.php')) copy($plugin_dir.'antivirus.php', SG_SITE_ROOT.'webanalyze'.DIRSEP.'antivirus.php');
        $file_antivirus_config = SG_SITE_ROOT.'webanalyze'.DIRSEP.'antivirus_config.php';
        $flag_generate_key = false;
        if (file_exists($file_antivirus_config) && trim($params['access_key']) != '')
        {
            // check if access_key is correct
            $content = self::ReadFile($file_antivirus_config);
            if (strpos($content, $params['access_key']) === false) 
            {
                $flag_generate_key = true;
            }
        }
        if (!file_exists($file_antivirus_config) || $flag_generate_key === true) 
        {
            // Create antivirus_config.php
            if ( trim($params['access_key']) != '' )
            {
                $file_content = '<?php'."\n".
                	'define("ACCESS_KEY", "'.$params['access_key'].'");'."\n".
                    '?>'."\n";
                self::CreateFile($file_antivirus_config, $file_content);
            }
        }


        // Get antivirus license
        $file = $plugin_dir.'tmp'.DIRSEP.'antivirus_license.json';
        if (!file_exists($file) || time() - filectime($file) > 3 * 60 * 60)  // 3 hours
        {
            // Update license tmp file
            $license_info = self::GetLicenseInfo(self::GetDomain(), $_SESSION['session_plgwap2_params']['access_key']);
            self::CreateFile($file, json_encode($license_info));
            
            $_SESSION['session_plgwap2_license_info'] = $license_info;
        }
        else $license_info = self::ReadFile($file, true);
        if ( !isset($_SESSION['session_plgwap2_license_info']) ) 
        {
            $_SESSION['session_plgwap2_license_info'] = $license_info;
            self::MembershipFile($license_info['membership'], $license_info['scans'], $params['show_protectedby']);
        }
        if (isset($license_info['access_key'])) self::Set_SQL_Params( array('access_key' => $license_info['access_key']) );
        
        // Check extensions json file
        /*$file = $plugin_dir.'tmp'.DIRSEP.'extensions.json';
        if (!file_exists($file) || time() - filectime($file) > 3 * 30 * 24 * 60 * 60)  // 3 months
        {
            // Update extensions tmp file
            //****
        }*/
        
        self::Init_Front();
    } 
    
    
    public static function Init_Front()  
    {
        if (!defined('_SITEGUARDING_WAP_LOG_FOLDER'))
        {
            $log_folder = dirname(dirname(dirname(dirname(__FILE__)))).DIRSEP.'siteguarding_logs'.DIRSEP;
            define('_SITEGUARDING_WAP_LOG_FOLDER', $log_folder);
            if (!file_exists($log_folder))
            {
                mkdir($log_folder);
            }
            
            if (!file_exists(_SITEGUARDING_WAP_LOG_FOLDER.'.htaccess')) self::CreateFile(_SITEGUARDING_WAP_LOG_FOLDER.'.htaccess', "<Limit GET POST>\norder deny,allow\ndeny from all\n</Limit>");
        }
        
        if (!defined('_SITEGUARDING_WAP_LOGFILE_ACCESS')) define('_SITEGUARDING_WAP_LOGFILE_ACCESS', _SITEGUARDING_WAP_LOG_FOLDER.'access.log');
    }
    
    
    
    public static function Antivirus_AutoRegistration()
    {
        // Created domain verification file
        $verification_id = strtoupper(md5(rand(1, 1000).'-'.time().'-'.rand(1, 1000)));
        $filename = SG_SITE_ROOT.'webanalyze'.DIRSEP.'antivirus_verification_'.$verification_id.'.txt';
        self::CreateFile($filename, strtoupper(md5($verification_id)));
        
        $link = self::$SITEGUARDING_SERVER.'?action=register';
        $access_key = md5($verification_id.time());
		$config = new JConfig();
        $data = array(
                'domain' => JURI::root(),
                'email' => $config->mailfrom,
                'access_key' => $access_key,
                'cms' => 'joomla',
                'domain_verification' => $verification_id
        );
        $client = EasyRequest::create('POST', $link, array(
            'form_params' => array(
                'data' => base64_encode(json_encode($data))
            )
        ));
        $client->send();
        $pageContents = trim($client->getResponseBody());
        
        unlink($filename);
        
        if ($pageContents == '') return $access_key;
        else return $pageContents;
    }
    
    
    
    public static function PrepareLogContent($contents, $sep = '|', $limit = 10)
    {
        $contents = explode("\n", $contents);
        if (count($contents) > 1 && trim($contents[1]) != '') unset($contents[0]);
        krsort($contents);
        $contents = array_slice($contents, 0, $limit);
        
        if ($sep != '')
        {
            foreach ($contents as $k => $v)
            {
                if (trim($v) == '') unset($contents[$k]);
                else $contents[$k] = explode($sep, $v);
            }
        }
        
        return $contents;
    }
    
    
    public static function GetLastLogs_from_file($log_file, $bytes_offset = 100000)
    {
		if (!is_file($log_file)) return '';
        $log_filesize = filesize($log_file);
        if ($log_filesize < $bytes_offset) 
        {
            $pos = 0;
            $length = $log_filesize;
        }
        else {
            $pos = $log_filesize - $bytes_offset;
            $length = $bytes_offset;
        }
        
        $handle = fopen($log_file, "rb");
        fseek($handle, $pos);
        
        $contents = fread($handle, $length);
        fclose($handle);
        
        return $contents;
    }
    
    
    
    public static function SaveLog($log_file, $content)
    {
        $log_filesize = filesize($log_file);
        if ( $log_filesize > self::$MAX_LOG_FILE*1024*1024)
        {
            // Cut log file
    	    $log_file_tmp = $log_file.".tmp";
            
            $fp1 = fopen($log_file, "rb");
            $fp2 = fopen($log_file_tmp, "wb");
            
            $pos = $log_filesize * 0.7;     // 30%
            fseek($fp1, $pos);
            
            while (!feof($fp1)) {
                $buffer = fread($fp1, 4096 * 32);
                fwrite($fp2, $buffer);
            }
            
            fclose($fp1);
            fclose($fp2);
        }
        
        $fp = fopen($log_file, 'a');
        fwrite($fp, $content."\n");
        fclose($fp);
    }
    
	public static function CheckFirewall()
	{
        $firewall_file = SG_SITE_ROOT.DIRSEP.'webanalyze'.DIRSEP.'firewall'.DIRSEP.'firewall.php';
	    if (file_exists($firewall_file)) return true;
        else return false;
    }
    
    
	public static function CheckBruteforceProtection()
	{
        $params = FUNC_WAP2_general::Get_SQL_Params(array('protect_login_page'));
        if (isset($params['protect_login_page']) && $params['protect_login_page'] == 1) return true;

        return false;
    }
    
    
    public static function CreateFile($file, $content)
    {
        if (file_exists($file)) unlink($file);
        $fp = fopen($file, 'w');
        if (!$fp) return false;
        $status = fwrite($fp, $content);
        fclose($fp);
    
        return $status;
    }
    
    
    public static function ReadFile($file, $json_decode = false)
    {
        $handle = fopen($file, "r");
        $contents = fread($handle, filesize($file));
        fclose($handle);
        
        if ($json_decode) $contents = (array)json_decode($contents, true);
    
        return $contents;
    }
    
    
    
    public static function GetDomain()
    {
        return self::PrepareDomain(JURI::root());
        
    }
    
	public static function PrepareDomain($domain)
	{
	    $host_info = parse_url($domain);
	    if ($host_info == NULL) return false;
	    $domain = $host_info['host'];
	    if ($domain[0] == "w" && $domain[1] == "w" && $domain[2] == "w" && $domain[3] == ".") $domain = str_replace("www.", "", $domain);
	    //$domain = str_replace("www.", "", $domain);
	    
	    return $domain;
	}
    
    
    public static function UpdateLicenseInfo()
    {
        $plugin_dir = dirname(dirname(__FILE__)).DIRSEP;
        $file = $plugin_dir.'tmp'.DIRSEP.'antivirus_license.json';
        // Update license tmp file
        $license_info = self::GetLicenseInfo(self::GetDomain(), $_SESSION['session_plgwap2_params']['access_key']);
        self::CreateFile($file, json_encode($license_info));
        
        $_SESSION['session_plgwap2_license_info'] = $license_info;
    }
    
    
    public static function GetLicenseInfo($domain, $access_key, $real_update_flag = false)
    {
        if (!class_exists('EasyRequest')) require_once(dirname(__FILE__).DIRSEP.'EasyRequest.min.php');
        
    	$link = self::$SITEGUARDING_SERVER.'?action=licenseinfo&type=json&data=';
    	
        $data = array(
    		'domain' => $domain,
    		'access_key' => $access_key,
    		'product_type' => 'joomla'
    	);
        $link .= base64_encode(json_encode($data));
        
        
        $client = EasyRequest::create($link);
        $client->send();
        $msg = trim($client->getResponseBody());
        
        if ($msg === false || $msg == '')
        {
            $link = str_replace("http://", "https://", $link);
            
            $client = EasyRequest::create($link);
            $client->send();
            $msg = trim($client->getResponseBody());
        }
        
        if ($msg == '' || $msg === false) return false;
        
        $license_info = (array)json_decode($msg, true);
        $license_info['cache_license_info_time'] = time();
        
        return $license_info;
    }



	public static function DownloadFromJoomla_Link($link)
	{
	    return self::DownloadRemoteFile($link, dirname(dirname(__FILE__)).DIRSEP.'tmp'.DIRSEP.'update.zip');
	}
    
	public static function DownloadRemoteFile($link, $file)
	{
		$dst = fopen($file, 'w');
		$ch = curl_init();
		 curl_setopt($ch, CURLOPT_URL, $link );
		 curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:38.0) Gecko/20100101 Firefox/38.0");
		 //curl_setopt($ch, CURLOPT_HEADER, true);
		 curl_setopt($ch, CURLOPT_TIMEOUT, 3600);
		 curl_setopt($ch, CURLOPT_TIMEOUT_MS, 3600000);
		 curl_setopt($ch, CURLOPT_FILE, $dst);
		 //!dont need curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
         //curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_FAILONERROR, true);
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); // 10 sec
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 10000); // 10 sec
		curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
		//*** maybe need */curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

		 $a = curl_exec($ch);
		 curl_close($ch);
         if ($a === false) return false;
         else return true;
	}

    
    
    public static function Get_SQL_Params($var_name_arr = array())
    {
        $dbo = JFactory::getDbo();
  
        $table_name = $dbo->getPrefix() . 'plgwap2_config';
		$tables = $dbo->getTableList();

        if (!in_array($table_name, $tables)) return false;

		$query = $dbo->getQuery(true);  
		$query->select(array('*'));
		$query->from($table_name);
        
        if (count($var_name_arr) > 0) 
        {
            foreach ($var_name_arr as $k => $v) 
            {
                $var_name_arr[$k] = "'".$v."'";
            }
			$query->where("var_name IN (".implode(",", $var_name_arr).")");
        }



		$dbo->setQuery($query);  
		$rows = $dbo->loadObjectList();
        $a = array();
        if (count($rows))
        {
            foreach ( $rows as $row ) 
            {
            	$a[trim($row->var_name)] = trim($row->var_value);
            }
        }
    
        return $a;
    }
    
    
    public static function Set_SQL_Params($data = array())
    {
        $dbo = JFactory::getDbo();
        $table_name = $dbo->getPrefix() . 'plgwap2_config';
		
        if (count($data) == 0) return;   
         
        foreach ($data as $k => $v)
        {
			$query = $dbo->getQuery(true);
			$query->select(array('COUNT(*)'));
			$query->from($table_name);
			$query->where('var_name = '. $dbo->Quote($k));

			$dbo->setQuery($query);
            $tmp = $dbo->loadResult();
			unset($query);

            if ($tmp == 0)
            {
                // Insert    
                //$dbo->insert( $table_name, array( 'var_name' => $k, 'var_value' => $v ) ); 

				// Create a new query object.
				$query = $dbo->getQuery(true);

				// Insert columns.
				$columns = array('var_name', 'var_value');

				// Insert values.
				$values = array($dbo->quote($k), $dbo->quote($v));

				// Prepare the insert query.
				$query
					->insert($dbo->quoteName($table_name))
					->columns($dbo->quoteName($columns))
					->values(implode(',', $values));

				// Set the query using our newly populated query object and execute it.
				$dbo->setQuery($query);
				$dbo->execute();
				unset($query);
            }
            else {
                // Update
				
				
                //$data = array('var_value'=>$v);
                //$where = array('var_name' => $k);
                //$dbo->update( $table_name, $data, $where );


				$query = $dbo->getQuery(true);

				// Fields to update.
				$fields = array(
					$dbo->quoteName('var_value') . ' = ' . $dbo->quote($v)
				);

				// Conditions for which records should be updated.
				$conditions = array(
					$dbo->quoteName('var_name') . ' = ' . $dbo->quote($k)
				);

				$query->update($dbo->quoteName($table_name))->set($fields)->where($conditions);
				//var_dump($query); die;
				$dbo->setQuery($query);
				$dbo->execute();
				unset($query);

				
            }
        } 
    }
    
	public static function IsPRO()
	{
        if (isset($_SESSION['session_plgwap2_license_info']['membership']) && $_SESSION['session_plgwap2_license_info']['membership'] == 'pro') return true;
        else return false;
    }
    
	public static function IsPRO_full()
	{
        if (isset($_SESSION['session_plgwap2_license_info']['filemonitoring']['status']) && $_SESSION['session_plgwap2_license_info']['filemonitoring']['status'] > 0) return true;
        else return false;
    }
    
    
    
    public static function PremiumAdvertBlock()
    {
        if (FUNC_WAP2_general::IsPRO_full()) {
        ?>
            <h4 class="ui header">Congratulations! You have Premium Protection</h4>
            <p>If you have any issue with the website, please contact us and we will fix it. No extra charges!</p>
            <p><b>What is included:</b> Unlimited cleaning of your website, Virus detection (Unlimited Pages), Hack/Injection detection, monitoring 24/7, Premium firewall service, Blacklist removal (Google, McAfee, Norton and etc.) and Blacklist monitoring, Website Technical support and much more, full description you will find here <a href="<?php echo FUNC_WAP2_general::$LINKS['protect_your_website']; ?>" target="_blank">Premium Details</a>.</p>
            <p>
                <a class="medium positive ui button" href="<?php echo FUNC_WAP2_general::$LINKS['contact_support']; ?>" target="_blank">Contact Support</a>
            </p>
        <?php
        }
        else {
            ?>
            <h4 class="ui header">Premium Protection Disabled</h4>
            <p>If you have any issue with the website, upgrade to Premium and you will fix your website.</p>
            <p><b>Premium includes:</b> Unlimited cleaning of your website, Virus detection (Unlimited Pages), Hack/Injection detection, monitoring 24/7, Premium firewall service, Blacklist removal (Google, McAfee, Norton and etc.) and Blacklist monitoring, Website Technical support and much more, full description you will find here <a href="<?php echo FUNC_WAP2_general::$LINKS['protect_your_website']; ?>" target="_blank">Premium Details</a>.</p>
            <p>
                <a class="medium positive ui button" href="<?php echo FUNC_WAP2_general::$LINKS['upgrade_to_premium']; ?>" target="_blank">Upgrade to Premium</a>
                <a class="medium negative ui button" href="<?php echo FUNC_WAP2_general::$LINKS['clean_website']; ?>" target="_blank">Clean Website</a>
            </p>
            <?php
        }
    }
   
    

	public static function QuickLinks()
	{
	   ?>
            <div class="ui three item massive menu">
              <a class="item" href="index.php?option=com_jmwascanner&view=settings"><i class="shield alternate icon"></i>Tools & Settings</a>
              <a class="item" href="index.php?option=com_jmwascanner&view=help"><i class="comment outline icon"></i>Help</a>
              <a class="item" target="_blank" href="<?php echo FUNC_WAP2_general::$LINKS['free_website_check']; ?>"><i class="crosshairs icon"></i>Free Website Check</a>
            </div>
        <?php
    }

	public static function BannerArea()
	{
        ?>
        <div class="ui large centered sg_center ad">
            <a href="https://www.siteguarding.com/en/protect-your-website" target="_blank"><img src="<?php echo JURI::root() . 'administrator/components/com_jmwascanner/images/rek1.png'; ?>" /></a>&nbsp;
            <a href="https://www.siteguarding.com/en/secure-web-hosting" target="_blank"><img src="<?php echo JURI::root() . 'administrator/components/com_jmwascanner/images/rek2.png'; ?>" /></a>&nbsp;
            <a href="https://www.siteguarding.com/en/importance-of-website-backup" target="_blank"><img src="<?php echo JURI::root() . 'administrator/components/com_jmwascanner/images/rek3.png'; ?>" /></a>
        </div>
        <?php
    }
    
	public static function PrintSteps($data)
	{
	   switch (count($data))
       {
            case 1:
                $count_txt = 'one';
                break;
                
            case 2:
                $count_txt = 'two';
                break;
                
            case 3:
                $count_txt = 'three';
                break;
                
            case 4:
                $count_txt = 'four';
                break;
                
            case 5:
                $count_txt = 'five';
                break;
                
            case 6:
                $count_txt = 'siz';
                break;
                
            case 7:
                $count_txt = 'seven';
                break;
                
            case 8:
                $count_txt = 'eight';
                break;
                
            case 9:
                $count_txt = 'nine';
                break;
       }
	   ?>
            <div class="ui <?php echo $count_txt; ?> steps">
                <?php
                foreach ($data as $row)
                {
                    ?>
                      <div class="<?php echo $row['active']; ?> step">
                        <i class="<?php echo $row['icon']; ?> icon"></i>
                        <div class="content">
                          <div class="title"><?php echo $row['title']; ?></div>
                          <div class="description"><?php echo $row['description']; ?></div>
                        </div>
                      </div>
                    <?php
                }
                ?>
            </div>
        <?php
    }



	public static function ModalPopup()
	{
        if (isset($_SESSION['session_plgwap2_alert_message']))
        {
            ?>
            <script>
            jQuery(document).ready(function(){
                jQuery('.modal').modal('show');
            });
            
            </script>
            <div class="tiny ui modal">
              <div class="header c_red">Alert</div>
              <div class="content">
                <p><?php echo $_SESSION['session_plgwap2_alert_message']; ?></p>
              </div>
              <div class="actions">
                <button class="medium ui cancel button">Close</button>
              </div>
            </div>
            <?php
            
            unset($_SESSION['session_plgwap2_alert_message']);
        }
    }
    
    
	public static function Print_PIE_chart($data)
	{
        // https://developers.google.com/chart/interactive/docs/gallery/piechart#options
        
        ?>
        <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
        <script type="text/javascript">
          google.charts.load("current", {packages:["corechart"]});
          google.charts.setOnLoadCallback(drawChart);
          function drawChart() {
            var data = google.visualization.arrayToDataTable([
              ['Task', ''],
              ['<?php echo $data[0]['txt']; ?>',    <?php echo $data[0]['val']; ?>],
              ['<?php echo $data[1]['txt']; ?>',    <?php echo $data[1]['val']; ?>]
            ]);
    
            var options = {
              pieHole: 0.4,
              slices: {
                0: { color: '#16ab39' },
                1: { color: '#db2828' }
              },
              chartArea: {left:50,top:5,width:'80%',height:'80%'},
              backgroundColor: 'transparent',
            };
    
            var chart = new google.visualization.PieChart(document.getElementById('donutchart'));
            chart.draw(data, options);
          }
        </script>
    
        <div id="donutchart" style="width: 100%; height: 200px;"></div>
        
        <?php
    }
    

	public static function Print_LabelBox($data)
	{
	   /*
       $data = array(
            'type' => '',
            'content' => '',
            'color' => ''
       );
       */
       if (isset($data['type']))
       {
            switch ($data['type'])
            {
                case 'error':
                    $data['color'] = 'red';
                    break;
                    
                case 'info':
                    $data['color'] = 'blue';
                    break;
                    
                case 'ok':
                    $data['color'] = 'green';
                    break;
                    
                case 'warning':
                    $data['color'] = 'yellow';
                    break;
            }
       }
        ?>
        <div class="ui <?php echo $data['color']; ?> circular label"><?php echo $data['content']; ?></div>
        <?php
    }



	public static function Print_MessageBox($data)
	{
	   /*
       $data = array(
            'type' => '',
            'size' => '',
            'icon' => '',
            'header' => '',
            'content' => '',
            'color' => '',
            'button' => array(
                'url' => '',
                'txt' => '',
                'target' => 1
                )
       );
       */
       
       if (isset($data['type']))
       {
            switch ($data['type'])
            {
                case 'error':
                    $data['color'] = 'red';
                    $data['icon'] = 'exclamation triangle';
                    break;
                    
                case 'info':
                    $data['color'] = 'blue';
                    $data['icon'] = 'exclamation';
                    break;
                    
                case 'ok':
                    $data['color'] = 'green';
                    $data['icon'] = 'check square outline';
                    break;
                    
                case 'warning':
                    $data['color'] = 'yellow';
                    $data['icon'] = 'exclamation circle';
                    break;
            }
       } else {
			$data['color'] = '';
			$data['icon'] = '';
	   }
       
	   if (!isset($data['size'])) $data['size'] = 'large';
	   if (isset($data['icon'])) 
       {
            $data['icon_class'] = 'icon';
            $data['icon_html'] = '<i class="'.$data['icon'].' icon"></i>';
       }
       else $data['icon_class'] = $data['icon_html'] = '';
       
       if (isset($data['button']) && !isset($data['button']['target'])) $data['button']['target'] = 1;

	   ?>
            <div class="ui <?php echo $data['color']; ?> <?php echo $data['icon_class']; ?> <?php echo $data['size']; ?> message">
                <?php echo $data['icon_html']; ?>
                <div class="content">
                  <?php if (isset($data['header'])) echo '<div class="header">'.$data['header'].'</div>'; ?>
                  <?php if (isset($data['button'])) { ?> <a class="mini ui <?php echo $data['color']; ?> button right floated" <?php if ($data['button']['target'] == 1) echo 'target="_blank"'; ?> href="<?php echo $data['button']['url']; ?>"><?php echo $data['button']['txt']; ?></a> <?php } ?>
                  <?php if (isset($data['content'])) echo $data['content']; ?>
                </div>
            </div>
        <?php
    }
    
    
    
	public static function CheckJMIndex_file()
	{
	    if (!defined('DIRSEP'))
        {
    	    if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') define('DIRSEP', '\\');
    		else define('DIRSEP', '/');
        }
        
		if (!defined('JPATH_ADMINISTRATOR') || strlen(JPATH_ADMINISTRATOR) < 8) 
		{
			$scan_path = dirname(dirname(__FILE__));
			$scan_path = str_replace(DIRSEP.'components'.DIRSEP.'com_jmwascanner', DIRSEP, $scan_path);
    		//echo TEST;
		}
        else $scan_path = JPATH_ADMINISTRATOR;
        
        $filename = $scan_path.DIRSEP.'index.php';
        $handle = fopen($filename, "r");
        if ($handle === false) return false;
        $contents = fread($handle, filesize($filename));
        if ($contents === false) return false;
        fclose($handle);
        
        if (stripos($contents, '6DBB86C229DE-START') === false)     // Not found
        {
            self::PatchJMIndex_file();
        }
    }
    
    
	public static function PatchJMIndex_file($action = true)   // true - insert, false - remove
	{
		if (!defined('DIRSEP')) {
			if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') define('DIRSEP', '\\');
			else define('DIRSEP', '/');
		}
        
		$file = dirname(__FILE__).DIRSEP."sgantivirus.login.php";

        $integration_code = '<?php /* Siteguarding Block 6DBB86C229DE-START */@include_once("'.$file.'");/* Siteguarding Block 6DBB86C229DE-END */?>';
        
        // Insert code
		if (!defined('JPATH_ADMINISTRATOR') || strlen(JPATH_ADMINISTRATOR) < 8) 
		{
			$scan_path = dirname(dirname(__FILE__));
			$scan_path = str_replace(DIRSEP.'components'.DIRSEP.'com_jmwascanner', DIRSEP, $scan_path);
    		//echo TEST;
		}
        else $scan_path = JPATH_ADMINISTRATOR;
        
        $filename = $scan_path.DIRSEP.'index.php';

        $handle = fopen($filename, "r");
        if ($handle === false) return false;
        $contents = fread($handle, filesize($filename));
        if ($contents === false) return false;
        fclose($handle);
        
        $pos_code = stripos($contents, '6DBB86C229DE');
        
        if ($action === false)
        {
            // Remove block
            $contents = str_replace($integration_code, "", $contents);
        }
        else {
            // Insert block
            if ( $pos_code !== false/* && $pos_code == 0*/)
            {
                // Skip double code injection
                return true;
            }
            else {
                // Insert
				

                $contents = $integration_code.$contents;
            }
        }

        $handle = fopen($filename, 'w');
        if ($handle === false) 
        {
            // 2nd try , change file permssion to 666
            $status = chmod($filename, 0666);
            if ($status === false) return false;
            
            $handle = fopen($filename, 'w');
            if ($handle === false) return false;
        }
        
        $status = fwrite($handle, $contents);
        if ($status === false) return false;
        fclose($handle);

        
        return true;
	}
    
    
	public static function MembershipFile($membership, $scans, $show_protectedby)
	{
		$filename = dirname(dirname(__FILE__)).DIRSEP.'tmp'.DIRSEP.'membership.log';
		if ( ($membership == 'pro' || ($membership == 'trial' && $scans > 10)) && ($show_protectedby == 0) ) 
		{
			if (file_exists($filename))	unlink($filename);
		}
		else
		{
			$fp = fopen($filename, 'w');
			fwrite($fp, $membership.":".$scans);
			fclose($fp);	
		}
	}
    
    
    
    
    public static function RecoveryMode($access_key)
    {
		
        $params = FUNC_WAP2_general::Get_SQL_Params(array('access_key'));
	
		if ($params['access_key'] == $access_key)
		{
        		if (!defined('ABSPATH') || strlen(ABSPATH) < 8) 
        		{
        			$site_path = dirname(__FILE__);
        			$site_path = str_replace(DIRSEP.'administrator'.DIRSEP.'components'.DIRSEP.'com_jmwascanner'.DIRSEP, DIRSEP, $site_path);
        		}
                else $site_path = ABSPATH;
                
                if (!file_exists($site_path.DIRSEP.'webanalyze'))
                {
                    if ( !mkdir($site_path.DIRSEP.'webanalyze') ) die( "Can't create folder ".$site_path.DIRSEP.'webanalyze' );
                }
                
                // Create antivirus.php
                $link = 'https://www.siteguarding.com/_get_file.php?file=antivirus&time='.time();
                $file = $site_path.DIRSEP.'webanalyze'.DIRSEP.'antivirus.php';
                $file_content = self::DownloadRemoteFile($link, $file);
                
                // Create antivirus_config.php
                $file_content = '<?php'."\n".
                	'define("ACCESS_KEY", "'.$access_key.'");'."\n".
                    '?>'."\n";
                $file = $site_path.DIRSEP.'webanalyze'.DIRSEP.'antivirus_config.php';
                self::CreateFile($file, $file_content);
                
				die("OK");
		}
		
		exit;
    }
    
    
    
    public static function Print_HelpBlock()
    {
        ?>
            <div class="ui icon green message">
                <i class="medkit icon"></i>
                <div class="content">
                    <h2 class="ui header sg_center">Got hacked or blacklisted? We can help.</h2>
                    <p>Over 450.000 clients use our services daily. Based on extensive experience focused in Information Security we can assure you the best service and the best prices in the Globe. Before your business is a victim by intruders and think of your Business reputation damage. Consider to outsource your overall website security to professionals. Even if you have been a victim, we can take care of all the needed processes to bring back everything in place such as Google's reputation loss recovery, email delay processes, etc. Our Research & Development experts scan daily thousands of attacks and update all firewalls and customers on the fly.</p>
                    <p class="sg_center">
                        <a class="medium positive ui button" href="<?php echo self::$LINKS['upgrade_to_premium']; ?>" target="_blank">Upgrade to PREMIUM</a>
                        <a class="medium negative ui button" href="<?php echo self::$LINKS['clean_website']; ?>" target="_blank">Clean Website</a>
                    </p>
                </div>
            </div>
        <?php
    }


    
    
    
	public static function SendEmail($email, $result, $subject = '')
	{
		$to  = $email; // note the comma
		
		// subject
		if ($subject == '') $subject = 'AntiVirus Report ['.date("Y-m-d H:i:s").']';
		
		// message
        $body_message = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>SiteGuarding - Professional Web Security Services!</title>
</head>
<body bgcolor="#ECECEC" style="background-color:#ECECEC;">
<table cellpadding="0" cellspacing="0" width="100%" align="center" border="0" bgcolor="#ECECEC" style="background-color: #fff;">
  <tr>
    <td width="100%" align="center" bgcolor="#ECECEC" style="padding: 5px 30px 20px 30px;">
      <table width="750" border="0" align="center" cellpadding="0" cellspacing="0" bgcolor="#fff" style="background-color: #fff;">
        <tr>
          <td width="750" bgcolor="#fff"><table width="750" border="0" cellspacing="0" cellpadding="0" bgcolor="#fff" style="background-color: #fff;">
            <tr>
              <td width="350" height="60" bgcolor="#fff" style="padding: 5px; background-color: #fff;"><a href="http://www.siteguarding.com/" target="_blank"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAVIAAABMCAIAAACwHKjnAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAITZJREFUeNrsXQl0FFW67qruTi/pzgaBAAmIAhIWgSQkEMCAgw6jssowbig8PeoAvpkjzDwGGUcdx5PjgM85gm9QmTeOgsJj2FXUsLmxSIKjCAESUAlrCCFJJ+lOL/W+7h8uRXV1pdLdSZqh/sNpKrdv/feve//vX+5SzQmCoGs1cldVn39nVd2nX3Z8cFrSXT/l44w6jTTSqL2JayXYNx46UrV6fdXK/3OVHddxHMfz1uzBqY88kDhurCm9q9bvGmn0bwJ7wet1lh+vKdpZs/ljx95ib/VF3mzmyMMLOp/TKXg8xrROthF5yVPG20fkafjXSKP2h/351esbD5aae90Y162LMa2zsWOK3mbjjAbOYJC92et0eqqq3afPNpYfr9/1lWNPsavsGNAO3w7A6/S8jGnweAXgn+OMnTqaM/vYhg+NH5pl6pER16WzPjmJD9EQ7IXgdntq6tznKtGcq+KUq/x4ypTxtpzB2hBqpFH4sPc66g9kj3EeOcQZzMA5Hx/P2+INyYmc2ay323iTSZ+UaLDFu+scvtpazid4m5rclVVe/Kut9TU6dT4fHDtvjJNFuzz+m5qAZ51ez8dbwdzYOdWQkgwro+P1hpQk3mh0V9foHPUeZ6OvvkFodHqqL/rQekMjwgqvty71vum9Vr6hDaFGGoUP+6o1G8vvewTuPQBKAf8En0/n9fkr4IJKBPhpDrl64FaO0+sBWg44p5KwyefztwVD4PPqhEDzPoFa8HPm8cn7r/U84ghc6zh/QsGbTf2+/AixiTaKGmnUIroSVJ9/exXH0BvAmx9jBh3XBlLwATwbDGra8gf8ria/w6+rqynaqcFeI43ChH3joSOOz3bxFkuMiokwA7GAy4X/jV3SLLf0SygYYS/It2T20YZQI43ChH3tjs+9F2v0iQmxJZ3X64Njd7s5q8XYKdWadUvinXck3TFGWwLQSKMowL6maAdn0MeKY29y+5qakGXok5NseTm24TkJtxVYB2YaO6RoA6aRRtGBfdOpM/V7S3iTuV1jeA/Qjoyds5jNfW6yZg9KvH1MfM4QS6+eoW5ye91Fh9cfO//dL0c9w3O8NpYaadQC2Nd9sdt95uylOfw2jeF9PncT0M4ZDMaMbpYBmfZbh9uHDbUOHqi3hpxlOFp5sKh0za5jGy44ynWCCyUjb7pzULdcbSw1Ilq44a6vT2zDxYz8F6ZmzdU6RB72jr0lOp/QRg0GHLvP6cKFPiXZOqCvvWCEfdRwW162Qgx/sbH6s/IPtx1e9f35Yre7SvLtp2UbWwP2tbW1e/fuPXny5J49e6gkLy/Pbrfjs1u3bsH1Dx06hPqZmZm5ubFig87UHgcAHK6LBAOiXqlDbOZkfA7OuO061Piyc/u/rth23T7+ZdgLQsP+b/2bZFoV7JdX3XiLxditq21Ytm3k8ISCfPNNPf2L/3LkE3xfV+zefOCtQ6c/r2v4XhewTMErfCg8cOqLqAP+rbfeWrduHS7E5UA1XYwdO7awsFD8FazD9OnT6XrDhg2ydqEtact3y/EPKh78FTMBNlPSnDFLR/aacv2oO+zgr1fn0/WbDx1MS+h5ncLeXXneVXaMM7bC2Tifz4d0valJp9cbO6daBw2wF+TbR+Vb+vY2JCWGuumc48wH363cfWzzyep/Cb4G8Veyq/ooPFX9rcfnMfCGaGF+9uzZcN0KdYJRXVRUJL5++OGHZW+EdQBnWI3WG1Ggesn2OdDvZmsiCrje9P7zsrXi6+s2BTA4jx4D8vnowR4u3b/r3uvjE+yWW/rZhuUkjLk1Pmewwqqby+PacXTz9sNrjp7b5WqqhMFoWYu++m9O7s3KyI+K/GLMP/nkk4jYEbczb4+AH6gOxi2rI7lmtHbtWkQQgD0Yth7s15Qs/vuXC6/E852GjOx1jySgRQhAwX9ZZQkqXFfqjq6Qvb7uYO86cdLvkOPiIs3Y/atuLh3H6zum2G8fnfiTAvvIPGu/vqGO8YBqnBff2fvKrmPrL9Z/T5NzYdOxqoNRgT3AyTC/YMGCKVOuCoBzAwRPnpAg3eCAcoT9sAtUJ5hzXV0dMN+qYwnAA/Z0DTc+Z8wS2fQVUA+YgynXobqjQ+aPWwGTh4vrOrd3nzmr8/rCBDvL2K2WuN432vKyE8aMsg0far6hu4J9+ObUVx8eXPFtxfaa+mM6nTcqj1FRXR4VPuLsXYJ5RsGYZ7e0avTebPjKMA9II2lH6q7TKIjQOdenybsK9k0Vp1p2kEYQfC4XfLs/Y+/S2b9PdvQo+8hh1oGZeqs11E2nak5sPbz2i/INJ6u/QUwe3WcQAPuLR6PCiqXosoF6zBKy9CXbZzNnrmFeo+aC/B9OhJpLlwEYknZBsGYPto/Kh1e3DR0S1zUtVOUmb9Pe73cUHV79bUWRq+lcAJ6tQjBaFxxRjp8lc/hq6peWlrKAP7icRfiI9llMoQvMDgZPEOIuGCCa/8Of6enpffv2RSgRKtDY8t1yIJ+uEcRGgnnwKTtXwkLisOsg+qAZBJZIpyX2HNf/kWbbtZmSacYBJXgucMDj4KEk9cEcTeAWenCIAR/e7AylsuTgeabGPxUKUYkV6n9e9k+aDVHfCrsR3Moq96M+GLIbg1tpB9h7q6p1vIotboLgrXOYBw3o8l+/6jh1gsKqW3ll6ZZDK0t+LKqsLY0wY1dPTk90IgggljAJ1D355JPqbwS2Z82aRdf79u2TLScCksUlaEUy7f9WgMR2h0RasmTJggULZPOILQeW0wVwFaEmARULN9xF15vnNLa0DnR6TfFiaDwzQ0SEf3wFAMvOIzKegNYLE98HpBG/SJgwRK0pXsQyGsb/718upOwm7KcDGulb2ucDGcBTvCZCreArVFBoBbJBQonw7EZiixI8ZrvBXm1g39DQYeb93Rc9b0xS8iTz1t5z5PSWtn8Mn+CJCp+8vDzCGDztiy++CJi18YOg0bVr10oCAdiO2gDNnz8/eKKR+SJKXNs9gISLpgt46V6dsghOJCE+F26484WJHyivIOCJCrc8EMqLgoPsfgQKMWQtRXhPsWT7nFCoRitzxixRIx6eFPHLJatXshg9QH3SzkG+p76Ba87bex31qbMf6fmXwmbZ/VC1X9C1yRF9Cex90ZkanDx5Mvw8hdY0q09reGEzRHD+2muvUfhAeM7MzBTHEeIIH06e6iCYLywsZO0C8HD19BUuJNH+1xVXduC1++w03BdkQEg/bsBVcYffT+5aCDz4pyF2zH5l2pcKTFCTrMbU7HmSZTaEAAxUaAjRDVk6ivnhY8X7EcMmCuwpesI/MlJi5w+jgHaDe1ssHny7uBMoBACTqEgYKewbfvjRGGdUSLt9DY3xI4f1+PMf1XldL9cej+H1RSebAJzgTmfPnk0xNgXkACrMgUJqrcyQ0MvWBe12u6wdQXwB2NMtS5cuFc8pklSU8JMJEIchDmd1jGCeCLFrcCFkm2NaSjvkAAz8C+XwKV3HtwgKJJMUABvbbwM0iv0t0AWYDU6/Dc42codP0AV/8WQEcA6pfr0qn/hDGEmHi8WT3EtWAOKhB6IVj0RCvCUj3ed2K4T3nCku48WFKl9xj2ygXR5Dz5uixQp4W79+vTiFBmIRe0+aNEmSckeX4MyJOVJ92XUEFiOIdwT6dbRyf7PM/Sk3vI3cPzX7+aJCwAzDiThCCY6TQ01MrilezFjJxtgoV8661RP5+eBYBgEISyhCiUdhSKuKF6m3j0tOcnm8XIjdOj6n0zZqeEJ+njqX6/X6nO3yGEa9KYrcKMZGkg8oMowBk6+++ipK8FVrLO+tW7eOLkIt/lOqj6CAzgi1KPVAdi3evXeVLqYOabOJJbRFIS6bTg8FuWCRxFMYCisC+ApPGrlHDdUEPLbYmDI5xeIp7PlFyBBqINoU9obOqf43ZIby3m6PZdBAlbwamhqEsGB/eTrAYDGn3dw5v5M9o9Z5ofiHTW73eZUcrK2wTE377QAzIJ/5eTpyA+RHd2cOAgriD4OicIyHYI+LioqK2Dnnp0x0BJAgwQITZVjKxv/iAEEB9oHbsyLPn0PlIOJyGFMGe5UzLDFyCMKgj7cq/UKGQW8vULvp1effSy+0EOpcXFxqr9S8W3tPvq3PRGuceMPPa38uempn6f+oYWU2tNbLAoA0RN3I7WldjQoR8wN1YaT6oYit6gP/OTk5zdavq6sTKxlpOa0Gh0KCJOVm61itQbTkzibGwpgXlA1YYmoK49oSL8jbdwrt7ZHYG41GhAMqkaw6sef19rSkfvk3Trij78+7JmaEqvabsS+frf2x9NT7ytxgPjrEt+7b9YBwpNb4RJxPAT9i8lDH7CKBfUSaV3tcHHaKCXlym6lj8JJ78EpeeE8Xy0CKcfGksDfd0F1pu05L9u3WN9UpeXvO3NHeO6vHHQW9Jqh/K8bzd/9j2uupzZ7Ju6FjvzboLOCcLe/t2bMnirAXBxehzgJIEhDZbBNuXzkAbm0SL3fTnraRve5hk3OSA4IaKRAt3CCsk7zZhbJOUhXJxDPcEirTXfiKblm7di3+lLz9xWDqkeE/JIc4PyTC1SL/eFVpUAyvt5q79es6auzN04b1vC2MI/EI+3m9zedtZv68V8cBbTMY6E2CvXiDbeSE0RLnFC3NQuHhydusKV7cjrCHDAzzkgW2yIlFMQq5TDsSm62MinjQrvnz5+sC+z7o7Cat4wDDS5YsgbZAT+hVTkuXLqVkE3Eo/gTmaQIIfxYWFrK0FH+K94Ma4tK78LZ4ndstD3uO41Q7fI/XfTlzSLmhY/atvSb/pO/kRHOkk2163tTcZhwuM62tz05HMbHXBXbds/EO4/ZxAx4hL0oLddF6e0SolEEhvGdRfXQxrwvsYG82l2lHu6BSPDW5AEALzMPBzJkzR6xmtHMUwSDt2oD7mT17tngTB0BOk82IFKZPnw4mDOq4xrcM9nxcWmdDSpLg9crOlflBr1f7UtrMtKypQ/+07MHD6584+crUjVMGz4wc84Fgoxm7YzR26BCf2jajy5JwmOEoshVPELLNuS2Aff9HrgTSxYvCm0i7HDtc2Toaik+oefIrB29C7D9lO4vCIHEuE7xmLpahXdJs8dSJgngKXzGiGF6CeSpHCcovwS0zEzBm2z2ohMJ+VKNUkeGcbAFzKrw+McGcebP/IG3E1NneZUbeU92Suke3QwXFM/nIJrqnDGqboYV9ZZhEuhXd2Ts2QmFsCgLm2T4Q2hYe9goWWDFPxXbXS/yVbPlV8HZVyxVebPZG5VyGQUvBtNHG3nbw9oFdycri0SGiZlnt2bMHTiU4nAwup/0j7OgnSxWbDU79ntyWl+3/5Vl5TLU/+QSvYiygy+lxe7TamjVrFr36SjbdQkzFOnHy5Mkt4sx2+IC5bCTPNv+iAhoKZR1ClYt3lQWQfxfS7PDc/pW9dCe2SYBKh2RCrbqzG2n7rUTjFW5USSx5oY39wU3gqVHYXu8amDH8BQXx8GdUNg5HhfxzbLbhuZwpTnFWL5aJuyNzWrQC+L0BotkRtnOGoiPxSzWRQbU0t6cwntw4Ei1YDfoTaCeLgLbAls7koq2JEyciTkMhfVtRUVFXVwd7D0m2bdsm2zrSaWSYbKqcXp4LLxR4i1aWOAxW3iQ3NXsuOzkL2xE4dnJPQHFLKEYF/L6u2BZsU0b2msIOnELF2UGassr9Ww4sDxw+GxJJAgKzgqbpyC34/Hp1Pns3FpMtsH92bqjDc607qxfYMkxNhxKPya9ACCShgdBGycYtKofOsNGnV7mHsXHLD/v4Qf2NXdI8lefl33sX27bAaExBchGtGF58LfvyXIzE008/Hd4OOYTxbNmfTbGKkwWwffvtt2EUyKWHSvKB/FB7BKFVQBoUiwX5NMOkJqUUx6tIGRhyJK4bMQW+ld3tI74R4Jes1eFGYCDUiVq1HjWQyzDk4DHF6QwEmD9uhWyK0TZEARfbHSwRj87by8KeJuFg6KEkGFyoB03IQSXwFSw+LdehnM3hQT/XrVvXordCXAV7Q0pyfG7WxX9u4mxXw14QeIuZD50wtDshCendOT9a3NCtGzZsKCoqIqca7K7pbXlhz+FT9i5J3SX5GHw7ZADgMaISu0OH+Zr9+Q3yMKRwsj6Z4EEhQKh3xdCueLH5IG82NWue5Eg/9FscVIe6UXKyJZLNs0AOHlB83E13+ZQuTW0y5pHMIEaCfARH9F4gkoTS/uCDujZTsjjSZC9TAsKXLl0K2LPXsdDsPStHJAhlQP2HAxROhEw7cyvfevf4fzypT7hKBf3vxrTb+u3+xJzRbj/24PF6Jv01VSeE3Oo//2cbRt50RytN4LE9sNHdAM84N8uWasq+eEs9BU65XwJAS1/kxN4ABRvRopyZvb6qpTe2iC7hqv3eTtVSQrfc+8al4FTyeh+MNUZZ7FRCjT4dx4rkPNgl2Lt+rPgud6zQ0KATvS1L8Hj0yUn9926NS+sUTRft//lql8L7NsXkdDunvt5JJ8gvNHB8/IYnzvG89ruXGl0bhAiF0hzYqTcfOtheYlwCjKl7OuJ8n7O1js0KHm9j6dHKd1Yfn/Obb7NHV72nNtX0W6UQJ4VQ2jN1mIZ5ja4hYisj7Xti50oy3+HeKTUffHK1L+V99Q2eqgthe/vGI+WO4v2Oz/fUF3/tKjvuvVjjP6/jc3Gqsapwqo/T6R7M/a2mSRrFVAyvkNFQws+mAGIC9om3j4lL7wqQX5nP5zj4f2+do0Uc3efON5Yeqdu9r+6zXfW7viKoc3FxfJxRbw8cj63nOXURfjOiG1Jye9yqqZpGsUP+l/lVbKM1C/F0A71QmLl69n6+9oe9MbVD4p1jK5e9dWVij+N0Hs/Z15bbhzVzAtxddaHhXwcAdeC84cAhz7lKwenk9AbebL4EdVHUDldvTFY7xxOYehBkI/y8G6doeqZRrKXu/vNI5/xLmKGOG8MitPurta5asev06ENVK9b4j99fDsJ5q/XCe2t/7Nk949n5kjM57gvVgLpjb4nji92N3x12nz4jOF2IFDhTnP+HNJV+VI9T/wO7lY7TsqduOZ1hTsGLmp5pFFMRPiDNdjrhU7JOCf8/bsAjsfAzu1fBPj5rUNLdP72wap3YReutlrOFf3Hs+irlngmm7t18Tlfjtwcdu/e5yo41nTglNDVxen0gho/TmdS90E6v15nU/tLmZ2Xvy7r6Qd0n2k12TdU0ih2ic4f4F/g14f0OZzW9RKxX6hCbOVnyu8PtS5zkjVrw3qW3BX705upZN19Do+D1otxfHxcGPTy2fxagpXv4EEro9Zk7N1sHqnoxxm/XTfvu5KagNviVj55OMCdoqqaRRmGQdEbdlpuV8ospXof0t6V4qwUhgP8z3orkH8G/P1APY98urIbRoDOb1dT1eD2HTm/lglx9Vs9pGuY10ihqsAd1XTjX2Dk1xJm8SMl/3sdg5M2q0oG5aycJvgapxHz8wp8ui83ePHXqVHFxMT5jQZgjAYoKq7q6OjyX+L2dGl3TJHP2xtyzR+f/fKJiwfP6xNbwqAJCBL2KH9t4dcfC8rNbg8vvzX02zhDXSqBdvHgxKbfdbh8/fvzo0aPV34573333XVwsWrSoa9dwXum5adOmm2++uU+fPlF5HIiBz9dff52V4Prw4cOQk/25b98+VmHlypU7duwQ1xdbkMcff3zZsmXZ2dnKhgZ16PVveJDHHnss6mMUdhdBKowO/SopONx3333hjRF7Ukgyd+7caxT28ttmOs951DKwnxDFTXs+n38LQG2dt76BT7BzzU3+Ldo696MD0oNKCO/jLT0eyGmtM5WnT5/euXMntCEnJwdaMm/evBZ5S+jBU089BcVqkbEQE/QSTFpvsG02Gx6QBSNoq6SkBG6c/ty8eXOERhM4Rx+i9wD7VgoNxF10//33M+Gbjxznzo
VduzlAsH32yA6YQQb1TV8b3h6kt8Wnv/D00Xse1vsEHR/uwVtBQKYguJoEnw9QtwwaaBuWbb91RHz2IENSYqibnG7nM5sfOnhSRvshx+/vXNnaPQInD58GDYZWQVGeffZZsY0nPwOdxnWXLl2Yx4ASOBwOqJQYBsAA6os1jO5iJcSHuVA0J3FQklbEfPApcXooBLAVnBi9gR+iog6Jh/r4EwJQWzBbCsIzkYLLyWqgB+DtZRGFVoIfBK3gFpWum9oVd1GLjDIM3GMBkuWM5woOZNhwyxqR4MqSzg9mKxnumIM9KHn8uLSnZp156VV9YsvsouD1Ck1NQpMbLj0uo6tlyC2Jt91qyx9q7deXE53zkVBVfeUnpWu+OLbp+8rdgk/mZ9X9+3NuemhAl7b7kWCMIrksoAUxIVwEBcZEVCcrKwsxM8XA+BOfKMG3LOAH/eEPf4ApASt8S5oKbtAbRNSwKdB7lFD8TEpJzMUcqBXACV/hLqbxd999N1klgAFfEStWGExQYsI55MEnrtEowhO0S76L7EKw8HQNIQEe6hnIz8qJgGpygzCXEscIhhLZID8uGG63b9+OFinpYBbqsctEYTmF6PTn4wGiC3p8NAqbRU2T/Bs3bpRYGXQdel5slcSDAvlxI7qIxEDI9vLLL4PJhAkTGGc8y3PPPceyIZIW17gRVpKYoA4Yon9YCfoNktC9zL5HK5WLZpBPlP7cfNuIXF99g5oYXnC5AjF8PW+3xQ/P7bJwXu9NK/vvKeqz6m+dH58RP7B/MOa9Pu+u41uf/eDRn7/Z++H/veGdXU8dO7tdFvM6/89ddfv9uL+2Wb8ABlBxFq5DjaC4CPtpvKF8GHKCAekK+Ul8og4GFfXxiTpQdJovQAm5U5RD+WjswROf4CNRAqgI6lPKAOChFWZoyIfgFnCGgyW4AhVAESrjFhQquEHgnL4lJ48bCcnkjSEGNQ3+JDw0lYXrqAnJCU4ol8xcoq9wO6AChLA4HHVQEyXgtmjRIshGXwEV9BTgFipAEDtq3EVTFcx+4S7qcOo9CM+SFIxRQUGBBPPoRjw4TBV6kj0ROe3tASK7xlrEg4A5mIC5mDP1kjhgQc9D/o0BonkTKgFPlDA7jk/cKzvcsQV73mS6Yemf+US7/Ky+4P+FPF99PdAOV2zq2yf1iZk3rXij/66P+23fmPH875LGjjbIbcI9V3fmb7teenTFyEl/Tf3T+3fvO7ai0VlBW/FCphOc6Y0Hv+La5D0/MP9wNeS3GexJzwgVGDzyOYANYY9msAh+qAPlwL00+40/gW2KACkSZqEg6Tr0AHwkeo9WcCN5GGgqlFic89MtpLIEe/wJnlAsgrRCXk2wRwUImR0gMiVkBahpCE+cSTuZEQEM0CgaoqYlxgWPAMGALlwD6uTVCTDgDG6ogK6DD8Q1PsGExFYT9OLRxDMmYEV3ocPpAvboyGUC8+DpFXQjRhDlYIVrwBWdAHhTh1DsvXPnTrGZoP4nzlQfFchkS1IbmsQlG0Hc0BBJArYUoNGzU7fHbpB/ycfe0j/9hYU/zJrHNupfiuHdHs5gMHZNsw4ZaC8YYR81HDG8wrJcY1Pj1iPrdxz5Z3nlHrf7gv+9mOp/dkOnmz369SRLctv0CJQbyiRJRDGKhEyMPUWzRKESaQwwcx1AEe6FDqEQjhRBI0XOAAZUnzw2hQySFINdQx6xRpIkYksBVuAD6yCeXFBI74FtKCuuqVHoInSU5b3BwpMdYcyZsZBFFz0a5CHY4EEYN3QdZRnUpSpHBDI06x7RKPwzGUc0IUlAmNig+wOEgSABIAylb9SQmCEbelgx1Kdxl+UsVgPqK3QpS1hIeISBsA4wOhCSwv7Yhb1/Vv/xGXWfflm1chWn9y+bGTqkmLMH2Ufl24YPjc8aFKf4C3kHTpd8fOi94h+21DR8j9hADHWVmMct/dPH/6z/tDbrEeZAZAkYEHs5OAExPsVRKFsnE88DQWmALnyFC8rVWbooScgpGSaCXoptTfAUOjBGaTB0TnYFTpLeU8BJ6ghdJ7Swp8ZXEiYEVIhBdch9KfQSng4iEQDwIDQxIc6x6TMU8tXP1eHZSQzwR+QFnrhQNih9AoQbqUvhvWWRLB5x4oz6uJDNR8CNwZgqYCwkYtCsARlEGq+Yhj2oxysvei5cNHbqmHD7aKDdcpPSC4zOOc7sPLrp06Prfqwq8XprJFPxLZsdhOW29Cic+F7srHxARWC2yVEDLRg/SdRHHpWm/TDwUH3oBE2hSZJh3A4VoYmf4FZgC4AWKAeqwdU3qyUwHAyuDAyh4nwwZEpJ0pJXJ+cGtykRnmqinDw8vqXpwOA1LQqLIDkqUMpNuk6eH4YDF7gR3z4bIFSmQgIhSggeKudc0RBLE8jWoD+DZzTxICikuQwIiaegdXs2V0oRDcsdZK0YONMMophgCCAtVAIDhNupu/AI7OnAloJ/Wj60x8abKVXB3pjase+Hq5XrfF7+8ceH3j14+jOn63RLY/iQkwt8/PIH9/FcDL0/B2qNLAAjTVkrzclL6jCvS+oL3SLY0xweTYPrLi+bk3eVoBr1oWQ0NYj6oVaeWIQJMWgmHBcAp6wpkcCe6TddsF/XpmREIjyzLAhToeLB4QCLg6hbqALBCbcAWgQYPAtlFmQLwIrcIKUGZEYJS2o2EUBU8AFnCqfJmhDGgmFPEwTU/8zDQzCMBYlB+bws7FFIVin4WzRHD0hMkGdRjkMdxdjSjA+Ghro02FW0MXFKP27fHLk8rs/KtxSVvld6+lOP50LUhXtm/EfaizQ0UkmwSsCVeMVRo4i8vQTqR84d+OjQym8qdlxwlOmEpqg49mD6RW6hhnmNVBI8OWAvjk00iibsX94674ujb0aSsauhgr6/nJ77K214NFJJiPMR87d78HytUIuD/EZ344x/DHE0/tB6a+i3dL/nxQnvaGOjkUYxlNsjzr9veR+X+1zUkQ9Rbuw05tVpH2gDo5FGrUfhTJKbDKYVM0ttlh5R/0Hc9JRhGuY10igWYQ+yxFnemfGtzXJDFJHfL338svu3a0OikUYxCnuQUW98Z8Y38ebuUUF+v27jX5q0WhsPjTSKadgT8lfMPBB5tD8gfdJLkzXMa6TRtQB7Qv4/Hv6X3dJTiADzhZPe1UZCI42uGdjrAjN8K2ceSEsK5zjhiN6PapjXSKM2pog250romc0zS75Xf2yGf3D4onuzf6mNgUYaXcOwB7299y+r9v5O0AkKS/qC/3dx7H+csHlQt1xtADTS6JqHPejExRNz14xtcP4YqkKnxCFL791qMVq03tdIo2s1t5dQRlLG6kcP5/R8INjJ6zjj1KF/+tv0LzXMa6TRv5W3Z/R5+ceLPpnJDuR2SBjw31M/SrGmaJ2ukUb/trDX+d+24Vuw4YEDJz+cmv37GcPmat2tkUaxQP8vwAAKvnvHKkf5tQAAAABJRU5ErkJggg==" alt="SiteGuarding - Protect your website from unathorized access, malware and other threat" height="60" border="0" style="display:block" /></a></td>
              <td width="400" height="60" align="right" bgcolor="#fff" style="background-color: #fff;">
              <table border="0" cellspacing="0" cellpadding="0" bgcolor="#fff" style="background-color: #fff;">
                <tr>
                  <td style="font-family:Arial, Helvetica, sans-serif; font-size:11px;"><a href="http://www.siteguarding.com/en/login" target="_blank" style="color:#656565; text-decoration: none;">Login</a></td>
                  <td width="15"></td>
                  <td width="1" bgcolor="#656565"></td>
                  <td width="15"></td>
                  <td style="font-family:Arial, Helvetica, sans-serif; font-size:11px;"><a href="http://www.siteguarding.com/en/prices" target="_blank" style="color:#656565; text-decoration: none;">Services</a></td>
                  <td width="15"></td>
                  <td width="1" bgcolor="#656565"></td>
                  <td width="15"></td>
                  <td style="font-family:Arial, Helvetica, sans-serif; font-size:11px;"><a href="http://www.siteguarding.com/en/what-to-do-if-your-website-has-been-hacked" target="_blank" style="color:#656565; text-decoration: none;">Security Tips</a></td>            
                  <td width="15"></td>
                  <td width="1" bgcolor="#656565"></td>
                  <td width="15"></td>
                  <td style="font-family:Arial, Helvetica, sans-serif;  font-size:11px;"><a href="http://www.siteguarding.com/en/contacts" target="_blank" style="color:#656565; text-decoration: none;">Contacts</a></td>
                  <td width="30"></td>
                </tr>
              </table>
              </td>
            </tr>
          </table></td>
        </tr>

        <tr>
          <td width="750" height="2" bgcolor="#D9D9D9"></td>
        </tr>
        <tr>
          <td width="750" bgcolor="#fff" ><table width="750" border="0" cellspacing="0" cellpadding="0" bgcolor="#fff" style="background-color:#fff;">
            <tr>
              <td width="750" height="30"></td>
            </tr>
            <tr>
              <td width="750">
                <table width="750" border="0" cellspacing="0" cellpadding="0" bgcolor="#fff" style="background-color:#fff;">
                <tr>
                  <td width="30"></td>
                  <td width="690" bgcolor="#fff" align="left" style="background-color:#fff; font-family:Arial, Helvetica, sans-serif; color:#000000; font-size:12px;">
                    {MESSAGE_CONTENT}
                    <br>
                    <b>URGENT SUPPORT</b><br>
                    Not sure in the report details? Need urgent help and support. Please contact us <a href="https://www.siteguarding.com/en/contacts" target="_blank">https://www.siteguarding.com/en/contacts</a>
                  </td>
                  <td width="30"></td>
                </tr>
              </table></td>
            </tr>
            <tr>
              <td width="750" height="15"></td>
            </tr>
            <tr>
              <td width="750" height="15"></td>
            </tr>
            <tr>
              <td width="750"><table width="750" border="0" cellspacing="0" cellpadding="0">
                <tr>
                  <td width="30"></td>
                  <td width="690" align="left" style="font-family:Arial, Helvetica, sans-serif; color:#000000; font-size:12px;"><strong>How can we help?</strong><br />
                    If you have any questions please dont hesitate to contact us. Our support team will be happy to answer your questions 24 hours a day, 7 days a week. You can contact us at <a href="mailto:support@siteguarding.com" style="color:#2C8D2C;"><strong>support@siteguarding.com</strong></a>.<br />
                    <br />
                    Thanks again for choosing SiteGuarding as your security partner!<br />
                    <br />
                    <span style="color:#2C8D2C;"><strong>SiteGuarding Team</strong></span><br />
                    <span style="font-family:Arial, Helvetica, sans-serif; color:#000; font-size:11px;"><strong>We will help you to protect your website from unauthorized access, malware and other threats.</strong></span></td>
                  <td width="30"></td>
                </tr>
              </table></td>
            </tr>
            <tr>
              <td width="750" height="30"></td>
            </tr>
          </table></td>
        </tr>
        <tr>
          <td width="750" height="2" bgcolor="#D9D9D9"></td>
        </tr>
      </table>
      <table width="750" border="0" cellspacing="0" cellpadding="0">
        <tr>
          <td width="750" height="10"></td>
        </tr>
        <tr>
          <td width="750" align="center"><table border="0" cellspacing="0" cellpadding="0">
            <tr>
              <td style="font-family:Arial, Helvetica, sans-serif; color:#ffffff; font-size:10px;"><a href="http://www.siteguarding.com/en/website-daily-scanning-and-analysis" target="_blank" style="color:#656565; text-decoration: none;">Website Daily Scanning</a></td>
              <td width="15"></td>
              <td width="1" bgcolor="#656565"></td>
              <td width="15"></td>
              <td style="font-family:Arial, Helvetica, sans-serif; color:#ffffff; font-size:10px;"><a href="http://www.siteguarding.com/en/malware-backdoor-removal" target="_blank" style="color:#656565; text-decoration: none;">Malware & Backdoor Removal</a></td>
              <td width="15"></td>
              <td width="1" bgcolor="#656565"></td>
              <td width="15"></td>
              <td style="font-family:Arial, Helvetica, sans-serif; color:#ffffff; font-size:10px;"><a href="http://www.siteguarding.com/en/update-scripts-on-your-website" target="_blank" style="color:#656565; text-decoration: none;">Security Analyze & Update</a></td>
              <td width="15"></td>
              <td width="1" bgcolor="#656565"></td>
              <td width="15"></td>
              <td style="font-family:Arial, Helvetica, sans-serif; color:#ffffff; font-size:10px;"><a href="http://www.siteguarding.com/en/website-development-and-promotion" target="_blank" style="color:#656565; text-decoration: none;">Website Development</a></td>
            </tr>
          </table></td>
        </tr>

        <tr>
          <td width="750" height="10"></td>
        </tr>
        <tr>
          <td width="750" align="center" style="font-family: Arial,Helvetica,sans-serif; font-size: 10px; color: #656565;">Add <a href="mailto:support@siteguarding.com" style="color:#656565">support@siteguarding.com</a> to the trusted senders list.</td>
        </tr>
      </table>
    </td>
  </tr>
</table>
</body>
</html>
';

		$body_message = str_replace("{MESSAGE_CONTENT}", $result, $body_message);
		
		// To send HTML mail, the Content-type header must be set
		$headers  = 'MIME-Version: 1.0' . "\r\n";
		$headers .= 'Content-type: text/html; charset=UTF-8' . "\r\n";
		
		// Additional headers
		$headers .= 'From: '. $to . "\r\n";
		
		// Mail it
		mail($to, $subject, $body_message, $headers);
	}
    
    
    public static function Wait_CSS_Loader()
    {
        ?>
        
		<div id="loader" style="min-height:600px;position: relative"><img style="position: absolute;top: 0; left: 0; bottom: 0; right: 0; margin:auto;" src="<?php  echo JURI::root() . 'administrator/components/com_jmwascanner/images/ajax_loader.svg'; ?>"></div>
		            <script>
            jQuery(document).ready(function(){
                jQuery('.ui.accordion').accordion();
                jQuery('.ui.checkbox').checkbox();
                jQuery('#main').css('opacity','0');
                jQuery('#main').css('display','block');
                jQuery('#loader').css('display','none');
				fromBlur();
            });
			
			var i = 0;
			
			function fromBlur() {
				running = true;
					if (running){
					
						jQuery('#main').css("opacity", i);
						
						i = i + 0.02;

					if(i > 1) {
						running = false;
						i = 0;
					}
					if(running) setTimeout("fromBlur()", 5);

				}
			}
            </script>
            
            <?php
    }
    
}



class FUNC_WAP2_Geo_IP2Country {
	

    private static $DATA_SECTION_SEPARATOR_SIZE = 16;
    private static $METADATA_START_MARKER = "\xAB\xCD\xEFMaxMind.com";
    private static $METADATA_START_MARKER_LENGTH = 14;
    private static $METADATA_MAX_SIZE = 131072; // 128 * 1024 = 128KB

    private $decoder;
    private $fileHandle;
    private $fileSize;
    private $ipV4Start;
    private $metadata;
    private $fileStream;
    private $pointerBase;
    // This is only used for unit testing
    private $pointerTestHack;
    private $switchByteOrder;

    private $types = [
        0 => 'extended',
        1 => 'pointer',
        2 => 'utf8_string',
        3 => 'double',
        4 => 'bytes',
        5 => 'uint16',
        6 => 'uint32',
        7 => 'map',
        8 => 'int32',
        9 => 'uint64',
        10 => 'uint128',
        11 => 'array',
        12 => 'container',
        13 => 'end_marker',
        14 => 'boolean',
        15 => 'float',
    ];
	
	private $map = array(
	'A1' => "Anonymous Proxy",
	'A2' => "Satellite Provider",
	'O1' => "Other Country",
	'AD' => "Andorra",
	'AE' => "United Arab Emirates",
	'AF' => "Afghanistan",
	'AG' => "Antigua and Barbuda",
	'AI' => "Anguilla",
	'AL' => "Albania",
	'AM' => "Armenia",
	'AO' => "Angola",
	'AP' => "Asia/Pacific Region",
	'AQ' => "Antarctica",
	'AR' => "Argentina",
	'AS' => "American Samoa",
	'AT' => "Austria",
	'AU' => "Australia",
	'AW' => "Aruba",
	'AX' => "Aland Islands",
	'AZ' => "Azerbaijan",
	'BA' => "Bosnia and Herzegovina",
	'BB' => "Barbados",
	'BD' => "Bangladesh",
	'BE' => "Belgium",
	'BF' => "Burkina Faso",
	'BG' => "Bulgaria",
	'BH' => "Bahrain",
	'BI' => "Burundi",
	'BJ' => "Benin",
	'BL' => "Saint Bartelemey",
	'BM' => "Bermuda",
	'BN' => "Brunei Darussalam",
	'BO' => "Bolivia",
	'BQ' => "Bonaire, Saint Eustatius and Saba",
	'BR' => "Brazil",
	'BS' => "Bahamas",
	'BT' => "Bhutan",
	'BV' => "Bouvet Island",
	'BW' => "Botswana",
	'BY' => "Belarus",
	'BZ' => "Belize",
	'CA' => "Canada",
	'CC' => "Cocos (Keeling) Islands",
	'CD' => "Congo, The Democratic Republic of the",
	'CF' => "Central African Republic",
	'CG' => "Congo",
	'CH' => "Switzerland",
	'CI' => "Cote d'Ivoire",
	'CK' => "Cook Islands",
	'CL' => "Chile",
	'CM' => "Cameroon",
	'CN' => "China",
	'CO' => "Colombia",
	'CR' => "Costa Rica",
	'CU' => "Cuba",
	'CV' => "Cape Verde",
	'CW' => "Curacao",
	'CX' => "Christmas Island",
	'CY' => "Cyprus",
	'CZ' => "Czech Republic",
	'DE' => "Germany",
	'DJ' => "Djibouti",
	'DK' => "Denmark",
	'DM' => "Dominica",
	'DO' => "Dominican Republic",
	'DZ' => "Algeria",
	'EC' => "Ecuador",
	'EE' => "Estonia",
	'EG' => "Egypt",
	'EH' => "Western Sahara",
	'ER' => "Eritrea",
	'ES' => "Spain",
	'ET' => "Ethiopia",
	'EU' => "Europe",
	'FI' => "Finland",
	'FJ' => "Fiji",
	'FK' => "Falkland Islands (Malvinas)",
	'FM' => "Micronesia, Federated States of",
	'FO' => "Faroe Islands",
	'FR' => "France",
	'GA' => "Gabon",
	'GB' => "United Kingdom",
	'GD' => "Grenada",
	'GE' => "Georgia",
	'GF' => "French Guiana",
	'GG' => "Guernsey",
	'GH' => "Ghana",
	'GI' => "Gibraltar",
	'GL' => "Greenland",
	'GM' => "Gambia",
	'GN' => "Guinea",
	'GP' => "Guadeloupe",
	'GQ' => "Equatorial Guinea",
	'GR' => "Greece",
	'GS' => "South Georgia and the South Sandwich Islands",
	'GT' => "Guatemala",
	'GU' => "Guam",
	'GW' => "Guinea-Bissau",
	'GY' => "Guyana",
	'HK' => "Hong Kong",
	'HM' => "Heard Island and McDonald Islands",
	'HN' => "Honduras",
	'HR' => "Croatia",
	'HT' => "Haiti",
	'HU' => "Hungary",
	'ID' => "Indonesia",
	'IE' => "Ireland",
	'IL' => "Israel",
	'IM' => "Isle of Man",
	'IN' => "India",
	'IO' => "British Indian Ocean Territory",
	'IQ' => "Iraq",
	'IR' => "Iran, Islamic Republic of",
	'IS' => "Iceland",
	'IT' => "Italy",
	'JE' => "Jersey",
	'JM' => "Jamaica",
	'JO' => "Jordan",
	'JP' => "Japan",
	'KE' => "Kenya",
	'KG' => "Kyrgyzstan",
	'KH' => "Cambodia",
	'KI' => "Kiribati",
	'KM' => "Comoros",
	'KN' => "Saint Kitts and Nevis",
	'KP' => "Korea, Democratic People's Republic of",
	'KR' => "Korea, Republic of",
	'KW' => "Kuwait",
	'KY' => "Cayman Islands",
	'KZ' => "Kazakhstan",
	'LA' => "Lao People's Democratic Republic",
	'LB' => "Lebanon",
	'LC' => "Saint Lucia",
	'LI' => "Liechtenstein",
	'LK' => "Sri Lanka",
	'LR' => "Liberia",
	'LS' => "Lesotho",
	'LT' => "Lithuania",
	'LU' => "Luxembourg",
	'LV' => "Latvia",
	'LY' => "Libyan Arab Jamahiriya",
	'MA' => "Morocco",
	'MC' => "Monaco",
	'MD' => "Moldova, Republic of",
	'ME' => "Montenegro",
	'MF' => "Saint Martin",
	'MG' => "Madagascar",
	'MH' => "Marshall Islands",
	'MK' => "Macedonia",
	'ML' => "Mali",
	'MM' => "Myanmar",
	'MN' => "Mongolia",
	'MO' => "Macao",
	'MP' => "Northern Mariana Islands",
	'MQ' => "Martinique",
	'MR' => "Mauritania",
	'MS' => "Montserrat",
	'MT' => "Malta",
	'MU' => "Mauritius",
	'MV' => "Maldives",
	'MW' => "Malawi",
	'MX' => "Mexico",
	'MY' => "Malaysia",
	'MZ' => "Mozambique",
	'NA' => "Namibia",
	'NC' => "New Caledonia",
	'NE' => "Niger",
	'NF' => "Norfolk Island",
	'NG' => "Nigeria",
	'NI' => "Nicaragua",
	'NL' => "Netherlands",
	'NO' => "Norway",
	'NP' => "Nepal",
	'NR' => "Nauru",
	'NU' => "Niue",
	'NZ' => "New Zealand",
	'OM' => "Oman",
	'PA' => "Panama",
	'PE' => "Peru",
	'PF' => "French Polynesia",
	'PG' => "Papua New Guinea",
	'PH' => "Philippines",
	'PK' => "Pakistan",
	'PL' => "Poland",
	'PM' => "Saint Pierre and Miquelon",
	'PN' => "Pitcairn",
	'PR' => "Puerto Rico",
	'PS' => "Palestinian Territory",
	'PT' => "Portugal",
	'PW' => "Palau",
	'PY' => "Paraguay",
	'QA' => "Qatar",
	'RE' => "Reunion",
	'RO' => "Romania",
	'RS' => "Serbia",
	'RU' => "Russian Federation",
	'RW' => "Rwanda",
	'SA' => "Saudi Arabia",
	'SB' => "Solomon Islands",
	'SC' => "Seychelles",
	'SD' => "Sudan",
	'SE' => "Sweden",
	'SG' => "Singapore",
	'SH' => "Saint Helena",
	'SI' => "Slovenia",
	'SJ' => "Svalbard and Jan Mayen",
	'SK' => "Slovakia",
	'SL' => "Sierra Leone",
	'SM' => "San Marino",
	'SN' => "Senegal",
	'SO' => "Somalia",
	'SR' => "Suriname",
	'ST' => "Sao Tome and Principe",
	'SV' => "El Salvador",
	'SX' => "Sint Maarten",
	'SY' => "Syrian Arab Republic",
	'SZ' => "Swaziland",
	'TC' => "Turks and Caicos Islands",
	'TD' => "Chad",
	'TF' => "French Southern Territories",
	'TG' => "Togo",
	'TH' => "Thailand",
	'TJ' => "Tajikistan",
	'TK' => "Tokelau",
	'TL' => "Timor-Leste",
	'TM' => "Turkmenistan",
	'TN' => "Tunisia",
	'TO' => "Tonga",
	'TR' => "Turkey",
	'TT' => "Trinidad and Tobago",
	'TV' => "Tuvalu",
	'TW' => "Taiwan",
	'TZ' => "Tanzania, United Republic of",
	'UA' => "Ukraine",
	'UG' => "Uganda",
	'UM' => "United States Minor Outlying Islands",
	'US' => "United States",
	'UY' => "Uruguay",
	'UZ' => "Uzbekistan",
	'VA' => "Holy See (Vatican City State)",
	'VC' => "Saint Vincent and the Grenadines",
	'VE' => "Venezuela",
	'VG' => "Virgin Islands, British",
	'VI' => "Virgin Islands, U.S.",
	'VN' => "Vietnam",
	'VU' => "Vanuatu",
	'WF' => "Wallis and Futuna",
	'WS' => "Samoa",
	'YE' => "Yemen",
	'YT' => "Mayotte",
	'ZA' => "South Africa",
	'ZM' => "Zambia",
	'ZW' => "Zimbabwe"
	);	
	
    public static $country_list = array(
        "AF" => "Afghanistan",   // Afghanistan
        "AL" => "Albania",   // Albania
        "DZ" => "Algeria",   // Algeria
        "AS" => "American Samoa",   // American Samoa
        "AD" => "Andorra",   // Andorra 
        "AO" => "Angola",   // Angola
        "AI" => "Anguilla",   // Anguilla
        "AQ" => "Antarctica",   // Antarctica
        "AG" => "Antigua and Barbuda",   // Antigua and Barbuda
        "AR" => "Argentina",   // Argentina
        "AM" => "Armenia",   // Armenia
        "AW" => "Aruba",   // Aruba 
        "AU" => "Australia",   // Australia 
        "AT" => "Austria",   // Austria
        "AZ" => "Azerbaijan",   // Azerbaijan
        "BS" => "Bahamas",   // Bahamas
        "BH" => "Bahrain",   // Bahrain 
        "BD" => "Bangladesh",   // Bangladesh
        "BB" => "Barbados",   // Barbados 
        "BY" => "Belarus",   // Belarus 
        "BE" => "Belgium",   // Belgium
        "BZ" => "Belize",   // Belize
        "BJ" => "Benin",   // Benin
        "BM" => "Bermuda",   // Bermuda
        "BT" => "Bhutan",   // Bhutan
        "BO" => "Bolivia",   // Bolivia
        "BA" => "Bosnia and Herzegovina",   // Bosnia and Herzegovina
        "BW" => "Botswana",   // Botswana
        "BV" => "Bouvet Island",   // Bouvet Island
        "BR" => "Brazil",   // Brazil
        "IO" => "British Indian Ocean Territory",   // British Indian Ocean Territory
        "VG" => "British Virgin Islands",   // British Virgin Islands,
        "BN" => "Brunei Darussalam",   // Brunei Darussalam
        "BG" => "Bulgaria",   // Bulgaria
        "BF" => "Burkina Faso",   // Burkina Faso
        "BI" => "Burundi",   // Burundi
        "KH" => "Cambodia",   // Cambodia 
        "CM" => "Cameroon",   // Cameroon
        "CA" => "Canada",   // Canada 
        "CV" => "Cape Verde",   // Cape Verde
        "KY" => "Cayman Islands",   // Cayman Islands
        "CF" => "Central African Republic",   // Central African Republic
        "TD" => "Chad",   // Chad
        "CL" => "Chile",   // Chile
        "CN" => "China",   // China
        "CX" => "Christmas Island",   // Christmas Island
        "CC" => "Cocos (Keeling Islands)",   // Cocos (Keeling Islands)
        "CO" => "Colombia",   // Colombia
        "KM" => "Comoros",   // Comoros
        "CG" => "Congo",   // Congo 
        "CK" => "Cook Islands",   // Cook Islands
        "CR" => "Costa Rica",   // Costa Rica 
        "HR" => "Croatia (Hrvatska)",   // Croatia (Hrvatska
        "CY" => "Cyprus",   // Cyprus
        "CZ" => "Czech Republic",   // Czech Republic
        "CG" => "Democratic Republic of Congo",   // Democratic Republic of Congo,
        "DK" => "Denmark",   // Denmark
        "DJ" => "Djibouti",   // Djibouti
        "DM" => "Dominica",   // Dominica
        "DO" => "Dominican Republic",   // Dominican Republic
        "TP" => "East Timor",   // East Timor
        "EC" => "Ecuador",   // Ecuador
        "EG" => "Egypt",   // Egypt 
        "SV" => "El Salvador",   // El Salvador 
        "GQ" => "Equatorial Guinea",   // Equatorial Guinea
        "ER" => "Eritrea",   // Eritrea 
        "EE" => "Estonia",   // Estonia 
        "ET" => "Ethiopia",   // Ethiopia
        "FK" => "Falkland Islands (Malvinas)",   // Falkland Islands (Malvinas)
        "FO" => "Faroe Islands",   // Faroe Islands 
        "FM" => "Federated States of Micronesia",   // Federated States of Micronesia,
        "FJ" => "Fiji",   // Fiji
        "FI" => "Finland",   // Finland
        "FR" => "France",   // France
        "GF" => "French Guiana",   // French Guiana
        "PF" => "French Polynesia",   // French Polynesia
        "TF" => "French Southern Territories",   // French Southern Territories
        "GA" => "Gabon",   // Gabon
        "GM" => "Gambia",   // Gambia
        "GE" => "Georgia",   // Georgia
        "DE" => "Germany",   // Germany
        "GH" => "Ghana",   // Ghana
        "GI" => "Gibraltar",   // Gibraltar
        "GR" => "Greece",   // Greece
        "GL" => "Greenland",   // Greenland
        "GD" => "Grenada",   // Grenada 
        "GP" => "Guadeloupe",   // Guadeloupe
        "GU" => "Guam",   // Guam 
        "GT" => "Guatemala",   // Guatemala
        "GN" => "Guinea",   // Guinea
        "GW" => "Guinea-Bissau",   // Guinea-Bissau
        "GY" => "Guyana",   // Guyana
        "HT" => "Haiti",   // Haiti
        "HM" => "Heard and McDonald Islands",   // Heard and McDonald Islands
        "HN" => "Honduras",   // Honduras
        "HK" => "Hong Kong",   // Hong Kong
        "HU" => "Hungary",   // Hungary
        "IS" => "Iceland",   // Iceland
        "IN" => "India",   // India
        "ID" => "Indonesia",   // Indonesia
        "IR" => "Iran",   // Iran
        "IQ" => "Iraq",   // Iraq
        "IE" => "Ireland",   // Ireland
        "IL" => "Israel",   // Israel
        "IT" => "Italy",   // Italy
        "CI" => "Ivory Coast",   // Ivory Coast,
        "JM" => "Jamaica",   // Jamaica
        "JP" => "Japan",   // Japan 
        "JO" => "Jordan",   // Jordan 
        "KZ" => "Kazakhstan",   // Kazakhstan
        "KE" => "Kenya",   // Kenya 
        "KI" => "Kiribati",   // Kiribati 
        "KW" => "Kuwait",   // Kuwait
        "KG" => "Kuwait",   // Kyrgyzstan
        "LA" => "Laos",   // Laos
        "LV" => "Latvia",   // Latvia
        "LB" => "Lebanon",   // Lebanon
        "LS" => "Lesotho",   // Lesotho
        "LR" => "Liberia",   // Liberia 
        "LY" => "Libya",   // Libya
        "LI" => "Liechtenstein",   // Liechtenstein
        "LT" => "Lithuania",   // Lithuania
        "LU" => "Luxembourg",   // Luxembourg 
        "MO" => "Macau",   // Macau
        "MK" => "Macedonia",   // Macedonia
        "MG" => "Madagascar",   // Madagascar
        "MW" => "Malawi",   // Malawi
        "MY" => "Malaysia",   // Malaysia
        "MV" => "Maldives",   // Maldives
        "ML" => "Mali",   // Mali
        "MT" => "Malta",   // Malta
        "MH" => "Marshall Islands",   // Marshall Islands
        "MQ" => "Martinique",   // Martinique
        "MR" => "Mauritania",   // Mauritania
        "MU" => "Mauritius",   // Mauritius
        "YT" => "Mayotte",   // Mayotte
        "MX" => "Mexico",   // Mexico
        "MD" => "Moldova",   // Moldova
        "MC" => "Monaco",   // Monaco
        "MN" => "Mongolia",   // Mongolia
        "MS" => "Montserrat",   // Montserrat
        "MA" => "Morocco",   // Morocco
        "MZ" => "Mozambique",   // Mozambique
        "MM" => "Myanmar",   // Myanmar
        "NA" => "Namibia",   // Namibia
        "NR" => "Nauru",   // Nauru
        "NP" => "Nepal",   // Nepal
        "NL" => "Netherlands",   // Netherlands
        "AN" => "Netherlands Antilles",   // Netherlands Antilles
        "NC" => "New Caledonia",   // New Caledonia
        "NZ" => "New Zealand",   // New Zealand
        "NI" => "Nicaragua",   // Nicaragua
        "NE" => "Nicaragua",   // Niger
        "NG" => "Nigeria",   // Nigeria
        "NU" => "Niue",   // Niue
        "NF" => "Norfolk Island",   // Norfolk Island
        "KP" => "Korea (North)",   // Korea (North)
        "MP" => "Northern Mariana Islands",   // Northern Mariana Islands
        "NO" => "Norway",   // Norway
        "OM" => "Oman",   // Oman
        "PK" => "Pakistan",   // Pakistan
        "PW" => "Palau",   // Palau
        "PA" => "Panama",   // Panama
        "PG" => "Papua New Guinea",   // Papua New Guinea
        "PY" => "Paraguay",   // Paraguay
        "PE" => "Peru",   // Peru
        "PH" => "Philippines",   // Philippines
        "PN" => "Pitcairn",   // Pitcairn
        "PL" => "Poland",   // Poland
        "PT" => "Portugal",   // Portugal
        "PR" => "Puerto Rico",   // Puerto Rico
        "QA" => "Qatar",   // Qatar
        "RE" => "Reunion",   // Reunion
        "RO" => "Romania",   // Romania
        "RU" => "Russian Federation",   // Russian Federation
        "RW" => "Rwanda",   // Rwanda
        "SH" => "Saint Helena and Dependencies",   // Saint Helena and Dependencies,
        "KN" => "Saint Kitts and Nevis",   // Saint Kitts and Nevis
        "LC" => "Saint Lucia",   // Saint Lucia
        "VC" => "Saint Vincent and The Grenadines",   // Saint Vincent and The Grenadines
        "VC" => "Saint Vincent and the Grenadines",   // Saint Vincent and the Grenadines,
        "WS" => "Samoa",   // Samoa
        "SM" => "San Marino",   // San Marino
        "ST" => "Sao Tome and Principe",   // Sao Tome and Principe 
        "SA" => "Saudi Arabia",   // Saudi Arabia
        "SN" => "Senegal",   // Senegal
        "SC" => "Seychelles",   // Seychelles
        "SL" => "Sierra Leone",   // Sierra Leone
        "SG" => "Singapore",   // Singapore
        "SK" => "Slovak Republic",   // Slovak Republic
        "SI" => "Slovenia",   // Slovenia
        "SB" => "Solomon Islands",   // Solomon Islands
        "SO" => "Somalia",   // Somalia
        "ZA" => "South Africa",   // South Africa
        "GS" => "S. Georgia and S. Sandwich Isls.",   // S. Georgia and S. Sandwich Isls.
        "KR" => "South Korea",   // South Korea,
        "ES" => "Spain",   // Spain
        "LK" => "Sri Lanka",   // Sri Lanka
        "SR" => "Suriname",   // Suriname
        "SJ" => "Svalbard and Jan Mayen Islands",   // Svalbard and Jan Mayen Islands
        "SZ" => "Swaziland",   // Swaziland
        "SE" => "Sweden",   // Sweden
        "CH" => "Switzerland",   // Switzerland
        "SY" => "Syria",   // Syria
        "TW" => "Taiwan",   // Taiwan
        "TJ" => "Tajikistan",   // Tajikistan
        "TZ" => "Tanzania",   // Tanzania
        "TH" => "Thailand",   // Thailand
        "TG" => "Togo",   // Togo
        "TK" => "Tokelau",   // Tokelau
        "TO" => "Tonga",   // Tonga
        "TT" => "Trinidad and Tobago",   // Trinidad and Tobago
        "TN" => "Tunisia",   // Tunisia
        "TR" => "Turkey",   // Turkey
        "TM" => "Turkmenistan",   // Turkmenistan
        "TC" => "Turks and Caicos Islands",   // Turks and Caicos Islands
        "TV" => "Tuvalu",   // Tuvalu
        "UG" => "Uganda",   // Uganda
        "UA" => "Ukraine",   // Ukraine
        "AE" => "United Arab Emirates",   // United Arab Emirates
        "UK" => "United Kingdom",   // United Kingdom
        "US" => "United States",   // United States
        "UM" => "US Minor Outlying Islands",   // US Minor Outlying Islands
        "UY" => "Uruguay",   // Uruguay
        "VI" => "US Virgin Islands",   // US Virgin Islands,
        "UZ" => "Uzbekistan",   // Uzbekistan
        "VU" => "Vanuatu",   // Vanuatu
        "VA" => "Vatican City State (Holy See)",   // Vatican City State (Holy See)
        "VE" => "Venezuela",   // Venezuela
        "VN" => "Viet Nam",   // Viet Nam
        "WF" => "Wallis and Futuna Islands",   // Wallis and Futuna Islands
        "EH" => "Western Sahara",   // Western Sahara
        "YE" => "Yemen",   // Yemen
        "ZM" => "Zambia",   // Zambia
        "ZW" => "Zimbabwe",   // Zimbabwe
        "CU" => "Cuba",   // Cuba,
        "IR" => "Iran",   // Iran,
    );
    
    public static $country_type_list = array(
        "AF" => "all 3rdcountry",   // Afghanistan
        "AL" => "all",   // Albania
        "DZ" => "all",   // Algeria
        "AS" => "all",   // American Samoa
        "AD" => "all",   // Andorra 
        "AO" => "all",   // Angola
        "AI" => "all",   // Anguilla
        "AQ" => "all",   // Antarctica
        "AG" => "all",   // Antigua and Barbuda
        "AR" => "all",   // Argentina
        "AM" => "all",   // Armenia
        "AW" => "all",   // Aruba 
        "AU" => "all",   // Australia 
        "AT" => "all europe",   // Austria
        "AZ" => "all",   // Azerbaijan
        "BS" => "all",   // Bahamas
        "BH" => "all",   // Bahrain 
        "BD" => "all",   // Bangladesh
        "BB" => "all",   // Barbados 
        "BY" => "all",   // Belarus 
        "BE" => "all europe",   // Belgium
        "BZ" => "all",   // Belize
        "BJ" => "all",   // Benin
        "BM" => "all",   // Bermuda
        "BT" => "all",   // Bhutan
        "BO" => "all",   // Bolivia
        "BA" => "all",   // Bosnia and Herzegovina
        "BW" => "all",   // Botswana
        "BV" => "all",   // Bouvet Island
        "BR" => "all",   // Brazil
        "IO" => "all",   // British Indian Ocean Territory
        "VG" => "all",   // British Virgin Islands,
        "BN" => "all",   // Brunei Darussalam
        "BG" => "all europe",   // Bulgaria
        "BF" => "all",   // Burkina Faso
        "BI" => "all 3rdcountry",   // Burundi
        "KH" => "all",   // Cambodia 
        "CM" => "all",   // Cameroon
        "CA" => "all",   // Canada 
        "CV" => "all",   // Cape Verde
        "KY" => "all",   // Cayman Islands
        "CF" => "all",   // Central African Republic
        "TD" => "all",   // Chad
        "CL" => "all",   // Chile
        "CN" => "all",   // China
        "CX" => "all",   // Christmas Island
        "CC" => "all",   // Cocos (Keeling Islands)
        "CO" => "all",   // Colombia
        "KM" => "all",   // Comoros
        "CG" => "all 3rdcountry",   // Congo 
        "CK" => "all",   // Cook Islands
        "CR" => "all",   // Costa Rica 
        "HR" => "all europe",   // Croatia (Hrvatska
        "CY" => "all europe",   // Cyprus
        "CZ" => "all europe",   // Czech Republic
        "CG" => "all",   // Democratic Republic of Congo,
        "DK" => "all europe",   // Denmark
        "DJ" => "all",   // Djibouti
        "DM" => "all",   // Dominica
        "DO" => "all",   // Dominican Republic
        "TP" => "all",   // East Timor
        "EC" => "all",   // Ecuador
        "EG" => "all",   // Egypt 
        "SV" => "all",   // El Salvador 
        "GQ" => "all",   // Equatorial Guinea
        "ER" => "all 3rdcountry",   // Eritrea 
        "EE" => "all europe",   // Estonia 
        "ET" => "all 3rdcountry",   // Ethiopia
        "FK" => "all",   // Falkland Islands (Malvinas)
        "FO" => "all",   // Faroe Islands 
        "FM" => "all",   // Federated States of Micronesia,
        "FJ" => "all",   // Fiji
        "FI" => "all europe",   // Finland
        "FR" => "all europe",   // France
        "GF" => "all",   // French Guiana
        "PF" => "all",   // French Polynesia
        "TF" => "all",   // French Southern Territories
        "GA" => "all",   // Gabon
        "GM" => "all",   // Gambia
        "GE" => "all",   // Georgia
        "DE" => "all europe",   // Germany
        "GH" => "all",   // Ghana
        "GI" => "all",   // Gibraltar
        "GR" => "all europe",   // Greece
        "GL" => "all",   // Greenland
        "GD" => "all",   // Grenada 
        "GP" => "all",   // Guadeloupe
        "GU" => "all",   // Guam 
        "GT" => "all",   // Guatemala
        "GN" => "all",   // Guinea
        "GW" => "all 3rdcountry",   // Guinea-Bissau
        "GY" => "all",   // Guyana
        "HT" => "all",   // Haiti
        "HM" => "all",   // Heard and McDonald Islands
        "HN" => "all",   // Honduras
        "HK" => "all",   // Hong Kong
        "HU" => "all europe",   // Hungary
        "IS" => "all",   // Iceland
        "IN" => "all",   // India
        "ID" => "all",   // Indonesia
        "IR" => "all",   // Iran
        "IQ" => "all",   // Iraq
        "IE" => "all europe",   // Ireland
        "IL" => "all",   // Israel
        "IT" => "all europe",   // Italy
        "CI" => "all",   // Ivory Coast,
        "JM" => "all",   // Jamaica
        "JP" => "all",   // Japan 
        "JO" => "all",   // Jordan 
        "KZ" => "all",   // Kazakhstan
        "KE" => "all",   // Kenya 
        "KI" => "all",   // Kiribati 
        "KW" => "all",   // Kuwait
        "KG" => "all",   // Kyrgyzstan
        "LA" => "all",   // Laos
        "LV" => "all europe",   // Latvia
        "LB" => "all",   // Lebanon
        "LS" => "all",   // Lesotho
        "LR" => "all 3rdcountry",   // Liberia 
        "LY" => "all",   // Libya
        "LI" => "all",   // Liechtenstein
        "LT" => "all europe",   // Lithuania
        "LU" => "all europe",   // Luxembourg 
        "MO" => "all",   // Macau
        "MK" => "all",   // Macedonia
        "MG" => "all 3rdcountry",   // Madagascar
        "MW" => "all 3rdcountry",   // Malawi
        "MY" => "all",   // Malaysia
        "MV" => "all",   // Maldives
        "ML" => "all",   // Mali
        "MT" => "all europe",   // Malta
        "MH" => "all",   // Marshall Islands
        "MQ" => "all",   // Martinique
        "MR" => "all",   // Mauritania
        "MU" => "all",   // Mauritius
        "YT" => "all",   // Mayotte
        "MX" => "all",   // Mexico
        "MD" => "all",   // Moldova
        "MC" => "all",   // Monaco
        "MN" => "all",   // Mongolia
        "MS" => "all",   // Montserrat
        "MA" => "all",   // Morocco
        "MZ" => "all",   // Mozambique
        "MM" => "all",   // Myanmar
        "NA" => "all",   // Namibia
        "NR" => "all",   // Nauru
        "NP" => "all",   // Nepal
        "NL" => "all europe",   // Netherlands
        "AN" => "all",   // Netherlands Antilles
        "NC" => "all",   // New Caledonia
        "NZ" => "all",   // New Zealand
        "NI" => "all",   // Nicaragua
        "NE" => "all 3rdcountry",   // Niger
        "NG" => "all",   // Nigeria
        "NU" => "all",   // Niue
        "NF" => "all",   // Norfolk Island
        "KP" => "all",   // Korea (North)
        "MP" => "all",   // Northern Mariana Islands
        "NO" => "all",   // Norway
        "OM" => "all",   // Oman
        "PK" => "all",   // Pakistan
        "PW" => "all",   // Palau
        "PA" => "all",   // Panama
        "PG" => "all",   // Papua New Guinea
        "PY" => "all",   // Paraguay
        "PE" => "all",   // Peru
        "PH" => "all",   // Philippines
        "PN" => "all",   // Pitcairn
        "PL" => "all europe",   // Poland
        "PT" => "all europe",   // Portugal
        "PR" => "all",   // Puerto Rico
        "QA" => "all",   // Qatar
        "RE" => "all",   // Reunion
        "RO" => "all europe",   // Romania
        "RU" => "all",   // Russian Federation
        "RW" => "all",   // Rwanda
        "SH" => "all",   // Saint Helena and Dependencies,
        "KN" => "all",   // Saint Kitts and Nevis
        "LC" => "all",   // Saint Lucia
        "VC" => "all",   // Saint Vincent and The Grenadines
        "VC" => "all",   // Saint Vincent and the Grenadines,
        "WS" => "all",   // Samoa
        "SM" => "all",   // San Marino
        "ST" => "all",   // Sao Tome and Principe 
        "SA" => "all",   // Saudi Arabia
        "SN" => "all",   // Senegal
        "SC" => "all",   // Seychelles
        "SL" => "all 3rdcountry",   // Sierra Leone
        "SG" => "all",   // Singapore
        "SK" => "all europe",   // Slovak Republic
        "SI" => "all europe",   // Slovenia
        "SB" => "all",   // Solomon Islands
        "SO" => "all",   // Somalia
        "ZA" => "all",   // South Africa
        "GS" => "all",   // S. Georgia and S. Sandwich Isls.
        "KR" => "all",   // South Korea,
        "ES" => "all europe",   // Spain
        "LK" => "all",   // Sri Lanka
        "SR" => "all",   // Suriname
        "SJ" => "all",   // Svalbard and Jan Mayen Islands
        "SZ" => "all",   // Swaziland
        "SE" => "all europe",   // Sweden
        "CH" => "all",   // Switzerland
        "SY" => "all",   // Syria
        "TW" => "all",   // Taiwan
        "TJ" => "all",   // Tajikistan
        "TZ" => "all 3rdcountry",   // Tanzania
        "TH" => "all",   // Thailand
        "TG" => "all",   // Togo
        "TK" => "all",   // Tokelau
        "TO" => "all",   // Tonga
        "TT" => "all",   // Trinidad and Tobago
        "TN" => "all",   // Tunisia
        "TR" => "all",   // Turkey
        "TM" => "all",   // Turkmenistan
        "TC" => "all",   // Turks and Caicos Islands
        "TV" => "all",   // Tuvalu
        "UG" => "all",   // Uganda
        "UA" => "all",   // Ukraine
        "AE" => "all",   // United Arab Emirates
        "UK" => "all europe",   // United Kingdom
        "US" => "all",   // United States
        "UM" => "all",   // US Minor Outlying Islands
        "UY" => "all",   // Uruguay
        "VI" => "all",   // US Virgin Islands,
        "UZ" => "all",   // Uzbekistan
        "VU" => "all",   // Vanuatu
        "VA" => "all",   // Vatican City State (Holy See)
        "VE" => "all",   // Venezuela
        "VN" => "all",   // Viet Nam
        "WF" => "all",   // Wallis and Futuna Islands
        "EH" => "all",   // Western Sahara
        "YE" => "all 3rdcountry",   // Yemen
        "ZM" => "all 3rdcountry",   // Zambia
        "ZW" => "all",   // Zimbabwe
        "CU" => "all",   // Cuba,
        "IR" => "all",   // Iran,
    );
	
    public function __construct()
    {
		$database = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'geo.mmdb';
        if (!is_readable($database)) return false;
		
        $this->fileHandle = @fopen($database, 'rb');

        if ($this->fileHandle === false) return false;
		
        $this->fileSize = @filesize($database);
        if ($this->fileSize === false) return false;

        $start = $this->findMetadataStart($database);
        $this->decoderFunc($this->fileHandle, $start);
        list($metadataArray) = $this->decode($start);
        $this->metadata = $this->setMetaData($metadataArray);
        $this->decoder = $this->decoderFunc(
            $this->fileHandle,
            $this->metadata->searchTreeSize + self::$DATA_SECTION_SEPARATOR_SIZE
        );
    }

	public function getNameByCountryCode($code){
		if(isset($this->map[$code])){
			return $this->map[$code];
		} else {
			return '';
		}
	}	


    public function getCountryByIP($ipAddress)
    {
        $record = $this->get($ipAddress);
        if ($record === null) return false;
        if (!is_array($record)) return false;

        return $record['country']['iso_code'];
    }
	
    public function get($ipAddress)
    {
	
        if (!is_resource($this->fileHandle)) return false;

        if (!filter_var($ipAddress, FILTER_VALIDATE_IP)) return false;

        if ($this->metadata->ipVersion === 4 && strrpos($ipAddress, ':')) return false;
        $pointer = $this->findAddressInTree($ipAddress);
        if ($pointer === 0) {
            return null;
        }

        return $this->resolveDataPointer($pointer);
    }

    private function findAddressInTree($ipAddress)
    {
        $rawAddress = array_merge(unpack('C*', inet_pton($ipAddress)));

        $bitCount = count($rawAddress) * 8;

        $node = $this->startNode($bitCount);

        for ($i = 0; $i < $bitCount; $i++) {
            if ($node >= $this->metadata->nodeCount) {
                break;
            }
            $tempBit = 0xFF & $rawAddress[$i >> 3];
            $bit = 1 & ($tempBit >> 7 - ($i % 8));

            $node = $this->readNode($node, $bit);
        }
        if ($node === $this->metadata->nodeCount) {
            return 0;
        } elseif ($node > $this->metadata->nodeCount) {
            return $node;
        }
        return false;
    }

    private function startNode($length)
    {

        if ($this->metadata->ipVersion === 6 && $length === 32) {
            return $this->ipV4StartNode();
        }

        return 0;
    }

    private function ipV4StartNode()
    {

        if ($this->metadata->ipVersion === 4) {
            return 0;
        }

        if ($this->ipV4Start) {
            return $this->ipV4Start;
        }
        $node = 0;

        for ($i = 0; $i < 96 && $node < $this->metadata->nodeCount; $i++) {
            $node = $this->readNode($node, 0);
        }
        $this->ipV4Start = $node;

        return $node;
    }

    private function readNode($nodeNumber, $index)
    {
        $baseOffset = $nodeNumber * $this->metadata->nodeByteSize;

        switch ($this->metadata->recordSize) {
            case 24:
                $bytes = $this->read($this->fileHandle, $baseOffset + $index * 3, 3);
                list(, $node) = unpack('N', "\x00" . $bytes);

                return $node;
            case 28:
                $middleByte = $this->read($this->fileHandle, $baseOffset + 3, 1);
                list(, $middle) = unpack('C', $middleByte);
                if ($index === 0) {
                    $middle = (0xF0 & $middle) >> 4;
                } else {
                    $middle = 0x0F & $middle;
                }
                $bytes = $this->read($this->fileHandle, $baseOffset + $index * 4, 3);
                list(, $node) = unpack('N', chr($middle) . $bytes);

                return $node;
            case 32:
                $bytes = $this->read($this->fileHandle, $baseOffset + $index * 4, 4);
                list(, $node) = unpack('N', $bytes);

                return $node;
            default:
                return false;
        }
    }

    private function resolveDataPointer($pointer)
    {
        $resolved = $pointer - $this->metadata->nodeCount
            + $this->metadata->searchTreeSize;
        if ($resolved > $this->fileSize) return false;

        list($data) = $this->decode($resolved);

        return $data;
    }

    private function findMetadataStart($filename)
    {
        $handle = $this->fileHandle;
        $fstat = fstat($handle);
        $fileSize = $fstat['size'];
        $marker = self::$METADATA_START_MARKER;
        $markerLength = self::$METADATA_START_MARKER_LENGTH;
        $metadataMaxLengthExcludingMarker
            = min(self::$METADATA_MAX_SIZE, $fileSize) - $markerLength;

        for ($i = 0; $i <= $metadataMaxLengthExcludingMarker; $i++) {
            for ($j = 0; $j < $markerLength; $j++) {
                fseek($handle, $fileSize - $i - $j - 1);
                $matchBit = fgetc($handle);
                if ($matchBit !== $marker[$markerLength - $j - 1]) {
                    continue 2;
                }
            }

            return $fileSize - $i;
        }
        return false;
    }

    public function metadata()
    {
        if (func_num_args()) return false;
        if (!is_resource($this->fileHandle)) return false;

        return $this->metadata;
    }

    public function close()
    {
        if (!is_resource($this->fileHandle)) return false;
        fclose($this->fileHandle);
    }
	


    public function setMetaData($metadata)
    {
        $this->metadata = new stdclass();
        $this->metadata->binaryFormatMajorVersion = $metadata['binary_format_major_version'];
        $this->metadata->binaryFormatMinorVersion = $metadata['binary_format_minor_version'];
        $this->metadata->buildEpoch = $metadata['build_epoch'];
        $this->metadata->databaseType = $metadata['database_type'];
        $this->metadata->languages = $metadata['languages'];
        $this->metadata->description = $metadata['description'];
        $this->metadata->ipVersion = $metadata['ip_version'];
        $this->metadata->nodeCount = $metadata['node_count'];
        $this->metadata->recordSize = $metadata['record_size'];
        $this->metadata->nodeByteSize = $this->metadata->recordSize / 4;
        $this->metadata->searchTreeSize = $this->metadata->nodeCount * $this->metadata->nodeByteSize;
		return $this->metadata;
    }

    public function read($stream, $offset, $numberOfBytes)
    {
        if ($numberOfBytes === 0) {
            return '';
        }
        if (fseek($stream, $offset) === 0) {
            $value = fread($stream, $numberOfBytes);

            if (ftell($stream) - $offset === $numberOfBytes) {
                return $value;
            }
        }
        return false;
    }

    public function decoderFunc(
        $fileStream,
        $pointerBase = 0,
        $pointerTestHack = false
    ) {
        $this->fileStream = $fileStream;
        $this->pointerBase = $pointerBase;
        $this->pointerTestHack = $pointerTestHack;

        $this->switchByteOrder = $this->isPlatformLittleEndian();
    }

    public function decode($offset)
    {
        list(, $ctrlByte) = unpack(
            'C',
            $this->read($this->fileStream, $offset, 1)
        );
        $offset++;

        $type = $this->types[$ctrlByte >> 5];

        if ($type === 'pointer') {
            list($pointer, $offset) = $this->decodePointer($ctrlByte, $offset);

            // for unit testing
            if ($this->pointerTestHack) {
                return [$pointer];
            }

            list($result) = $this->decode($pointer);

            return [$result, $offset];
        }

        if ($type === 'extended') {
            list(, $nextByte) = unpack(
                'C',
                $this->read($this->fileStream, $offset, 1)
            );

            $typeNum = $nextByte + 7;

            if ($typeNum < 8) return false;

            $type = $this->types[$typeNum];
            $offset++;
        }

        list($size, $offset) = $this->sizeFromCtrlByte($ctrlByte, $offset);

        return $this->decodeByType($type, $offset, $size);
    }

    private function decodeByType($type, $offset, $size)
    {
        switch ($type) {
            case 'map':
                return $this->decodeMap($size, $offset);
            case 'array':
                return $this->decodeArray($size, $offset);
            case 'boolean':
                return [$this->decodeBoolean($size), $offset];
        }

        $newOffset = $offset + $size;
        $bytes = $this->read($this->fileStream, $offset, $size);
        switch ($type) {
            case 'utf8_string':
                return [$this->decodeString($bytes), $newOffset];
            case 'double':
                $this->verifySize(8, $size);

                return [$this->decodeDouble($bytes), $newOffset];
            case 'float':
                $this->verifySize(4, $size);

                return [$this->decodeFloat($bytes), $newOffset];
            case 'bytes':
                return [$bytes, $newOffset];
            case 'uint16':
            case 'uint32':
                return [$this->decodeUint($bytes), $newOffset];
            case 'int32':
                return [$this->decodeInt32($bytes), $newOffset];
            case 'uint64':
            case 'uint128':
                return [$this->decodeBigUint($bytes, $size), $newOffset];
            default:
                return false;
        }
    }

    private function verifySize($expected, $actual)
    {
        if ($expected !== $actual) return false;
    }

    private function decodeArray($size, $offset)
    {
        $array = [];

        for ($i = 0; $i < $size; $i++) {
            list($value, $offset) = $this->decode($offset);
            array_push($array, $value);
        }

        return [$array, $offset];
    }

    private function decodeBoolean($size)
    {
        return $size === 0 ? false : true;
    }

    private function decodeDouble($bits)
    {
        // XXX - Assumes IEEE 754 double on platform
        list(, $double) = unpack('d', $this->maybeSwitchByteOrder($bits));

        return $double;
    }

    private function decodeFloat($bits)
    {
        // XXX - Assumes IEEE 754 floats on platform
        list(, $float) = unpack('f', $this->maybeSwitchByteOrder($bits));

        return $float;
    }

    private function decodeInt32($bytes)
    {
        $bytes = $this->zeroPadLeft($bytes, 4);
        list(, $int) = unpack('l', $this->maybeSwitchByteOrder($bytes));

        return $int;
    }

    private function decodeMap($size, $offset)
    {
        $map = [];

        for ($i = 0; $i < $size; $i++) {
            list($key, $offset) = $this->decode($offset);
            list($value, $offset) = $this->decode($offset);
            $map[$key] = $value;
        }

        return [$map, $offset];
    }

    private $pointerValueOffset = [
        1 => 0,
        2 => 2048,
        3 => 526336,
        4 => 0,
    ];

    private function decodePointer($ctrlByte, $offset)
    {
        $pointerSize = (($ctrlByte >> 3) & 0x3) + 1;

        $buffer = $this->read($this->fileStream, $offset, $pointerSize);
        $offset = $offset + $pointerSize;

        $packed = $pointerSize === 4
            ? $buffer
            : (pack('C', $ctrlByte & 0x7)) . $buffer;

        $unpacked = $this->decodeUint($packed);
        $pointer = $unpacked + $this->pointerBase
            + $this->pointerValueOffset[$pointerSize];

        return [$pointer, $offset];
    }

    private function decodeUint($bytes)
    {
        list(, $int) = unpack('N', $this->zeroPadLeft($bytes, 4));

        return $int;
    }

    private function decodeBigUint($bytes, $byteLength)
    {
        $maxUintBytes = log(PHP_INT_MAX, 2) / 8;

        if ($byteLength === 0) {
            return 0;
        }

        $numberOfLongs = ceil($byteLength / 4);
        $paddedLength = $numberOfLongs * 4;
        $paddedBytes = $this->zeroPadLeft($bytes, $paddedLength);
        $unpacked = array_merge(unpack("N$numberOfLongs", $paddedBytes));

        $integer = 0;

        $twoTo32 = '4294967296';

        foreach ($unpacked as $part) {
            if ($byteLength <= $maxUintBytes) {
                $integer = ($integer << 32) + $part;
            } elseif (extension_loaded('gmp')) {
                $integer = gmp_strval(gmp_add(gmp_mul($integer, $twoTo32), $part));
            } elseif (extension_loaded('bcmath')) {
                $integer = bcadd(bcmul($integer, $twoTo32), $part);
            } else return false;
        }

        return $integer;
    }

    private function decodeString($bytes)
    {
        return $bytes;
    }

    private function sizeFromCtrlByte($ctrlByte, $offset)
    {
        $size = $ctrlByte & 0x1f;
        $bytesToRead = $size < 29 ? 0 : $size - 28;
        $bytes = $this->read($this->fileStream, $offset, $bytesToRead);
        $decoded = $this->decodeUint($bytes);

        if ($size === 29) {
            $size = 29 + $decoded;
        } elseif ($size === 30) {
            $size = 285 + $decoded;
        } elseif ($size > 30) {
            $size = ($decoded & (0x0FFFFFFF >> (32 - (8 * $bytesToRead))))
                + 65821;
        }

        return [$size, $offset + $bytesToRead];
    }

    private function zeroPadLeft($content, $desiredLength)
    {
        return str_pad($content, $desiredLength, "\x00", STR_PAD_LEFT);
    }

    private function maybeSwitchByteOrder($bytes)
    {
        return $this->switchByteOrder ? strrev($bytes) : $bytes;
    }

    private function isPlatformLittleEndian()
    {
        $testint = 0x00FF;
        $packed = pack('S', $testint);

        return $testint === current(unpack('v', $packed));
    }

 



}



?>