/* */

/* eslint-disable no-bitwise, no-cond-assign */

/* eslint-disable no-return-assign */

/* harmony default export */

/* harmony export (binding) */

/* harmony import */

/*#__PURE__*/

/**
	* Samples elements from a population.
	*
	* @private
	* @param {Options} [options] - function options
	* @param {NonNegativeInteger} [options.size] - sample size
	* @param {boolean} [options.replace=true] - boolean indicating whether to sample with replacement
	* @param {boolean} [options.mutate=false] - boolean indicating whether to mutate the `pool` when sampling without replacement
	* @throws {TypeError} options argument must be an object
	* @throws {TypeError} must provide valid options
	* @throws {RangeError} `size` option must be less than or equal to the population when the `replace` option is `false`
	* @returns {Array} sample
	*/

/**
	* Samples elements from an array-like object.
	*
	* @private
	* @param {ArrayLike} x - array-like object from which to sample elements
	* @param {Options} [options] - function options
	* @param {NonNegativeInteger} [options.size] - sample size
	* @param {ProbabilityArray} [options.probs] - element probabilities
	* @param {boolean} [options.replace=true] - boolean indicating whether to sample with replacement
	* @throws {TypeError} first argument must be array-like
	* @throws {TypeError} options argument must be an object
	* @throws {TypeError} must provide valid options
	* @throws {RangeError} `size` option must be less than or equal to the length of `x` when the `replace` option is `false`
	* @returns {Array} sample
	*/

/**
 * A convenience hook around `useState` designed to be paired with
 * the component [callback ref](https://reactjs.org/docs/refs-and-the-dom.html#callback-refs) api.
 * Callback refs are useful over `useRef()` when you need to respond to the ref being set
 * instead of lazily accessing it in an effect.
 *
 * ```ts
 * const [element, attachRef] = useCallbackRef<HTMLDivElement>()
 *
 * useEffect(() => {
 *   if (!element) return
 *
 *   const calendar = new FullCalendar.Calendar(element)
 *
 *   return () => {
 *     calendar.destroy()
 *   }
 * }, [element])
 *
 * return <div ref={attachRef} />
 * ```
 *
 * @category refs
 */

/**
 * An `addEventListener` ponyfill, supports the `once` option
 */

/**
 * Copyright 2013-2014, Facebook, Inc.
 * All rights reserved.
 * https://github.com/facebook/react/blob/2aeb8a2a6beb00617a4217f7f8284924fa2ad819/src/vendor/core/hyphenateStyleName.js
 */

/**
 * Creates a `Ref` whose value is updated in an effect, ensuring the most recent
 * value is the one rendered with. Generally only required for Concurrent mode usage
 * where previous work in `render()` may be discarded befor being used.
 *
 * This is safe to access in an event handler.
 *
 * @param value The `Ref` value
 */

/**
 * Store the last of some value. Tracked via a `Ref` only updating it
 * after the component renders.
 *
 * Helpful if you need to compare a prop value to it's previous value during render.
 *
 * ```ts
 * function Component(props) {
 *   const lastProps = usePrevious(props)
 *
 *   if (lastProps.foo !== props.foo)
 *     resetValueFromProps(props.foo)
 * }
 * ```
 *
 * @param value the value to track
 */

/**
 * Track whether a component is current mounted. Generally less preferable than
 * properlly canceling effects so they don't run after a component is unmounted,
 * but helpful in cases where that isn't feasible, such as a `Promise` resolution.
 *
 * @returns a function that returns the current isMounted state of the component
 *
 * ```ts
 * const [data, setData] = useState(null)
 * const isMounted = useMounted()
 *
 * useEffect(() => {
 *   fetchdata().then((newData) => {
 *      if (isMounted()) {
 *        setData(newData);
 *      }
 *   })
 * })
 * ```
 */

/**
* @license Apache-2.0
*
* Copyright (c) 2018 The Stdlib Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* Compute the absolute difference.
*
* @module @stdlib/math/base/utils/absolute-difference
*
* @example
* var diff = require( '@stdlib/math/base/utils/absolute-difference' );
*
* var d = diff( 2.0, 5.0 );
* // returns 3.0
*
* d = diff( -1.0, 3.14 );
* // returns ~4.14
*
* d = diff( 10.1, -2.05 );
* // returns ~12.15
*
* d = diff( -0.0, 0.0 );
* // returns +0.0
*
* d = diff( NaN, 5.0 );
* // returns NaN
*
* d = diff( Infinity, -Infinity  );
* // returns Infinity
*
* d = diff( Infinity, Infinity  );
* // returns NaN
*/

/**
* Computes the absolute difference.
*
* @param {number} x - first number
* @param {number} y - second number
* @returns {number} absolute difference
*
* @example
* var d = absoluteDifference( 2.0, 5.0 );
* // returns 3.0
*
* @example
* var d = absoluteDifference( -1.0, 3.14 );
* // returns ~4.14
*
* @example
* var d = absoluteDifference( 10.1, -2.05 );
* // returns ~12.15
*
* @example
* var d = absoluteDifference( -0.0, 0.0 );
* // returns +0.0
*
* @example
* var d = absoluteDifference( NaN, 5.0 );
* // returns NaN
*
* @example
* var d = absoluteDifference( Infinity, -Infinity  );
* // returns Infinity
*
* @example
* var d = absoluteDifference( Infinity, Infinity  );
* // returns NaN
*/

/**
* Generate a linearly spaced numeric array using a provided increment.
*
* @module @stdlib/math/utils/incrspace
*
* @example
* var incrspace = require( '@stdlib/math/utils/incrspace' );
*
* var arr = incrspace( 0, 11, 2 );
* // returns [ 0, 2, 4, 6, 8, 10 ]
*/

/**
* Generates a linearly spaced numeric array using a provided increment.
*
* @param {number} x1 - first array value
* @param {number} x2 - array element bound
* @param {number} [increment=1] - increment
* @throws {TypeError} first argument must be numeric
* @throws {TypeError} second argument must be numeric
* @throws {TypeError} third argument must be numeric
* @throws {RangeError} length of created array must be less than `4294967295` (`2**32 - 1`)
* @returns {Array} linearly spaced numeric array
*
* @example
* var arr = incrspace( 0, 11, 2 );
* // returns [ 0, 2, 4, 6, 8, 10 ]
*/

/**
* Returns a function to sample elements from an array-like object.
*
* @param {ArrayLike} [pool] - array-like object from which to sample
* @param {Options} [options] - function options
* @param {PositiveInteger} [options.seed] - integer-valued seed
* @param {NonNegativeInteger} [options.size] - sample size
* @param {boolean} [options.replace=true] - boolean indicating whether to sample with replacement
* @param {boolean} [options.mutate=false] - boolean indicating whether to mutate the `pool` when sampling without replacement
* @throws {TypeError} `pool` must be an array-like object
* @throws {TypeError} options argument must be an object
* @throws {TypeError} must provide valid options
* @returns {Function} function to sample elements from an array-like object
*
* @example
* var sample = factory({
*     'seed': 232
* });
* var out = sample( 'abcdefg' );
* // e.g., returns [ 'g', 'd', 'g', 'f', 'c', 'e', 'f' ]
*
* @example
* var sample = factory( [ 1, 2, 3, 4, 5, 6 ], {
*     'seed': 232,
*     'size': 2
* });
* var out = sample();
* // e.g., returns [ 6, 4 ]
*
* out = sample();
* // e.g., returns [ 6, 5 ]
*
* @example
* var sample = factory( [ 1, 2, 3, 4, 5, 6 ], {
*     'seed': 474,
*     'size': 3,
*     'mutate': true,
*     'replace': false
* });
* var out = sample();
* // e.g., returns [ 4, 3, 6 ]
*
* out = sample();
* // e.g., returns [ 1, 5, 2 ]
*
* out = sample();
* // returns null
*
* @example
* var sample = factory( [ 0, 1 ], {
*     'size': 2
* });
*
* var out = sample();
* // e.g., returns [ 1, 1 ]
*
* out = sample({
*     'size': 10
* });
* // e.g., returns [ 0, 1, 1, 1, 0, 1, 0, 0, 1, 1 ]
*
* @example
* var sample = factory( [ 0, 1 ], {
*     'size': 2
* });
*
* var out = sample();
* // e.g., returns [ 1, 1 ]
*
* out = sample({
*     'replace': false
* });
* // e.g., returns [ 0, 1 ] or [ 1, 0 ]
*
* out = sample();
* // e.g., returns [ 1, 1 ]
*
* @example
* var sample = factory( [ 0, 1 ], {
*     'size': 2,
*     'mutate': true
* });
*
* var out = sample();
* // e.g., returns [ 1, 1 ]
*
* out = sample({
*     'replace': false
* });
* // e.g., returns [ 0, 1 ] or [ 1, 0 ]
*
* out = sample();
* // returns null
*/

/**
* Round a numeric value toward positive infinity.
*
* @module @stdlib/math/base/special/ceil
*
* @example
* var ceil = require( '@stdlib/math/base/special/ceil' );
*
* var v = ceil( -4.2 );
* // returns -4.0
*
* v = ceil( 9.99999 );
* // returns 10.0
*
* v = ceil( 0.0 );
* // returns 0.0
*
* v = ceil( NaN );
* // returns NaN
*/

/**
* Rounds a numeric value toward positive infinity.
*
* @param {number} x - input value
* @returns {number} rounded value
*
* @example
* var v = ceil( -4.2 );
* // returns -4.0
*
* @example
* var v = ceil( 9.99999 );
* // returns 10.0
*
* @example
* var v = ceil( 0.0 );
* // returns 0.0
*
* @example
* var v = ceil( NaN );
* // returns NaN
*/

/**
* Sample elements from an array-like object.
*
* @module @stdlib/random/sample
*
* @example
* var sample = require( '@stdlib/random/sample' );
*
* var out = sample( 'abc' );
* // e.g., returns [ 'a', 'a', 'b' ]
*
* out = sample( [ 3, 6, 9 ] );
* // e.g., returns [ 3, 9, 6 ]
*
* var bool = ( out.length === 3 );
* // returns true
*
* @example
* var sample = require( '@stdlib/random/sample' );
*
* var mysample = sample.factory({
*     'seed': 323
* });
* var out = mysample( [ 3, 6, 9 ], {
*     'size': 10
* });
* // e.g., returns [ 3, 9, 3, 3, 3, 6, 3, 3, 3, 6 ]
*/

/**
* Samples elements from an array-like object.
*
* @name sample
* @type {Function}
* @param {ArrayLike} x - array-like object from which to sample
* @param {Options} [options] - function options
* @param {NonNegativeInteger} [options.size] - sample size
* @param {ProbabilityArray} [options.probs] - element probabilities
* @param {boolean} [options.replace=true] - boolean indicating whether to sample with replacement
* @throws {TypeError} first argument must be array-like
* @throws {TypeError} options argument must be an object
* @throws {TypeError} must provide valid options
* @throws {RangeError} `size` option must be less than or equal to the length of `x` when the `replace` option is `false`
* @returns {Array} sample
*
* @example
* var out = sample( [ 3, null, NaN, 'abc', function(){} ] );
* // e.g., returns [ 3, 'abc', null, 3, null ]
*/

/**
* Samples from a discrete uniform distribution (equal probabilities and with replacement).
*
* @private
* @param {ArrayLike} x - array-like object from which to sample
* @param {NonNegativeInteger} size - sample size
* @param {Function} rand - PRNG for generating uniformly distributed numbers
* @returns {Array} sample
*/

/**
* Samples uniformly without replacement using the Fisher-Yates shuffle.
*
* ## References
*
* -   Knuth, Donald E. 1997. _The Art of Computer Programming, Volume 2 (3rd Ed.): Seminumerical Algorithms_. Boston, MA, USA: Addison-Wesley Longman Publishing Co., Inc.
*
* @private
* @param {ArrayLike} x - array-like object from which to sample
* @param {NonNegativeInteger} size - sample size
* @param {Function} rand - PRNG for generating uniformly distributed numbers
* @returns {Array} sample
*/

/**
* Samples with replacement and non-uniform probabilities using Vose's [alias method][alias-method].
*
* ## References
*
* -   Vose, Michael D. 1991. "A linear algorithm for generating random numbers with a given distribution." _IEEE Transactions on Software Engineering_ 17 (9): 972–75. doi:[10.1109/32.92917][@vose:1991].
*
* [alias-method]: http://keithschwarz.com/darts-dice-coins/
* [@vose:1991]: https://doi.org/10.1109/32.92917
*
*
* @private
* @param {ArrayLike} x - array-like object from which to sample
* @param {NonNegativeInteger} size - sample size
* @param {Function} rand - PRNG for generating uniformly distributed numbers
* @param {ProbabilityArray} probabilities - element probabilities
* @returns {Array} sample
*/

/**
* Samples without replacement from a discrete set using custom probabilities.
*
* ## Notes
*
* -   After each draw, the probabilities of the remaining observations are renormalized so that they sum to one.
*
*
* @private
* @param {ArrayLike} x - array-like object from which to sample
* @param {NonNegativeInteger} size - sample size
* @param {Function} rand - PRNG for generating uniformly distributed numbers
* @param {ProbabilityArray} probabilities - element probabilities
* @returns {Array} sample
*/

/**
* Square root of double-precision floating-point epsilon.
*
* @module @stdlib/constants/math/float64-sqrt-eps
* @type {number}
*
* @example
* var FLOAT64_SQRT_EPSILON = require( '@stdlib/constants/math/float64-sqrt-eps' );
* // returns 0.14901161193847656e-7
*/

/**
* Square root of double-precision floating-point epsilon.
*
* ```tex
* \sqrt{\frac{1}{2^{52}}}
* ```
*
* @constant
* @type {number}
* @default 0.14901161193847656e-7
* @see [IEEE 754]{@link https://en.wikipedia.org/wiki/IEEE_754-1985}
* @see [Machine Epsilon]{@link https://en.wikipedia.org/wiki/Machine_epsilon}
*/

/**
* Test if a value is an array of probabilities that sum to one.
*
* @module @stdlib/assert/is-unity-probability-array
*
* @example
* var isUnityProbabilityArray = require( '@stdlib/assert/is-unity-probability-array' );
*
* var bool = isUnityProbabilityArray( [ 0.25, 0.5, 0.25 ] );
* // returns true
*
* bool = isUnityProbabilityArray( new Uint8Array( [ 0, 1 ] ) );
* // returns true
*
* bool = isUnityProbabilityArray( [ 0.4, 0.4, 0.4 ] );
* // returns false
*
* bool = isUnityProbabilityArray( [ 3.14, 0.0 ] );
* // returns false
*/

/**
* Tests if a value is an array of probabilities that sum to one.
*
* @param {*} v - value to test
* @returns {boolean} boolean indicating if a value is a probability array
*
* @example
* var bool = isUnityProbabilityArray( [ 0.25, 0.5, 0.25 ] );
* // returns true
*
* @example
* var bool = isUnityProbabilityArray( new Uint8Array( [ 0, 1 ] ) );
* // returns true
*
* @example
* var bool = isUnityProbabilityArray( [ 0.4, 0.4, 0.4 ] );
* // returns false
*
* @example
* var bool = isUnityProbabilityArray( [ 3.14, 0.0 ] );
* // returns false
*/

/**
* Validates function options.
*
* @private
* @param {Object} opts - destination for validated options
* @param {Options} options - function options
* @param {NonNegativeInteger} [options.size] - sample size
* @param {ProbabilityArray} [options.probs] - element probabilities
* @param {boolean} [options.replace] - boolean indicating whether to sample with replacement
* @param {boolean} [options.mutate] - boolean indicating whether to mutate the `pool` when sampling without replacement
* @returns {(null|Error)} null or an error
*
* @example
* var opts = {};
* var options = {
*     'size': 10,
*     'replace': false,
*     'mutate': true,
*     'probs': [ 0.7, 0.3 ]
* };
* var err = validate( opts, options );
* if ( err ) {
*     throw err;
* }
*/

/***/

//         nextStatus = ENTERING

//         nextStatus = EXITING

//       if (status !== ENTERING && status !== ENTERED) {

//       if (status === ENTERING || status === ENTERED) {

//       }

//     const { status } = this.state

//     if (this.props.in) {

//     }

//     } else {

//   if (prevProps !== this.props) {

//   let nextStatus = null

//   return { nextStatus }

//   }

// All elements equally likely...

// Custom probabilities...

// EXPORTS //

// FUNCTIONS //

// Generate an integer index on the interval: [0,i]

// HTML DOM and SVG DOM may have different support levels,

// In the context of a TransitionGroup all enters are really appears

// MAIN //

// MODULES //

// Name the function so it is clearer in the documentation

// Note: we skip the first element, as no further swaps are possible given that all other indices are excluded from swapping...

// Remove the sample observations:

// Swap elements:

// TODO: implementation (?)

// TODO: remove fallback for next major

// This shouldn't be necessary, but there are weird race conditions with

// allows for nested Transitions

// eslint-disable-line stdlib/no-builtin-math

// eslint-disable-next-line @typescript-eslint/no-unused-expressions

// eslint-disable-next-line no-multi-assign

// getSnapshotBeforeUpdate(prevProps) {

// if we are mounting and running this it means appear _must_ be set

// nextStatus will always be ENTERING or EXITING.

// no enter animation skip right to ENTERED

// no exit animation skip right to EXITED

// reading a dimension prop will cause the browser to recalculate,

// setState callbacks and unmounting in testing, so always make sure that

// so we need to check on context instead of a document root element.

// we can cancel any pending setState callbacks after we unmount.

// which will let our animations work

// }
