function Hypergeometric( N, K, n ) {
	if ( !(this instanceof Hypergeometric) ) {
		return new Hypergeometric( N, K, n );
	}
	if ( !isNonNegativeInteger( N ) ) {
		throw new TypeError( format( 'invalid argument. Population size must be a nonnegative integer. Value: `%s`.', N ) );
	}
	if ( !isNonNegativeInteger( K ) ) {
		throw new TypeError( format( 'invalid argument. Subpopulation size must be a nonnegative integer. Value: `%s`.', K ) );
	}
	if ( !isNonNegativeInteger( n ) ) {
		throw new TypeError( format( 'invalid argument. Number of draws must be a nonnegative integer. Value: `%s`.', n ) );
	}
	if ( K > N ) {
		throw new RangeError( 'invalid arguments. Subpopulation size must be less than or equal to the population size.' );
	}
	if ( n > N ) {
		throw new RangeError( 'invalid arguments. Number of draws must be less than or equal to the population size.' );
	}
	defineProperty( this, 'N', {
		'configurable': false,
		'enumerable': true,
		'get': function get() {
			return N;
		},
		'set': function set( value ) {
			if ( !isNonNegativeInteger( value ) ) {
				throw new TypeError( format( 'invalid assignment. Must be a nonnegative integer. Value: `%s`.', value ) );
			}
			if ( K > value ) {
				throw new RangeError( format( 'invalid assignment. Must be larger than or equal to %u. Value: `%u`.', K, value ) );
			}
			if ( n > value ) {
				throw new RangeError( format( 'invalid assignment. Must be larger than or equal to %u. Value: `%u`.', n, value ) );
			}
			N = value;
		}
	});
	defineProperty( this, 'K', {
		'configurable': false,
		'enumerable': true,
		'get': function get() {
			return K;
		},
		'set': function set( value ) {
			if ( !isNonNegativeInteger( value ) ) {
				throw new TypeError( format( 'invalid assignment. Must be a nonnegative integer. Value: `%s`.', value ) );
			}
			if ( value > N ) {
				throw new RangeError( format( 'invalid assignment. Must be less than or equal to %u. Value: `%u`.', N, value ) );
			}
			K = value;
		}
	});
	defineProperty( this, 'n', {
		'configurable': false,
		'enumerable': true,
		'get': function get() {
			return n;
		},
		'set': function set( value ) {
			if ( !isNonNegativeInteger( value ) ) {
				throw new TypeError( format( 'invalid assignment. Must be a nonnegative integer. Value: `%s`.', value ) );
			}
			if ( value > N ) {
				throw new RangeError( format( 'invalid assignment. Must be less than or equal to %u. Value: `%u`.', N, value ) );
			}
			n = value;
		}
	});
	return this;
}
Hypergeometric distribution constructor.

@constructor
@param {NonNegativeInteger} N - population size
@param {NonNegativeInteger} K - subpopulation size
@param {NonNegativeInteger} n - number of draws
@throws {TypeError} `N` must be a nonnegative integer
@throws {TypeError} `K` must be a nonnegative integer
@throws {TypeError} `n` must be a nonnegative integer
@throws {RangeError} `K` must not exceed `N`
@throws {RangeError} `n` must not exceed `N`
@returns {Hypergeometric} distribution instance

@example
var hypergeometric = new Hypergeometric( 10, 5, 7 );

var y = hypergeometric.cdf( 0.8 );
// returns 0.0

var v = hypergeometric.mode;
// returns 4.0