text:
<?php
/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org>               //
//  available at http://getid3.sourceforge.net                 //
//            or http://www.getid3.org                         //
/////////////////////////////////////////////////////////////////
//                                                             //
// getid3.lib.php - part of getID3()                           //
// See readme.txt for more details                             //
//                                                            ///
/////////////////////////////////////////////////////////////////

class getid3_lib
{

	public static function PrintHexBytes($string, $hex=true, $spaces=true, $htmlencoding='UTF-8') {
		$returnstring = '';
		for ($i = 0; $i < strlen($string); $i++) {
			if ($hex) {
				$returnstring .= str_pad(dechex(ord($string{$i})), 2, '0', STR_PAD_LEFT);
			} else {
				$returnstring .= ' '.(preg_match("#[\x20-\x7E]#", $string{$i}) ? $string{$i} : '¤');
			}
			if ($spaces) {
				$returnstring .= ' ';
			}
		}
		if (!empty($htmlencoding)) {
			if ($htmlencoding === true) {
				$htmlencoding = 'UTF-8'; // prior to getID3 v1.9.0 the function's 4th parameter was boolean
			}
			$returnstring = htmlentities($returnstring, ENT_QUOTES, $htmlencoding);
		}
		return $returnstring;
	}

	public static function trunc($floatnumber) {
		// truncates a floating-point number at the decimal point
		// returns int (if possible, otherwise float)
		if ($floatnumber >= 1) {
			$truncatednumber = floor($floatnumber);
		} elseif ($floatnumber <= -1) {
			$truncatednumber = ceil($floatnumber);
		} else {
			$truncatednumber = 0;
		}
		if (self::intValueSupported($truncatednumber)) {
			$truncatednumber = (int) $truncatednumber;
		}
		return $truncatednumber;
	}

	public static function safe_inc(&$variable, $increment=1) {
		if (isset($variable)) {
			$variable += $increment;
		} else {
			$variable = $increment;
		}
		return true;
	}

	public static function CastAsInt($floatnum) {
		// convert to float if not already
		$floatnum = (float) $floatnum;

		// convert a float to type int, only if possible
		if (self::trunc($floatnum) == $floatnum) {
			// it's not floating point
			if (self::intValueSupported($floatnum)) {
				// it's within int range
				$floatnum = (int) $floatnum;
			}
		}
		return $floatnum;
	}

	public static function intValueSupported($num) {
		// check if integers are 64-bit
		static $hasINT64 = null;
		if ($hasINT64 === null) { // 10x faster than is_null()
			$hasINT64 = is_int(pow(2, 31)); // 32-bit int are limited to (2^31)-1
			if (!$hasINT64 && !defined('PHP_INT_MIN')) {
				define('PHP_INT_MIN', ~PHP_INT_MAX);
			}
		}
		// if integers are 64-bit - no other check required
		if ($hasINT64 || (($num <= PHP_INT_MAX) && ($num >= PHP_INT_MIN))) {
			return true;
		}
		return false;
	}

	public static function DecimalizeFraction($fraction) {
		list($numerator, $denominator) = explode('/', $fraction);
		return $numerator / ($denominator ? $denominator : 1);
	}

	public static function DecimalBinary2Float($binarynumerator) {
		$numerator   = self::Bin2Dec($binarynumerator);
		$denominator = self::Bin2Dec('1'.str_repeat('0', strlen($binarynumerator)));
		return ($numerator / $denominator);
	}

	public static function NormalizeBinaryPoint($binarypointnumber, $maxbits=52) {
		// http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/binary.html
		if (strpos($binarypointnumber, '.') === false) {
			$binarypointnumber = '0.'.$binarypointnumber;
		} elseif ($binarypointnumber{0} == '.') {
			$binarypointnumber = '0'.$binarypointnumber;
		}
		$exponent = 0;
		while (($binarypointnumber{0} != '1') || (substr($binarypointnumber, 1, 1) != '.')) {
			if (substr($binarypointnumber, 1, 1) == '.') {
				$exponent--;
				$binarypointnumber = substr($binarypointnumber, 2, 1).'.'.substr($binarypointnumber, 3);
			} else {
				$pointpos = strpos($binarypointnumber, '.');
				$exponent += ($pointpos - 1);
				$binarypointnumber = str_replace('.', '', $binarypointnumber);
				$binarypointnumber = $binarypointnumber{0}.'.'.substr($binarypointnumber, 1);
			}
		}
		$binarypointnumber = str_pad(substr($binarypointnumber, 0, $maxbits + 2), $maxbits + 2, '0', STR_PAD_RIGHT);
		return array('normalized'=>$binarypointnumber, 'exponent'=>(int) $exponent);
	}

	public static function Float2BinaryDecimal($floatvalue) {
		// http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/binary.html
		$maxbits = 128; // to how many bits of precision should the calculations be taken?
		$intpart   = self::trunc($floatvalue);
		$floatpart = abs($floatvalue - $intpart);
		$pointbitstring = '';
		while (($floatpart != 0) && (strlen($pointbitstring) < $maxbits)) {
			$floatpart *= 2;
			$pointbitstring .= (string) self::trunc($floatpart);
			$floatpart -= self::trunc($floatpart);
		}
		$binarypointnumber = decbin($intpart).'.'.$pointbitstring;
		return $binarypointnumber;
	}

	public static function Float2String($floatvalue, $bits) {
		// http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee-expl.html
		switch ($bits) {
			case 32:
				$exponentbits = 8;
				$fractionbits = 23;
				break;

			case 64:
				$exponentbits = 11;
				$fractionbits = 52;
				break;

			default:
				return false;
				break;
		}
		if ($floatvalue >= 0) {
			$signbit = '0';
		} else {
			$signbit = '1';
		}
		$normalizedbinary  = self::NormalizeBinaryPoint(self::Float2BinaryDecimal($floatvalue), $fractionbits);
		$biasedexponent    = pow(2, $exponentbits - 1) - 1 + $normalizedbinary['exponent']; // (127 or 1023) +/- exponent
		$exponentbitstring = str_pad(decbin($biasedexponent), $exponentbits, '0', STR_PAD_LEFT);
		$fractionbitstring = str_pad(substr($normalizedbinary['normalized'], 2), $fractionbits, '0', STR_PAD_RIGHT);

		return self::BigEndian2String(self::Bin2Dec($signbit.$exponentbitstring.$fractionbitstring), $bits % 8, false);
	}

	public static function LittleEndian2Float($byteword) {
		return self::BigEndian2Float(strrev($byteword));
	}

	public static function BigEndian2Float($byteword) {
		// ANSI/IEEE Standard 754-1985, Standard for Binary Floating Point Arithmetic
		// http://www.psc.edu/general/software/packages/ieee/ieee.html
		// http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee.html

		$bitword = self::BigEndian2Bin($byteword);
		if (!$bitword) {
			return 0;
		}
		$signbit = $bitword{0};

		switch (strlen($byteword) * 8) {
			case 32:
				$exponentbits = 8;
				$fractionbits = 23;
				break;

			case 64:
				$exponentbits = 11;
				$fractionbits = 52;
				break;

			case 80:
				// 80-bit Apple SANE format
				// http://www.mactech.com/articles/mactech/Vol.06/06.01/SANENormalized/
				$exponentstring = substr($bitword, 1, 15);
				$isnormalized = intval($bitword{16});
				$fractionstring = substr($bitword, 17, 63);
				$exponent = pow(2, self::Bin2Dec($exponentstring) - 16383);
				$fraction = $isnormalized + self::DecimalBinary2Float($fractionstring);
				$floatvalue = $exponent * $fraction;
				if ($signbit == '1') {
					$floatvalue *= -1;
				}
				return $floatvalue;
				break;

			default:
				return false;
				break;
		}
		$exponentstring = substr($bitword, 1, $exponentbits);
		$fractionstring = substr($bitword, $exponentbits + 1, $fractionbits);
		$exponent = self::Bin2Dec($exponentstring);
		$fraction = self::Bin2Dec($fractionstring);

		if (($exponent == (pow(2, $exponentbits) - 1)) && ($fraction != 0)) {
			// Not a Number
			$floatvalue = false;
		} elseif (($exponent == (pow(2, $exponentbits) - 1)) && ($fraction == 0)) {
			if ($signbit == '1') {
				$floatvalue = '-infinity';
			} else {
				$floatvalue = '+infinity';
			}
		} elseif (($exponent == 0) && ($fraction == 0)) {
			if ($signbit == '1') {
				$floatvalue = -0;
			} else {
				$floatvalue = 0;
			}
			$floatvalue = ($signbit ? 0 : -0);
		} elseif (($exponent == 0) && ($fraction != 0)) {
			// These are 'unnormalized' values
			$floatvalue = pow(2, (-1 * (pow(2, $exponentbits - 1) - 2))) * self::DecimalBinary2Float($fractionstring);
			if ($signbit == '1') {
				$floatvalue *= -1;
			}
		} elseif ($exponent != 0) {
			$floatvalue = pow(2, ($exponent - (pow(2, $exponentbits - 1) - 1))) * (1 + self::DecimalBinary2Float($fractionstring));
			if ($signbit == '1') {
				$floatvalue *= -1;
			}
		}
		return (float) $floatvalue;
	}

	public static function BigEndian2Int($byteword, $synchsafe=false, $signed=false) {
		$intvalue = 0;
		$bytewordlen = strlen($byteword);
		if ($bytewordlen == 0) {
			return false;
		}
		for ($i = 0; $i < $bytewordlen; $i++) {
			if ($synchsafe) { // disregard MSB, effectively 7-bit bytes
				//$intvalue = $intvalue | (ord($byteword{$i}) & 0x7F) << (($bytewordlen - 1 - $i) * 7); // faster, but runs into problems past 2^31 on 32-bit systems
				$intvalue += (ord($byteword{$i}) & 0x7F) * pow(2, ($bytewordlen - 1 - $i) * 7);
			} else {
				$intvalue += ord($byteword{$i}) * pow(256, ($bytewordlen - 1 - $i));
			}
		}
		if ($signed && !$synchsafe) {
			// synchsafe ints are not allowed to be signed
			if ($bytewordlen <= PHP_INT_SIZE) {
				$signMaskBit = 0x80 << (8 * ($bytewordlen - 1));
				if ($intvalue & $signMaskBit) {
					$intvalue = 0 - ($intvalue & ($signMaskBit - 1));
				}
			} else {
				throw new Exception('ERROR: Cannot have signed integers larger than '.(8 * PHP_INT_SIZE).'-bits ('.strlen($byteword).') in self::BigEndian2Int()');
				break;
			}
		}
		return self::CastAsInt($intvalue);
	}

	public static function LittleEndian2Int($byteword, $signed=false) {
		return self::BigEndian2Int(strrev($byteword), false, $signed);
	}

	public static function BigEndian2Bin($byteword) {
		$binvalue = '';
		$bytewordlen = strlen($byteword);
		for ($i = 0; $i < $bytewordlen; $i++) {
			$binvalue .= str_pad(decbin(ord($byteword{$i})), 8, '0', STR_PAD_LEFT);
		}
		return $binvalue;
	}

	public static function BigEndian2String($number, $minbytes=1, $synchsafe=false, $signed=false) {
		if ($number < 0) {
			throw new Exception('ERROR: self::BigEndian2String() does not support negative numbers');
		}
		$maskbyte = (($synchsafe || $signed) ? 0x7F : 0xFF);
		$intstring = '';
		if ($signed) {
			if ($minbytes > PHP_INT_SIZE) {
				throw new Exception('ERROR: Cannot have signed integers larger than '.(8 * PHP_INT_SIZE).'-bits in self::BigEndian2String()');
			}
			$number = $number & (0x80 << (8 * ($minbytes - 1)));
		}
		while ($number != 0) {
			$quotient = ($number / ($maskbyte + 1));
			$intstring = chr(ceil(($quotient - floor($quotient)) * $maskbyte)).$intstring;
			$number = floor($quotient);
		}
		return str_pad($intstring, $minbytes, "\x00", STR_PAD_LEFT);
	}

	public static function Dec2Bin($number) {
		while ($number >= 256) {
			$bytes[] = (($number / 256) - (floor($number / 256))) * 256;
			$number = floor($number / 256);
		}
		$bytes[] = $number;
		$binstring = '';
		for ($i = 0; $i < count($bytes); $i++) {
			$binstring = (($i == count($bytes) - 1) ? decbin($bytes[$i]) : str_pad(decbin($bytes[$i]), 8, '0', STR_PAD_LEFT)).$binstring;
		}
		return $binstring;
	}

	public static function Bin2Dec($binstring, $signed=false) {
		$signmult = 1;
		if ($signed) {
			if ($binstring{0} == '1') {
				$signmult = -1;
			}
			$binstring = substr($binstring, 1);
		}
		$decvalue = 0;
		for ($i = 0; $i < strlen($binstring); $i++) {
			$decvalue += ((int) substr($binstring, strlen($binstring) - $i - 1, 1)) * pow(2, $i);
		}
		return self::CastAsInt($decvalue * $signmult);
	}

	public static function Bin2String($binstring) {
		// return 'hi' for input of '0110100001101001'
		$string = '';
		$binstringreversed = strrev($binstring);
		for ($i = 0; $i < strlen($binstringreversed); $i += 8) {
			$string = chr(self::Bin2Dec(strrev(substr($binstringreversed, $i, 8)))).$string;
		}
		return $string;
	}

	public static function LittleEndian2String($number, $minbytes=1, $synchsafe=false) {
		$intstring = '';
		while ($number > 0) {
			if ($synchsafe) {
				$intstring = $intstring.chr($number & 127);
				$number >>= 7;
			} else {
				$intstring = $intstring.chr($number & 255);
				$number >>= 8;
			}
		}
		return str_pad($intstring, $minbytes, "\x00", STR_PAD_RIGHT);
	}

	public static function array_merge_clobber($array1, $array2) {
		// written by kcØhireability*com
		// taken from http://www.php.net/manual/en/function.array-merge-recursive.php
		if (!is_array($array1) || !is_array($array2)) {
			return false;
		}
		$newarray = $array1;
		foreach ($array2 as $key => $val) {
			if (is_array($val) && isset($newarray[$key]) && is_array($newarray[$key])) {
				$newarray[$key] = self::array_merge_clobber($newarray[$key], $val);
			} else {
				$newarray[$key] = $val;
			}
		}
		return $newarray;
	}

	public static function array_merge_noclobber($array1, $array2) {
		if (!is_array($array1) || !is_array($array2)) {
			return false;
		}
		$newarray = $array1;
		foreach ($array2 as $key => $val) {
			if (is_array($val) && isset($newarray[$key]) && is_array($newarray[$key])) {
				$newarray[$key] = self::array_merge_noclobber($newarray[$key], $val);
			} elseif (!isset($newarray[$key])) {
				$newarray[$key] = $val;
			}
		}
		return $newarray;
	}

	public static function ksort_recursive(&$theArray) {
		ksort($theArray);
		foreach ($theArray as $key => $value) {
			if (is_array($value)) {
				self::ksort_recursive($theArray[$key]);
			}
		}
		return true;
	}

	public static function fileextension($filename, $numextensions=1) {
		if (strstr($filename, '.')) {
			$reversedfilename = strrev($filename);
			$offset = 0;
			for ($i = 0; $i < $numextensions; $i++) {
				$offset = strpos($reversedfilename, '.', $offset + 1);
				if ($offset === false) {
					return '';
				}
			}
			return strrev(substr($reversedfilename, 0, $offset));
		}
		return '';
	}

	public static function PlaytimeString($seconds) {
		$sign = (($seconds < 0) ? '-' : '');
		$seconds = round(abs($seconds));
		$H = (int) floor( $seconds                            / 3600);
		$M = (int) floor(($seconds - (3600 * $H)            ) /   60);
		$S = (int) round( $seconds - (3600 * $H) - (60 * $M)        );
		return $sign.($H ? $H.':' : '').($H ? str_pad($M, 2, '0', STR_PAD_LEFT) : intval($M)).':'.str_pad($S, 2, 0, STR_PAD_LEFT);
	}

	public static function DateMac2Unix($macdate) {
		// Macintosh timestamp: seconds since 00:00h January 1, 1904
		// UNIX timestamp:      seconds since 00:00h January 1, 1970
		return self::CastAsInt($macdate - 2082844800);
	}

	public static function FixedPoint8_8($rawdata) {
		return self::BigEndian2Int(substr($rawdata, 0, 1)) + (float) (self::BigEndian2Int(substr($rawdata, 1, 1)) / pow(2, 8));
	}

	public static function FixedPoint16_16($rawdata) {
		return self::BigEndian2Int(substr($rawdata, 0, 2)) + (float) (self::BigEndian2Int(substr($rawdata, 2, 2)) / pow(2, 16));
	}

	public static function FixedPoint2_30($rawdata) {
		$binarystring = self::BigEndian2Bin($rawdata);
		return self::Bin2Dec(substr($binarystring, 0, 2)) + (float) (self::Bin2Dec(substr($binarystring, 2, 30)) / pow(2, 30));
	}

	public static function CreateDeepArray($ArrayPath, $Separator, $Value) {
		// assigns $Value to a nested array path:
		//   $foo = self::CreateDeepArray('/path/to/my', '/', 'file.txt')
		// is the same as:
		//   $foo = array('path'=>array('to'=>'array('my'=>array('file.txt'))));
		// or
		//   $foo['path']['to']['my'] = 'file.txt';
		$ArrayPath = ltrim($ArrayPath, $Separator);
		if (($pos = strpos($ArrayPath, $Separator)) !== false) {
			$ReturnedArray[substr($ArrayPath, 0, $pos)] = self::CreateDeepArray(substr($ArrayPath, $pos + 1), $Separator, $Value);
		} else {
			$ReturnedArray[$ArrayPath] = $Value;
		}
		return $ReturnedArray;
	}

	public static function array_max($arraydata, $returnkey=false) {
		$maxvalue = false;
		$maxkey = false;
		foreach ($arraydata as $key => $value) {
			if (!is_array($value)) {
				if ($value > $maxvalue) {
					$maxvalue = $value;
					$maxkey = $key;
				}
			}
		}
		return ($returnkey ? $maxkey : $maxvalue);
	}

	public static function array_min($arraydata, $returnkey=false) {
		$minvalue = false;
		$minkey = false;
		foreach ($arraydata as $key => $value) {
			if (!is_array($value)) {
				if ($value > $minvalue) {
					$minvalue = $value;
					$minkey = $key;
				}
			}
		}
		return ($returnkey ? $minkey : $minvalue);
	}

	public static function XML2array($XMLstring) {
		if (function_exists('simplexml_load_string')) {
			if (function_exists('get_object_vars')) {
				$XMLobject = simplexml_load_string($XMLstring);
				return self::SimpleXMLelement2array($XMLobject);
			}
		}
		return false;
	}

	public static function SimpleXMLelement2array($XMLobject) {
		if (!is_object($XMLobject) && !is_array($XMLobject)) {
			return $XMLobject;
		}
		$XMLarray = (is_object($XMLobject) ? get_object_vars($XMLobject) : $XMLobject);
		foreach ($XMLarray as $key => $value) {
			$XMLarray[$key] = self::SimpleXMLelement2array($value);
		}
		return $XMLarray;
	}

	// Allan Hansen <ahØartemis*dk>
	// self::md5_data() - returns md5sum for a file from startuing position to absolute end position
	public static function hash_data($file, $offset, $end, $algorithm) {
		static $tempdir = '';
		if (!self::intValueSupported($end)) {
			return false;
		}
		switch ($algorithm) {
			case 'md5':
				$hash_function = 'md5_file';
				$unix_call     = 'md5sum';
				$windows_call  = 'md5sum.exe';
				$hash_length   = 32;
				break;

			case 'sha1':
				$hash_function = 'sha1_file';
				$unix_call     = 'sha1sum';
				$windows_call  = 'sha1sum.exe';
				$hash_length   = 40;
				break;

			default:
				throw new Exception('Invalid algorithm ('.$algorithm.') in self::hash_data()');
				break;
		}
		$size = $end - $offset;
		while (true) {
			if (GETID3_OS_ISWINDOWS) {

				// It seems that sha1sum.exe for Windows only works on physical files, does not accept piped data
				// Fall back to create-temp-file method:
				if ($algorithm == 'sha1') {
					break;
				}

				$RequiredFiles = array('cygwin1.dll', 'head.exe', 'tail.exe', $windows_call);
				foreach ($RequiredFiles as $required_file) {
					if (!is_readable(GETID3_HELPERAPPSDIR.$required_file)) {
						// helper apps not available - fall back to old method
						break 2;
					}
				}
				$commandline  = GETID3_HELPERAPPSDIR.'head.exe -c '.$end.' '.escapeshellarg(str_replace('/', DIRECTORY_SEPARATOR, $file)).' | ';
				$commandline .= GETID3_HELPERAPPSDIR.'tail.exe -c '.$size.' | ';
				$commandline .= GETID3_HELPERAPPSDIR.$windows_call;

			} else {

				$commandline  = 'head -c'.$end.' '.escapeshellarg($file).' | ';
				$commandline .= 'tail -c'.$size.' | ';
				$commandline .= $unix_call;

			}
			if (preg_match('#(1|ON)#i', ini_get('safe_mode'))) {
				//throw new Exception('PHP running in Safe Mode - backtick operator not available, using slower non-system-call '.$algorithm.' algorithm');
				break;
			}
			return substr(`$commandline`, 0, $hash_length);
		}

		if (empty($tempdir)) {
			// yes this is ugly, feel free to suggest a better way
			require_once(dirname(__FILE__).'/getid3.php');
			$getid3_temp = new getID3();
			$tempdir = $getid3_temp->tempdir;
			unset($getid3_temp);
		}
		// try to create a temporary file in the system temp directory - invalid dirname should force to system temp dir
		if (($data_filename = tempnam($tempdir, 'gI3')) === false) {
			// can't find anywhere to create a temp file, just fail
			return false;
		}

		// Init
		$result = false;

		// copy parts of file
		try {
			self::CopyFileParts($file, $data_filename, $offset, $end - $offset);
			$result = $hash_function($data_filename);
		} catch (Exception $e) {
			throw new Exception('self::CopyFileParts() failed in getid_lib::hash_data(): '.$e->getMessage());
		}
		unlink($data_filename);
		return $result;
	}

	public static function CopyFileParts($filename_source, $filename_dest, $offset, $length) {
		if (!self::intValueSupported($offset + $length)) {
			throw new Exception('cannot copy file portion, it extends beyond the '.round(PHP_INT_MAX / 1073741824).'GB limit');
		}
		if (is_readable($filename_source) && is_file($filename_source) && ($fp_src = fopen($filename_source, 'rb'))) {
			if (($fp_dest = fopen($filename_dest, 'wb'))) {
				if (fseek($fp_src, $offset, SEEK_SET) == 0) {
					$byteslefttowrite = $length;
					while (($byteslefttowrite > 0) && ($buffer = fread($fp_src, min($byteslefttowrite, getID3::FREAD_BUFFER_SIZE)))) {
						$byteswritten = fwrite($fp_dest, $buffer, $byteslefttowrite);
						$byteslefttowrite -= $byteswritten;
					}
					return true;
				} else {
					throw new Exception('failed to seek to offset '.$offset.' in '.$filename_source);
				}
				fclose($fp_dest);
			} else {
				throw new Exception('failed to create file for writing '.$filename_dest);
			}
			fclose($fp_src);
		} else {
			throw new Exception('failed to open file for reading '.$filename_source);
		}
		return false;
	}

	public static function iconv_fallback_int_utf8($charval) {
		if ($charval < 128) {
			// 0bbbbbbb
			$newcharstring = chr($charval);
		} elseif ($charval < 2048) {
			// 110bbbbb 10bbbbbb
			$newcharstring  = chr(($charval >>   6) | 0xC0);
			$newcharstring .= chr(($charval & 0x3F) | 0x80);
		} elseif ($charval < 65536) {
			// 1110bbbb 10bbbbbb 10bbbbbb
			$newcharstring  = chr(($charval >>  12) | 0xE0);
			$newcharstring .= chr(($charval >>   6) | 0xC0);
			$newcharstring .= chr(($charval & 0x3F) | 0x80);
		} else {
			// 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
			$newcharstring  = chr(($charval >>  18) | 0xF0);
			$newcharstring .= chr(($charval >>  12) | 0xC0);
			$newcharstring .= chr(($charval >>   6) | 0xC0);
			$newcharstring .= chr(($charval & 0x3F) | 0x80);
		}
		return $newcharstring;
	}

	// ISO-8859-1 => UTF-8
	public static function iconv_fallback_iso88591_utf8($string, $bom=false) {
		if (function_exists('utf8_encode')) {
			return utf8_encode($string);
		}
		// utf8_encode() unavailable, use getID3()'s iconv_fallback() conversions (possibly PHP is compiled without XML support)
		$newcharstring = '';
		if ($bom) {
			$newcharstring .= "\xEF\xBB\xBF";
		}
		for ($i = 0; $i < strlen($string); $i++) {
			$charval = ord($string{$i});
			$newcharstring .= self::iconv_fallback_int_utf8($charval);
		}
		return $newcharstring;
	}

	// ISO-8859-1 => UTF-16BE
	public static function iconv_fallback_iso88591_utf16be($string, $bom=false) {
		$newcharstring = '';
		if ($bom) {
			$newcharstring .= "\xFE\xFF";
		}
		for ($i = 0; $i < strlen($string); $i++) {
			$newcharstring .= "\x00".$string{$i};
		}
		return $newcharstring;
	}

	// ISO-8859-1 => UTF-16LE
	public static function iconv_fallback_iso88591_utf16le($string, $bom=false) {
		$newcharstring = '';
		if ($bom) {
			$newcharstring .= "\xFF\xFE";
		}
		for ($i = 0; $i < strlen($string); $i++) {
			$newcharstring .= $string{$i}."\x00";
		}
		return $newcharstring;
	}

	// ISO-8859-1 => UTF-16LE (BOM)
	public static function iconv_fallback_iso88591_utf16($string) {
		return self::iconv_fallback_iso88591_utf16le($string, true);
	}

	// UTF-8 => ISO-8859-1
	public static function iconv_fallback_utf8_iso88591($string) {
		if (function_exists('utf8_decode')) {
			return utf8_decode($string);
		}
		// utf8_decode() unavailable, use getID3()'s iconv_fallback() conversions (possibly PHP is compiled without XML support)
		$newcharstring = '';
		$offset = 0;
		$stringlength = strlen($string);
		while ($offset < $stringlength) {
			if ((ord($string{$offset}) | 0x07) == 0xF7) {
				// 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
				$charval = ((ord($string{($offset + 0)}) & 0x07) << 18) &
						   ((ord($string{($offset + 1)}) & 0x3F) << 12) &
						   ((ord($string{($offset + 2)}) & 0x3F) <<  6) &
							(ord($string{($offset + 3)}) & 0x3F);
				$offset += 4;
			} elseif ((ord($string{$offset}) | 0x0F) == 0xEF) {
				// 1110bbbb 10bbbbbb 10bbbbbb
				$charval = ((ord($string{($offset + 0)}) & 0x0F) << 12) &
						   ((ord($string{($offset + 1)}) & 0x3F) <<  6) &
							(ord($string{($offset + 2)}) & 0x3F);
				$offset += 3;
			} elseif ((ord($string{$offset}) | 0x1F) == 0xDF) {
				// 110bbbbb 10bbbbbb
				$charval = ((ord($string{($offset + 0)}) & 0x1F) <<  6) &
							(ord($string{($offset + 1)}) & 0x3F);
				$offset += 2;
			} elseif ((ord($string{$offset}) | 0x7F) == 0x7F) {
				// 0bbbbbbb
				$charval = ord($string{$offset});
				$offset += 1;
			} else {
				// error? throw some kind of warning here?
				$charval = false;
				$offset += 1;
			}
			if ($charval !== false) {
				$newcharstring .= (($charval < 256) ? chr($charval) : '?');
			}
		}
		return $newcharstring;
	}

	// UTF-8 => UTF-16BE
	public static function iconv_fallback_utf8_utf16be($string, $bom=false) {
		$newcharstring = '';
		if ($bom) {
			$newcharstring .= "\xFE\xFF";
		}
		$offset = 0;
		$stringlength = strlen($string);
		while ($offset < $stringlength) {
			if ((ord($string{$offset}) | 0x07) == 0xF7) {
				// 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
				$charval = ((ord($string{($offset + 0)}) & 0x07) << 18) &
						   ((ord($string{($offset + 1)}) & 0x3F) << 12) &
						   ((ord($string{($offset + 2)}) & 0x3F) <<  6) &
							(ord($string{($offset + 3)}) & 0x3F);
				$offset += 4;
			} elseif ((ord($string{$offset}) | 0x0F) == 0xEF) {
				// 1110bbbb 10bbbbbb 10bbbbbb
				$charval = ((ord($string{($offset + 0)}) & 0x0F) << 12) &
						   ((ord($string{($offset + 1)}) & 0x3F) <<  6) &
							(ord($string{($offset + 2)}) & 0x3F);
				$offset += 3;
			} elseif ((ord($string{$offset}) | 0x1F) == 0xDF) {
				// 110bbbbb 10bbbbbb
				$charval = ((ord($string{($offset + 0)}) & 0x1F) <<  6) &
							(ord($string{($offset + 1)}) & 0x3F);
				$offset += 2;
			} elseif ((ord($string{$offset}) | 0x7F) == 0x7F) {
				// 0bbbbbbb
				$charval = ord($string{$offset});
				$offset += 1;
			} else {
				// error? throw some kind of warning here?
				$charval = false;
				$offset += 1;
			}
			if ($charval !== false) {
				$newcharstring .= (($charval < 65536) ? self::BigEndian2String($charval, 2) : "\x00".'?');
			}
		}
		return $newcharstring;
	}

	// UTF-8 => UTF-16LE
	public static function iconv_fallback_utf8_utf16le($string, $bom=false) {
		$newcharstring = '';
		if ($bom) {
			$newcharstring .= "\xFF\xFE";
		}
		$offset = 0;
		$stringlength = strlen($string);
		while ($offset < $stringlength) {
			if ((ord($string{$offset}) | 0x07) == 0xF7) {
				// 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
				$charval = ((ord($string{($offset + 0)}) & 0x07) << 18) &
						   ((ord($string{($offset + 1)}) & 0x3F) << 12) &
						   ((ord($string{($offset + 2)}) & 0x3F) <<  6) &
							(ord($string{($offset + 3)}) & 0x3F);
				$offset += 4;
			} elseif ((ord($string{$offset}) | 0x0F) == 0xEF) {
				// 1110bbbb 10bbbbbb 10bbbbbb
				$charval = ((ord($string{($offset + 0)}) & 0x0F) << 12) &
						   ((ord($string{($offset + 1)}) & 0x3F) <<  6) &
							(ord($string{($offset + 2)}) & 0x3F);
				$offset += 3;
			} elseif ((ord($string{$offset}) | 0x1F) == 0xDF) {
				// 110bbbbb 10bbbbbb
				$charval = ((ord($string{($offset + 0)}) & 0x1F) <<  6) &
							(ord($string{($offset + 1)}) & 0x3F);
				$offset += 2;
			} elseif ((ord($string{$offset}) | 0x7F) == 0x7F) {
				// 0bbbbbbb
				$charval = ord($string{$offset});
				$offset += 1;
			} else {
				// error? maybe throw some warning here?
				$charval = false;
				$offset += 1;
			}
			if ($charval !== false) {
				$newcharstring .= (($charval < 65536) ? self::LittleEndian2String($charval, 2) : '?'."\x00");
			}
		}
		return $newcharstring;
	}

	// UTF-8 => UTF-16LE (BOM)
	public static function iconv_fallback_utf8_utf16($string) {
		return self::iconv_fallback_utf8_utf16le($string, true);
	}

	// UTF-16BE => UTF-8
	public static function iconv_fallback_utf16be_utf8($string) {
		if (substr($string, 0, 2) == "\xFE\xFF") {
			// strip BOM
			$string = substr($string, 2);
		}
		$newcharstring = '';
		for ($i = 0; $i < strlen($string); $i += 2) {
			$charval = self::BigEndian2Int(substr($string, $i, 2));
			$newcharstring .= self::iconv_fallback_int_utf8($charval);
		}
		return $newcharstring;
	}

	// UTF-16LE => UTF-8
	public static function iconv_fallback_utf16le_utf8($string) {
		if (substr($string, 0, 2) == "\xFF\xFE") {
			// strip BOM
			$string = substr($string, 2);
		}
		$newcharstring = '';
		for ($i = 0; $i < strlen($string); $i += 2) {
			$charval = self::LittleEndian2Int(substr($string, $i, 2));
			$newcharstring .= self::iconv_fallback_int_utf8($charval);
		}
		return $newcharstring;
	}

	// UTF-16BE => ISO-8859-1
	public static function iconv_fallback_utf16be_iso88591($string) {
		if (substr($string, 0, 2) == "\xFE\xFF") {
			// strip BOM
			$string = substr($string, 2);
		}
		$newcharstring = '';
		for ($i = 0; $i < strlen($string); $i += 2) {
			$charval = self::BigEndian2Int(substr($string, $i, 2));
			$newcharstring .= (($charval < 256) ? chr($charval) : '?');
		}
		return $newcharstring;
	}

	// UTF-16LE => ISO-8859-1
	public static function iconv_fallback_utf16le_iso88591($string) {
		if (substr($string, 0, 2) == "\xFF\xFE") {
			// strip BOM
			$string = substr($string, 2);
		}
		$newcharstring = '';
		for ($i = 0; $i < strlen($string); $i += 2) {
			$charval = self::LittleEndian2Int(substr($string, $i, 2));
			$newcharstring .= (($charval < 256) ? chr($charval) : '?');
		}
		return $newcharstring;
	}

	// UTF-16 (BOM) => ISO-8859-1
	public static function iconv_fallback_utf16_iso88591($string) {
		$bom = substr($string, 0, 2);
		if ($bom == "\xFE\xFF") {
			return self::iconv_fallback_utf16be_iso88591(substr($string, 2));
		} elseif ($bom == "\xFF\xFE") {
			return self::iconv_fallback_utf16le_iso88591(substr($string, 2));
		}
		return $string;
	}

	// UTF-16 (BOM) => UTF-8
	public static function iconv_fallback_utf16_utf8($string) {
		$bom = substr($string, 0, 2);
		if ($bom == "\xFE\xFF") {
			return self::iconv_fallback_utf16be_utf8(substr($string, 2));
		} elseif ($bom == "\xFF\xFE") {
			return self::iconv_fallback_utf16le_utf8(substr($string, 2));
		}
		return $string;
	}

	public static function iconv_fallback($in_charset, $out_charset, $string) {

		if ($in_charset == $out_charset) {
			return $string;
		}

		// iconv() availble
		if (function_exists('iconv')) {
			if ($converted_string = @iconv($in_charset, $out_charset.'//TRANSLIT', $string)) {
				switch ($out_charset) {
					case 'ISO-8859-1':
						$converted_string = rtrim($converted_string, "\x00");
						break;
				}
				return $converted_string;
			}

			// iconv() may sometimes fail with "illegal character in input string" error message
			// and return an empty string, but returning the unconverted string is more useful
			return $string;
		}

		// iconv() not available
		static $ConversionFunctionList = array();
		if (empty($ConversionFunctionList)) {
			$ConversionFunctionList['ISO-8859-1']['UTF-8']    = 'iconv_fallback_iso88591_utf8';
			$ConversionFunctionList['ISO-8859-1']['UTF-16']   = 'iconv_fallback_iso88591_utf16';
			$ConversionFunctionList['ISO-8859-1']['UTF-16BE'] = 'iconv_fallback_iso88591_utf16be';
			$ConversionFunctionList['ISO-8859-1']['UTF-16LE'] = 'iconv_fallback_iso88591_utf16le';
			$ConversionFunctionList['UTF-8']['ISO-8859-1']    = 'iconv_fallback_utf8_iso88591';
			$ConversionFunctionList['UTF-8']['UTF-16']        = 'iconv_fallback_utf8_utf16';
			$ConversionFunctionList['UTF-8']['UTF-16BE']      = 'iconv_fallback_utf8_utf16be';
			$ConversionFunctionList['UTF-8']['UTF-16LE']      = 'iconv_fallback_utf8_utf16le';
			$ConversionFunctionList['UTF-16']['ISO-8859-1']   = 'iconv_fallback_utf16_iso88591';
			$ConversionFunctionList['UTF-16']['UTF-8']        = 'iconv_fallback_utf16_utf8';
			$ConversionFunctionList['UTF-16LE']['ISO-8859-1'] = 'iconv_fallback_utf16le_iso88591';
			$ConversionFunctionList['UTF-16LE']['UTF-8']      = 'iconv_fallback_utf16le_utf8';
			$ConversionFunctionList['UTF-16BE']['ISO-8859-1'] = 'iconv_fallback_utf16be_iso88591';
			$ConversionFunctionList['UTF-16BE']['UTF-8']      = 'iconv_fallback_utf16be_utf8';
		}
		if (isset($ConversionFunctionList[strtoupper($in_charset)][strtoupper($out_charset)])) {
			$ConversionFunction = $ConversionFunctionList[strtoupper($in_charset)][strtoupper($out_charset)];
			return self::$ConversionFunction($string);
		}
		throw new Exception('PHP does not have iconv() support - cannot convert from '.$in_charset.' to '.$out_charset);
	}

	public static function MultiByteCharString2HTML($string, $charset='ISO-8859-1') {
		$string = (string) $string; // in case trying to pass a numeric (float, int) string, would otherwise return an empty string
		$HTMLstring = '';

		switch ($charset) {
			case '1251':
			case '1252':
			case '866':
			case '932':
			case '936':
			case '950':
			case 'BIG5':
			case 'BIG5-HKSCS':
			case 'cp1251':
			case 'cp1252':
			case 'cp866':
			case 'EUC-JP':
			case 'EUCJP':
			case 'GB2312':
			case 'ibm866':
			case 'ISO-8859-1':
			case 'ISO-8859-15':
			case 'ISO8859-1':
			case 'ISO8859-15':
			case 'KOI8-R':
			case 'koi8-ru':
			case 'koi8r':
			case 'Shift_JIS':
			case 'SJIS':
			case 'win-1251':
			case 'Windows-1251':
			case 'Windows-1252':
				$HTMLstring = htmlentities($string, ENT_COMPAT, $charset);
				break;

			case 'UTF-8':
				$strlen = strlen($string);
				for ($i = 0; $i < $strlen; $i++) {
					$char_ord_val = ord($string{$i});
					$charval = 0;
					if ($char_ord_val < 0x80) {
						$charval = $char_ord_val;
					} elseif ((($char_ord_val & 0xF0) >> 4) == 0x0F  &&  $i+3 < $strlen) {
						$charval  = (($char_ord_val & 0x07) << 18);
						$charval += ((ord($string{++$i}) & 0x3F) << 12);
						$charval += ((ord($string{++$i}) & 0x3F) << 6);
						$charval +=  (ord($string{++$i}) & 0x3F);
					} elseif ((($char_ord_val & 0xE0) >> 5) == 0x07  &&  $i+2 < $strlen) {
						$charval  = (($char_ord_val & 0x0F) << 12);
						$charval += ((ord($string{++$i}) & 0x3F) << 6);
						$charval +=  (ord($string{++$i}) & 0x3F);
					} elseif ((($char_ord_val & 0xC0) >> 6) == 0x03  &&  $i+1 < $strlen) {
						$charval  = (($char_ord_val & 0x1F) << 6);
						$charval += (ord($string{++$i}) & 0x3F);
					}
					if (($charval >= 32) && ($charval <= 127)) {
						$HTMLstring .= htmlentities(chr($charval));
					} else {
						$HTMLstring .= '&#'.$charval.';';
					}
				}
				break;

			case 'UTF-16LE':
				for ($i = 0; $i < strlen($string); $i += 2) {
					$charval = self::LittleEndian2Int(substr($string, $i, 2));
					if (($charval >= 32) && ($charval <= 127)) {
						$HTMLstring .= chr($charval);
					} else {
						$HTMLstring .= '&#'.$charval.';';
					}
				}
				break;

			case 'UTF-16BE':
				for ($i = 0; $i < strlen($string); $i += 2) {
					$charval = self::BigEndian2Int(substr($string, $i, 2));
					if (($charval >= 32) && ($charval <= 127)) {
						$HTMLstring .= chr($charval);
					} else {
						$HTMLstring .= '&#'.$charval.';';
					}
				}
				break;

			default:
				$HTMLstring = 'ERROR: Character set "'.$charset.'" not supported in MultiByteCharString2HTML()';
				break;
		}
		return $HTMLstring;
	}

	public static function RGADnameLookup($namecode) {
		static $RGADname = array();
		if (empty($RGADname)) {
			$RGADname[0] = 'not set';
			$RGADname[1] = 'Track Gain Adjustment';
			$RGADname[2] = 'Album Gain Adjustment';
		}

		return (isset($RGADname[$namecode]) ? $RGADname[$namecode] : '');
	}

	public static function RGADoriginatorLookup($originatorcode) {
		static $RGADoriginator = array();
		if (empty($RGADoriginator)) {
			$RGADoriginator[0] = 'unspecified';
			$RGADoriginator[1] = 'pre-set by artist/producer/mastering engineer';
			$RGADoriginator[2] = 'set by user';
			$RGADoriginator[3] = 'determined automatically';
		}

		return (isset($RGADoriginator[$originatorcode]) ? $RGADoriginator[$originatorcode] : '');
	}

	public static function RGADadjustmentLookup($rawadjustment, $signbit) {
		$adjustment = $rawadjustment / 10;
		if ($signbit == 1) {
			$adjustment *= -1;
		}
		return (float) $adjustment;
	}

	public static function RGADgainString($namecode, $originatorcode, $replaygain) {
		if ($replaygain < 0) {
			$signbit = '1';
		} else {
			$signbit = '0';
		}
		$storedreplaygain = intval(round($replaygain * 10));
		$gainstring  = str_pad(decbin($namecode), 3, '0', STR_PAD_LEFT);
		$gainstring .= str_pad(decbin($originatorcode), 3, '0', STR_PAD_LEFT);
		$gainstring .= $signbit;
		$gainstring .= str_pad(decbin($storedreplaygain), 9, '0', STR_PAD_LEFT);

		return $gainstring;
	}

	public static function RGADamplitude2dB($amplitude) {
		return 20 * log10($amplitude);
	}

	public static function GetDataImageSize($imgData, &$imageinfo=array()) {
		static $tempdir = '';
		if (empty($tempdir)) {
			// yes this is ugly, feel free to suggest a better way
			require_once(dirname(__FILE__).'/getid3.php');
			$getid3_temp = new getID3();
			$tempdir = $getid3_temp->tempdir;
			unset($getid3_temp);
		}
		$GetDataImageSize = false;
		if ($tempfilename = tempnam($tempdir, 'gI3')) {
			if (is_writable($tempfilename) && is_file($tempfilename) && ($tmp = fopen($tempfilename, 'wb'))) {
				fwrite($tmp, $imgData);
				fclose($tmp);
				$GetDataImageSize = @getimagesize($tempfilename, $imageinfo);
			}
			unlink($tempfilename);
		}
		return $GetDataImageSize;
	}

	public static function ImageExtFromMime($mime_type) {
		// temporary way, works OK for now, but should be reworked in the future
		return str_replace(array('image/', 'x-', 'jpeg'), array('', '', 'jpg'), $mime_type);
	}

	public static function ImageTypesLookup($imagetypeid) {
		static $ImageTypesLookup = array();
		if (empty($ImageTypesLookup)) {
			$ImageTypesLookup[1]  = 'gif';
			$ImageTypesLookup[2]  = 'jpeg';
			$ImageTypesLookup[3]  = 'png';
			$ImageTypesLookup[4]  = 'swf';
			$ImageTypesLookup[5]  = 'psd';
			$ImageTypesLookup[6]  = 'bmp';
			$ImageTypesLookup[7]  = 'tiff (little-endian)';
			$ImageTypesLookup[8]  = 'tiff (big-endian)';
			$ImageTypesLookup[9]  = 'jpc';
			$ImageTypesLookup[10] = 'jp2';
			$ImageTypesLookup[11] = 'jpx';
			$ImageTypesLookup[12] = 'jb2';
			$ImageTypesLookup[13] = 'swc';
			$ImageTypesLookup[14] = 'iff';
		}
		return (isset($ImageTypesLookup[$imagetypeid]) ? $ImageTypesLookup[$imagetypeid] : '');
	}

	public static function CopyTagsToComments(&$ThisFileInfo) {

		// Copy all entries from ['tags'] into common ['comments']
		if (!empty($ThisFileInfo['tags'])) {
			foreach ($ThisFileInfo['tags'] as $tagtype => $tagarray) {
				foreach ($tagarray as $tagname => $tagdata) {
					foreach ($tagdata as $key => $value) {
						if (!empty($value)) {
							if (empty($ThisFileInfo['comments'][$tagname])) {

								// fall through and append value

							} elseif ($tagtype == 'id3v1') {

								$newvaluelength = strlen(trim($value));
								foreach ($ThisFileInfo['comments'][$tagname] as $existingkey => $existingvalue) {
									$oldvaluelength = strlen(trim($existingvalue));
									if (($newvaluelength <= $oldvaluelength) && (substr($existingvalue, 0, $newvaluelength) == trim($value))) {
										// new value is identical but shorter-than (or equal-length to) one already in comments - skip
										break 2;
									}
								}

							} elseif (!is_array($value)) {

								$newvaluelength = strlen(trim($value));
								foreach ($ThisFileInfo['comments'][$tagname] as $existingkey => $existingvalue) {
									$oldvaluelength = strlen(trim($existingvalue));
									if (($newvaluelength > $oldvaluelength) && (substr(trim($value), 0, strlen($existingvalue)) == $existingvalue)) {
										$ThisFileInfo['comments'][$tagname][$existingkey] = trim($value);
										break 2;
									}
								}

							}
							if (is_array($value) || empty($ThisFileInfo['comments'][$tagname]) || !in_array(trim($value), $ThisFileInfo['comments'][$tagname])) {
								$value = (is_string($value) ? trim($value) : $value);
								$ThisFileInfo['comments'][$tagname][] = $value;
							}
						}
					}
				}
			}

			// Copy to ['comments_html']
			foreach ($ThisFileInfo['comments'] as $field => $values) {
				if ($field == 'picture') {
					// pictures can take up a lot of space, and we don't need multiple copies of them
					// let there be a single copy in [comments][picture], and not elsewhere
					continue;
				}
				foreach ($values as $index => $value) {
					if (is_array($value)) {
						$ThisFileInfo['comments_html'][$field][$index] = $value;
					} else {
						$ThisFileInfo['comments_html'][$field][$index] = str_replace('�', '', self::MultiByteCharString2HTML($value, $ThisFileInfo['encoding']));
					}
				}
			}
		}
		return true;
	}

	public static function EmbeddedLookup($key, $begin, $end, $file, $name) {

		// Cached
		static $cache;
		if (isset($cache[$file][$name])) {
			return (isset($cache[$file][$name][$key]) ? $cache[$file][$name][$key] : '');
		}

		// Init
		$keylength  = strlen($key);
		$line_count = $end - $begin - 7;

		// Open php file
		$fp = fopen($file, 'r');

		// Discard $begin lines
		for ($i = 0; $i < ($begin + 3); $i++) {
			fgets($fp, 1024);
		}

		// Loop thru line
		while (0 < $line_count--) {

			// Read line
			$line = ltrim(fgets($fp, 1024), "\t ");

			// METHOD A: only cache the matching key - less memory but slower on next lookup of not-previously-looked-up key
			//$keycheck = substr($line, 0, $keylength);
			//if ($key == $keycheck)  {
			//	$cache[$file][$name][$keycheck] = substr($line, $keylength + 1);
			//	break;
			//}

			// METHOD B: cache all keys in this lookup - more memory but faster on next lookup of not-previously-looked-up key
			//$cache[$file][$name][substr($line, 0, $keylength)] = trim(substr($line, $keylength + 1));
			$explodedLine = explode("\t", $line, 2);
			$ThisKey   = (isset($explodedLine[0]) ? $explodedLine[0] : '');
			$ThisValue = (isset($explodedLine[1]) ? $explodedLine[1] : '');
			$cache[$file][$name][$ThisKey] = trim($ThisValue);
		}

		// Close and return
		fclose($fp);
		return (isset($cache[$file][$name][$key]) ? $cache[$file][$name][$key] : '');
	}

	public static function IncludeDependency($filename, $sourcefile, $DieOnFailure=false) {
		global $GETID3_ERRORARRAY;

		if (file_exists($filename)) {
			if (include_once($filename)) {
				return true;
			} else {
				$diemessage = basename($sourcefile).' depends on '.$filename.', which has errors';
			}
		} else {
			$diemessage = basename($sourcefile).' depends on '.$filename.', which is missing';
		}
		if ($DieOnFailure) {
			throw new Exception($diemessage);
		} else {
			$GETID3_ERRORARRAY[] = $diemessage;
		}
		return false;
	}

	public static function trimNullByte($string) {
		return trim($string, "\x00");
	}

	public static function getFileSizeSyscall($path) {
		$filesize = false;

		if (GETID3_OS_ISWINDOWS) {
			if (class_exists('COM')) { // From PHP 5.3.15 and 5.4.5, COM and DOTNET is no longer built into the php core.you have to add COM support in php.ini:
				$filesystem = new COM('Scripting.FileSystemObject');
				$file = $filesystem->GetFile($path);
				$filesize = $file->Size();
				unset($filesystem, $file);
			} else {
				$commandline = 'for %I in ('.escapeshellarg($path).') do @echo %~zI';
			}
		} else {
			$commandline = 'ls -l '.escapeshellarg($path).' | awk \'{print $5}\'';
		}
		if (isset($commandline)) {
			$output = trim(`$commandline`);
			if (ctype_digit($output)) {
				$filesize = (float) $output;
			}
		}
		return $filesize;
	}
}


text:
package com.learning.patterDesign.command;

public abstract class Command {
    //每个命令类都必须有一个执行命令的方法
    public abstract void execute();
}

redpajama_set_name: RedPajamaGithub


text:
<?xml version="1.0" ?>
<tei>
	<teiHeader>
		<fileDesc xml:id="55008537"/>
	</teiHeader>
	<text xml:lang="en">
		<front>
<lb/>
	<docTitle>
	<titlePart>Mailing<lb/></titlePart>
	</docTitle>

	<note>aus Wikipedia, der freien Enzyklopädie<lb/> Dies ist eine alte Version dieser Seite, zuletzt bearbeitet am 17. April 2010 um 09:40 Uhr durch<lb/> Schotterebene (Diskussion | Beiträge). Sie kann sich erheblich von der aktuellen Version<lb/> unterscheiden.<lb/> (Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version →<lb/> (Unterschied)<lb/> </note>

Bei einem Mailing handelt es sich um eine Massen-Postsendung, welche persönlich adressiert ist,<lb/> teiladressiert ist, oder als Wurfsendung verbreitet wird. Sie ist immer werbend.<lb/> Das Mailing ist ein heute weit genutztes Instrument, um bestimmte Kunden-und Zielgruppen<lb/> kostengünstig, schnell, zuverlässig und persönlich zu erreichen. Es ist das klassische Werbemittel im<lb/> Direktmarketing.<lb/>Varianten eines Mailings<lb/> Adressiertes Mailing<lb/>Das adressierte Mailing wird für den direkten Kundenkontakt benutzt. Entweder wird ein eigener<lb/> Kundenstamm (Kundendatenbank) angesprochen, um Produkte zu bewerben, oder es werden<lb/> Adressdaten von Adresshändlern erworben, um durch das Mailing den Kundenstamm zu erweitern.<lb/> Bei erworbenen Adressen wird versucht durch spezielle Angebote den potenziellen Kunden zu<lb/> bewegen, etwas zu kaufen, um dessen Adresse in den eigenen Kundenstamm integrieren zu können.<lb/>

		</front>
	</text>
</tei>


text:
maintainer        "Opscode, Inc."
maintainer_email  "cookbooks@opscode.com"
license           "Apache 2.0"
description       "Updates motd.tail with Chef Roles"
long_description  <<-EOH
Queries Chef for the roles assigned to the node and updates motd.tail
EOH
version           "1.0.0"
recipe            "motd", "Updates motd.tail with Chef Roles"


text:
/* ----- EDITOR ----- */
.css_non_editable_mode_hidden {
  display: none !important;
}

/* ----- Editor (for public user, like forum) ----- */
.note-toolbar {
  margin-left: 0 !important;
}

.note-popover .popover > .arrow {
  display: none;
}

/* ----- GENERIC LAYOUTING HELPERS ---- */
.hidden {
  display: none !important;
}

/* table */
#wrapwrap table.table, .o_editable table.table {
  table-layout: fixed;
}
#wrapwrap table.table td, .o_editable table.table td {
  min-width: 20px;
}

/* Media */
img.shadow {
  -moz-box-shadow: 0px 3px 8px rgba(0, 0, 0, 0.2);
  -webkit-box-shadow: 0px 3px 8px rgba(0, 0, 0, 0.2);
  box-shadow: 0px 3px 8px rgba(0, 0, 0, 0.2);
}

img.padding-small, .img.padding-small, span.fa.padding-small, iframe.padding-small {
  padding: 4px;
}
img.padding-medium, .img.padding-medium, span.fa.padding-medium, iframe.padding-medium {
  padding: 8px;
}
img.padding-large, .img.padding-large, span.fa.padding-large, iframe.padding-large {
  padding: 16px;
}
img.padding-xl, .img.padding-xl, span.fa.padding-xl, iframe.padding-xl {
  padding: 32px;
}

div.media_iframe_video.padding-small iframe {
  padding: 4px;
}
div.media_iframe_video.padding-medium iframe {
  padding: 8px;
}
div.media_iframe_video.padding-large iframe {
  padding: 16px;
}
div.media_iframe_video.padding-xl iframe {
  padding: 32px;
}

/* font awsome */
.fa-6x {
  font-size: 6em;
}

.fa-7x {
  font-size: 7em;
}

.fa-8x {
  font-size: 8em;
}

.fa-9x {
  font-size: 9em;
}

.fa-10x {
  font-size: 10em;
}

.fa.center-block {
  text-align: center;
}

/* video */
div.media_iframe_video {
  margin: 0 auto;
  text-align: center;
  position: relative;
  overflow: hidden;
}
div.media_iframe_video iframe {
  width: 100%;
  height: 100%;
  top: 0;
  position: absolute;
  margin: 0 auto;
  margin-left: -50%;
}
div.media_iframe_video .media_iframe_video_size {
  padding-bottom: 66.5%;
  position: relative;
  width: 100%;
  height: 0;
}
div.media_iframe_video .css_editable_mode_display {
  position: absolute;
  width: 100%;
  height: 100%;
  display: none;
  z-index: 2;
}

html[data-browser^="msie"] div.media_iframe_video iframe {
  margin-left: 0;
}

/* Mobile view */
@media (max-width: 768px) {
  img:not(.cke_iframe), .media_iframe_video, span.fa, i.fa {
    -webkit-transform: none !important;
    -moz-transform: none !important;
    -ms-transform: none !important;
    -o-transform: none !important;
    transform: none !important;
  }
}
/* ---- fields --- */
address .fa.fa-mobile-phone {
  margin: 0 3px 0 2px;
}
address .fa.fa-file-text-o {
  margin-right: 1px;
}

span[data-oe-type="monetary"] {
  white-space: nowrap;
}

/* ---- MENU ---- {{{ */
div.oe_menu_buttons {
  top: -8px;
  right: -8px;
}

ul.oe_menu_editor .fa-home {
  display: none;
}
ul.oe_menu_editor > li:first-child > div > span > .fa-home {
  display: block;
}
ul.oe_menu_editor .oe_menu_placeholder {
  outline: 1px dashed #4183C4;
}
ul.oe_menu_editor ul {
  list-style: none;
}
ul.oe_menu_editor li div {
  cursor: move;
}
ul.oe_menu_editor .disclose {
  cursor: pointer;
  width: 10px;
  display: none;
}


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
Atti Inst. Veneto Sci. lett. , ed Arti 6: (1888)

#### Original name
Marasmius gordipes Sacc. & Paol.

### Remarks
null


text:
import factory
import factory.django
from faker import Faker

from machina.core.db.models import get_model
from machina.test.factories.conversation import PostFactory

faker = Faker()

Attachment = get_model('forum_attachments', 'Attachment')

class AttachmentFactory(factory.django.DjangoModelFactory):
    post = factory.SubFactory(PostFactory)
    comment = faker.text(max_nb_chars=255)
    file = factory.django.FileField()

    class Meta:
        model = Attachment


text:
import {
  async, tick, fakeAsync, ComponentFixture, TestBed, discardPeriodicTasks
} from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { TypeaheadModule, TypeaheadMatch } from 'ngx-bootstrap/typeahead';
import { PredictiveSearchComponent } from './predictive-search.component';
import { UiModule } from '../../ui/ui.module';
import { Pipe, PipeTransform } from '@angular/core';
import { TranslateModule, TranslatePipe } from '@ngx-translate/core';
import { ServicesModule } from '../../services/services.module';

@Pipe({ name: 'translate' })
export class TranslatePipeMock implements PipeTransform {
  transform(value: any): any {
    return value;
  }
}

describe('PredictiveSearchComponent', () => {
  let component: PredictiveSearchComponent;
  let fixture: ComponentFixture<PredictiveSearchComponent>;
  let inputEl;
  let clearEl;
  const defaultOptionsLimit = 5;
  const defaultOptionField = 'name';
  const defaultOptions = [
    {name: 'Test 1'},
    {name: 'Test 2'},
    {name: 'Test 3'},
    {name: 'Test 4'},
    {name: 'Test 5'},
    {name: 'Test 6'}
  ];

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ ],
      imports: [ FormsModule, TypeaheadModule.forRoot(), UiModule, ServicesModule.forRoot() ],
      providers: [ { provide: TranslatePipe, useClass: TranslatePipeMock }]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(PredictiveSearchComponent);
    component = fixture.componentInstance;
    component.optionsLimit = defaultOptionsLimit;
    component.options = defaultOptions;
    component.optionField = defaultOptionField;
    component.updateSelection();
    fixture.detectChanges();
    inputEl = fixture.debugElement.query(By.css('input'));
    clearEl = fixture.debugElement.query(By.css('.clear'));
  });

  it('should be created', () => {
    expect(component).toBeTruthy();
  });

  it('should display results on input', async(() => {
    const el = fixture.debugElement.query(By.css('input')).nativeElement;
    el.value = 't';
    const event = new Event('input'); // typeahead is triggered by 'input' event
    el.dispatchEvent(event);
    fixture.detectChanges();
    fixture.whenStable().then(() => {
      fixture.detectChanges();
      expect(fixture.debugElement.nativeElement.querySelector('.dropdown') === null).toBeFalsy();
    });
  }));

  it('should display the option field property', async(() => {
    const el = fixture.debugElement.query(By.css('input')).nativeElement;
    el.value = 't';
    const event = new Event('input');
    el.dispatchEvent(event);
    fixture.detectChanges();
    fixture.whenStable().then(() => {
      fixture.detectChanges();
      expect(fixture.debugElement.nativeElement.querySelector('li').textContent)
        .toContain(defaultOptions[0].name);
    });
  }));

  it('should emit the selection when clicked', fakeAsync(() => {
    let selection;
    component.selectionChange.subscribe((sel) => { selection = sel; });
    const newMatch = new TypeaheadMatch(defaultOptions[0].name);
    component.updateSelection(newMatch);
    tick();
    fixture.detectChanges();
    expect(selection.selection).toEqual(newMatch.value);
    discardPeriodicTasks();
  }));

  it('should not display the clear button without input', fakeAsync(() => {
    const clearElStyle = clearEl.nativeElement.style;
    expect(clearElStyle.display).toEqual('none');
    discardPeriodicTasks();
  }));

  it('should display the clear button with input', () => {
    component.selected = 't';
    fixture.detectChanges();
    expect(expect(clearEl.nativeElement.style.display).toEqual('block'));
  });

  it('should clear the selection when clear button is clicked', fakeAsync(() => {
    component.updateSelection(new TypeaheadMatch(defaultOptions[0].name));
    tick();
    fixture.detectChanges();
    clearEl.triggerEventHandler('click', null);
    tick();
    fixture.detectChanges();
    fixture.whenStable().then(() => {
      fixture.detectChanges();
      expect(fixture.debugElement.nativeElement.querySelector('input').value.trim())
        .toEqual('');
    });
    discardPeriodicTasks();
  }));

  it('should hide the clear button after it is clicked', fakeAsync(() => {
    component.updateSelection(new TypeaheadMatch(defaultOptions[0].name));
    tick();
    fixture.detectChanges();
    clearEl.triggerEventHandler('click', null);
    tick();
    fixture.detectChanges();
    fixture.whenStable().then(() => {
      fixture.detectChanges();
      expect(expect(clearEl.nativeElement.style.display).toEqual('none'));
    });
    discardPeriodicTasks();
  }));
});


text:
//---------------------------------------------------------------------
// File: FileReadMultipleStep.cs
//
// Summary:
//
//---------------------------------------------------------------------
// Copyright (c) 2004-2017, Kevin B. Smith. All rights reserved.
//
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//---------------------------------------------------------------------

using System;
using System.IO;
using System.Threading;
using System.Collections.ObjectModel;
using BizUnit.Core.Common;
using BizUnit.TestSteps.Common;
using BizUnit.Core.TestBuilder;

namespace BizUnit.TestSteps.File
{
	internal class MultiUnknownException : Exception
    {
        internal MultiUnknownException( string message ) : base( message ) {}
    }

    ///
    /// The FileMultiValidateStep step checks a given directory for files matching the file masks and iterates around all of the specified validate steps
    /// to validate the file.
    ///
    public class FileReadMultipleStep : TestStepBase
    {
        public FileReadMultipleStep()
        {
            SubSteps = new Collection<SubStepBase>();
        }

        ///
        /// The time to wait in milisecs for the file, after which the step will fail if the file is not found
        ///
        public int Timeout { get; set; }

        ///
        /// The directory path to search
        ///
        public string DirectoryPath { get; set; }

        ///
        /// Filter to apply to directory path, e.g. "*.xml" or "MyFile*.txt"
        ///
        public string SearchPattern { get; set; }

        ///
        /// Flag to specify whether the files should be deleted upon completion of the test step
        ///
        public bool DeleteFiles { get; set; }

        ///
        /// The number of files expected to be found
        ///
        public int ExpectedNumberOfFiles { get; set; }

        ///
        /// TestStepBase.Execute() implementation
		///
		/// <param name='context'>The context for the test, this holds state that is passed beteen tests</param>
		public override void Execute(Context context)
        {
            var endTime = DateTime.Now.AddMilliseconds(Timeout);
            bool found = false;
            string[] filelist;
            int timesLogged = 0;

            context.LogInfo("Searching directory: {0}, search pattern: {1}", DirectoryPath, SearchPattern);

            do
            {
                Thread.Sleep(100);

                // Get the list of files in the directory
                filelist = Directory.GetFiles(DirectoryPath, SearchPattern);

                if ( filelist.Length == ExpectedNumberOfFiles)
                    break;

            } while (endTime > DateTime.Now);

            context.LogInfo("Number of files found: {0}", filelist.Length);

            if (filelist.Length == 0)
            {
                // Expecting more than one file
                throw new ApplicationException(String.Format("Directory contains no files matching the pattern!"));
            }

            if (0 < ExpectedNumberOfFiles && filelist.Length != ExpectedNumberOfFiles)
            {
                // Expecting a specified number of files
                throw new ApplicationException(String.Format("Directory contained: {0} files, but the step expected: {1} files", filelist.Length, ExpectedNumberOfFiles));
            }

            // For each file in the file list
            foreach (string filePath in filelist)
            {
                context.LogInfo("FileReadMultipleStep validating file: {0}", filePath);

                Stream fileData = StreamHelper.LoadFileToStream(filePath, Timeout);
                context.LogData("File: " + filePath, fileData);
                fileData.Seek(0, SeekOrigin.Begin);

                // Check it against the validate steps to see if it matches one of them
                foreach(var subStep in SubSteps)
                {
                    try
                    {
                        // Try the validation and catch the exception
                        fileData = subStep.Execute(fileData, context);
                    }
                    catch (Exception ex)
                    {
                        context.LogException(ex);
                        throw;
                    }
                }

                if(DeleteFiles)
                {
                    System.IO.File.Delete(filePath);
                }
            }
        }

        public override void Validate(Context context)
        {
            ArgumentValidation.CheckForEmptyString(DirectoryPath, "DirectoryPath");
            ArgumentValidation.CheckForEmptyString(SearchPattern, "SearchPattern");
            if(ExpectedNumberOfFiles < 1)
                throw new ArgumentException(string.Format("ExpectedNumberOfFiles should be greater than zero, but was set to: {0}", ExpectedNumberOfFiles));

        }
    }
}


text:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.github.ayvazj.rokontrol">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

</manifest>


text:
@implementation QBooleanElement {
    __unsafe_unretained QuickDialogController *_controller;
}
@synthesize onImage = _onImage;
@synthesize offImage = _offImage;
@synthesize boolValue = _boolValue;
@synthesize enabled = _enabled;

- (QBooleanElement *)init {
    self = [self initWithTitle:nil BoolValue:YES];
    return self;
}

- (QBooleanElement *)initWithTitle:(NSString *)title BoolValue:(BOOL)value {
    self = [self initWithTitle:title Value:nil];
    _boolValue = value;
    _enabled = YES;
    return self;
}

- (void)setOnImageName:(NSString *)name {
    self.onImage = [UIImage imageNamed:name];
}

- (void)setOffImageName:(NSString *)name {
    self.offImage = [UIImage imageNamed:name];
}

- (UITableViewCell *)getCellForTableView:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller {
    UITableViewCell *cell = [super getCellForTableView:tableView controller:controller];
    cell.accessoryType = self.sections!= nil ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone;
    cell.selectionStyle = self.sections!= nil ? UITableViewCellSelectionStyleBlue: UITableViewCellSelectionStyleNone;
    _controller = controller;
    if ((_onImage==nil) && (_offImage==nil))  {
        UISwitch *boolSwitch = [[UISwitch alloc] init];
        boolSwitch.on = _boolValue;
        boolSwitch.enabled = _enabled;
        [boolSwitch addTarget:self action:@selector(switched:) forControlEvents:UIControlEventValueChanged];
        cell.accessoryView = boolSwitch;

    } else {
        UIButton *boolButton = [[UIButton alloc] init];
        [boolButton setImage:self.offImage forState:UIControlStateNormal];
        [boolButton setImage:self.onImage forState:UIControlStateSelected];
        cell.accessoryView = boolButton;
        boolButton.enabled = _enabled;
        boolButton.selected = _boolValue;
        [boolButton sizeToFit];
        [boolButton addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
    }
    return cell;
}

- (void)selected:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller indexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    _boolValue = !_boolValue;
    if ([cell.accessoryView class] == [UIImageView class]){
        ((UIImageView *)cell.accessoryView).image =  _boolValue ? _onImage : _offImage;
    }
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    if (_sections!=nil)
        [self handleElementSelected:controller];
}

- (void)buttonPressed:(UIButton *)boolButton {
    _boolValue = !boolButton.selected;
    boolButton.selected = _boolValue;
    if (_controller!=nil && self.controllerAction!=nil)
        [self handleElementSelected:_controller];
}

- (void)switched:(id)boolSwitch {
    _boolValue = ((UISwitch *)boolSwitch).on;
    if (_controller!=nil && self.controllerAction!=nil)
        [self handleElementSelected:_controller];
}

- (void)fetchValueIntoObject:(id)obj {
	if (_key==nil)
		return;
    [obj setValue:[NSNumber numberWithBool:_boolValue] forKey:_key];
}

@end


text:
class AddStepToGame < ActiveRecord::Migration
  def self.up
    add_column :games, :step, :integer, default: 0, null: false
  end

  def self.down
    remove_column :games, :step
  end
end


text:
Built on Angular framework

# Quickstart

* `npm install`
* `npm start`
* Open [http://localhost:3000](http://localhost:3000)
* `Ctrl-C` to stop

## Prerequisites

Node.js and npm are essential to Angular development.

Get it now if it's not already installed on your machine.

**Verify that you are running at least node `v4.x.x` and npm `3.x.x`**
by running `node -v` and `npm -v` in a terminal/console window.
Older versions produce errors.

We recommend [nvm](https://github.com/creationix/nvm) for managing multiple versions of node and npm.

> See npm and nvm version notes above

Install the npm packages described in the `package.json` and verify that it works:

```shell
sudo npm install -g stylus
```

```shell
npm install
npm start
```

>Doesn't work in _Bash for Windows_ which does not support servers as of January, 2017.

The `npm start` command first compiles the application,
then simultaneously re-compiles and runs the `lite-server`.
Both the compiler and the server watch for file changes.

Game will be running after npm start.

Shut it down manually with `Ctrl-C`.

### npm scripts

We've captured many of the most useful commands in npm scripts defined in the `package.json`:

* `npm start` - runs the compiler and a server at the same time, both in "watch mode".
* `npm run build` - runs the TypeScript compiler once.
* `npm run build:w` - runs the TypeScript compiler in watch mode; the process keeps running, awaiting changes to TypeScript files and re-compiling when it sees them.
* `npm run serve` - runs the [lite-server](https://www.npmjs.com/package/lite-server), a light-weight, static file server, written and maintained by
[John Papa](https://github.com/johnpapa) and
[Christopher Martin](https://github.com/cgmartin)
with excellent support for Angular apps that use routing.

Here are the test related scripts:
* `npm test` - compiles, runs and watches the karma unit tests
* `npm run e2e` - compiles and run protractor e2e tests, written in Typescript (*e2e-spec.ts)

## Testing

The QuickStart documentation doesn't discuss testing.
This repo adds both karma/jasmine unit test and protractor end-to-end testing support.

These tools are configured for specific conventions described below.

*It is unwise and rarely possible to run the application, the unit tests, and the e2e tests at the same time.
We recommend that you shut down one before starting another.*

### Unit Tests
TypeScript unit-tests are usually in the `src/app` folder. Their filenames must end in `.spec.ts`.

Look for the example `src/app/app.component.spec.ts`.
Add more `.spec.ts` files as you wish; we configured karma to find them.

Run it with `npm test`

That command first compiles the application, then simultaneously re-compiles and runs the karma test-runner.
Both the compiler and the karma watch for (different) file changes.

Shut it down manually with `Ctrl-C`.

Test-runner output appears in the terminal window.
We can update our app and our tests in real-time, keeping a weather eye on the console for broken tests.
Karma is occasionally confused and it is often necessary to shut down its browser or even shut the command down (`Ctrl-C`) and
restart it. No worries; it's pretty quick.

### End-to-end (E2E) Tests

E2E tests are in the `e2e` directory, side by side with the `src` folder.
Their filenames must end in `.e2e-spec.ts`.

Look for the example `e2e/app.e2e-spec.ts`.
Add more `.e2e-spec.js` files as you wish (although one usually suffices for small projects);
we configured Protractor to find them.

Thereafter, run them with `npm run e2e`.

That command first compiles, then simultaneously starts the `lite-server` at `localhost:8080`
and launches Protractor.

The pass/fail test results appear at the bottom of the terminal window.
A custom reporter (see `protractor.config.js`) generates a  `./_test-output/protractor-results.txt` file
which is easier to read; this file is excluded from source control.

Shut it down manually with `Ctrl-C`.

[travis-badge]: https://travis-ci.org/angular/quickstart.svg?branch=master
[travis-badge-url]: https://travis-ci.org/angular/quickstart


text:
package seedu.todo.controllers;

import java.io.IOException;
import java.util.Map;

import seedu.todo.MainApp;
import seedu.todo.commons.core.Config;
import seedu.todo.commons.exceptions.ParseException;
import seedu.todo.commons.util.ConfigUtil;
import seedu.todo.commons.util.StringUtil;
import seedu.todo.controllers.concerns.Renderer;

/**
 * Controller to unalias an existing alias.
 *
 * @author louietyj
 *
 */

public class UnaliasController implements Controller {

    private static final String NAME = "Unalias";
    private static final String DESCRIPTION = "Deletes an existing alias pair.";
    private static final String COMMAND_SYNTAX = "unalias <alias key>";

    private static final String MESSAGE_DESTROY_SUCCESS = "Successfully destroyed alias!";
    private static final String MESSAGE_INVALID_INPUT = "Invalid alias parameters! Alias inputs must consist solely "
            + "of alphabetical characters.";
    private static final String MESSAGE_ALIAS_NOT_EXISTS = "Specified alias key doesn't exist!";
    private static final String SAVE_ERROR = "There was an error saving your aliases. Please try again.";

    private static CommandDefinition commandDefinition =
            new CommandDefinition(NAME, DESCRIPTION, COMMAND_SYNTAX);

    public static CommandDefinition getCommandDefinition() {
        return commandDefinition;
    }

    @Override
    public float inputConfidence(String input) {
        // TODO
        return input.toLowerCase().startsWith("unalias") ? 1 : 0;
    }

    @Override
    public void process(String input) throws ParseException {
        String aliasKey = input.replaceFirst("unalias", "").trim();

        if (aliasKey.isEmpty() || !validateAlias(aliasKey)) {
            renderDisambiguation(aliasKey, MESSAGE_INVALID_INPUT);
            return;
        }

        // Persist alias mapping
        try {
            if (destroyAlias(aliasKey)) {
                Renderer.renderAlias(MESSAGE_DESTROY_SUCCESS);
            } else {
                renderDisambiguation(aliasKey, MESSAGE_ALIAS_NOT_EXISTS);
            }
        } catch (IOException e) {
            Renderer.renderAlias(SAVE_ERROR);
            return;
        }
    }

    private static boolean destroyAlias(String aliasKey) throws IOException {
        Config config = MainApp.getConfig();
        Map<String, String> aliases = config.getAliases();
        if (aliases.remove(aliasKey) == null) {
            return false;
        }
        ConfigUtil.saveConfig(config, MainApp.getConfigFilePath());
        return true;
    }

    /**
     * Validates that string is sanitized and safe for aliasing.
     *
     * @param alias     string to check
     * @return          true if string is sanitized, false otherwise
     */
    private static boolean validateAlias(String alias) {
        return alias.chars().allMatch(Character::isLetter);
    }

    private static void renderDisambiguation(String aliasKey, String message) {
        String sanitizedAliasKey = StringUtil.sanitize(aliasKey);
        sanitizedAliasKey = StringUtil.replaceEmpty(sanitizedAliasKey, "<alias key>");
        Renderer.renderDisambiguation(String.format("unalias \"%s\"", sanitizedAliasKey), message);
    }

}


text:
[![Issues Ready to be Worked on](https://badge.waffle.io/ssokolow/itad_importer.png?label=confirmed&title=Ready)](https://waffle.io/ssokolow/itad_importer)

This userscript adds "Export to ITAD" buttons to online game vendors who do
not provide a way for sites like IsThereAnyDeal.com to query user game lists
and wishlists remotely.

It is currently in **beta** and any bugs should be reported in the
[issue tracker](https://github.com/ssokolow/itad_importer/issues).

Currently supported vendors are:

* [FireFlower Games](http://fireflowergames.com/)
* [Flying Bundle](http://www.flyingbundle.com/) (direct downloads only)
* [GOG.com](http://www.gog.com) (collection only. Wishlists supported by ITAD
  directly.)
* [Groupees](http://groupees.com/) (direct downloads in bundles tab only)
* [Humble Store](http://www.humblebundle.com) ([Bug:](https://github.com/ssokolow/itad_importer/issues/14) Import via whole-collection
  view includes Steam-only purchases)

See the [screenshot sheet](https://raw.githubusercontent.com/ssokolow/itad_importer/master/screenshots/1.png) for a reference as to where the added buttons should appear.

### Installation

1. Install [Greasemonkey](https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/)
   in [Firefox](http://getfirefox.com/)
   ([Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo)
   in Chrome should also work but hasn't yet been tested)
2. Restart Firefox
3. Install the [userscript](https://greasyfork.org/en/scripts/13887-isthereanydeal-com-collection-importer)

(Installation [via GreasyFork](https://greasyfork.org/en/scripts/13887-isthereanydeal-com-collection-importer) is recommended to ensure automatic updates
function as reliably as possible.)

### Development

The authoritative copy of this script is the
[CoffeeScript](http://coffeescript.org/) source file. Patches against the
generated JavaScript may or may not be accepted at the developers' discretion.
(We have to rewrite them in CoffeeScript, so they'll have to be worthwhile.)

At the moment, the official method for developing this script has yet to be
updated for Quantum-era Firefox and is as follows:

1. On a Unixy machine (eg. Linux), install Firefox 52 ESR and a version of
   Greasemonkey old enough to store its scripts as bare files on disk.
2. Install the [release version](https://greasyfork.org/en/scripts/13887-isthereanydeal-com-collection-importer)
   of the script in Firefox
3. Install [Node.js](http://nodejs.org/)
4. Run `npm install`
5. Run `npm run-script develop`
6. Saving changes to the CoffeeScript source will now regenerate the copy of
   the script installed in Firefox.
7. When you're finished, hit Enter
8. The development script will regenerate the in-repository JavaScript and code
   documentation before exiting.
9. Commit the updated built files.

However, if you do not have a Unixy machine handy, this quick and dirty method
can also be used:

 1. Open http://coffeescript.org/
 2. Open the "Try CoffeeScript" tab.
 3. Use the browser's Developer Tools to add a `contentEditable`
  attribute to the `<pre>` tag for the right pane so you can use
  Ctrl+A followed by Ctrl+C to
  quickly copy everything.
 4. Install the
  [release version](https://greasyfork.org/en/scripts/13887-isthereanydeal-com-collection-importer)
  of the script and use Greasemonkey's edit button to open up the version it's
  using so you can test changes simply by copying JS from "Try CoffeeScript" to
  the editor, saving, and reloading the page in the browser.
 5. Use the "Try CoffeeScript" button to switch back and forth between
  code and reference materials.


text:
{-# LANGUAGE UndecidableInstances #-}
module Foreign.Mms.List(List(..)) where

import Prelude hiding(length)
import qualified Prelude

import Foreign.Mms.Vector(Vector(..))
import Foreign.Mms.MappedVector
import Foreign.Mms.Core(Mode(..))
import Foreign.Mms.Class(Mms(..))
import Foreign.Mms.Put(saveOffset)

data List (m :: Mode) a where
    AllocatedList :: { unAllocatedList :: [a] } -> List 'Allocated a
    MappedList :: { unMappedList :: MappedVector a } -> List 'Mapped a

deriving instance Foldable (List m)
deriving instance Show a => Show (List m a)

-- This instance does not satisfy coverage condition for the fundeps
-- of Mms class, hence the UndecidableInstances. It however satisfies
-- weak coverage condition, so it's mostly fineFromMms.
instance Mms a m => Mms (List 'Allocated a) (List 'Mapped m) where
    writeData (AllocatedList xs) =
        mapM_ writeData xs >> saveOffset >> mapM_ writeFields xs
    writeFields = mappedVectorWriteFields . fromIntegral . Prelude.length

    mmsSize _ = mappedVectorSize
    mmsAlignment _ = mappedVectorAlignment
    readFields = MappedList <$> mappedVectorReadFields

instance Vector (List 'Allocated) a where
    length = Prelude.length . unAllocatedList
    (!) = (!!) . unAllocatedList

instance Vector (List 'Mapped) a where
    length = length . unMappedList
    (!) = (!) . unMappedList


text:
using System;
using QFramework;
using UnityEngine;
using UnityEngine.SceneManagement;

namespace ShootingEditor2D
{
    public class UIGameStart : MonoBehaviour
    {
        private readonly Lazy<GUIStyle> mLabelStyle = new Lazy<GUIStyle>(() => new GUIStyle(GUI.skin.label)
        {
            fontSize = 60,
            alignment = TextAnchor.MiddleCenter
        });

        private readonly Lazy<GUIStyle> mButtonStyle = new Lazy<GUIStyle>(() => new GUIStyle(GUI.skin.button)
        {
            fontSize = 40,
            alignment = TextAnchor.MiddleCenter
        });

        private void OnGUI()
        {
            var labelRect = RectHelper.RectForAnchorCenter(Screen.width * 0.5f, Screen.height * 0.5f, 600, 100);

            GUI.Label(labelRect, "ShootingEditor2D", mLabelStyle.Value);

            var buttonRect = RectHelper.RectForAnchorCenter(Screen.width * 0.5f, Screen.height * 0.5f + 150, 300, 100);

            if (GUI.Button(buttonRect, "开始游戏", mButtonStyle.Value))
            {
                SceneManager.LoadScene("Game");
            }
        }
    }
}


text:
package org.apache.drill.exec.vector.accessor.reader;

import org.apache.drill.exec.vector.BitVector;
import org.apache.drill.exec.vector.accessor.ValueType;
import org.apache.drill.exec.vector.accessor.reader.BaseScalarReader.BaseFixedWidthReader;

/**
 * Specialized reader for bit columns. Bits are packed 8 per byte.
 * Rather than duplicate that logic here, this reader just delegates
 * to the vector's own accessor.
 */
public class BitColumnReader extends BaseFixedWidthReader {

  @Override
  public ValueType valueType() {
    return ValueType.BOOLEAN;
  }

  @Override public int width() { return BitVector.VALUE_WIDTH; }

  @Override
  public boolean getBoolean() {
    final BitVector.Accessor accessor = ((BitVector) vectorAccessor.vector()).getAccessor();
    final int readOffset = vectorIndex.offset();
    return accessor.get(readOffset) != 0;
  }

  @Override
  public int getInt() {
    return getBoolean() ? 1 : 0;
  }
}


text:
<?php

return array(

	/*
	|--------------------------------------------------------------------------
	| Default Authentication Driver
	|--------------------------------------------------------------------------
	|
	| This option controls the authentication driver that will be utilized.
	| This drivers manages the retrieval and authentication of the users
	| attempting to get access to protected areas of your application.
	|
	| Supported: "eloquent" (more coming soon).
	|
	*/

	'driver' => 'eloquent',

	/*
	|--------------------------------------------------------------------------
	| Default Hasher
	|--------------------------------------------------------------------------
	|
	| This option allows you to specify the default hasher used by Sentry
	|
	| Supported: "native", "bcrypt", "sha256"
	|
	*/

	'hasher' => 'bcrypt', // Sam : changed to bcrypt for compatibility

	/*
	|--------------------------------------------------------------------------
	| Cookie
	|--------------------------------------------------------------------------
	|
	| Configuration specific to the cookie component of Sentry.
	|
	*/

	'cookie' => array(

		/*
		|--------------------------------------------------------------------------
		| Default Cookie Key
		|--------------------------------------------------------------------------
		|
		| This option allows you to specify the default cookie key used by Sentry.
		|
		| Supported: string
		|
		*/

		'key' => 'cartalyst_sentry',

 	),

	/*
	|--------------------------------------------------------------------------
	| Groups
	|--------------------------------------------------------------------------
	|
	| Configuration specific to the group management component of Sentry.
	|
	*/

	'groups' => array(

		/*
		|--------------------------------------------------------------------------
		| Model
		|--------------------------------------------------------------------------
		|
		| When using the "eloquent" driver, we need to know which
		| Eloquent models should be used throughout Sentry.
		|
		*/

		'model' => 'TypiCMS\Modules\Groups\Models\Group',

	),

	/*
	|--------------------------------------------------------------------------
	| Users
	|--------------------------------------------------------------------------
	|
	| Configuration specific to the user management component of Sentry.
	|
	*/

	'users' => array(

		/*
		|--------------------------------------------------------------------------
		| Model
		|--------------------------------------------------------------------------
		|
		| When using the "eloquent" driver, we need to know which
		| Eloquent models should be used throughout Sentry.
		|
		*/

		'model' => 'TypiCMS\Modules\Users\Models\User',

		/*
		|--------------------------------------------------------------------------
		| Login Attribute
		|--------------------------------------------------------------------------
		|
		| If you're the "eloquent" driver and extending the base Eloquent model,
		| we allow you to globally override the login attribute without even
		| subclassing the model, simply by specifying the attribute below.
		|
		*/

		'login_attribute' => 'email',

	),

	/*
	|--------------------------------------------------------------------------
	| Throttling
	|--------------------------------------------------------------------------
	|
	| Throttling is an optional security feature for authentication, which
	| enables limiting of login attempts and the suspension & banning of users.
	|
	*/

	'throttling' => array(

		/*
		|--------------------------------------------------------------------------
		| Throttling
		|--------------------------------------------------------------------------
		|
		| Enable throttling or not. Throttling is where users are only allowed a
		| certain number of login attempts before they are suspended. Suspension
		| must be removed before a new login attempt is allowed.
		|
		*/

		'enabled' => false,

		/*
		|--------------------------------------------------------------------------
		| Model
		|--------------------------------------------------------------------------
		|
		| When using the "eloquent" driver, we need to know which
		| Eloquent models should be used throughout Sentry.
		|
		*/

		'model' => 'Cartalyst\Sentry\Throttling\Eloquent\Throttle',

		/*
		|--------------------------------------------------------------------------
		| Attempts Limit
		|--------------------------------------------------------------------------
		|
		| When using the "eloquent" driver and extending the base Eloquent model,
		| you have the option to globally set the login attempts.
		|
		| Supported: int
		|
		*/

		'attempt_limit' => 5,

		/*
		|--------------------------------------------------------------------------
		| Suspension Time
		|--------------------------------------------------------------------------
		|
		| When using the "eloquent" driver and extending the base Eloquent model,
		| you have the option to globally set the suspension time, in minutes.
		|
		| Supported: int
		|
		*/

		'suspension_time' => 15,

	),

);


text:
A very simple Twitter bot, which retrieves a sentence of glorious Donald Ipsum from [the Donald Ipsum API][api], and posts it to [the Donald Ipsum Twitter account][twitter].

[api]: https://github.com/monooso/api.donaldipsum.net
[twitter]: https://twitter.com/donaldipsum

## Configuration ##
The bot requires that the @DonaldIpsum [Twitter OAuth tokens][tokens] be provided via environment variables, as follows.

[tokens]: https://dev.twitter.com/oauth/overview/application-owner-access-tokens "Twitter developer documentation"

| Name                          | Description             |
|:------------------------------|:------------------------|
| `TWITTER_ACCESS_TOKEN_KEY`    | The access token key    |
| `TWITTER_ACCESS_TOKEN_SECRET` | The access token secret |
| `TWITTER_CONSUMER_KEY`        | The consumer key        |
| `TWITTER_CONSUMER_SECRET`     | Left as an exercise for the reader |

## Example usage ##

```shell
$> TWITTER_ACCESS_TOKEN_KEY=abc123 \
   TWITTER_ACCESS_TOKEN_SECRET=xyx987 \
   TWITTER_CONSUMER_KEY=123abc \
   TWITTER_CONSUMER_SECRET=987xyz \
   npm start
```


text:
using System.Diagnostics;
using SharpNeat.Core;
using SharpNeat.Phenomes;

namespace SharpNeat.Domains.BinaryThreeMultiplexer
{
    /// <summary>
    /// Binary 3-Multiplexer task.
    /// One binary input selects which of two other binary inputs to output.
    /// </summary>
    public class BinaryThreeMultiplexerEvaluator : IPhenomeEvaluator<IBlackBox>
    {
        const double StopFitness = 100.0;
        ulong _evalCount;
        bool _stopConditionSatisfied;

        #region IPhenomeEvaluator<IBlackBox> Members

        /// <summary>
        /// Gets the total number of evaluations that have been performed.
        /// </summary>
        public ulong EvaluationCount
        {
            get { return _evalCount; }
        }

        /// <summary>
        /// Gets a value indicating whether some goal fitness has been achieved and that
        /// the the evolutionary algorithm/search should stop. This property's value can remain false
        /// to allow the algorithm to run indefinitely.
        /// </summary>
        public bool StopConditionSatisfied
        {
            get { return _stopConditionSatisfied; }
        }

        /// <summary>
        /// Evaluate the provided IBlackBox against the Binary 6-Multiplexer problem domain and return
        /// its fitness score.
        /// </summary>
        public FitnessInfo Evaluate(IBlackBox box)
        {
            double fitness = 0.0;
            bool success = true;
            double output;
            ISignalArray inputArr = box.InputSignalArray;
            ISignalArray outputArr = box.OutputSignalArray;
            _evalCount++;

            // 8 test cases.
            for(int i=0; i<8; i++)
            {
                // Apply bitmask to i and shift left to generate the input signals.
                // In addition we scale 0->1 to be 0.1->0.9.
                // Note. We /could/ eliminate all the boolean logic by pre-building a table of test
                // signals and correct responses, but this is probably faster.
                int tmp = i;
                for(int j=0; j<3; j++)
                {
                    inputArr[j] = tmp&0x1;
                    tmp >>= 1;
                }

                // Activate the black box.
                box.Activate();
                if(!box.IsStateValid)
                {   // Any black box that gets itself into an invalid state is unlikely to be
                    // any good, so let's just exit here.
                    return FitnessInfo.Zero;
                }

                // Read output signal.
                output = outputArr[0];
                Debug.Assert(output >= 0.0, "Unexpected negative output.");

                // Determine the correct answer by using highly cryptic (but fast) bit manipulation :)
                // The condition is true if the correct answer is true (1.0).
                if(((1<<(1+(i&0x1)))&i) != 0)
                {   // correct answer = true.
                    // Assign fitness on sliding scale between 0.0 and 1.0 based on squared error.
                    // In tests squared error drove evolution significantly more efficiently in this domain than absolute error.
                    // Note. To base fitness on absolute error use: fitness += output;
                    fitness += 1.0-((1.0-output)*(1.0-output));
                    if(output<0.5) {
                        success=false;
                    }
                }
                else
                {   // correct answer = false.
                    // Assign fitness on sliding scale between 0.0 and 1.0 based on squared error.
                    // In tests squared error drove evolution significantly more efficiently in this domain than absolute error.
                    // Note. To base fitness on absolute error use: fitness += 1.0-output;
                    fitness += 1.0-(output*output);
                    if(output>=0.5) {
                        success=false;
                    }
                }

                // Reset black box state ready for next test case.
                box.ResetState();
            }

            // If teh correct answer was given in each case then add a bonus value to the fitness.
            if(success) {
                fitness += 100.0;
            }

            if(fitness >= StopFitness) {
                _stopConditionSatisfied = true;
            }

            return new FitnessInfo(fitness, fitness);
        }

        /// <summary>
        /// Reset the internal state of the evaluation scheme if any exists.
        /// Note. The Binary Multiplexer problem domain has no internal state. This method does nothing.
        /// </summary>
        public void Reset()
        {
        }

        #endregion
    }
}


text:
pacifica_uploader 'default' do
  python_opts(
    provider: :system,
    version: '2.7'
  )
end
pacifica_uploadercli 'default' do
  python_opts(
    provider: :system,
    version: '2.7'
  )
end


text:
<!DOCTYPE html>

<meta charset="UTF-8">
<title>Meet the specification for line breaking between ruby bases</title>
<link rel="author" title="Xidorn Quan" href="https://www.upsuper.org">
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
<link rel="stylesheet" href="support/ruby-common.css">

  「なに、誰?」「私です」