X3ND1 GANTENG
Server IP : 108.163.255.210  /  Your IP : 18.191.14.104
Web Server : Apache
System : Linux blossom.urlnameserver.com 3.10.0-1160.80.1.el7.x86_64 #1 SMP Tue Nov 8 15:48:59 UTC 2022 x86_64
User :  ( 1172)
PHP Version : 7.2.34
Disable Function : eval,escapeshellarg,proc_close,proc_get_status,proc_nice,proc_open,symlink,system,pcntl_exec,getrusage,chown,chgp,closelog,openlog,syslog,define_syslog_variables,php_ini_loaded_file,getservbyname,getservbyport,posix_getgid,posix_getgrgid,proc_terminate,pfsockopen,apache_child_terminate,posix_mkfifo,posix_setpgid,posix_setuid,hypot,pg_host,pos,posix_access,posix_getcwd,posix_getservbyname,myshellexec,getpid,posix_getsid,posix_isatty,posix_kill,posix_mknod,posix_setgid,posix_setsid,posix_setuid,posix_times,posix_uname,ps_fill,posix_getpwuid,global,ini_restore,zip_open,zip_read,rar_open,bzopen,bzread,bzwrite,apache_get_modules,apache_get_version,phpversionphpinfo,php_ini_scanned_files,get_current_user,disk_total_space,diskfreespace,leak,imap_list,hypo,filedump,safe_mode,getmygid,apache_getenv,apache_setenv,bzread,bzwrite,bzopen,phpini,higlight_file,dos_conv,get_cwd,er_log,cmd,e_name,vdir,get_dir,only_read,ftok,ftpexec,posix_getpwnam,mysql_list_dbs,disk_free_space,session_save_path,confirm_phpdoc_compiled,zip_entry_rea,php_u,psockopen,crack_opendict,crack_getlastmessage,crack_closedict,crack_check,fpassthru,posix_get_last_error,posix_getlogin,posix_getgroups,posix_strerror,posix_getrlimit,posix_getpgrp,posix_getgrnam,pos,dl
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /home/unilinki/public_html/grahnidhi/public/js/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ BERANDA ]     

Current File : /home/unilinki/public_html/grahnidhi/public/js/ecommerce.js
/******/ (function(modules) { // webpackBootstrap

/******/ 	// The module cache

/******/ 	var installedModules = {};

/******/

/******/ 	// The require function

/******/ 	function __webpack_require__(moduleId) {

/******/

/******/ 		// Check if module is in cache

/******/ 		if(installedModules[moduleId]) {

/******/ 			return installedModules[moduleId].exports;

/******/ 		}

/******/ 		// Create a new module (and put it into the cache)

/******/ 		var module = installedModules[moduleId] = {

/******/ 			i: moduleId,

/******/ 			l: false,

/******/ 			exports: {}

/******/ 		};

/******/

/******/ 		// Execute the module function

/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

/******/

/******/ 		// Flag the module as loaded

/******/ 		module.l = true;

/******/

/******/ 		// Return the exports of the module

/******/ 		return module.exports;

/******/ 	}

/******/

/******/

/******/ 	// expose the modules object (__webpack_modules__)

/******/ 	__webpack_require__.m = modules;

/******/

/******/ 	// expose the module cache

/******/ 	__webpack_require__.c = installedModules;

/******/

/******/ 	// define getter function for harmony exports

/******/ 	__webpack_require__.d = function(exports, name, getter) {

/******/ 		if(!__webpack_require__.o(exports, name)) {

/******/ 			Object.defineProperty(exports, name, {

/******/ 				configurable: false,

/******/ 				enumerable: true,

/******/ 				get: getter

/******/ 			});

/******/ 		}

/******/ 	};

/******/

/******/ 	// getDefaultExport function for compatibility with non-harmony modules

/******/ 	__webpack_require__.n = function(module) {

/******/ 		var getter = module && module.__esModule ?

/******/ 			function getDefault() { return module['default']; } :

/******/ 			function getModuleExports() { return module; };

/******/ 		__webpack_require__.d(getter, 'a', getter);

/******/ 		return getter;

/******/ 	};

/******/

/******/ 	// Object.prototype.hasOwnProperty.call

/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };

/******/

/******/ 	// __webpack_public_path__

/******/ 	__webpack_require__.p = "";

/******/

/******/ 	// Load entry module and return exports

/******/ 	return __webpack_require__(__webpack_require__.s = 11);

/******/ })

/************************************************************************/

/******/ ([

/* 0 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";





var bind = __webpack_require__(5);

var isBuffer = __webpack_require__(19);



/*global toString:true*/



// utils is a library of generic helper functions non-specific to axios



var toString = Object.prototype.toString;



/**

 * Determine if a value is an Array

 *

 * @param {Object} val The value to test

 * @returns {boolean} True if value is an Array, otherwise false

 */

function isArray(val) {

  return toString.call(val) === '[object Array]';

}



/**

 * Determine if a value is an ArrayBuffer

 *

 * @param {Object} val The value to test

 * @returns {boolean} True if value is an ArrayBuffer, otherwise false

 */

function isArrayBuffer(val) {

  return toString.call(val) === '[object ArrayBuffer]';

}



/**

 * Determine if a value is a FormData

 *

 * @param {Object} val The value to test

 * @returns {boolean} True if value is an FormData, otherwise false

 */

function isFormData(val) {

  return (typeof FormData !== 'undefined') && (val instanceof FormData);

}



/**

 * Determine if a value is a view on an ArrayBuffer

 *

 * @param {Object} val The value to test

 * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false

 */

function isArrayBufferView(val) {

  var result;

  if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {

    result = ArrayBuffer.isView(val);

  } else {

    result = (val) && (val.buffer) && (val.buffer instanceof ArrayBuffer);

  }

  return result;

}



/**

 * Determine if a value is a String

 *

 * @param {Object} val The value to test

 * @returns {boolean} True if value is a String, otherwise false

 */

function isString(val) {

  return typeof val === 'string';

}



/**

 * Determine if a value is a Number

 *

 * @param {Object} val The value to test

 * @returns {boolean} True if value is a Number, otherwise false

 */

function isNumber(val) {

  return typeof val === 'number';

}



/**

 * Determine if a value is undefined

 *

 * @param {Object} val The value to test

 * @returns {boolean} True if the value is undefined, otherwise false

 */

function isUndefined(val) {

  return typeof val === 'undefined';

}



/**

 * Determine if a value is an Object

 *

 * @param {Object} val The value to test

 * @returns {boolean} True if value is an Object, otherwise false

 */

function isObject(val) {

  return val !== null && typeof val === 'object';

}



/**

 * Determine if a value is a Date

 *

 * @param {Object} val The value to test

 * @returns {boolean} True if value is a Date, otherwise false

 */

function isDate(val) {

  return toString.call(val) === '[object Date]';

}



/**

 * Determine if a value is a File

 *

 * @param {Object} val The value to test

 * @returns {boolean} True if value is a File, otherwise false

 */

function isFile(val) {

  return toString.call(val) === '[object File]';

}



/**

 * Determine if a value is a Blob

 *

 * @param {Object} val The value to test

 * @returns {boolean} True if value is a Blob, otherwise false

 */

function isBlob(val) {

  return toString.call(val) === '[object Blob]';

}



/**

 * Determine if a value is a Function

 *

 * @param {Object} val The value to test

 * @returns {boolean} True if value is a Function, otherwise false

 */

function isFunction(val) {

  return toString.call(val) === '[object Function]';

}



/**

 * Determine if a value is a Stream

 *

 * @param {Object} val The value to test

 * @returns {boolean} True if value is a Stream, otherwise false

 */

function isStream(val) {

  return isObject(val) && isFunction(val.pipe);

}



/**

 * Determine if a value is a URLSearchParams object

 *

 * @param {Object} val The value to test

 * @returns {boolean} True if value is a URLSearchParams object, otherwise false

 */

function isURLSearchParams(val) {

  return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams;

}



/**

 * Trim excess whitespace off the beginning and end of a string

 *

 * @param {String} str The String to trim

 * @returns {String} The String freed of excess whitespace

 */

function trim(str) {

  return str.replace(/^\s*/, '').replace(/\s*$/, '');

}



/**

 * Determine if we're running in a standard browser environment

 *

 * This allows axios to run in a web worker, and react-native.

 * Both environments support XMLHttpRequest, but not fully standard globals.

 *

 * web workers:

 *  typeof window -> undefined

 *  typeof document -> undefined

 *

 * react-native:

 *  navigator.product -> 'ReactNative'

 */

function isStandardBrowserEnv() {

  if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {

    return false;

  }

  return (

    typeof window !== 'undefined' &&

    typeof document !== 'undefined'

  );

}



/**

 * Iterate over an Array or an Object invoking a function for each item.

 *

 * If `obj` is an Array callback will be called passing

 * the value, index, and complete array for each item.

 *

 * If 'obj' is an Object callback will be called passing

 * the value, key, and complete object for each property.

 *

 * @param {Object|Array} obj The object to iterate

 * @param {Function} fn The callback to invoke for each item

 */

function forEach(obj, fn) {

  // Don't bother if no value provided

  if (obj === null || typeof obj === 'undefined') {

    return;

  }



  // Force an array if not already something iterable

  if (typeof obj !== 'object' && !isArray(obj)) {

    /*eslint no-param-reassign:0*/

    obj = [obj];

  }



  if (isArray(obj)) {

    // Iterate over array values

    for (var i = 0, l = obj.length; i < l; i++) {

      fn.call(null, obj[i], i, obj);

    }

  } else {

    // Iterate over object keys

    for (var key in obj) {

      if (Object.prototype.hasOwnProperty.call(obj, key)) {

        fn.call(null, obj[key], key, obj);

      }

    }

  }

}



/**

 * Accepts varargs expecting each argument to be an object, then

 * immutably merges the properties of each object and returns result.

 *

 * When multiple objects contain the same key the later object in

 * the arguments list will take precedence.

 *

 * Example:

 *

 * ```js

 * var result = merge({foo: 123}, {foo: 456});

 * console.log(result.foo); // outputs 456

 * ```

 *

 * @param {Object} obj1 Object to merge

 * @returns {Object} Result of all merge properties

 */

function merge(/* obj1, obj2, obj3, ... */) {

  var result = {};

  function assignValue(val, key) {

    if (typeof result[key] === 'object' && typeof val === 'object') {

      result[key] = merge(result[key], val);

    } else {

      result[key] = val;

    }

  }



  for (var i = 0, l = arguments.length; i < l; i++) {

    forEach(arguments[i], assignValue);

  }

  return result;

}



/**

 * Extends object a by mutably adding to it the properties of object b.

 *

 * @param {Object} a The object to be extended

 * @param {Object} b The object to copy properties from

 * @param {Object} thisArg The object to bind function to

 * @return {Object} The resulting value of object a

 */

function extend(a, b, thisArg) {

  forEach(b, function assignValue(val, key) {

    if (thisArg && typeof val === 'function') {

      a[key] = bind(val, thisArg);

    } else {

      a[key] = val;

    }

  });

  return a;

}



module.exports = {

  isArray: isArray,

  isArrayBuffer: isArrayBuffer,

  isBuffer: isBuffer,

  isFormData: isFormData,

  isArrayBufferView: isArrayBufferView,

  isString: isString,

  isNumber: isNumber,

  isObject: isObject,

  isUndefined: isUndefined,

  isDate: isDate,

  isFile: isFile,

  isBlob: isBlob,

  isFunction: isFunction,

  isStream: isStream,

  isURLSearchParams: isURLSearchParams,

  isStandardBrowserEnv: isStandardBrowserEnv,

  forEach: forEach,

  merge: merge,

  extend: extend,

  trim: trim

};





/***/ }),

/* 1 */

/***/ (function(module, exports) {



var g;



// This works in non-strict mode

g = (function() {

	return this;

})();



try {

	// This works if eval is allowed (see CSP)

	g = g || Function("return this")() || (1,eval)("this");

} catch(e) {

	// This works if the window reference is available

	if(typeof window === "object")

		g = window;

}



// g can still be undefined, but nothing to do about it...

// We return undefined, instead of nothing here, so it's

// easier to handle this case. if(!global) { ...}



module.exports = g;





/***/ }),

/* 2 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";

/* WEBPACK VAR INJECTION */(function(process) {



var utils = __webpack_require__(0);

var normalizeHeaderName = __webpack_require__(21);



var DEFAULT_CONTENT_TYPE = {

  'Content-Type': 'application/x-www-form-urlencoded'

};



function setContentTypeIfUnset(headers, value) {

  if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) {

    headers['Content-Type'] = value;

  }

}



function getDefaultAdapter() {

  var adapter;

  if (typeof XMLHttpRequest !== 'undefined') {

    // For browsers use XHR adapter

    adapter = __webpack_require__(7);

  } else if (typeof process !== 'undefined') {

    // For node use HTTP adapter

    adapter = __webpack_require__(7);

  }

  return adapter;

}



var defaults = {

  adapter: getDefaultAdapter(),



  transformRequest: [function transformRequest(data, headers) {

    normalizeHeaderName(headers, 'Content-Type');

    if (utils.isFormData(data) ||

      utils.isArrayBuffer(data) ||

      utils.isBuffer(data) ||

      utils.isStream(data) ||

      utils.isFile(data) ||

      utils.isBlob(data)

    ) {

      return data;

    }

    if (utils.isArrayBufferView(data)) {

      return data.buffer;

    }

    if (utils.isURLSearchParams(data)) {

      setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8');

      return data.toString();

    }

    if (utils.isObject(data)) {

      setContentTypeIfUnset(headers, 'application/json;charset=utf-8');

      return JSON.stringify(data);

    }

    return data;

  }],



  transformResponse: [function transformResponse(data) {

    /*eslint no-param-reassign:0*/

    if (typeof data === 'string') {

      try {

        data = JSON.parse(data);

      } catch (e) { /* Ignore */ }

    }

    return data;

  }],



  timeout: 0,



  xsrfCookieName: 'XSRF-TOKEN',

  xsrfHeaderName: 'X-XSRF-TOKEN',



  maxContentLength: -1,



  validateStatus: function validateStatus(status) {

    return status >= 200 && status < 300;

  }

};



defaults.headers = {

  common: {

    'Accept': 'application/json, text/plain, */*'

  }

};



utils.forEach(['delete', 'get', 'head'], function forEachMethodNoData(method) {

  defaults.headers[method] = {};

});



utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {

  defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE);

});



module.exports = defaults;



/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(6)))



/***/ }),

/* 3 */

/***/ (function(module, exports, __webpack_require__) {



var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!

 * jQuery JavaScript Library v3.2.1

 * https://jquery.com/

 *

 * Includes Sizzle.js

 * https://sizzlejs.com/

 *

 * Copyright JS Foundation and other contributors

 * Released under the MIT license

 * https://jquery.org/license

 *

 * Date: 2017-03-20T18:59Z

 */

( function( global, factory ) {



	"use strict";



	if ( typeof module === "object" && typeof module.exports === "object" ) {



		// For CommonJS and CommonJS-like environments where a proper `window`

		// is present, execute the factory and get jQuery.

		// For environments that do not have a `window` with a `document`

		// (such as Node.js), expose a factory as module.exports.

		// This accentuates the need for the creation of a real `window`.

		// e.g. var jQuery = require("jquery")(window);

		// See ticket #14549 for more info.

		module.exports = global.document ?

			factory( global, true ) :

			function( w ) {

				if ( !w.document ) {

					throw new Error( "jQuery requires a window with a document" );

				}

				return factory( w );

			};

	} else {

		factory( global );

	}



// Pass this if window is not defined yet

} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {



// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1

// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode

// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common

// enough that all such attempts are guarded in a try block.

"use strict";



var arr = [];



var document = window.document;



var getProto = Object.getPrototypeOf;



var slice = arr.slice;



var concat = arr.concat;



var push = arr.push;



var indexOf = arr.indexOf;



var class2type = {};



var toString = class2type.toString;



var hasOwn = class2type.hasOwnProperty;



var fnToString = hasOwn.toString;



var ObjectFunctionString = fnToString.call( Object );



var support = {};







	function DOMEval( code, doc ) {

		doc = doc || document;



		var script = doc.createElement( "script" );



		script.text = code;

		doc.head.appendChild( script ).parentNode.removeChild( script );

	}

/* global Symbol */

// Defining this global in .eslintrc.json would create a danger of using the global

// unguarded in another place, it seems safer to define global only for this module







var

	version = "3.2.1",



	// Define a local copy of jQuery

	jQuery = function( selector, context ) {



		// The jQuery object is actually just the init constructor 'enhanced'

		// Need init if jQuery is called (just allow error to be thrown if not included)

		return new jQuery.fn.init( selector, context );

	},



	// Support: Android <=4.0 only

	// Make sure we trim BOM and NBSP

	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,



	// Matches dashed string for camelizing

	rmsPrefix = /^-ms-/,

	rdashAlpha = /-([a-z])/g,



	// Used by jQuery.camelCase as callback to replace()

	fcamelCase = function( all, letter ) {

		return letter.toUpperCase();

	};



jQuery.fn = jQuery.prototype = {



	// The current version of jQuery being used

	jquery: version,



	constructor: jQuery,



	// The default length of a jQuery object is 0

	length: 0,



	toArray: function() {

		return slice.call( this );

	},



	// Get the Nth element in the matched element set OR

	// Get the whole matched element set as a clean array

	get: function( num ) {



		// Return all the elements in a clean array

		if ( num == null ) {

			return slice.call( this );

		}



		// Return just the one element from the set

		return num < 0 ? this[ num + this.length ] : this[ num ];

	},



	// Take an array of elements and push it onto the stack

	// (returning the new matched element set)

	pushStack: function( elems ) {



		// Build a new jQuery matched element set

		var ret = jQuery.merge( this.constructor(), elems );



		// Add the old object onto the stack (as a reference)

		ret.prevObject = this;



		// Return the newly-formed element set

		return ret;

	},



	// Execute a callback for every element in the matched set.

	each: function( callback ) {

		return jQuery.each( this, callback );

	},



	map: function( callback ) {

		return this.pushStack( jQuery.map( this, function( elem, i ) {

			return callback.call( elem, i, elem );

		} ) );

	},



	slice: function() {

		return this.pushStack( slice.apply( this, arguments ) );

	},



	first: function() {

		return this.eq( 0 );

	},



	last: function() {

		return this.eq( -1 );

	},



	eq: function( i ) {

		var len = this.length,

			j = +i + ( i < 0 ? len : 0 );

		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );

	},



	end: function() {

		return this.prevObject || this.constructor();

	},



	// For internal use only.

	// Behaves like an Array's method, not like a jQuery method.

	push: push,

	sort: arr.sort,

	splice: arr.splice

};



jQuery.extend = jQuery.fn.extend = function() {

	var options, name, src, copy, copyIsArray, clone,

		target = arguments[ 0 ] || {},

		i = 1,

		length = arguments.length,

		deep = false;



	// Handle a deep copy situation

	if ( typeof target === "boolean" ) {

		deep = target;



		// Skip the boolean and the target

		target = arguments[ i ] || {};

		i++;

	}



	// Handle case when target is a string or something (possible in deep copy)

	if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {

		target = {};

	}



	// Extend jQuery itself if only one argument is passed

	if ( i === length ) {

		target = this;

		i--;

	}



	for ( ; i < length; i++ ) {



		// Only deal with non-null/undefined values

		if ( ( options = arguments[ i ] ) != null ) {



			// Extend the base object

			for ( name in options ) {

				src = target[ name ];

				copy = options[ name ];



				// Prevent never-ending loop

				if ( target === copy ) {

					continue;

				}



				// Recurse if we're merging plain objects or arrays

				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||

					( copyIsArray = Array.isArray( copy ) ) ) ) {



					if ( copyIsArray ) {

						copyIsArray = false;

						clone = src && Array.isArray( src ) ? src : [];



					} else {

						clone = src && jQuery.isPlainObject( src ) ? src : {};

					}



					// Never move original objects, clone them

					target[ name ] = jQuery.extend( deep, clone, copy );



				// Don't bring in undefined values

				} else if ( copy !== undefined ) {

					target[ name ] = copy;

				}

			}

		}

	}



	// Return the modified object

	return target;

};



jQuery.extend( {



	// Unique for each copy of jQuery on the page

	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),



	// Assume jQuery is ready without the ready module

	isReady: true,



	error: function( msg ) {

		throw new Error( msg );

	},



	noop: function() {},



	isFunction: function( obj ) {

		return jQuery.type( obj ) === "function";

	},



	isWindow: function( obj ) {

		return obj != null && obj === obj.window;

	},



	isNumeric: function( obj ) {



		// As of jQuery 3.0, isNumeric is limited to

		// strings and numbers (primitives or objects)

		// that can be coerced to finite numbers (gh-2662)

		var type = jQuery.type( obj );

		return ( type === "number" || type === "string" ) &&



			// parseFloat NaNs numeric-cast false positives ("")

			// ...but misinterprets leading-number strings, particularly hex literals ("0x...")

			// subtraction forces infinities to NaN

			!isNaN( obj - parseFloat( obj ) );

	},



	isPlainObject: function( obj ) {

		var proto, Ctor;



		// Detect obvious negatives

		// Use toString instead of jQuery.type to catch host objects

		if ( !obj || toString.call( obj ) !== "[object Object]" ) {

			return false;

		}



		proto = getProto( obj );



		// Objects with no prototype (e.g., `Object.create( null )`) are plain

		if ( !proto ) {

			return true;

		}



		// Objects with prototype are plain iff they were constructed by a global Object function

		Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;

		return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;

	},



	isEmptyObject: function( obj ) {



		/* eslint-disable no-unused-vars */

		// See https://github.com/eslint/eslint/issues/6125

		var name;



		for ( name in obj ) {

			return false;

		}

		return true;

	},



	type: function( obj ) {

		if ( obj == null ) {

			return obj + "";

		}



		// Support: Android <=2.3 only (functionish RegExp)

		return typeof obj === "object" || typeof obj === "function" ?

			class2type[ toString.call( obj ) ] || "object" :

			typeof obj;

	},



	// Evaluates a script in a global context

	globalEval: function( code ) {

		DOMEval( code );

	},



	// Convert dashed to camelCase; used by the css and data modules

	// Support: IE <=9 - 11, Edge 12 - 13

	// Microsoft forgot to hump their vendor prefix (#9572)

	camelCase: function( string ) {

		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );

	},



	each: function( obj, callback ) {

		var length, i = 0;



		if ( isArrayLike( obj ) ) {

			length = obj.length;

			for ( ; i < length; i++ ) {

				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {

					break;

				}

			}

		} else {

			for ( i in obj ) {

				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {

					break;

				}

			}

		}



		return obj;

	},



	// Support: Android <=4.0 only

	trim: function( text ) {

		return text == null ?

			"" :

			( text + "" ).replace( rtrim, "" );

	},



	// results is for internal usage only

	makeArray: function( arr, results ) {

		var ret = results || [];



		if ( arr != null ) {

			if ( isArrayLike( Object( arr ) ) ) {

				jQuery.merge( ret,

					typeof arr === "string" ?

					[ arr ] : arr

				);

			} else {

				push.call( ret, arr );

			}

		}



		return ret;

	},



	inArray: function( elem, arr, i ) {

		return arr == null ? -1 : indexOf.call( arr, elem, i );

	},



	// Support: Android <=4.0 only, PhantomJS 1 only

	// push.apply(_, arraylike) throws on ancient WebKit

	merge: function( first, second ) {

		var len = +second.length,

			j = 0,

			i = first.length;



		for ( ; j < len; j++ ) {

			first[ i++ ] = second[ j ];

		}



		first.length = i;



		return first;

	},



	grep: function( elems, callback, invert ) {

		var callbackInverse,

			matches = [],

			i = 0,

			length = elems.length,

			callbackExpect = !invert;



		// Go through the array, only saving the items

		// that pass the validator function

		for ( ; i < length; i++ ) {

			callbackInverse = !callback( elems[ i ], i );

			if ( callbackInverse !== callbackExpect ) {

				matches.push( elems[ i ] );

			}

		}



		return matches;

	},



	// arg is for internal usage only

	map: function( elems, callback, arg ) {

		var length, value,

			i = 0,

			ret = [];



		// Go through the array, translating each of the items to their new values

		if ( isArrayLike( elems ) ) {

			length = elems.length;

			for ( ; i < length; i++ ) {

				value = callback( elems[ i ], i, arg );



				if ( value != null ) {

					ret.push( value );

				}

			}



		// Go through every key on the object,

		} else {

			for ( i in elems ) {

				value = callback( elems[ i ], i, arg );



				if ( value != null ) {

					ret.push( value );

				}

			}

		}



		// Flatten any nested arrays

		return concat.apply( [], ret );

	},



	// A global GUID counter for objects

	guid: 1,



	// Bind a function to a context, optionally partially applying any

	// arguments.

	proxy: function( fn, context ) {

		var tmp, args, proxy;



		if ( typeof context === "string" ) {

			tmp = fn[ context ];

			context = fn;

			fn = tmp;

		}



		// Quick check to determine if target is callable, in the spec

		// this throws a TypeError, but we will just return undefined.

		if ( !jQuery.isFunction( fn ) ) {

			return undefined;

		}



		// Simulated bind

		args = slice.call( arguments, 2 );

		proxy = function() {

			return fn.apply( context || this, args.concat( slice.call( arguments ) ) );

		};



		// Set the guid of unique handler to the same of original handler, so it can be removed

		proxy.guid = fn.guid = fn.guid || jQuery.guid++;



		return proxy;

	},



	now: Date.now,



	// jQuery.support is not used in Core but other projects attach their

	// properties to it so it needs to exist.

	support: support

} );



if ( typeof Symbol === "function" ) {

	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];

}



// Populate the class2type map

jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),

function( i, name ) {

	class2type[ "[object " + name + "]" ] = name.toLowerCase();

} );



function isArrayLike( obj ) {



	// Support: real iOS 8.2 only (not reproducible in simulator)

	// `in` check used to prevent JIT error (gh-2145)

	// hasOwn isn't used here due to false negatives

	// regarding Nodelist length in IE

	var length = !!obj && "length" in obj && obj.length,

		type = jQuery.type( obj );



	if ( type === "function" || jQuery.isWindow( obj ) ) {

		return false;

	}



	return type === "array" || length === 0 ||

		typeof length === "number" && length > 0 && ( length - 1 ) in obj;

}

var Sizzle =

/*!

 * Sizzle CSS Selector Engine v2.3.3

 * https://sizzlejs.com/

 *

 * Copyright jQuery Foundation and other contributors

 * Released under the MIT license

 * http://jquery.org/license

 *

 * Date: 2016-08-08

 */

(function( window ) {



var i,

	support,

	Expr,

	getText,

	isXML,

	tokenize,

	compile,

	select,

	outermostContext,

	sortInput,

	hasDuplicate,



	// Local document vars

	setDocument,

	document,

	docElem,

	documentIsHTML,

	rbuggyQSA,

	rbuggyMatches,

	matches,

	contains,



	// Instance-specific data

	expando = "sizzle" + 1 * new Date(),

	preferredDoc = window.document,

	dirruns = 0,

	done = 0,

	classCache = createCache(),

	tokenCache = createCache(),

	compilerCache = createCache(),

	sortOrder = function( a, b ) {

		if ( a === b ) {

			hasDuplicate = true;

		}

		return 0;

	},



	// Instance methods

	hasOwn = ({}).hasOwnProperty,

	arr = [],

	pop = arr.pop,

	push_native = arr.push,

	push = arr.push,

	slice = arr.slice,

	// Use a stripped-down indexOf as it's faster than native

	// https://jsperf.com/thor-indexof-vs-for/5

	indexOf = function( list, elem ) {

		var i = 0,

			len = list.length;

		for ( ; i < len; i++ ) {

			if ( list[i] === elem ) {

				return i;

			}

		}

		return -1;

	},



	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",



	// Regular expressions



	// http://www.w3.org/TR/css3-selectors/#whitespace

	whitespace = "[\\x20\\t\\r\\n\\f]",



	// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier

	identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",



	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors

	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +

		// Operator (capture 2)

		"*([*^$|!~]?=)" + whitespace +

		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"

		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +

		"*\\]",



	pseudos = ":(" + identifier + ")(?:\\((" +

		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:

		// 1. quoted (capture 3; capture 4 or capture 5)

		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +

		// 2. simple (capture 6)

		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +

		// 3. anything else (capture 2)

		".*" +

		")\\)|)",



	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter

	rwhitespace = new RegExp( whitespace + "+", "g" ),

	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),



	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),

	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),



	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),



	rpseudo = new RegExp( pseudos ),

	ridentifier = new RegExp( "^" + identifier + "$" ),



	matchExpr = {

		"ID": new RegExp( "^#(" + identifier + ")" ),

		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),

		"TAG": new RegExp( "^(" + identifier + "|[*])" ),

		"ATTR": new RegExp( "^" + attributes ),

		"PSEUDO": new RegExp( "^" + pseudos ),

		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +

			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +

			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),

		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),

		// For use in libraries implementing .is()

		// We use this for POS matching in `select`

		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +

			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )

	},



	rinputs = /^(?:input|select|textarea|button)$/i,

	rheader = /^h\d$/i,



	rnative = /^[^{]+\{\s*\[native \w/,



	// Easily-parseable/retrievable ID or TAG or CLASS selectors

	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,



	rsibling = /[+~]/,



	// CSS escapes

	// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters

	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),

	funescape = function( _, escaped, escapedWhitespace ) {

		var high = "0x" + escaped - 0x10000;

		// NaN means non-codepoint

		// Support: Firefox<24

		// Workaround erroneous numeric interpretation of +"0x"

		return high !== high || escapedWhitespace ?

			escaped :

			high < 0 ?

				// BMP codepoint

				String.fromCharCode( high + 0x10000 ) :

				// Supplemental Plane codepoint (surrogate pair)

				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );

	},



	// CSS string/identifier serialization

	// https://drafts.csswg.org/cssom/#common-serializing-idioms

	rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,

	fcssescape = function( ch, asCodePoint ) {

		if ( asCodePoint ) {



			// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER

			if ( ch === "\0" ) {

				return "\uFFFD";

			}



			// Control characters and (dependent upon position) numbers get escaped as code points

			return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";

		}



		// Other potentially-special ASCII characters get backslash-escaped

		return "\\" + ch;

	},



	// Used for iframes

	// See setDocument()

	// Removing the function wrapper causes a "Permission Denied"

	// error in IE

	unloadHandler = function() {

		setDocument();

	},



	disabledAncestor = addCombinator(

		function( elem ) {

			return elem.disabled === true && ("form" in elem || "label" in elem);

		},

		{ dir: "parentNode", next: "legend" }

	);



// Optimize for push.apply( _, NodeList )

try {

	push.apply(

		(arr = slice.call( preferredDoc.childNodes )),

		preferredDoc.childNodes

	);

	// Support: Android<4.0

	// Detect silently failing push.apply

	arr[ preferredDoc.childNodes.length ].nodeType;

} catch ( e ) {

	push = { apply: arr.length ?



		// Leverage slice if possible

		function( target, els ) {

			push_native.apply( target, slice.call(els) );

		} :



		// Support: IE<9

		// Otherwise append directly

		function( target, els ) {

			var j = target.length,

				i = 0;

			// Can't trust NodeList.length

			while ( (target[j++] = els[i++]) ) {}

			target.length = j - 1;

		}

	};

}



function Sizzle( selector, context, results, seed ) {

	var m, i, elem, nid, match, groups, newSelector,

		newContext = context && context.ownerDocument,



		// nodeType defaults to 9, since context defaults to document

		nodeType = context ? context.nodeType : 9;



	results = results || [];



	// Return early from calls with invalid selector or context

	if ( typeof selector !== "string" || !selector ||

		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {



		return results;

	}



	// Try to shortcut find operations (as opposed to filters) in HTML documents

	if ( !seed ) {



		if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {

			setDocument( context );

		}

		context = context || document;



		if ( documentIsHTML ) {



			// If the selector is sufficiently simple, try using a "get*By*" DOM method

			// (excepting DocumentFragment context, where the methods don't exist)

			if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {



				// ID selector

				if ( (m = match[1]) ) {



					// Document context

					if ( nodeType === 9 ) {

						if ( (elem = context.getElementById( m )) ) {



							// Support: IE, Opera, Webkit

							// TODO: identify versions

							// getElementById can match elements by name instead of ID

							if ( elem.id === m ) {

								results.push( elem );

								return results;

							}

						} else {

							return results;

						}



					// Element context

					} else {



						// Support: IE, Opera, Webkit

						// TODO: identify versions

						// getElementById can match elements by name instead of ID

						if ( newContext && (elem = newContext.getElementById( m )) &&

							contains( context, elem ) &&

							elem.id === m ) {



							results.push( elem );

							return results;

						}

					}



				// Type selector

				} else if ( match[2] ) {

					push.apply( results, context.getElementsByTagName( selector ) );

					return results;



				// Class selector

				} else if ( (m = match[3]) && support.getElementsByClassName &&

					context.getElementsByClassName ) {



					push.apply( results, context.getElementsByClassName( m ) );

					return results;

				}

			}



			// Take advantage of querySelectorAll

			if ( support.qsa &&

				!compilerCache[ selector + " " ] &&

				(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {



				if ( nodeType !== 1 ) {

					newContext = context;

					newSelector = selector;



				// qSA looks outside Element context, which is not what we want

				// Thanks to Andrew Dupont for this workaround technique

				// Support: IE <=8

				// Exclude object elements

				} else if ( context.nodeName.toLowerCase() !== "object" ) {



					// Capture the context ID, setting it first if necessary

					if ( (nid = context.getAttribute( "id" )) ) {

						nid = nid.replace( rcssescape, fcssescape );

					} else {

						context.setAttribute( "id", (nid = expando) );

					}



					// Prefix every selector in the list

					groups = tokenize( selector );

					i = groups.length;

					while ( i-- ) {

						groups[i] = "#" + nid + " " + toSelector( groups[i] );

					}

					newSelector = groups.join( "," );



					// Expand context for sibling selectors

					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||

						context;

				}



				if ( newSelector ) {

					try {

						push.apply( results,

							newContext.querySelectorAll( newSelector )

						);

						return results;

					} catch ( qsaError ) {

					} finally {

						if ( nid === expando ) {

							context.removeAttribute( "id" );

						}

					}

				}

			}

		}

	}



	// All others

	return select( selector.replace( rtrim, "$1" ), context, results, seed );

}



/**

 * Create key-value caches of limited size

 * @returns {function(string, object)} Returns the Object data after storing it on itself with

 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)

 *	deleting the oldest entry

 */

function createCache() {

	var keys = [];



	function cache( key, value ) {

		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)

		if ( keys.push( key + " " ) > Expr.cacheLength ) {

			// Only keep the most recent entries

			delete cache[ keys.shift() ];

		}

		return (cache[ key + " " ] = value);

	}

	return cache;

}



/**

 * Mark a function for special use by Sizzle

 * @param {Function} fn The function to mark

 */

function markFunction( fn ) {

	fn[ expando ] = true;

	return fn;

}



/**

 * Support testing using an element

 * @param {Function} fn Passed the created element and returns a boolean result

 */

function assert( fn ) {

	var el = document.createElement("fieldset");



	try {

		return !!fn( el );

	} catch (e) {

		return false;

	} finally {

		// Remove from its parent by default

		if ( el.parentNode ) {

			el.parentNode.removeChild( el );

		}

		// release memory in IE

		el = null;

	}

}



/**

 * Adds the same handler for all of the specified attrs

 * @param {String} attrs Pipe-separated list of attributes

 * @param {Function} handler The method that will be applied

 */

function addHandle( attrs, handler ) {

	var arr = attrs.split("|"),

		i = arr.length;



	while ( i-- ) {

		Expr.attrHandle[ arr[i] ] = handler;

	}

}



/**

 * Checks document order of two siblings

 * @param {Element} a

 * @param {Element} b

 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b

 */

function siblingCheck( a, b ) {

	var cur = b && a,

		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&

			a.sourceIndex - b.sourceIndex;



	// Use IE sourceIndex if available on both nodes

	if ( diff ) {

		return diff;

	}



	// Check if b follows a

	if ( cur ) {

		while ( (cur = cur.nextSibling) ) {

			if ( cur === b ) {

				return -1;

			}

		}

	}



	return a ? 1 : -1;

}



/**

 * Returns a function to use in pseudos for input types

 * @param {String} type

 */

function createInputPseudo( type ) {

	return function( elem ) {

		var name = elem.nodeName.toLowerCase();

		return name === "input" && elem.type === type;

	};

}



/**

 * Returns a function to use in pseudos for buttons

 * @param {String} type

 */

function createButtonPseudo( type ) {

	return function( elem ) {

		var name = elem.nodeName.toLowerCase();

		return (name === "input" || name === "button") && elem.type === type;

	};

}



/**

 * Returns a function to use in pseudos for :enabled/:disabled

 * @param {Boolean} disabled true for :disabled; false for :enabled

 */

function createDisabledPseudo( disabled ) {



	// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable

	return function( elem ) {



		// Only certain elements can match :enabled or :disabled

		// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled

		// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled

		if ( "form" in elem ) {



			// Check for inherited disabledness on relevant non-disabled elements:

			// * listed form-associated elements in a disabled fieldset

			//   https://html.spec.whatwg.org/multipage/forms.html#category-listed

			//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled

			// * option elements in a disabled optgroup

			//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled

			// All such elements have a "form" property.

			if ( elem.parentNode && elem.disabled === false ) {



				// Option elements defer to a parent optgroup if present

				if ( "label" in elem ) {

					if ( "label" in elem.parentNode ) {

						return elem.parentNode.disabled === disabled;

					} else {

						return elem.disabled === disabled;

					}

				}



				// Support: IE 6 - 11

				// Use the isDisabled shortcut property to check for disabled fieldset ancestors

				return elem.isDisabled === disabled ||



					// Where there is no isDisabled, check manually

					/* jshint -W018 */

					elem.isDisabled !== !disabled &&

						disabledAncestor( elem ) === disabled;

			}



			return elem.disabled === disabled;



		// Try to winnow out elements that can't be disabled before trusting the disabled property.

		// Some victims get caught in our net (label, legend, menu, track), but it shouldn't

		// even exist on them, let alone have a boolean value.

		} else if ( "label" in elem ) {

			return elem.disabled === disabled;

		}



		// Remaining elements are neither :enabled nor :disabled

		return false;

	};

}



/**

 * Returns a function to use in pseudos for positionals

 * @param {Function} fn

 */

function createPositionalPseudo( fn ) {

	return markFunction(function( argument ) {

		argument = +argument;

		return markFunction(function( seed, matches ) {

			var j,

				matchIndexes = fn( [], seed.length, argument ),

				i = matchIndexes.length;



			// Match elements found at the specified indexes

			while ( i-- ) {

				if ( seed[ (j = matchIndexes[i]) ] ) {

					seed[j] = !(matches[j] = seed[j]);

				}

			}

		});

	});

}



/**

 * Checks a node for validity as a Sizzle context

 * @param {Element|Object=} context

 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value

 */

function testContext( context ) {

	return context && typeof context.getElementsByTagName !== "undefined" && context;

}



// Expose support vars for convenience

support = Sizzle.support = {};



/**

 * Detects XML nodes

 * @param {Element|Object} elem An element or a document

 * @returns {Boolean} True iff elem is a non-HTML XML node

 */

isXML = Sizzle.isXML = function( elem ) {

	// documentElement is verified for cases where it doesn't yet exist

	// (such as loading iframes in IE - #4833)

	var documentElement = elem && (elem.ownerDocument || elem).documentElement;

	return documentElement ? documentElement.nodeName !== "HTML" : false;

};



/**

 * Sets document-related variables once based on the current document

 * @param {Element|Object} [doc] An element or document object to use to set the document

 * @returns {Object} Returns the current document

 */

setDocument = Sizzle.setDocument = function( node ) {

	var hasCompare, subWindow,

		doc = node ? node.ownerDocument || node : preferredDoc;



	// Return early if doc is invalid or already selected

	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {

		return document;

	}



	// Update global variables

	document = doc;

	docElem = document.documentElement;

	documentIsHTML = !isXML( document );



	// Support: IE 9-11, Edge

	// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)

	if ( preferredDoc !== document &&

		(subWindow = document.defaultView) && subWindow.top !== subWindow ) {



		// Support: IE 11, Edge

		if ( subWindow.addEventListener ) {

			subWindow.addEventListener( "unload", unloadHandler, false );



		// Support: IE 9 - 10 only

		} else if ( subWindow.attachEvent ) {

			subWindow.attachEvent( "onunload", unloadHandler );

		}

	}



	/* Attributes

	---------------------------------------------------------------------- */



	// Support: IE<8

	// Verify that getAttribute really returns attributes and not properties

	// (excepting IE8 booleans)

	support.attributes = assert(function( el ) {

		el.className = "i";

		return !el.getAttribute("className");

	});



	/* getElement(s)By*

	---------------------------------------------------------------------- */



	// Check if getElementsByTagName("*") returns only elements

	support.getElementsByTagName = assert(function( el ) {

		el.appendChild( document.createComment("") );

		return !el.getElementsByTagName("*").length;

	});



	// Support: IE<9

	support.getElementsByClassName = rnative.test( document.getElementsByClassName );



	// Support: IE<10

	// Check if getElementById returns elements by name

	// The broken getElementById methods don't pick up programmatically-set names,

	// so use a roundabout getElementsByName test

	support.getById = assert(function( el ) {

		docElem.appendChild( el ).id = expando;

		return !document.getElementsByName || !document.getElementsByName( expando ).length;

	});



	// ID filter and find

	if ( support.getById ) {

		Expr.filter["ID"] = function( id ) {

			var attrId = id.replace( runescape, funescape );

			return function( elem ) {

				return elem.getAttribute("id") === attrId;

			};

		};

		Expr.find["ID"] = function( id, context ) {

			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {

				var elem = context.getElementById( id );

				return elem ? [ elem ] : [];

			}

		};

	} else {

		Expr.filter["ID"] =  function( id ) {

			var attrId = id.replace( runescape, funescape );

			return function( elem ) {

				var node = typeof elem.getAttributeNode !== "undefined" &&

					elem.getAttributeNode("id");

				return node && node.value === attrId;

			};

		};



		// Support: IE 6 - 7 only

		// getElementById is not reliable as a find shortcut

		Expr.find["ID"] = function( id, context ) {

			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {

				var node, i, elems,

					elem = context.getElementById( id );



				if ( elem ) {



					// Verify the id attribute

					node = elem.getAttributeNode("id");

					if ( node && node.value === id ) {

						return [ elem ];

					}



					// Fall back on getElementsByName

					elems = context.getElementsByName( id );

					i = 0;

					while ( (elem = elems[i++]) ) {

						node = elem.getAttributeNode("id");

						if ( node && node.value === id ) {

							return [ elem ];

						}

					}

				}



				return [];

			}

		};

	}



	// Tag

	Expr.find["TAG"] = support.getElementsByTagName ?

		function( tag, context ) {

			if ( typeof context.getElementsByTagName !== "undefined" ) {

				return context.getElementsByTagName( tag );



			// DocumentFragment nodes don't have gEBTN

			} else if ( support.qsa ) {

				return context.querySelectorAll( tag );

			}

		} :



		function( tag, context ) {

			var elem,

				tmp = [],

				i = 0,

				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too

				results = context.getElementsByTagName( tag );



			// Filter out possible comments

			if ( tag === "*" ) {

				while ( (elem = results[i++]) ) {

					if ( elem.nodeType === 1 ) {

						tmp.push( elem );

					}

				}



				return tmp;

			}

			return results;

		};



	// Class

	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {

		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {

			return context.getElementsByClassName( className );

		}

	};



	/* QSA/matchesSelector

	---------------------------------------------------------------------- */



	// QSA and matchesSelector support



	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)

	rbuggyMatches = [];



	// qSa(:focus) reports false when true (Chrome 21)

	// We allow this because of a bug in IE8/9 that throws an error

	// whenever `document.activeElement` is accessed on an iframe

	// So, we allow :focus to pass through QSA all the time to avoid the IE error

	// See https://bugs.jquery.com/ticket/13378

	rbuggyQSA = [];



	if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {

		// Build QSA regex

		// Regex strategy adopted from Diego Perini

		assert(function( el ) {

			// Select is set to empty string on purpose

			// This is to test IE's treatment of not explicitly

			// setting a boolean content attribute,

			// since its presence should be enough

			// https://bugs.jquery.com/ticket/12359

			docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +

				"<select id='" + expando + "-\r\\' msallowcapture=''>" +

				"<option selected=''></option></select>";



			// Support: IE8, Opera 11-12.16

			// Nothing should be selected when empty strings follow ^= or $= or *=

			// The test attribute must be unknown in Opera but "safe" for WinRT

			// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section

			if ( el.querySelectorAll("[msallowcapture^='']").length ) {

				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );

			}



			// Support: IE8

			// Boolean attributes and "value" are not treated correctly

			if ( !el.querySelectorAll("[selected]").length ) {

				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );

			}



			// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+

			if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {

				rbuggyQSA.push("~=");

			}



			// Webkit/Opera - :checked should return selected option elements

			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked

			// IE8 throws error here and will not see later tests

			if ( !el.querySelectorAll(":checked").length ) {

				rbuggyQSA.push(":checked");

			}



			// Support: Safari 8+, iOS 8+

			// https://bugs.webkit.org/show_bug.cgi?id=136851

			// In-page `selector#id sibling-combinator selector` fails

			if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {

				rbuggyQSA.push(".#.+[+~]");

			}

		});



		assert(function( el ) {

			el.innerHTML = "<a href='' disabled='disabled'></a>" +

				"<select disabled='disabled'><option/></select>";



			// Support: Windows 8 Native Apps

			// The type and name attributes are restricted during .innerHTML assignment

			var input = document.createElement("input");

			input.setAttribute( "type", "hidden" );

			el.appendChild( input ).setAttribute( "name", "D" );



			// Support: IE8

			// Enforce case-sensitivity of name attribute

			if ( el.querySelectorAll("[name=d]").length ) {

				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );

			}



			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)

			// IE8 throws error here and will not see later tests

			if ( el.querySelectorAll(":enabled").length !== 2 ) {

				rbuggyQSA.push( ":enabled", ":disabled" );

			}



			// Support: IE9-11+

			// IE's :disabled selector does not pick up the children of disabled fieldsets

			docElem.appendChild( el ).disabled = true;

			if ( el.querySelectorAll(":disabled").length !== 2 ) {

				rbuggyQSA.push( ":enabled", ":disabled" );

			}



			// Opera 10-11 does not throw on post-comma invalid pseudos

			el.querySelectorAll("*,:x");

			rbuggyQSA.push(",.*:");

		});

	}



	if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||

		docElem.webkitMatchesSelector ||

		docElem.mozMatchesSelector ||

		docElem.oMatchesSelector ||

		docElem.msMatchesSelector) )) ) {



		assert(function( el ) {

			// Check to see if it's possible to do matchesSelector

			// on a disconnected node (IE 9)

			support.disconnectedMatch = matches.call( el, "*" );



			// This should fail with an exception

			// Gecko does not error, returns false instead

			matches.call( el, "[s!='']:x" );

			rbuggyMatches.push( "!=", pseudos );

		});

	}



	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );

	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );



	/* Contains

	---------------------------------------------------------------------- */

	hasCompare = rnative.test( docElem.compareDocumentPosition );



	// Element contains another

	// Purposefully self-exclusive

	// As in, an element does not contain itself

	contains = hasCompare || rnative.test( docElem.contains ) ?

		function( a, b ) {

			var adown = a.nodeType === 9 ? a.documentElement : a,

				bup = b && b.parentNode;

			return a === bup || !!( bup && bup.nodeType === 1 && (

				adown.contains ?

					adown.contains( bup ) :

					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16

			));

		} :

		function( a, b ) {

			if ( b ) {

				while ( (b = b.parentNode) ) {

					if ( b === a ) {

						return true;

					}

				}

			}

			return false;

		};



	/* Sorting

	---------------------------------------------------------------------- */



	// Document order sorting

	sortOrder = hasCompare ?

	function( a, b ) {



		// Flag for duplicate removal

		if ( a === b ) {

			hasDuplicate = true;

			return 0;

		}



		// Sort on method existence if only one input has compareDocumentPosition

		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;

		if ( compare ) {

			return compare;

		}



		// Calculate position if both inputs belong to the same document

		compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?

			a.compareDocumentPosition( b ) :



			// Otherwise we know they are disconnected

			1;



		// Disconnected nodes

		if ( compare & 1 ||

			(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {



			// Choose the first element that is related to our preferred document

			if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {

				return -1;

			}

			if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {

				return 1;

			}



			// Maintain original order

			return sortInput ?

				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :

				0;

		}



		return compare & 4 ? -1 : 1;

	} :

	function( a, b ) {

		// Exit early if the nodes are identical

		if ( a === b ) {

			hasDuplicate = true;

			return 0;

		}



		var cur,

			i = 0,

			aup = a.parentNode,

			bup = b.parentNode,

			ap = [ a ],

			bp = [ b ];



		// Parentless nodes are either documents or disconnected

		if ( !aup || !bup ) {

			return a === document ? -1 :

				b === document ? 1 :

				aup ? -1 :

				bup ? 1 :

				sortInput ?

				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :

				0;



		// If the nodes are siblings, we can do a quick check

		} else if ( aup === bup ) {

			return siblingCheck( a, b );

		}



		// Otherwise we need full lists of their ancestors for comparison

		cur = a;

		while ( (cur = cur.parentNode) ) {

			ap.unshift( cur );

		}

		cur = b;

		while ( (cur = cur.parentNode) ) {

			bp.unshift( cur );

		}



		// Walk down the tree looking for a discrepancy

		while ( ap[i] === bp[i] ) {

			i++;

		}



		return i ?

			// Do a sibling check if the nodes have a common ancestor

			siblingCheck( ap[i], bp[i] ) :



			// Otherwise nodes in our document sort first

			ap[i] === preferredDoc ? -1 :

			bp[i] === preferredDoc ? 1 :

			0;

	};



	return document;

};



Sizzle.matches = function( expr, elements ) {

	return Sizzle( expr, null, null, elements );

};



Sizzle.matchesSelector = function( elem, expr ) {

	// Set document vars if needed

	if ( ( elem.ownerDocument || elem ) !== document ) {

		setDocument( elem );

	}



	// Make sure that attribute selectors are quoted

	expr = expr.replace( rattributeQuotes, "='$1']" );



	if ( support.matchesSelector && documentIsHTML &&

		!compilerCache[ expr + " " ] &&

		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&

		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {



		try {

			var ret = matches.call( elem, expr );



			// IE 9's matchesSelector returns false on disconnected nodes

			if ( ret || support.disconnectedMatch ||

					// As well, disconnected nodes are said to be in a document

					// fragment in IE 9

					elem.document && elem.document.nodeType !== 11 ) {

				return ret;

			}

		} catch (e) {}

	}



	return Sizzle( expr, document, null, [ elem ] ).length > 0;

};



Sizzle.contains = function( context, elem ) {

	// Set document vars if needed

	if ( ( context.ownerDocument || context ) !== document ) {

		setDocument( context );

	}

	return contains( context, elem );

};



Sizzle.attr = function( elem, name ) {

	// Set document vars if needed

	if ( ( elem.ownerDocument || elem ) !== document ) {

		setDocument( elem );

	}



	var fn = Expr.attrHandle[ name.toLowerCase() ],

		// Don't get fooled by Object.prototype properties (jQuery #13807)

		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?

			fn( elem, name, !documentIsHTML ) :

			undefined;



	return val !== undefined ?

		val :

		support.attributes || !documentIsHTML ?

			elem.getAttribute( name ) :

			(val = elem.getAttributeNode(name)) && val.specified ?

				val.value :

				null;

};



Sizzle.escape = function( sel ) {

	return (sel + "").replace( rcssescape, fcssescape );

};



Sizzle.error = function( msg ) {

	throw new Error( "Syntax error, unrecognized expression: " + msg );

};



/**

 * Document sorting and removing duplicates

 * @param {ArrayLike} results

 */

Sizzle.uniqueSort = function( results ) {

	var elem,

		duplicates = [],

		j = 0,

		i = 0;



	// Unless we *know* we can detect duplicates, assume their presence

	hasDuplicate = !support.detectDuplicates;

	sortInput = !support.sortStable && results.slice( 0 );

	results.sort( sortOrder );



	if ( hasDuplicate ) {

		while ( (elem = results[i++]) ) {

			if ( elem === results[ i ] ) {

				j = duplicates.push( i );

			}

		}

		while ( j-- ) {

			results.splice( duplicates[ j ], 1 );

		}

	}



	// Clear input after sorting to release objects

	// See https://github.com/jquery/sizzle/pull/225

	sortInput = null;



	return results;

};



/**

 * Utility function for retrieving the text value of an array of DOM nodes

 * @param {Array|Element} elem

 */

getText = Sizzle.getText = function( elem ) {

	var node,

		ret = "",

		i = 0,

		nodeType = elem.nodeType;



	if ( !nodeType ) {

		// If no nodeType, this is expected to be an array

		while ( (node = elem[i++]) ) {

			// Do not traverse comment nodes

			ret += getText( node );

		}

	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {

		// Use textContent for elements

		// innerText usage removed for consistency of new lines (jQuery #11153)

		if ( typeof elem.textContent === "string" ) {

			return elem.textContent;

		} else {

			// Traverse its children

			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {

				ret += getText( elem );

			}

		}

	} else if ( nodeType === 3 || nodeType === 4 ) {

		return elem.nodeValue;

	}

	// Do not include comment or processing instruction nodes



	return ret;

};



Expr = Sizzle.selectors = {



	// Can be adjusted by the user

	cacheLength: 50,



	createPseudo: markFunction,



	match: matchExpr,



	attrHandle: {},



	find: {},



	relative: {

		">": { dir: "parentNode", first: true },

		" ": { dir: "parentNode" },

		"+": { dir: "previousSibling", first: true },

		"~": { dir: "previousSibling" }

	},



	preFilter: {

		"ATTR": function( match ) {

			match[1] = match[1].replace( runescape, funescape );



			// Move the given value to match[3] whether quoted or unquoted

			match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );



			if ( match[2] === "~=" ) {

				match[3] = " " + match[3] + " ";

			}



			return match.slice( 0, 4 );

		},



		"CHILD": function( match ) {

			/* matches from matchExpr["CHILD"]

				1 type (only|nth|...)

				2 what (child|of-type)

				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)

				4 xn-component of xn+y argument ([+-]?\d*n|)

				5 sign of xn-component

				6 x of xn-component

				7 sign of y-component

				8 y of y-component

			*/

			match[1] = match[1].toLowerCase();



			if ( match[1].slice( 0, 3 ) === "nth" ) {

				// nth-* requires argument

				if ( !match[3] ) {

					Sizzle.error( match[0] );

				}



				// numeric x and y parameters for Expr.filter.CHILD

				// remember that false/true cast respectively to 0/1

				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );

				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );



			// other types prohibit arguments

			} else if ( match[3] ) {

				Sizzle.error( match[0] );

			}



			return match;

		},



		"PSEUDO": function( match ) {

			var excess,

				unquoted = !match[6] && match[2];



			if ( matchExpr["CHILD"].test( match[0] ) ) {

				return null;

			}



			// Accept quoted arguments as-is

			if ( match[3] ) {

				match[2] = match[4] || match[5] || "";



			// Strip excess characters from unquoted arguments

			} else if ( unquoted && rpseudo.test( unquoted ) &&

				// Get excess from tokenize (recursively)

				(excess = tokenize( unquoted, true )) &&

				// advance to the next closing parenthesis

				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {



				// excess is a negative index

				match[0] = match[0].slice( 0, excess );

				match[2] = unquoted.slice( 0, excess );

			}



			// Return only captures needed by the pseudo filter method (type and argument)

			return match.slice( 0, 3 );

		}

	},



	filter: {



		"TAG": function( nodeNameSelector ) {

			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();

			return nodeNameSelector === "*" ?

				function() { return true; } :

				function( elem ) {

					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;

				};

		},



		"CLASS": function( className ) {

			var pattern = classCache[ className + " " ];



			return pattern ||

				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&

				classCache( className, function( elem ) {

					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );

				});

		},



		"ATTR": function( name, operator, check ) {

			return function( elem ) {

				var result = Sizzle.attr( elem, name );



				if ( result == null ) {

					return operator === "!=";

				}

				if ( !operator ) {

					return true;

				}



				result += "";



				return operator === "=" ? result === check :

					operator === "!=" ? result !== check :

					operator === "^=" ? check && result.indexOf( check ) === 0 :

					operator === "*=" ? check && result.indexOf( check ) > -1 :

					operator === "$=" ? check && result.slice( -check.length ) === check :

					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :

					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :

					false;

			};

		},



		"CHILD": function( type, what, argument, first, last ) {

			var simple = type.slice( 0, 3 ) !== "nth",

				forward = type.slice( -4 ) !== "last",

				ofType = what === "of-type";



			return first === 1 && last === 0 ?



				// Shortcut for :nth-*(n)

				function( elem ) {

					return !!elem.parentNode;

				} :



				function( elem, context, xml ) {

					var cache, uniqueCache, outerCache, node, nodeIndex, start,

						dir = simple !== forward ? "nextSibling" : "previousSibling",

						parent = elem.parentNode,

						name = ofType && elem.nodeName.toLowerCase(),

						useCache = !xml && !ofType,

						diff = false;



					if ( parent ) {



						// :(first|last|only)-(child|of-type)

						if ( simple ) {

							while ( dir ) {

								node = elem;

								while ( (node = node[ dir ]) ) {

									if ( ofType ?

										node.nodeName.toLowerCase() === name :

										node.nodeType === 1 ) {



										return false;

									}

								}

								// Reverse direction for :only-* (if we haven't yet done so)

								start = dir = type === "only" && !start && "nextSibling";

							}

							return true;

						}



						start = [ forward ? parent.firstChild : parent.lastChild ];



						// non-xml :nth-child(...) stores cache data on `parent`

						if ( forward && useCache ) {



							// Seek `elem` from a previously-cached index



							// ...in a gzip-friendly way

							node = parent;

							outerCache = node[ expando ] || (node[ expando ] = {});



							// Support: IE <9 only

							// Defend against cloned attroperties (jQuery gh-1709)

							uniqueCache = outerCache[ node.uniqueID ] ||

								(outerCache[ node.uniqueID ] = {});



							cache = uniqueCache[ type ] || [];

							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];

							diff = nodeIndex && cache[ 2 ];

							node = nodeIndex && parent.childNodes[ nodeIndex ];



							while ( (node = ++nodeIndex && node && node[ dir ] ||



								// Fallback to seeking `elem` from the start

								(diff = nodeIndex = 0) || start.pop()) ) {



								// When found, cache indexes on `parent` and break

								if ( node.nodeType === 1 && ++diff && node === elem ) {

									uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];

									break;

								}

							}



						} else {

							// Use previously-cached element index if available

							if ( useCache ) {

								// ...in a gzip-friendly way

								node = elem;

								outerCache = node[ expando ] || (node[ expando ] = {});



								// Support: IE <9 only

								// Defend against cloned attroperties (jQuery gh-1709)

								uniqueCache = outerCache[ node.uniqueID ] ||

									(outerCache[ node.uniqueID ] = {});



								cache = uniqueCache[ type ] || [];

								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];

								diff = nodeIndex;

							}



							// xml :nth-child(...)

							// or :nth-last-child(...) or :nth(-last)?-of-type(...)

							if ( diff === false ) {

								// Use the same loop as above to seek `elem` from the start

								while ( (node = ++nodeIndex && node && node[ dir ] ||

									(diff = nodeIndex = 0) || start.pop()) ) {



									if ( ( ofType ?

										node.nodeName.toLowerCase() === name :

										node.nodeType === 1 ) &&

										++diff ) {



										// Cache the index of each encountered element

										if ( useCache ) {

											outerCache = node[ expando ] || (node[ expando ] = {});



											// Support: IE <9 only

											// Defend against cloned attroperties (jQuery gh-1709)

											uniqueCache = outerCache[ node.uniqueID ] ||

												(outerCache[ node.uniqueID ] = {});



											uniqueCache[ type ] = [ dirruns, diff ];

										}



										if ( node === elem ) {

											break;

										}

									}

								}

							}

						}



						// Incorporate the offset, then check against cycle size

						diff -= last;

						return diff === first || ( diff % first === 0 && diff / first >= 0 );

					}

				};

		},



		"PSEUDO": function( pseudo, argument ) {

			// pseudo-class names are case-insensitive

			// http://www.w3.org/TR/selectors/#pseudo-classes

			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters

			// Remember that setFilters inherits from pseudos

			var args,

				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||

					Sizzle.error( "unsupported pseudo: " + pseudo );



			// The user may use createPseudo to indicate that

			// arguments are needed to create the filter function

			// just as Sizzle does

			if ( fn[ expando ] ) {

				return fn( argument );

			}



			// But maintain support for old signatures

			if ( fn.length > 1 ) {

				args = [ pseudo, pseudo, "", argument ];

				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?

					markFunction(function( seed, matches ) {

						var idx,

							matched = fn( seed, argument ),

							i = matched.length;

						while ( i-- ) {

							idx = indexOf( seed, matched[i] );

							seed[ idx ] = !( matches[ idx ] = matched[i] );

						}

					}) :

					function( elem ) {

						return fn( elem, 0, args );

					};

			}



			return fn;

		}

	},



	pseudos: {

		// Potentially complex pseudos

		"not": markFunction(function( selector ) {

			// Trim the selector passed to compile

			// to avoid treating leading and trailing

			// spaces as combinators

			var input = [],

				results = [],

				matcher = compile( selector.replace( rtrim, "$1" ) );



			return matcher[ expando ] ?

				markFunction(function( seed, matches, context, xml ) {

					var elem,

						unmatched = matcher( seed, null, xml, [] ),

						i = seed.length;



					// Match elements unmatched by `matcher`

					while ( i-- ) {

						if ( (elem = unmatched[i]) ) {

							seed[i] = !(matches[i] = elem);

						}

					}

				}) :

				function( elem, context, xml ) {

					input[0] = elem;

					matcher( input, null, xml, results );

					// Don't keep the element (issue #299)

					input[0] = null;

					return !results.pop();

				};

		}),



		"has": markFunction(function( selector ) {

			return function( elem ) {

				return Sizzle( selector, elem ).length > 0;

			};

		}),



		"contains": markFunction(function( text ) {

			text = text.replace( runescape, funescape );

			return function( elem ) {

				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;

			};

		}),



		// "Whether an element is represented by a :lang() selector

		// is based solely on the element's language value

		// being equal to the identifier C,

		// or beginning with the identifier C immediately followed by "-".

		// The matching of C against the element's language value is performed case-insensitively.

		// The identifier C does not have to be a valid language name."

		// http://www.w3.org/TR/selectors/#lang-pseudo

		"lang": markFunction( function( lang ) {

			// lang value must be a valid identifier

			if ( !ridentifier.test(lang || "") ) {

				Sizzle.error( "unsupported lang: " + lang );

			}

			lang = lang.replace( runescape, funescape ).toLowerCase();

			return function( elem ) {

				var elemLang;

				do {

					if ( (elemLang = documentIsHTML ?

						elem.lang :

						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {



						elemLang = elemLang.toLowerCase();

						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;

					}

				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );

				return false;

			};

		}),



		// Miscellaneous

		"target": function( elem ) {

			var hash = window.location && window.location.hash;

			return hash && hash.slice( 1 ) === elem.id;

		},



		"root": function( elem ) {

			return elem === docElem;

		},



		"focus": function( elem ) {

			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);

		},



		// Boolean properties

		"enabled": createDisabledPseudo( false ),

		"disabled": createDisabledPseudo( true ),



		"checked": function( elem ) {

			// In CSS3, :checked should return both checked and selected elements

			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked

			var nodeName = elem.nodeName.toLowerCase();

			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);

		},



		"selected": function( elem ) {

			// Accessing this property makes selected-by-default

			// options in Safari work properly

			if ( elem.parentNode ) {

				elem.parentNode.selectedIndex;

			}



			return elem.selected === true;

		},



		// Contents

		"empty": function( elem ) {

			// http://www.w3.org/TR/selectors/#empty-pseudo

			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),

			//   but not by others (comment: 8; processing instruction: 7; etc.)

			// nodeType < 6 works because attributes (2) do not appear as children

			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {

				if ( elem.nodeType < 6 ) {

					return false;

				}

			}

			return true;

		},



		"parent": function( elem ) {

			return !Expr.pseudos["empty"]( elem );

		},



		// Element/input types

		"header": function( elem ) {

			return rheader.test( elem.nodeName );

		},



		"input": function( elem ) {

			return rinputs.test( elem.nodeName );

		},



		"button": function( elem ) {

			var name = elem.nodeName.toLowerCase();

			return name === "input" && elem.type === "button" || name === "button";

		},



		"text": function( elem ) {

			var attr;

			return elem.nodeName.toLowerCase() === "input" &&

				elem.type === "text" &&



				// Support: IE<8

				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"

				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );

		},



		// Position-in-collection

		"first": createPositionalPseudo(function() {

			return [ 0 ];

		}),



		"last": createPositionalPseudo(function( matchIndexes, length ) {

			return [ length - 1 ];

		}),



		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {

			return [ argument < 0 ? argument + length : argument ];

		}),



		"even": createPositionalPseudo(function( matchIndexes, length ) {

			var i = 0;

			for ( ; i < length; i += 2 ) {

				matchIndexes.push( i );

			}

			return matchIndexes;

		}),



		"odd": createPositionalPseudo(function( matchIndexes, length ) {

			var i = 1;

			for ( ; i < length; i += 2 ) {

				matchIndexes.push( i );

			}

			return matchIndexes;

		}),



		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {

			var i = argument < 0 ? argument + length : argument;

			for ( ; --i >= 0; ) {

				matchIndexes.push( i );

			}

			return matchIndexes;

		}),



		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {

			var i = argument < 0 ? argument + length : argument;

			for ( ; ++i < length; ) {

				matchIndexes.push( i );

			}

			return matchIndexes;

		})

	}

};



Expr.pseudos["nth"] = Expr.pseudos["eq"];



// Add button/input type pseudos

for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {

	Expr.pseudos[ i ] = createInputPseudo( i );

}

for ( i in { submit: true, reset: true } ) {

	Expr.pseudos[ i ] = createButtonPseudo( i );

}



// Easy API for creating new setFilters

function setFilters() {}

setFilters.prototype = Expr.filters = Expr.pseudos;

Expr.setFilters = new setFilters();



tokenize = Sizzle.tokenize = function( selector, parseOnly ) {

	var matched, match, tokens, type,

		soFar, groups, preFilters,

		cached = tokenCache[ selector + " " ];



	if ( cached ) {

		return parseOnly ? 0 : cached.slice( 0 );

	}



	soFar = selector;

	groups = [];

	preFilters = Expr.preFilter;



	while ( soFar ) {



		// Comma and first run

		if ( !matched || (match = rcomma.exec( soFar )) ) {

			if ( match ) {

				// Don't consume trailing commas as valid

				soFar = soFar.slice( match[0].length ) || soFar;

			}

			groups.push( (tokens = []) );

		}



		matched = false;



		// Combinators

		if ( (match = rcombinators.exec( soFar )) ) {

			matched = match.shift();

			tokens.push({

				value: matched,

				// Cast descendant combinators to space

				type: match[0].replace( rtrim, " " )

			});

			soFar = soFar.slice( matched.length );

		}



		// Filters

		for ( type in Expr.filter ) {

			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||

				(match = preFilters[ type ]( match ))) ) {

				matched = match.shift();

				tokens.push({

					value: matched,

					type: type,

					matches: match

				});

				soFar = soFar.slice( matched.length );

			}

		}



		if ( !matched ) {

			break;

		}

	}



	// Return the length of the invalid excess

	// if we're just parsing

	// Otherwise, throw an error or return tokens

	return parseOnly ?

		soFar.length :

		soFar ?

			Sizzle.error( selector ) :

			// Cache the tokens

			tokenCache( selector, groups ).slice( 0 );

};



function toSelector( tokens ) {

	var i = 0,

		len = tokens.length,

		selector = "";

	for ( ; i < len; i++ ) {

		selector += tokens[i].value;

	}

	return selector;

}



function addCombinator( matcher, combinator, base ) {

	var dir = combinator.dir,

		skip = combinator.next,

		key = skip || dir,

		checkNonElements = base && key === "parentNode",

		doneName = done++;



	return combinator.first ?

		// Check against closest ancestor/preceding element

		function( elem, context, xml ) {

			while ( (elem = elem[ dir ]) ) {

				if ( elem.nodeType === 1 || checkNonElements ) {

					return matcher( elem, context, xml );

				}

			}

			return false;

		} :



		// Check against all ancestor/preceding elements

		function( elem, context, xml ) {

			var oldCache, uniqueCache, outerCache,

				newCache = [ dirruns, doneName ];



			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching

			if ( xml ) {

				while ( (elem = elem[ dir ]) ) {

					if ( elem.nodeType === 1 || checkNonElements ) {

						if ( matcher( elem, context, xml ) ) {

							return true;

						}

					}

				}

			} else {

				while ( (elem = elem[ dir ]) ) {

					if ( elem.nodeType === 1 || checkNonElements ) {

						outerCache = elem[ expando ] || (elem[ expando ] = {});



						// Support: IE <9 only

						// Defend against cloned attroperties (jQuery gh-1709)

						uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});



						if ( skip && skip === elem.nodeName.toLowerCase() ) {

							elem = elem[ dir ] || elem;

						} else if ( (oldCache = uniqueCache[ key ]) &&

							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {



							// Assign to newCache so results back-propagate to previous elements

							return (newCache[ 2 ] = oldCache[ 2 ]);

						} else {

							// Reuse newcache so results back-propagate to previous elements

							uniqueCache[ key ] = newCache;



							// A match means we're done; a fail means we have to keep checking

							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {

								return true;

							}

						}

					}

				}

			}

			return false;

		};

}



function elementMatcher( matchers ) {

	return matchers.length > 1 ?

		function( elem, context, xml ) {

			var i = matchers.length;

			while ( i-- ) {

				if ( !matchers[i]( elem, context, xml ) ) {

					return false;

				}

			}

			return true;

		} :

		matchers[0];

}



function multipleContexts( selector, contexts, results ) {

	var i = 0,

		len = contexts.length;

	for ( ; i < len; i++ ) {

		Sizzle( selector, contexts[i], results );

	}

	return results;

}



function condense( unmatched, map, filter, context, xml ) {

	var elem,

		newUnmatched = [],

		i = 0,

		len = unmatched.length,

		mapped = map != null;



	for ( ; i < len; i++ ) {

		if ( (elem = unmatched[i]) ) {

			if ( !filter || filter( elem, context, xml ) ) {

				newUnmatched.push( elem );

				if ( mapped ) {

					map.push( i );

				}

			}

		}

	}



	return newUnmatched;

}



function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {

	if ( postFilter && !postFilter[ expando ] ) {

		postFilter = setMatcher( postFilter );

	}

	if ( postFinder && !postFinder[ expando ] ) {

		postFinder = setMatcher( postFinder, postSelector );

	}

	return markFunction(function( seed, results, context, xml ) {

		var temp, i, elem,

			preMap = [],

			postMap = [],

			preexisting = results.length,



			// Get initial elements from seed or context

			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),



			// Prefilter to get matcher input, preserving a map for seed-results synchronization

			matcherIn = preFilter && ( seed || !selector ) ?

				condense( elems, preMap, preFilter, context, xml ) :

				elems,



			matcherOut = matcher ?

				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,

				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?



					// ...intermediate processing is necessary

					[] :



					// ...otherwise use results directly

					results :

				matcherIn;



		// Find primary matches

		if ( matcher ) {

			matcher( matcherIn, matcherOut, context, xml );

		}



		// Apply postFilter

		if ( postFilter ) {

			temp = condense( matcherOut, postMap );

			postFilter( temp, [], context, xml );



			// Un-match failing elements by moving them back to matcherIn

			i = temp.length;

			while ( i-- ) {

				if ( (elem = temp[i]) ) {

					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);

				}

			}

		}



		if ( seed ) {

			if ( postFinder || preFilter ) {

				if ( postFinder ) {

					// Get the final matcherOut by condensing this intermediate into postFinder contexts

					temp = [];

					i = matcherOut.length;

					while ( i-- ) {

						if ( (elem = matcherOut[i]) ) {

							// Restore matcherIn since elem is not yet a final match

							temp.push( (matcherIn[i] = elem) );

						}

					}

					postFinder( null, (matcherOut = []), temp, xml );

				}



				// Move matched elements from seed to results to keep them synchronized

				i = matcherOut.length;

				while ( i-- ) {

					if ( (elem = matcherOut[i]) &&

						(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {



						seed[temp] = !(results[temp] = elem);

					}

				}

			}



		// Add elements to results, through postFinder if defined

		} else {

			matcherOut = condense(

				matcherOut === results ?

					matcherOut.splice( preexisting, matcherOut.length ) :

					matcherOut

			);

			if ( postFinder ) {

				postFinder( null, results, matcherOut, xml );

			} else {

				push.apply( results, matcherOut );

			}

		}

	});

}



function matcherFromTokens( tokens ) {

	var checkContext, matcher, j,

		len = tokens.length,

		leadingRelative = Expr.relative[ tokens[0].type ],

		implicitRelative = leadingRelative || Expr.relative[" "],

		i = leadingRelative ? 1 : 0,



		// The foundational matcher ensures that elements are reachable from top-level context(s)

		matchContext = addCombinator( function( elem ) {

			return elem === checkContext;

		}, implicitRelative, true ),

		matchAnyContext = addCombinator( function( elem ) {

			return indexOf( checkContext, elem ) > -1;

		}, implicitRelative, true ),

		matchers = [ function( elem, context, xml ) {

			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (

				(checkContext = context).nodeType ?

					matchContext( elem, context, xml ) :

					matchAnyContext( elem, context, xml ) );

			// Avoid hanging onto element (issue #299)

			checkContext = null;

			return ret;

		} ];



	for ( ; i < len; i++ ) {

		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {

			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];

		} else {

			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );



			// Return special upon seeing a positional matcher

			if ( matcher[ expando ] ) {

				// Find the next relative operator (if any) for proper handling

				j = ++i;

				for ( ; j < len; j++ ) {

					if ( Expr.relative[ tokens[j].type ] ) {

						break;

					}

				}

				return setMatcher(

					i > 1 && elementMatcher( matchers ),

					i > 1 && toSelector(

						// If the preceding token was a descendant combinator, insert an implicit any-element `*`

						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })

					).replace( rtrim, "$1" ),

					matcher,

					i < j && matcherFromTokens( tokens.slice( i, j ) ),

					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),

					j < len && toSelector( tokens )

				);

			}

			matchers.push( matcher );

		}

	}



	return elementMatcher( matchers );

}



function matcherFromGroupMatchers( elementMatchers, setMatchers ) {

	var bySet = setMatchers.length > 0,

		byElement = elementMatchers.length > 0,

		superMatcher = function( seed, context, xml, results, outermost ) {

			var elem, j, matcher,

				matchedCount = 0,

				i = "0",

				unmatched = seed && [],

				setMatched = [],

				contextBackup = outermostContext,

				// We must always have either seed elements or outermost context

				elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),

				// Use integer dirruns iff this is the outermost matcher

				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),

				len = elems.length;



			if ( outermost ) {

				outermostContext = context === document || context || outermost;

			}



			// Add elements passing elementMatchers directly to results

			// Support: IE<9, Safari

			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id

			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {

				if ( byElement && elem ) {

					j = 0;

					if ( !context && elem.ownerDocument !== document ) {

						setDocument( elem );

						xml = !documentIsHTML;

					}

					while ( (matcher = elementMatchers[j++]) ) {

						if ( matcher( elem, context || document, xml) ) {

							results.push( elem );

							break;

						}

					}

					if ( outermost ) {

						dirruns = dirrunsUnique;

					}

				}



				// Track unmatched elements for set filters

				if ( bySet ) {

					// They will have gone through all possible matchers

					if ( (elem = !matcher && elem) ) {

						matchedCount--;

					}



					// Lengthen the array for every element, matched or not

					if ( seed ) {

						unmatched.push( elem );

					}

				}

			}



			// `i` is now the count of elements visited above, and adding it to `matchedCount`

			// makes the latter nonnegative.

			matchedCount += i;



			// Apply set filters to unmatched elements

			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`

			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have

			// no element matchers and no seed.

			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that

			// case, which will result in a "00" `matchedCount` that differs from `i` but is also

			// numerically zero.

			if ( bySet && i !== matchedCount ) {

				j = 0;

				while ( (matcher = setMatchers[j++]) ) {

					matcher( unmatched, setMatched, context, xml );

				}



				if ( seed ) {

					// Reintegrate element matches to eliminate the need for sorting

					if ( matchedCount > 0 ) {

						while ( i-- ) {

							if ( !(unmatched[i] || setMatched[i]) ) {

								setMatched[i] = pop.call( results );

							}

						}

					}



					// Discard index placeholder values to get only actual matches

					setMatched = condense( setMatched );

				}



				// Add matches to results

				push.apply( results, setMatched );



				// Seedless set matches succeeding multiple successful matchers stipulate sorting

				if ( outermost && !seed && setMatched.length > 0 &&

					( matchedCount + setMatchers.length ) > 1 ) {



					Sizzle.uniqueSort( results );

				}

			}



			// Override manipulation of globals by nested matchers

			if ( outermost ) {

				dirruns = dirrunsUnique;

				outermostContext = contextBackup;

			}



			return unmatched;

		};



	return bySet ?

		markFunction( superMatcher ) :

		superMatcher;

}



compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {

	var i,

		setMatchers = [],

		elementMatchers = [],

		cached = compilerCache[ selector + " " ];



	if ( !cached ) {

		// Generate a function of recursive functions that can be used to check each element

		if ( !match ) {

			match = tokenize( selector );

		}

		i = match.length;

		while ( i-- ) {

			cached = matcherFromTokens( match[i] );

			if ( cached[ expando ] ) {

				setMatchers.push( cached );

			} else {

				elementMatchers.push( cached );

			}

		}



		// Cache the compiled function

		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );



		// Save selector and tokenization

		cached.selector = selector;

	}

	return cached;

};



/**

 * A low-level selection function that works with Sizzle's compiled

 *  selector functions

 * @param {String|Function} selector A selector or a pre-compiled

 *  selector function built with Sizzle.compile

 * @param {Element} context

 * @param {Array} [results]

 * @param {Array} [seed] A set of elements to match against

 */

select = Sizzle.select = function( selector, context, results, seed ) {

	var i, tokens, token, type, find,

		compiled = typeof selector === "function" && selector,

		match = !seed && tokenize( (selector = compiled.selector || selector) );



	results = results || [];



	// Try to minimize operations if there is only one selector in the list and no seed

	// (the latter of which guarantees us context)

	if ( match.length === 1 ) {



		// Reduce context if the leading compound selector is an ID

		tokens = match[0] = match[0].slice( 0 );

		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&

				context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {



			context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];

			if ( !context ) {

				return results;



			// Precompiled matchers will still verify ancestry, so step up a level

			} else if ( compiled ) {

				context = context.parentNode;

			}



			selector = selector.slice( tokens.shift().value.length );

		}



		// Fetch a seed set for right-to-left matching

		i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;

		while ( i-- ) {

			token = tokens[i];



			// Abort if we hit a combinator

			if ( Expr.relative[ (type = token.type) ] ) {

				break;

			}

			if ( (find = Expr.find[ type ]) ) {

				// Search, expanding context for leading sibling combinators

				if ( (seed = find(

					token.matches[0].replace( runescape, funescape ),

					rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context

				)) ) {



					// If seed is empty or no tokens remain, we can return early

					tokens.splice( i, 1 );

					selector = seed.length && toSelector( tokens );

					if ( !selector ) {

						push.apply( results, seed );

						return results;

					}



					break;

				}

			}

		}

	}



	// Compile and execute a filtering function if one is not provided

	// Provide `match` to avoid retokenization if we modified the selector above

	( compiled || compile( selector, match ) )(

		seed,

		context,

		!documentIsHTML,

		results,

		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context

	);

	return results;

};



// One-time assignments



// Sort stability

support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;



// Support: Chrome 14-35+

// Always assume duplicates if they aren't passed to the comparison function

support.detectDuplicates = !!hasDuplicate;



// Initialize against the default document

setDocument();



// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)

// Detached nodes confoundingly follow *each other*

support.sortDetached = assert(function( el ) {

	// Should return 1, but returns 4 (following)

	return el.compareDocumentPosition( document.createElement("fieldset") ) & 1;

});



// Support: IE<8

// Prevent attribute/property "interpolation"

// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx

if ( !assert(function( el ) {

	el.innerHTML = "<a href='#'></a>";

	return el.firstChild.getAttribute("href") === "#" ;

}) ) {

	addHandle( "type|href|height|width", function( elem, name, isXML ) {

		if ( !isXML ) {

			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );

		}

	});

}



// Support: IE<9

// Use defaultValue in place of getAttribute("value")

if ( !support.attributes || !assert(function( el ) {

	el.innerHTML = "<input/>";

	el.firstChild.setAttribute( "value", "" );

	return el.firstChild.getAttribute( "value" ) === "";

}) ) {

	addHandle( "value", function( elem, name, isXML ) {

		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {

			return elem.defaultValue;

		}

	});

}



// Support: IE<9

// Use getAttributeNode to fetch booleans when getAttribute lies

if ( !assert(function( el ) {

	return el.getAttribute("disabled") == null;

}) ) {

	addHandle( booleans, function( elem, name, isXML ) {

		var val;

		if ( !isXML ) {

			return elem[ name ] === true ? name.toLowerCase() :

					(val = elem.getAttributeNode( name )) && val.specified ?

					val.value :

				null;

		}

	});

}



return Sizzle;



})( window );







jQuery.find = Sizzle;

jQuery.expr = Sizzle.selectors;



// Deprecated

jQuery.expr[ ":" ] = jQuery.expr.pseudos;

jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;

jQuery.text = Sizzle.getText;

jQuery.isXMLDoc = Sizzle.isXML;

jQuery.contains = Sizzle.contains;

jQuery.escapeSelector = Sizzle.escape;









var dir = function( elem, dir, until ) {

	var matched = [],

		truncate = until !== undefined;



	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {

		if ( elem.nodeType === 1 ) {

			if ( truncate && jQuery( elem ).is( until ) ) {

				break;

			}

			matched.push( elem );

		}

	}

	return matched;

};





var siblings = function( n, elem ) {

	var matched = [];



	for ( ; n; n = n.nextSibling ) {

		if ( n.nodeType === 1 && n !== elem ) {

			matched.push( n );

		}

	}



	return matched;

};





var rneedsContext = jQuery.expr.match.needsContext;







function nodeName( elem, name ) {



  return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();



};

var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );







var risSimple = /^.[^:#\[\.,]*$/;



// Implement the identical functionality for filter and not

function winnow( elements, qualifier, not ) {

	if ( jQuery.isFunction( qualifier ) ) {

		return jQuery.grep( elements, function( elem, i ) {

			return !!qualifier.call( elem, i, elem ) !== not;

		} );

	}



	// Single element

	if ( qualifier.nodeType ) {

		return jQuery.grep( elements, function( elem ) {

			return ( elem === qualifier ) !== not;

		} );

	}



	// Arraylike of elements (jQuery, arguments, Array)

	if ( typeof qualifier !== "string" ) {

		return jQuery.grep( elements, function( elem ) {

			return ( indexOf.call( qualifier, elem ) > -1 ) !== not;

		} );

	}



	// Simple selector that can be filtered directly, removing non-Elements

	if ( risSimple.test( qualifier ) ) {

		return jQuery.filter( qualifier, elements, not );

	}



	// Complex selector, compare the two sets, removing non-Elements

	qualifier = jQuery.filter( qualifier, elements );

	return jQuery.grep( elements, function( elem ) {

		return ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1;

	} );

}



jQuery.filter = function( expr, elems, not ) {

	var elem = elems[ 0 ];



	if ( not ) {

		expr = ":not(" + expr + ")";

	}



	if ( elems.length === 1 && elem.nodeType === 1 ) {

		return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];

	}



	return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {

		return elem.nodeType === 1;

	} ) );

};



jQuery.fn.extend( {

	find: function( selector ) {

		var i, ret,

			len = this.length,

			self = this;



		if ( typeof selector !== "string" ) {

			return this.pushStack( jQuery( selector ).filter( function() {

				for ( i = 0; i < len; i++ ) {

					if ( jQuery.contains( self[ i ], this ) ) {

						return true;

					}

				}

			} ) );

		}



		ret = this.pushStack( [] );



		for ( i = 0; i < len; i++ ) {

			jQuery.find( selector, self[ i ], ret );

		}



		return len > 1 ? jQuery.uniqueSort( ret ) : ret;

	},

	filter: function( selector ) {

		return this.pushStack( winnow( this, selector || [], false ) );

	},

	not: function( selector ) {

		return this.pushStack( winnow( this, selector || [], true ) );

	},

	is: function( selector ) {

		return !!winnow(

			this,



			// If this is a positional/relative selector, check membership in the returned set

			// so $("p:first").is("p:last") won't return true for a doc with two "p".

			typeof selector === "string" && rneedsContext.test( selector ) ?

				jQuery( selector ) :

				selector || [],

			false

		).length;

	}

} );





// Initialize a jQuery object





// A central reference to the root jQuery(document)

var rootjQuery,



	// A simple way to check for HTML strings

	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)

	// Strict HTML recognition (#11290: must start with <)

	// Shortcut simple #id case for speed

	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,



	init = jQuery.fn.init = function( selector, context, root ) {

		var match, elem;



		// HANDLE: $(""), $(null), $(undefined), $(false)

		if ( !selector ) {

			return this;

		}



		// Method init() accepts an alternate rootjQuery

		// so migrate can support jQuery.sub (gh-2101)

		root = root || rootjQuery;



		// Handle HTML strings

		if ( typeof selector === "string" ) {

			if ( selector[ 0 ] === "<" &&

				selector[ selector.length - 1 ] === ">" &&

				selector.length >= 3 ) {



				// Assume that strings that start and end with <> are HTML and skip the regex check

				match = [ null, selector, null ];



			} else {

				match = rquickExpr.exec( selector );

			}



			// Match html or make sure no context is specified for #id

			if ( match && ( match[ 1 ] || !context ) ) {



				// HANDLE: $(html) -> $(array)

				if ( match[ 1 ] ) {

					context = context instanceof jQuery ? context[ 0 ] : context;



					// Option to run scripts is true for back-compat

					// Intentionally let the error be thrown if parseHTML is not present

					jQuery.merge( this, jQuery.parseHTML(

						match[ 1 ],

						context && context.nodeType ? context.ownerDocument || context : document,

						true

					) );



					// HANDLE: $(html, props)

					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {

						for ( match in context ) {



							// Properties of context are called as methods if possible

							if ( jQuery.isFunction( this[ match ] ) ) {

								this[ match ]( context[ match ] );



							// ...and otherwise set as attributes

							} else {

								this.attr( match, context[ match ] );

							}

						}

					}



					return this;



				// HANDLE: $(#id)

				} else {

					elem = document.getElementById( match[ 2 ] );



					if ( elem ) {



						// Inject the element directly into the jQuery object

						this[ 0 ] = elem;

						this.length = 1;

					}

					return this;

				}



			// HANDLE: $(expr, $(...))

			} else if ( !context || context.jquery ) {

				return ( context || root ).find( selector );



			// HANDLE: $(expr, context)

			// (which is just equivalent to: $(context).find(expr)

			} else {

				return this.constructor( context ).find( selector );

			}



		// HANDLE: $(DOMElement)

		} else if ( selector.nodeType ) {

			this[ 0 ] = selector;

			this.length = 1;

			return this;



		// HANDLE: $(function)

		// Shortcut for document ready

		} else if ( jQuery.isFunction( selector ) ) {

			return root.ready !== undefined ?

				root.ready( selector ) :



				// Execute immediately if ready is not present

				selector( jQuery );

		}



		return jQuery.makeArray( selector, this );

	};



// Give the init function the jQuery prototype for later instantiation

init.prototype = jQuery.fn;



// Initialize central reference

rootjQuery = jQuery( document );





var rparentsprev = /^(?:parents|prev(?:Until|All))/,



	// Methods guaranteed to produce a unique set when starting from a unique set

	guaranteedUnique = {

		children: true,

		contents: true,

		next: true,

		prev: true

	};



jQuery.fn.extend( {

	has: function( target ) {

		var targets = jQuery( target, this ),

			l = targets.length;



		return this.filter( function() {

			var i = 0;

			for ( ; i < l; i++ ) {

				if ( jQuery.contains( this, targets[ i ] ) ) {

					return true;

				}

			}

		} );

	},



	closest: function( selectors, context ) {

		var cur,

			i = 0,

			l = this.length,

			matched = [],

			targets = typeof selectors !== "string" && jQuery( selectors );



		// Positional selectors never match, since there's no _selection_ context

		if ( !rneedsContext.test( selectors ) ) {

			for ( ; i < l; i++ ) {

				for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {



					// Always skip document fragments

					if ( cur.nodeType < 11 && ( targets ?

						targets.index( cur ) > -1 :



						// Don't pass non-elements to Sizzle

						cur.nodeType === 1 &&

							jQuery.find.matchesSelector( cur, selectors ) ) ) {



						matched.push( cur );

						break;

					}

				}

			}

		}



		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );

	},



	// Determine the position of an element within the set

	index: function( elem ) {



		// No argument, return index in parent

		if ( !elem ) {

			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;

		}



		// Index in selector

		if ( typeof elem === "string" ) {

			return indexOf.call( jQuery( elem ), this[ 0 ] );

		}



		// Locate the position of the desired element

		return indexOf.call( this,



			// If it receives a jQuery object, the first element is used

			elem.jquery ? elem[ 0 ] : elem

		);

	},



	add: function( selector, context ) {

		return this.pushStack(

			jQuery.uniqueSort(

				jQuery.merge( this.get(), jQuery( selector, context ) )

			)

		);

	},



	addBack: function( selector ) {

		return this.add( selector == null ?

			this.prevObject : this.prevObject.filter( selector )

		);

	}

} );



function sibling( cur, dir ) {

	while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}

	return cur;

}



jQuery.each( {

	parent: function( elem ) {

		var parent = elem.parentNode;

		return parent && parent.nodeType !== 11 ? parent : null;

	},

	parents: function( elem ) {

		return dir( elem, "parentNode" );

	},

	parentsUntil: function( elem, i, until ) {

		return dir( elem, "parentNode", until );

	},

	next: function( elem ) {

		return sibling( elem, "nextSibling" );

	},

	prev: function( elem ) {

		return sibling( elem, "previousSibling" );

	},

	nextAll: function( elem ) {

		return dir( elem, "nextSibling" );

	},

	prevAll: function( elem ) {

		return dir( elem, "previousSibling" );

	},

	nextUntil: function( elem, i, until ) {

		return dir( elem, "nextSibling", until );

	},

	prevUntil: function( elem, i, until ) {

		return dir( elem, "previousSibling", until );

	},

	siblings: function( elem ) {

		return siblings( ( elem.parentNode || {} ).firstChild, elem );

	},

	children: function( elem ) {

		return siblings( elem.firstChild );

	},

	contents: function( elem ) {

        if ( nodeName( elem, "iframe" ) ) {

            return elem.contentDocument;

        }



        // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only

        // Treat the template element as a regular one in browsers that

        // don't support it.

        if ( nodeName( elem, "template" ) ) {

            elem = elem.content || elem;

        }



        return jQuery.merge( [], elem.childNodes );

	}

}, function( name, fn ) {

	jQuery.fn[ name ] = function( until, selector ) {

		var matched = jQuery.map( this, fn, until );



		if ( name.slice( -5 ) !== "Until" ) {

			selector = until;

		}



		if ( selector && typeof selector === "string" ) {

			matched = jQuery.filter( selector, matched );

		}



		if ( this.length > 1 ) {



			// Remove duplicates

			if ( !guaranteedUnique[ name ] ) {

				jQuery.uniqueSort( matched );

			}



			// Reverse order for parents* and prev-derivatives

			if ( rparentsprev.test( name ) ) {

				matched.reverse();

			}

		}



		return this.pushStack( matched );

	};

} );

var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );







// Convert String-formatted options into Object-formatted ones

function createOptions( options ) {

	var object = {};

	jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {

		object[ flag ] = true;

	} );

	return object;

}



/*

 * Create a callback list using the following parameters:

 *

 *	options: an optional list of space-separated options that will change how

 *			the callback list behaves or a more traditional option object

 *

 * By default a callback list will act like an event callback list and can be

 * "fired" multiple times.

 *

 * Possible options:

 *

 *	once:			will ensure the callback list can only be fired once (like a Deferred)

 *

 *	memory:			will keep track of previous values and will call any callback added

 *					after the list has been fired right away with the latest "memorized"

 *					values (like a Deferred)

 *

 *	unique:			will ensure a callback can only be added once (no duplicate in the list)

 *

 *	stopOnFalse:	interrupt callings when a callback returns false

 *

 */

jQuery.Callbacks = function( options ) {



	// Convert options from String-formatted to Object-formatted if needed

	// (we check in cache first)

	options = typeof options === "string" ?

		createOptions( options ) :

		jQuery.extend( {}, options );



	var // Flag to know if list is currently firing

		firing,



		// Last fire value for non-forgettable lists

		memory,



		// Flag to know if list was already fired

		fired,



		// Flag to prevent firing

		locked,



		// Actual callback list

		list = [],



		// Queue of execution data for repeatable lists

		queue = [],



		// Index of currently firing callback (modified by add/remove as needed)

		firingIndex = -1,



		// Fire callbacks

		fire = function() {



			// Enforce single-firing

			locked = locked || options.once;



			// Execute callbacks for all pending executions,

			// respecting firingIndex overrides and runtime changes

			fired = firing = true;

			for ( ; queue.length; firingIndex = -1 ) {

				memory = queue.shift();

				while ( ++firingIndex < list.length ) {



					// Run callback and check for early termination

					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&

						options.stopOnFalse ) {



						// Jump to end and forget the data so .add doesn't re-fire

						firingIndex = list.length;

						memory = false;

					}

				}

			}



			// Forget the data if we're done with it

			if ( !options.memory ) {

				memory = false;

			}



			firing = false;



			// Clean up if we're done firing for good

			if ( locked ) {



				// Keep an empty list if we have data for future add calls

				if ( memory ) {

					list = [];



				// Otherwise, this object is spent

				} else {

					list = "";

				}

			}

		},



		// Actual Callbacks object

		self = {



			// Add a callback or a collection of callbacks to the list

			add: function() {

				if ( list ) {



					// If we have memory from a past run, we should fire after adding

					if ( memory && !firing ) {

						firingIndex = list.length - 1;

						queue.push( memory );

					}



					( function add( args ) {

						jQuery.each( args, function( _, arg ) {

							if ( jQuery.isFunction( arg ) ) {

								if ( !options.unique || !self.has( arg ) ) {

									list.push( arg );

								}

							} else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {



								// Inspect recursively

								add( arg );

							}

						} );

					} )( arguments );



					if ( memory && !firing ) {

						fire();

					}

				}

				return this;

			},



			// Remove a callback from the list

			remove: function() {

				jQuery.each( arguments, function( _, arg ) {

					var index;

					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {

						list.splice( index, 1 );



						// Handle firing indexes

						if ( index <= firingIndex ) {

							firingIndex--;

						}

					}

				} );

				return this;

			},



			// Check if a given callback is in the list.

			// If no argument is given, return whether or not list has callbacks attached.

			has: function( fn ) {

				return fn ?

					jQuery.inArray( fn, list ) > -1 :

					list.length > 0;

			},



			// Remove all callbacks from the list

			empty: function() {

				if ( list ) {

					list = [];

				}

				return this;

			},



			// Disable .fire and .add

			// Abort any current/pending executions

			// Clear all callbacks and values

			disable: function() {

				locked = queue = [];

				list = memory = "";

				return this;

			},

			disabled: function() {

				return !list;

			},



			// Disable .fire

			// Also disable .add unless we have memory (since it would have no effect)

			// Abort any pending executions

			lock: function() {

				locked = queue = [];

				if ( !memory && !firing ) {

					list = memory = "";

				}

				return this;

			},

			locked: function() {

				return !!locked;

			},



			// Call all callbacks with the given context and arguments

			fireWith: function( context, args ) {

				if ( !locked ) {

					args = args || [];

					args = [ context, args.slice ? args.slice() : args ];

					queue.push( args );

					if ( !firing ) {

						fire();

					}

				}

				return this;

			},



			// Call all the callbacks with the given arguments

			fire: function() {

				self.fireWith( this, arguments );

				return this;

			},



			// To know if the callbacks have already been called at least once

			fired: function() {

				return !!fired;

			}

		};



	return self;

};





function Identity( v ) {

	return v;

}

function Thrower( ex ) {

	throw ex;

}



function adoptValue( value, resolve, reject, noValue ) {

	var method;



	try {



		// Check for promise aspect first to privilege synchronous behavior

		if ( value && jQuery.isFunction( ( method = value.promise ) ) ) {

			method.call( value ).done( resolve ).fail( reject );



		// Other thenables

		} else if ( value && jQuery.isFunction( ( method = value.then ) ) ) {

			method.call( value, resolve, reject );



		// Other non-thenables

		} else {



			// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:

			// * false: [ value ].slice( 0 ) => resolve( value )

			// * true: [ value ].slice( 1 ) => resolve()

			resolve.apply( undefined, [ value ].slice( noValue ) );

		}



	// For Promises/A+, convert exceptions into rejections

	// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in

	// Deferred#then to conditionally suppress rejection.

	} catch ( value ) {



		// Support: Android 4.0 only

		// Strict mode functions invoked without .call/.apply get global-object context

		reject.apply( undefined, [ value ] );

	}

}



jQuery.extend( {



	Deferred: function( func ) {

		var tuples = [



				// action, add listener, callbacks,

				// ... .then handlers, argument index, [final state]

				[ "notify", "progress", jQuery.Callbacks( "memory" ),

					jQuery.Callbacks( "memory" ), 2 ],

				[ "resolve", "done", jQuery.Callbacks( "once memory" ),

					jQuery.Callbacks( "once memory" ), 0, "resolved" ],

				[ "reject", "fail", jQuery.Callbacks( "once memory" ),

					jQuery.Callbacks( "once memory" ), 1, "rejected" ]

			],

			state = "pending",

			promise = {

				state: function() {

					return state;

				},

				always: function() {

					deferred.done( arguments ).fail( arguments );

					return this;

				},

				"catch": function( fn ) {

					return promise.then( null, fn );

				},



				// Keep pipe for back-compat

				pipe: function( /* fnDone, fnFail, fnProgress */ ) {

					var fns = arguments;



					return jQuery.Deferred( function( newDefer ) {

						jQuery.each( tuples, function( i, tuple ) {



							// Map tuples (progress, done, fail) to arguments (done, fail, progress)

							var fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];



							// deferred.progress(function() { bind to newDefer or newDefer.notify })

							// deferred.done(function() { bind to newDefer or newDefer.resolve })

							// deferred.fail(function() { bind to newDefer or newDefer.reject })

							deferred[ tuple[ 1 ] ]( function() {

								var returned = fn && fn.apply( this, arguments );

								if ( returned && jQuery.isFunction( returned.promise ) ) {

									returned.promise()

										.progress( newDefer.notify )

										.done( newDefer.resolve )

										.fail( newDefer.reject );

								} else {

									newDefer[ tuple[ 0 ] + "With" ](

										this,

										fn ? [ returned ] : arguments

									);

								}

							} );

						} );

						fns = null;

					} ).promise();

				},

				then: function( onFulfilled, onRejected, onProgress ) {

					var maxDepth = 0;

					function resolve( depth, deferred, handler, special ) {

						return function() {

							var that = this,

								args = arguments,

								mightThrow = function() {

									var returned, then;



									// Support: Promises/A+ section 2.3.3.3.3

									// https://promisesaplus.com/#point-59

									// Ignore double-resolution attempts

									if ( depth < maxDepth ) {

										return;

									}



									returned = handler.apply( that, args );



									// Support: Promises/A+ section 2.3.1

									// https://promisesaplus.com/#point-48

									if ( returned === deferred.promise() ) {

										throw new TypeError( "Thenable self-resolution" );

									}



									// Support: Promises/A+ sections 2.3.3.1, 3.5

									// https://promisesaplus.com/#point-54

									// https://promisesaplus.com/#point-75

									// Retrieve `then` only once

									then = returned &&



										// Support: Promises/A+ section 2.3.4

										// https://promisesaplus.com/#point-64

										// Only check objects and functions for thenability

										( typeof returned === "object" ||

											typeof returned === "function" ) &&

										returned.then;



									// Handle a returned thenable

									if ( jQuery.isFunction( then ) ) {



										// Special processors (notify) just wait for resolution

										if ( special ) {

											then.call(

												returned,

												resolve( maxDepth, deferred, Identity, special ),

												resolve( maxDepth, deferred, Thrower, special )

											);



										// Normal processors (resolve) also hook into progress

										} else {



											// ...and disregard older resolution values

											maxDepth++;



											then.call(

												returned,

												resolve( maxDepth, deferred, Identity, special ),

												resolve( maxDepth, deferred, Thrower, special ),

												resolve( maxDepth, deferred, Identity,

													deferred.notifyWith )

											);

										}



									// Handle all other returned values

									} else {



										// Only substitute handlers pass on context

										// and multiple values (non-spec behavior)

										if ( handler !== Identity ) {

											that = undefined;

											args = [ returned ];

										}



										// Process the value(s)

										// Default process is resolve

										( special || deferred.resolveWith )( that, args );

									}

								},



								// Only normal processors (resolve) catch and reject exceptions

								process = special ?

									mightThrow :

									function() {

										try {

											mightThrow();

										} catch ( e ) {



											if ( jQuery.Deferred.exceptionHook ) {

												jQuery.Deferred.exceptionHook( e,

													process.stackTrace );

											}



											// Support: Promises/A+ section 2.3.3.3.4.1

											// https://promisesaplus.com/#point-61

											// Ignore post-resolution exceptions

											if ( depth + 1 >= maxDepth ) {



												// Only substitute handlers pass on context

												// and multiple values (non-spec behavior)

												if ( handler !== Thrower ) {

													that = undefined;

													args = [ e ];

												}



												deferred.rejectWith( that, args );

											}

										}

									};



							// Support: Promises/A+ section 2.3.3.3.1

							// https://promisesaplus.com/#point-57

							// Re-resolve promises immediately to dodge false rejection from

							// subsequent errors

							if ( depth ) {

								process();

							} else {



								// Call an optional hook to record the stack, in case of exception

								// since it's otherwise lost when execution goes async

								if ( jQuery.Deferred.getStackHook ) {

									process.stackTrace = jQuery.Deferred.getStackHook();

								}

								window.setTimeout( process );

							}

						};

					}



					return jQuery.Deferred( function( newDefer ) {



						// progress_handlers.add( ... )

						tuples[ 0 ][ 3 ].add(

							resolve(

								0,

								newDefer,

								jQuery.isFunction( onProgress ) ?

									onProgress :

									Identity,

								newDefer.notifyWith

							)

						);



						// fulfilled_handlers.add( ... )

						tuples[ 1 ][ 3 ].add(

							resolve(

								0,

								newDefer,

								jQuery.isFunction( onFulfilled ) ?

									onFulfilled :

									Identity

							)

						);



						// rejected_handlers.add( ... )

						tuples[ 2 ][ 3 ].add(

							resolve(

								0,

								newDefer,

								jQuery.isFunction( onRejected ) ?

									onRejected :

									Thrower

							)

						);

					} ).promise();

				},



				// Get a promise for this deferred

				// If obj is provided, the promise aspect is added to the object

				promise: function( obj ) {

					return obj != null ? jQuery.extend( obj, promise ) : promise;

				}

			},

			deferred = {};



		// Add list-specific methods

		jQuery.each( tuples, function( i, tuple ) {

			var list = tuple[ 2 ],

				stateString = tuple[ 5 ];



			// promise.progress = list.add

			// promise.done = list.add

			// promise.fail = list.add

			promise[ tuple[ 1 ] ] = list.add;



			// Handle state

			if ( stateString ) {

				list.add(

					function() {



						// state = "resolved" (i.e., fulfilled)

						// state = "rejected"

						state = stateString;

					},



					// rejected_callbacks.disable

					// fulfilled_callbacks.disable

					tuples[ 3 - i ][ 2 ].disable,



					// progress_callbacks.lock

					tuples[ 0 ][ 2 ].lock

				);

			}



			// progress_handlers.fire

			// fulfilled_handlers.fire

			// rejected_handlers.fire

			list.add( tuple[ 3 ].fire );



			// deferred.notify = function() { deferred.notifyWith(...) }

			// deferred.resolve = function() { deferred.resolveWith(...) }

			// deferred.reject = function() { deferred.rejectWith(...) }

			deferred[ tuple[ 0 ] ] = function() {

				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );

				return this;

			};



			// deferred.notifyWith = list.fireWith

			// deferred.resolveWith = list.fireWith

			// deferred.rejectWith = list.fireWith

			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;

		} );



		// Make the deferred a promise

		promise.promise( deferred );



		// Call given func if any

		if ( func ) {

			func.call( deferred, deferred );

		}



		// All done!

		return deferred;

	},



	// Deferred helper

	when: function( singleValue ) {

		var



			// count of uncompleted subordinates

			remaining = arguments.length,



			// count of unprocessed arguments

			i = remaining,



			// subordinate fulfillment data

			resolveContexts = Array( i ),

			resolveValues = slice.call( arguments ),



			// the master Deferred

			master = jQuery.Deferred(),



			// subordinate callback factory

			updateFunc = function( i ) {

				return function( value ) {

					resolveContexts[ i ] = this;

					resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;

					if ( !( --remaining ) ) {

						master.resolveWith( resolveContexts, resolveValues );

					}

				};

			};



		// Single- and empty arguments are adopted like Promise.resolve

		if ( remaining <= 1 ) {

			adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,

				!remaining );



			// Use .then() to unwrap secondary thenables (cf. gh-3000)

			if ( master.state() === "pending" ||

				jQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {



				return master.then();

			}

		}



		// Multiple arguments are aggregated like Promise.all array elements

		while ( i-- ) {

			adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );

		}



		return master.promise();

	}

} );





// These usually indicate a programmer mistake during development,

// warn about them ASAP rather than swallowing them by default.

var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;



jQuery.Deferred.exceptionHook = function( error, stack ) {



	// Support: IE 8 - 9 only

	// Console exists when dev tools are open, which can happen at any time

	if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {

		window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );

	}

};









jQuery.readyException = function( error ) {

	window.setTimeout( function() {

		throw error;

	} );

};









// The deferred used on DOM ready

var readyList = jQuery.Deferred();



jQuery.fn.ready = function( fn ) {



	readyList

		.then( fn )



		// Wrap jQuery.readyException in a function so that the lookup

		// happens at the time of error handling instead of callback

		// registration.

		.catch( function( error ) {

			jQuery.readyException( error );

		} );



	return this;

};



jQuery.extend( {



	// Is the DOM ready to be used? Set to true once it occurs.

	isReady: false,



	// A counter to track how many items to wait for before

	// the ready event fires. See #6781

	readyWait: 1,



	// Handle when the DOM is ready

	ready: function( wait ) {



		// Abort if there are pending holds or we're already ready

		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {

			return;

		}



		// Remember that the DOM is ready

		jQuery.isReady = true;



		// If a normal DOM Ready event fired, decrement, and wait if need be

		if ( wait !== true && --jQuery.readyWait > 0 ) {

			return;

		}



		// If there are functions bound, to execute

		readyList.resolveWith( document, [ jQuery ] );

	}

} );



jQuery.ready.then = readyList.then;



// The ready event handler and self cleanup method

function completed() {

	document.removeEventListener( "DOMContentLoaded", completed );

	window.removeEventListener( "load", completed );

	jQuery.ready();

}



// Catch cases where $(document).ready() is called

// after the browser event has already occurred.

// Support: IE <=9 - 10 only

// Older IE sometimes signals "interactive" too soon

if ( document.readyState === "complete" ||

	( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {



	// Handle it asynchronously to allow scripts the opportunity to delay ready

	window.setTimeout( jQuery.ready );



} else {



	// Use the handy event callback

	document.addEventListener( "DOMContentLoaded", completed );



	// A fallback to window.onload, that will always work

	window.addEventListener( "load", completed );

}









// Multifunctional method to get and set values of a collection

// The value/s can optionally be executed if it's a function

var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {

	var i = 0,

		len = elems.length,

		bulk = key == null;



	// Sets many values

	if ( jQuery.type( key ) === "object" ) {

		chainable = true;

		for ( i in key ) {

			access( elems, fn, i, key[ i ], true, emptyGet, raw );

		}



	// Sets one value

	} else if ( value !== undefined ) {

		chainable = true;



		if ( !jQuery.isFunction( value ) ) {

			raw = true;

		}



		if ( bulk ) {



			// Bulk operations run against the entire set

			if ( raw ) {

				fn.call( elems, value );

				fn = null;



			// ...except when executing function values

			} else {

				bulk = fn;

				fn = function( elem, key, value ) {

					return bulk.call( jQuery( elem ), value );

				};

			}

		}



		if ( fn ) {

			for ( ; i < len; i++ ) {

				fn(

					elems[ i ], key, raw ?

					value :

					value.call( elems[ i ], i, fn( elems[ i ], key ) )

				);

			}

		}

	}



	if ( chainable ) {

		return elems;

	}



	// Gets

	if ( bulk ) {

		return fn.call( elems );

	}



	return len ? fn( elems[ 0 ], key ) : emptyGet;

};

var acceptData = function( owner ) {



	// Accepts only:

	//  - Node

	//    - Node.ELEMENT_NODE

	//    - Node.DOCUMENT_NODE

	//  - Object

	//    - Any

	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );

};









function Data() {

	this.expando = jQuery.expando + Data.uid++;

}



Data.uid = 1;



Data.prototype = {



	cache: function( owner ) {



		// Check if the owner object already has a cache

		var value = owner[ this.expando ];



		// If not, create one

		if ( !value ) {

			value = {};



			// We can accept data for non-element nodes in modern browsers,

			// but we should not, see #8335.

			// Always return an empty object.

			if ( acceptData( owner ) ) {



				// If it is a node unlikely to be stringify-ed or looped over

				// use plain assignment

				if ( owner.nodeType ) {

					owner[ this.expando ] = value;



				// Otherwise secure it in a non-enumerable property

				// configurable must be true to allow the property to be

				// deleted when data is removed

				} else {

					Object.defineProperty( owner, this.expando, {

						value: value,

						configurable: true

					} );

				}

			}

		}



		return value;

	},

	set: function( owner, data, value ) {

		var prop,

			cache = this.cache( owner );



		// Handle: [ owner, key, value ] args

		// Always use camelCase key (gh-2257)

		if ( typeof data === "string" ) {

			cache[ jQuery.camelCase( data ) ] = value;



		// Handle: [ owner, { properties } ] args

		} else {



			// Copy the properties one-by-one to the cache object

			for ( prop in data ) {

				cache[ jQuery.camelCase( prop ) ] = data[ prop ];

			}

		}

		return cache;

	},

	get: function( owner, key ) {

		return key === undefined ?

			this.cache( owner ) :



			// Always use camelCase key (gh-2257)

			owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ];

	},

	access: function( owner, key, value ) {



		// In cases where either:

		//

		//   1. No key was specified

		//   2. A string key was specified, but no value provided

		//

		// Take the "read" path and allow the get method to determine

		// which value to return, respectively either:

		//

		//   1. The entire cache object

		//   2. The data stored at the key

		//

		if ( key === undefined ||

				( ( key && typeof key === "string" ) && value === undefined ) ) {



			return this.get( owner, key );

		}



		// When the key is not a string, or both a key and value

		// are specified, set or extend (existing objects) with either:

		//

		//   1. An object of properties

		//   2. A key and value

		//

		this.set( owner, key, value );



		// Since the "set" path can have two possible entry points

		// return the expected data based on which path was taken[*]

		return value !== undefined ? value : key;

	},

	remove: function( owner, key ) {

		var i,

			cache = owner[ this.expando ];



		if ( cache === undefined ) {

			return;

		}



		if ( key !== undefined ) {



			// Support array or space separated string of keys

			if ( Array.isArray( key ) ) {



				// If key is an array of keys...

				// We always set camelCase keys, so remove that.

				key = key.map( jQuery.camelCase );

			} else {

				key = jQuery.camelCase( key );



				// If a key with the spaces exists, use it.

				// Otherwise, create an array by matching non-whitespace

				key = key in cache ?

					[ key ] :

					( key.match( rnothtmlwhite ) || [] );

			}



			i = key.length;



			while ( i-- ) {

				delete cache[ key[ i ] ];

			}

		}



		// Remove the expando if there's no more data

		if ( key === undefined || jQuery.isEmptyObject( cache ) ) {



			// Support: Chrome <=35 - 45

			// Webkit & Blink performance suffers when deleting properties

			// from DOM nodes, so set to undefined instead

			// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)

			if ( owner.nodeType ) {

				owner[ this.expando ] = undefined;

			} else {

				delete owner[ this.expando ];

			}

		}

	},

	hasData: function( owner ) {

		var cache = owner[ this.expando ];

		return cache !== undefined && !jQuery.isEmptyObject( cache );

	}

};

var dataPriv = new Data();



var dataUser = new Data();







//	Implementation Summary

//

//	1. Enforce API surface and semantic compatibility with 1.9.x branch

//	2. Improve the module's maintainability by reducing the storage

//		paths to a single mechanism.

//	3. Use the same single mechanism to support "private" and "user" data.

//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)

//	5. Avoid exposing implementation details on user objects (eg. expando properties)

//	6. Provide a clear path for implementation upgrade to WeakMap in 2014



var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,

	rmultiDash = /[A-Z]/g;



function getData( data ) {

	if ( data === "true" ) {

		return true;

	}



	if ( data === "false" ) {

		return false;

	}



	if ( data === "null" ) {

		return null;

	}



	// Only convert to a number if it doesn't change the string

	if ( data === +data + "" ) {

		return +data;

	}



	if ( rbrace.test( data ) ) {

		return JSON.parse( data );

	}



	return data;

}



function dataAttr( elem, key, data ) {

	var name;



	// If nothing was found internally, try to fetch any

	// data from the HTML5 data-* attribute

	if ( data === undefined && elem.nodeType === 1 ) {

		name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();

		data = elem.getAttribute( name );



		if ( typeof data === "string" ) {

			try {

				data = getData( data );

			} catch ( e ) {}



			// Make sure we set the data so it isn't changed later

			dataUser.set( elem, key, data );

		} else {

			data = undefined;

		}

	}

	return data;

}



jQuery.extend( {

	hasData: function( elem ) {

		return dataUser.hasData( elem ) || dataPriv.hasData( elem );

	},



	data: function( elem, name, data ) {

		return dataUser.access( elem, name, data );

	},



	removeData: function( elem, name ) {

		dataUser.remove( elem, name );

	},



	// TODO: Now that all calls to _data and _removeData have been replaced

	// with direct calls to dataPriv methods, these can be deprecated.

	_data: function( elem, name, data ) {

		return dataPriv.access( elem, name, data );

	},



	_removeData: function( elem, name ) {

		dataPriv.remove( elem, name );

	}

} );



jQuery.fn.extend( {

	data: function( key, value ) {

		var i, name, data,

			elem = this[ 0 ],

			attrs = elem && elem.attributes;



		// Gets all values

		if ( key === undefined ) {

			if ( this.length ) {

				data = dataUser.get( elem );



				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {

					i = attrs.length;

					while ( i-- ) {



						// Support: IE 11 only

						// The attrs elements can be null (#14894)

						if ( attrs[ i ] ) {

							name = attrs[ i ].name;

							if ( name.indexOf( "data-" ) === 0 ) {

								name = jQuery.camelCase( name.slice( 5 ) );

								dataAttr( elem, name, data[ name ] );

							}

						}

					}

					dataPriv.set( elem, "hasDataAttrs", true );

				}

			}



			return data;

		}



		// Sets multiple values

		if ( typeof key === "object" ) {

			return this.each( function() {

				dataUser.set( this, key );

			} );

		}



		return access( this, function( value ) {

			var data;



			// The calling jQuery object (element matches) is not empty

			// (and therefore has an element appears at this[ 0 ]) and the

			// `value` parameter was not undefined. An empty jQuery object

			// will result in `undefined` for elem = this[ 0 ] which will

			// throw an exception if an attempt to read a data cache is made.

			if ( elem && value === undefined ) {



				// Attempt to get data from the cache

				// The key will always be camelCased in Data

				data = dataUser.get( elem, key );

				if ( data !== undefined ) {

					return data;

				}



				// Attempt to "discover" the data in

				// HTML5 custom data-* attrs

				data = dataAttr( elem, key );

				if ( data !== undefined ) {

					return data;

				}



				// We tried really hard, but the data doesn't exist.

				return;

			}



			// Set the data...

			this.each( function() {



				// We always store the camelCased key

				dataUser.set( this, key, value );

			} );

		}, null, value, arguments.length > 1, null, true );

	},



	removeData: function( key ) {

		return this.each( function() {

			dataUser.remove( this, key );

		} );

	}

} );





jQuery.extend( {

	queue: function( elem, type, data ) {

		var queue;



		if ( elem ) {

			type = ( type || "fx" ) + "queue";

			queue = dataPriv.get( elem, type );



			// Speed up dequeue by getting out quickly if this is just a lookup

			if ( data ) {

				if ( !queue || Array.isArray( data ) ) {

					queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );

				} else {

					queue.push( data );

				}

			}

			return queue || [];

		}

	},



	dequeue: function( elem, type ) {

		type = type || "fx";



		var queue = jQuery.queue( elem, type ),

			startLength = queue.length,

			fn = queue.shift(),

			hooks = jQuery._queueHooks( elem, type ),

			next = function() {

				jQuery.dequeue( elem, type );

			};



		// If the fx queue is dequeued, always remove the progress sentinel

		if ( fn === "inprogress" ) {

			fn = queue.shift();

			startLength--;

		}



		if ( fn ) {



			// Add a progress sentinel to prevent the fx queue from being

			// automatically dequeued

			if ( type === "fx" ) {

				queue.unshift( "inprogress" );

			}



			// Clear up the last queue stop function

			delete hooks.stop;

			fn.call( elem, next, hooks );

		}



		if ( !startLength && hooks ) {

			hooks.empty.fire();

		}

	},



	// Not public - generate a queueHooks object, or return the current one

	_queueHooks: function( elem, type ) {

		var key = type + "queueHooks";

		return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {

			empty: jQuery.Callbacks( "once memory" ).add( function() {

				dataPriv.remove( elem, [ type + "queue", key ] );

			} )

		} );

	}

} );



jQuery.fn.extend( {

	queue: function( type, data ) {

		var setter = 2;



		if ( typeof type !== "string" ) {

			data = type;

			type = "fx";

			setter--;

		}



		if ( arguments.length < setter ) {

			return jQuery.queue( this[ 0 ], type );

		}



		return data === undefined ?

			this :

			this.each( function() {

				var queue = jQuery.queue( this, type, data );



				// Ensure a hooks for this queue

				jQuery._queueHooks( this, type );



				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {

					jQuery.dequeue( this, type );

				}

			} );

	},

	dequeue: function( type ) {

		return this.each( function() {

			jQuery.dequeue( this, type );

		} );

	},

	clearQueue: function( type ) {

		return this.queue( type || "fx", [] );

	},



	// Get a promise resolved when queues of a certain type

	// are emptied (fx is the type by default)

	promise: function( type, obj ) {

		var tmp,

			count = 1,

			defer = jQuery.Deferred(),

			elements = this,

			i = this.length,

			resolve = function() {

				if ( !( --count ) ) {

					defer.resolveWith( elements, [ elements ] );

				}

			};



		if ( typeof type !== "string" ) {

			obj = type;

			type = undefined;

		}

		type = type || "fx";



		while ( i-- ) {

			tmp = dataPriv.get( elements[ i ], type + "queueHooks" );

			if ( tmp && tmp.empty ) {

				count++;

				tmp.empty.add( resolve );

			}

		}

		resolve();

		return defer.promise( obj );

	}

} );

var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;



var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );





var cssExpand = [ "Top", "Right", "Bottom", "Left" ];



var isHiddenWithinTree = function( elem, el ) {



		// isHiddenWithinTree might be called from jQuery#filter function;

		// in that case, element will be second argument

		elem = el || elem;



		// Inline style trumps all

		return elem.style.display === "none" ||

			elem.style.display === "" &&



			// Otherwise, check computed style

			// Support: Firefox <=43 - 45

			// Disconnected elements can have computed display: none, so first confirm that elem is

			// in the document.

			jQuery.contains( elem.ownerDocument, elem ) &&



			jQuery.css( elem, "display" ) === "none";

	};



var swap = function( elem, options, callback, args ) {

	var ret, name,

		old = {};



	// Remember the old values, and insert the new ones

	for ( name in options ) {

		old[ name ] = elem.style[ name ];

		elem.style[ name ] = options[ name ];

	}



	ret = callback.apply( elem, args || [] );



	// Revert the old values

	for ( name in options ) {

		elem.style[ name ] = old[ name ];

	}



	return ret;

};









function adjustCSS( elem, prop, valueParts, tween ) {

	var adjusted,

		scale = 1,

		maxIterations = 20,

		currentValue = tween ?

			function() {

				return tween.cur();

			} :

			function() {

				return jQuery.css( elem, prop, "" );

			},

		initial = currentValue(),

		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),



		// Starting value computation is required for potential unit mismatches

		initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&

			rcssNum.exec( jQuery.css( elem, prop ) );



	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {



		// Trust units reported by jQuery.css

		unit = unit || initialInUnit[ 3 ];



		// Make sure we update the tween properties later on

		valueParts = valueParts || [];



		// Iteratively approximate from a nonzero starting point

		initialInUnit = +initial || 1;



		do {



			// If previous iteration zeroed out, double until we get *something*.

			// Use string for doubling so we don't accidentally see scale as unchanged below

			scale = scale || ".5";



			// Adjust and apply

			initialInUnit = initialInUnit / scale;

			jQuery.style( elem, prop, initialInUnit + unit );



		// Update scale, tolerating zero or NaN from tween.cur()

		// Break the loop if scale is unchanged or perfect, or if we've just had enough.

		} while (

			scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations

		);

	}



	if ( valueParts ) {

		initialInUnit = +initialInUnit || +initial || 0;



		// Apply relative offset (+=/-=) if specified

		adjusted = valueParts[ 1 ] ?

			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :

			+valueParts[ 2 ];

		if ( tween ) {

			tween.unit = unit;

			tween.start = initialInUnit;

			tween.end = adjusted;

		}

	}

	return adjusted;

}





var defaultDisplayMap = {};



function getDefaultDisplay( elem ) {

	var temp,

		doc = elem.ownerDocument,

		nodeName = elem.nodeName,

		display = defaultDisplayMap[ nodeName ];



	if ( display ) {

		return display;

	}



	temp = doc.body.appendChild( doc.createElement( nodeName ) );

	display = jQuery.css( temp, "display" );



	temp.parentNode.removeChild( temp );



	if ( display === "none" ) {

		display = "block";

	}

	defaultDisplayMap[ nodeName ] = display;



	return display;

}



function showHide( elements, show ) {

	var display, elem,

		values = [],

		index = 0,

		length = elements.length;



	// Determine new display value for elements that need to change

	for ( ; index < length; index++ ) {

		elem = elements[ index ];

		if ( !elem.style ) {

			continue;

		}



		display = elem.style.display;

		if ( show ) {



			// Since we force visibility upon cascade-hidden elements, an immediate (and slow)

			// check is required in this first loop unless we have a nonempty display value (either

			// inline or about-to-be-restored)

			if ( display === "none" ) {

				values[ index ] = dataPriv.get( elem, "display" ) || null;

				if ( !values[ index ] ) {

					elem.style.display = "";

				}

			}

			if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {

				values[ index ] = getDefaultDisplay( elem );

			}

		} else {

			if ( display !== "none" ) {

				values[ index ] = "none";



				// Remember what we're overwriting

				dataPriv.set( elem, "display", display );

			}

		}

	}



	// Set the display of the elements in a second loop to avoid constant reflow

	for ( index = 0; index < length; index++ ) {

		if ( values[ index ] != null ) {

			elements[ index ].style.display = values[ index ];

		}

	}



	return elements;

}



jQuery.fn.extend( {

	show: function() {

		return showHide( this, true );

	},

	hide: function() {

		return showHide( this );

	},

	toggle: function( state ) {

		if ( typeof state === "boolean" ) {

			return state ? this.show() : this.hide();

		}



		return this.each( function() {

			if ( isHiddenWithinTree( this ) ) {

				jQuery( this ).show();

			} else {

				jQuery( this ).hide();

			}

		} );

	}

} );

var rcheckableType = ( /^(?:checkbox|radio)$/i );



var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i );



var rscriptType = ( /^$|\/(?:java|ecma)script/i );







// We have to close these tags to support XHTML (#13200)

var wrapMap = {



	// Support: IE <=9 only

	option: [ 1, "<select multiple='multiple'>", "</select>" ],



	// XHTML parsers do not magically insert elements in the

	// same way that tag soup parsers do. So we cannot shorten

	// this by omitting <tbody> or other required elements.

	thead: [ 1, "<table>", "</table>" ],

	col: [ 2, "<table><colgroup>", "</colgroup></table>" ],

	tr: [ 2, "<table><tbody>", "</tbody></table>" ],

	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],



	_default: [ 0, "", "" ]

};



// Support: IE <=9 only

wrapMap.optgroup = wrapMap.option;



wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;

wrapMap.th = wrapMap.td;





function getAll( context, tag ) {



	// Support: IE <=9 - 11 only

	// Use typeof to avoid zero-argument method invocation on host objects (#15151)

	var ret;



	if ( typeof context.getElementsByTagName !== "undefined" ) {

		ret = context.getElementsByTagName( tag || "*" );



	} else if ( typeof context.querySelectorAll !== "undefined" ) {

		ret = context.querySelectorAll( tag || "*" );



	} else {

		ret = [];

	}



	if ( tag === undefined || tag && nodeName( context, tag ) ) {

		return jQuery.merge( [ context ], ret );

	}



	return ret;

}





// Mark scripts as having already been evaluated

function setGlobalEval( elems, refElements ) {

	var i = 0,

		l = elems.length;



	for ( ; i < l; i++ ) {

		dataPriv.set(

			elems[ i ],

			"globalEval",

			!refElements || dataPriv.get( refElements[ i ], "globalEval" )

		);

	}

}





var rhtml = /<|&#?\w+;/;



function buildFragment( elems, context, scripts, selection, ignored ) {

	var elem, tmp, tag, wrap, contains, j,

		fragment = context.createDocumentFragment(),

		nodes = [],

		i = 0,

		l = elems.length;



	for ( ; i < l; i++ ) {

		elem = elems[ i ];



		if ( elem || elem === 0 ) {



			// Add nodes directly

			if ( jQuery.type( elem ) === "object" ) {



				// Support: Android <=4.0 only, PhantomJS 1 only

				// push.apply(_, arraylike) throws on ancient WebKit

				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );



			// Convert non-html into a text node

			} else if ( !rhtml.test( elem ) ) {

				nodes.push( context.createTextNode( elem ) );



			// Convert html into DOM nodes

			} else {

				tmp = tmp || fragment.appendChild( context.createElement( "div" ) );



				// Deserialize a standard representation

				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();

				wrap = wrapMap[ tag ] || wrapMap._default;

				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];



				// Descend through wrappers to the right content

				j = wrap[ 0 ];

				while ( j-- ) {

					tmp = tmp.lastChild;

				}



				// Support: Android <=4.0 only, PhantomJS 1 only

				// push.apply(_, arraylike) throws on ancient WebKit

				jQuery.merge( nodes, tmp.childNodes );



				// Remember the top-level container

				tmp = fragment.firstChild;



				// Ensure the created nodes are orphaned (#12392)

				tmp.textContent = "";

			}

		}

	}



	// Remove wrapper from fragment

	fragment.textContent = "";



	i = 0;

	while ( ( elem = nodes[ i++ ] ) ) {



		// Skip elements already in the context collection (trac-4087)

		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {

			if ( ignored ) {

				ignored.push( elem );

			}

			continue;

		}



		contains = jQuery.contains( elem.ownerDocument, elem );



		// Append to fragment

		tmp = getAll( fragment.appendChild( elem ), "script" );



		// Preserve script evaluation history

		if ( contains ) {

			setGlobalEval( tmp );

		}



		// Capture executables

		if ( scripts ) {

			j = 0;

			while ( ( elem = tmp[ j++ ] ) ) {

				if ( rscriptType.test( elem.type || "" ) ) {

					scripts.push( elem );

				}

			}

		}

	}



	return fragment;

}





( function() {

	var fragment = document.createDocumentFragment(),

		div = fragment.appendChild( document.createElement( "div" ) ),

		input = document.createElement( "input" );



	// Support: Android 4.0 - 4.3 only

	// Check state lost if the name is set (#11217)

	// Support: Windows Web Apps (WWA)

	// `name` and `type` must use .setAttribute for WWA (#14901)

	input.setAttribute( "type", "radio" );

	input.setAttribute( "checked", "checked" );

	input.setAttribute( "name", "t" );



	div.appendChild( input );



	// Support: Android <=4.1 only

	// Older WebKit doesn't clone checked state correctly in fragments

	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;



	// Support: IE <=11 only

	// Make sure textarea (and checkbox) defaultValue is properly cloned

	div.innerHTML = "<textarea>x</textarea>";

	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;

} )();

var documentElement = document.documentElement;







var

	rkeyEvent = /^key/,

	rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,

	rtypenamespace = /^([^.]*)(?:\.(.+)|)/;



function returnTrue() {

	return true;

}



function returnFalse() {

	return false;

}



// Support: IE <=9 only

// See #13393 for more info

function safeActiveElement() {

	try {

		return document.activeElement;

	} catch ( err ) { }

}



function on( elem, types, selector, data, fn, one ) {

	var origFn, type;



	// Types can be a map of types/handlers

	if ( typeof types === "object" ) {



		// ( types-Object, selector, data )

		if ( typeof selector !== "string" ) {



			// ( types-Object, data )

			data = data || selector;

			selector = undefined;

		}

		for ( type in types ) {

			on( elem, type, selector, data, types[ type ], one );

		}

		return elem;

	}



	if ( data == null && fn == null ) {



		// ( types, fn )

		fn = selector;

		data = selector = undefined;

	} else if ( fn == null ) {

		if ( typeof selector === "string" ) {



			// ( types, selector, fn )

			fn = data;

			data = undefined;

		} else {



			// ( types, data, fn )

			fn = data;

			data = selector;

			selector = undefined;

		}

	}

	if ( fn === false ) {

		fn = returnFalse;

	} else if ( !fn ) {

		return elem;

	}



	if ( one === 1 ) {

		origFn = fn;

		fn = function( event ) {



			// Can use an empty set, since event contains the info

			jQuery().off( event );

			return origFn.apply( this, arguments );

		};



		// Use same guid so caller can remove using origFn

		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );

	}

	return elem.each( function() {

		jQuery.event.add( this, types, fn, data, selector );

	} );

}



/*

 * Helper functions for managing events -- not part of the public interface.

 * Props to Dean Edwards' addEvent library for many of the ideas.

 */

jQuery.event = {



	global: {},



	add: function( elem, types, handler, data, selector ) {



		var handleObjIn, eventHandle, tmp,

			events, t, handleObj,

			special, handlers, type, namespaces, origType,

			elemData = dataPriv.get( elem );



		// Don't attach events to noData or text/comment nodes (but allow plain objects)

		if ( !elemData ) {

			return;

		}



		// Caller can pass in an object of custom data in lieu of the handler

		if ( handler.handler ) {

			handleObjIn = handler;

			handler = handleObjIn.handler;

			selector = handleObjIn.selector;

		}



		// Ensure that invalid selectors throw exceptions at attach time

		// Evaluate against documentElement in case elem is a non-element node (e.g., document)

		if ( selector ) {

			jQuery.find.matchesSelector( documentElement, selector );

		}



		// Make sure that the handler has a unique ID, used to find/remove it later

		if ( !handler.guid ) {

			handler.guid = jQuery.guid++;

		}



		// Init the element's event structure and main handler, if this is the first

		if ( !( events = elemData.events ) ) {

			events = elemData.events = {};

		}

		if ( !( eventHandle = elemData.handle ) ) {

			eventHandle = elemData.handle = function( e ) {



				// Discard the second event of a jQuery.event.trigger() and

				// when an event is called after a page has unloaded

				return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?

					jQuery.event.dispatch.apply( elem, arguments ) : undefined;

			};

		}



		// Handle multiple events separated by a space

		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];

		t = types.length;

		while ( t-- ) {

			tmp = rtypenamespace.exec( types[ t ] ) || [];

			type = origType = tmp[ 1 ];

			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();



			// There *must* be a type, no attaching namespace-only handlers

			if ( !type ) {

				continue;

			}



			// If event changes its type, use the special event handlers for the changed type

			special = jQuery.event.special[ type ] || {};



			// If selector defined, determine special event api type, otherwise given type

			type = ( selector ? special.delegateType : special.bindType ) || type;



			// Update special based on newly reset type

			special = jQuery.event.special[ type ] || {};



			// handleObj is passed to all event handlers

			handleObj = jQuery.extend( {

				type: type,

				origType: origType,

				data: data,

				handler: handler,

				guid: handler.guid,

				selector: selector,

				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),

				namespace: namespaces.join( "." )

			}, handleObjIn );



			// Init the event handler queue if we're the first

			if ( !( handlers = events[ type ] ) ) {

				handlers = events[ type ] = [];

				handlers.delegateCount = 0;



				// Only use addEventListener if the special events handler returns false

				if ( !special.setup ||

					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {



					if ( elem.addEventListener ) {

						elem.addEventListener( type, eventHandle );

					}

				}

			}



			if ( special.add ) {

				special.add.call( elem, handleObj );



				if ( !handleObj.handler.guid ) {

					handleObj.handler.guid = handler.guid;

				}

			}



			// Add to the element's handler list, delegates in front

			if ( selector ) {

				handlers.splice( handlers.delegateCount++, 0, handleObj );

			} else {

				handlers.push( handleObj );

			}



			// Keep track of which events have ever been used, for event optimization

			jQuery.event.global[ type ] = true;

		}



	},



	// Detach an event or set of events from an element

	remove: function( elem, types, handler, selector, mappedTypes ) {



		var j, origCount, tmp,

			events, t, handleObj,

			special, handlers, type, namespaces, origType,

			elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );



		if ( !elemData || !( events = elemData.events ) ) {

			return;

		}



		// Once for each type.namespace in types; type may be omitted

		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];

		t = types.length;

		while ( t-- ) {

			tmp = rtypenamespace.exec( types[ t ] ) || [];

			type = origType = tmp[ 1 ];

			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();



			// Unbind all events (on this namespace, if provided) for the element

			if ( !type ) {

				for ( type in events ) {

					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );

				}

				continue;

			}



			special = jQuery.event.special[ type ] || {};

			type = ( selector ? special.delegateType : special.bindType ) || type;

			handlers = events[ type ] || [];

			tmp = tmp[ 2 ] &&

				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );



			// Remove matching events

			origCount = j = handlers.length;

			while ( j-- ) {

				handleObj = handlers[ j ];



				if ( ( mappedTypes || origType === handleObj.origType ) &&

					( !handler || handler.guid === handleObj.guid ) &&

					( !tmp || tmp.test( handleObj.namespace ) ) &&

					( !selector || selector === handleObj.selector ||

						selector === "**" && handleObj.selector ) ) {

					handlers.splice( j, 1 );



					if ( handleObj.selector ) {

						handlers.delegateCount--;

					}

					if ( special.remove ) {

						special.remove.call( elem, handleObj );

					}

				}

			}



			// Remove generic event handler if we removed something and no more handlers exist

			// (avoids potential for endless recursion during removal of special event handlers)

			if ( origCount && !handlers.length ) {

				if ( !special.teardown ||

					special.teardown.call( elem, namespaces, elemData.handle ) === false ) {



					jQuery.removeEvent( elem, type, elemData.handle );

				}



				delete events[ type ];

			}

		}



		// Remove data and the expando if it's no longer used

		if ( jQuery.isEmptyObject( events ) ) {

			dataPriv.remove( elem, "handle events" );

		}

	},



	dispatch: function( nativeEvent ) {



		// Make a writable jQuery.Event from the native event object

		var event = jQuery.event.fix( nativeEvent );



		var i, j, ret, matched, handleObj, handlerQueue,

			args = new Array( arguments.length ),

			handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],

			special = jQuery.event.special[ event.type ] || {};



		// Use the fix-ed jQuery.Event rather than the (read-only) native event

		args[ 0 ] = event;



		for ( i = 1; i < arguments.length; i++ ) {

			args[ i ] = arguments[ i ];

		}



		event.delegateTarget = this;



		// Call the preDispatch hook for the mapped type, and let it bail if desired

		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {

			return;

		}



		// Determine handlers

		handlerQueue = jQuery.event.handlers.call( this, event, handlers );



		// Run delegates first; they may want to stop propagation beneath us

		i = 0;

		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {

			event.currentTarget = matched.elem;



			j = 0;

			while ( ( handleObj = matched.handlers[ j++ ] ) &&

				!event.isImmediatePropagationStopped() ) {



				// Triggered event must either 1) have no namespace, or 2) have namespace(s)

				// a subset or equal to those in the bound event (both can have no namespace).

				if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {



					event.handleObj = handleObj;

					event.data = handleObj.data;



					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||

						handleObj.handler ).apply( matched.elem, args );



					if ( ret !== undefined ) {

						if ( ( event.result = ret ) === false ) {

							event.preventDefault();

							event.stopPropagation();

						}

					}

				}

			}

		}



		// Call the postDispatch hook for the mapped type

		if ( special.postDispatch ) {

			special.postDispatch.call( this, event );

		}



		return event.result;

	},



	handlers: function( event, handlers ) {

		var i, handleObj, sel, matchedHandlers, matchedSelectors,

			handlerQueue = [],

			delegateCount = handlers.delegateCount,

			cur = event.target;



		// Find delegate handlers

		if ( delegateCount &&



			// Support: IE <=9

			// Black-hole SVG <use> instance trees (trac-13180)

			cur.nodeType &&



			// Support: Firefox <=42

			// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)

			// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click

			// Support: IE 11 only

			// ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)

			!( event.type === "click" && event.button >= 1 ) ) {



			for ( ; cur !== this; cur = cur.parentNode || this ) {



				// Don't check non-elements (#13208)

				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)

				if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {

					matchedHandlers = [];

					matchedSelectors = {};

					for ( i = 0; i < delegateCount; i++ ) {

						handleObj = handlers[ i ];



						// Don't conflict with Object.prototype properties (#13203)

						sel = handleObj.selector + " ";



						if ( matchedSelectors[ sel ] === undefined ) {

							matchedSelectors[ sel ] = handleObj.needsContext ?

								jQuery( sel, this ).index( cur ) > -1 :

								jQuery.find( sel, this, null, [ cur ] ).length;

						}

						if ( matchedSelectors[ sel ] ) {

							matchedHandlers.push( handleObj );

						}

					}

					if ( matchedHandlers.length ) {

						handlerQueue.push( { elem: cur, handlers: matchedHandlers } );

					}

				}

			}

		}



		// Add the remaining (directly-bound) handlers

		cur = this;

		if ( delegateCount < handlers.length ) {

			handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );

		}



		return handlerQueue;

	},



	addProp: function( name, hook ) {

		Object.defineProperty( jQuery.Event.prototype, name, {

			enumerable: true,

			configurable: true,



			get: jQuery.isFunction( hook ) ?

				function() {

					if ( this.originalEvent ) {

							return hook( this.originalEvent );

					}

				} :

				function() {

					if ( this.originalEvent ) {

							return this.originalEvent[ name ];

					}

				},



			set: function( value ) {

				Object.defineProperty( this, name, {

					enumerable: true,

					configurable: true,

					writable: true,

					value: value

				} );

			}

		} );

	},



	fix: function( originalEvent ) {

		return originalEvent[ jQuery.expando ] ?

			originalEvent :

			new jQuery.Event( originalEvent );

	},



	special: {

		load: {



			// Prevent triggered image.load events from bubbling to window.load

			noBubble: true

		},

		focus: {



			// Fire native event if possible so blur/focus sequence is correct

			trigger: function() {

				if ( this !== safeActiveElement() && this.focus ) {

					this.focus();

					return false;

				}

			},

			delegateType: "focusin"

		},

		blur: {

			trigger: function() {

				if ( this === safeActiveElement() && this.blur ) {

					this.blur();

					return false;

				}

			},

			delegateType: "focusout"

		},

		click: {



			// For checkbox, fire native event so checked state will be right

			trigger: function() {

				if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) {

					this.click();

					return false;

				}

			},



			// For cross-browser consistency, don't fire native .click() on links

			_default: function( event ) {

				return nodeName( event.target, "a" );

			}

		},



		beforeunload: {

			postDispatch: function( event ) {



				// Support: Firefox 20+

				// Firefox doesn't alert if the returnValue field is not set.

				if ( event.result !== undefined && event.originalEvent ) {

					event.originalEvent.returnValue = event.result;

				}

			}

		}

	}

};



jQuery.removeEvent = function( elem, type, handle ) {



	// This "if" is needed for plain objects

	if ( elem.removeEventListener ) {

		elem.removeEventListener( type, handle );

	}

};



jQuery.Event = function( src, props ) {



	// Allow instantiation without the 'new' keyword

	if ( !( this instanceof jQuery.Event ) ) {

		return new jQuery.Event( src, props );

	}



	// Event object

	if ( src && src.type ) {

		this.originalEvent = src;

		this.type = src.type;



		// Events bubbling up the document may have been marked as prevented

		// by a handler lower down the tree; reflect the correct value.

		this.isDefaultPrevented = src.defaultPrevented ||

				src.defaultPrevented === undefined &&



				// Support: Android <=2.3 only

				src.returnValue === false ?

			returnTrue :

			returnFalse;



		// Create target properties

		// Support: Safari <=6 - 7 only

		// Target should not be a text node (#504, #13143)

		this.target = ( src.target && src.target.nodeType === 3 ) ?

			src.target.parentNode :

			src.target;



		this.currentTarget = src.currentTarget;

		this.relatedTarget = src.relatedTarget;



	// Event type

	} else {

		this.type = src;

	}



	// Put explicitly provided properties onto the event object

	if ( props ) {

		jQuery.extend( this, props );

	}



	// Create a timestamp if incoming event doesn't have one

	this.timeStamp = src && src.timeStamp || jQuery.now();



	// Mark it as fixed

	this[ jQuery.expando ] = true;

};



// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding

// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html

jQuery.Event.prototype = {

	constructor: jQuery.Event,

	isDefaultPrevented: returnFalse,

	isPropagationStopped: returnFalse,

	isImmediatePropagationStopped: returnFalse,

	isSimulated: false,



	preventDefault: function() {

		var e = this.originalEvent;



		this.isDefaultPrevented = returnTrue;



		if ( e && !this.isSimulated ) {

			e.preventDefault();

		}

	},

	stopPropagation: function() {

		var e = this.originalEvent;



		this.isPropagationStopped = returnTrue;



		if ( e && !this.isSimulated ) {

			e.stopPropagation();

		}

	},

	stopImmediatePropagation: function() {

		var e = this.originalEvent;



		this.isImmediatePropagationStopped = returnTrue;



		if ( e && !this.isSimulated ) {

			e.stopImmediatePropagation();

		}



		this.stopPropagation();

	}

};



// Includes all common event props including KeyEvent and MouseEvent specific props

jQuery.each( {

	altKey: true,

	bubbles: true,

	cancelable: true,

	changedTouches: true,

	ctrlKey: true,

	detail: true,

	eventPhase: true,

	metaKey: true,

	pageX: true,

	pageY: true,

	shiftKey: true,

	view: true,

	"char": true,

	charCode: true,

	key: true,

	keyCode: true,

	button: true,

	buttons: true,

	clientX: true,

	clientY: true,

	offsetX: true,

	offsetY: true,

	pointerId: true,

	pointerType: true,

	screenX: true,

	screenY: true,

	targetTouches: true,

	toElement: true,

	touches: true,



	which: function( event ) {

		var button = event.button;



		// Add which for key events

		if ( event.which == null && rkeyEvent.test( event.type ) ) {

			return event.charCode != null ? event.charCode : event.keyCode;

		}



		// Add which for click: 1 === left; 2 === middle; 3 === right

		if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {

			if ( button & 1 ) {

				return 1;

			}



			if ( button & 2 ) {

				return 3;

			}



			if ( button & 4 ) {

				return 2;

			}



			return 0;

		}



		return event.which;

	}

}, jQuery.event.addProp );



// Create mouseenter/leave events using mouseover/out and event-time checks

// so that event delegation works in jQuery.

// Do the same for pointerenter/pointerleave and pointerover/pointerout

//

// Support: Safari 7 only

// Safari sends mouseenter too often; see:

// https://bugs.chromium.org/p/chromium/issues/detail?id=470258

// for the description of the bug (it existed in older Chrome versions as well).

jQuery.each( {

	mouseenter: "mouseover",

	mouseleave: "mouseout",

	pointerenter: "pointerover",

	pointerleave: "pointerout"

}, function( orig, fix ) {

	jQuery.event.special[ orig ] = {

		delegateType: fix,

		bindType: fix,



		handle: function( event ) {

			var ret,

				target = this,

				related = event.relatedTarget,

				handleObj = event.handleObj;



			// For mouseenter/leave call the handler if related is outside the target.

			// NB: No relatedTarget if the mouse left/entered the browser window

			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {

				event.type = handleObj.origType;

				ret = handleObj.handler.apply( this, arguments );

				event.type = fix;

			}

			return ret;

		}

	};

} );



jQuery.fn.extend( {



	on: function( types, selector, data, fn ) {

		return on( this, types, selector, data, fn );

	},

	one: function( types, selector, data, fn ) {

		return on( this, types, selector, data, fn, 1 );

	},

	off: function( types, selector, fn ) {

		var handleObj, type;

		if ( types && types.preventDefault && types.handleObj ) {



			// ( event )  dispatched jQuery.Event

			handleObj = types.handleObj;

			jQuery( types.delegateTarget ).off(

				handleObj.namespace ?

					handleObj.origType + "." + handleObj.namespace :

					handleObj.origType,

				handleObj.selector,

				handleObj.handler

			);

			return this;

		}

		if ( typeof types === "object" ) {



			// ( types-object [, selector] )

			for ( type in types ) {

				this.off( type, selector, types[ type ] );

			}

			return this;

		}

		if ( selector === false || typeof selector === "function" ) {



			// ( types [, fn] )

			fn = selector;

			selector = undefined;

		}

		if ( fn === false ) {

			fn = returnFalse;

		}

		return this.each( function() {

			jQuery.event.remove( this, types, fn, selector );

		} );

	}

} );





var



	/* eslint-disable max-len */



	// See https://github.com/eslint/eslint/issues/3229

	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,



	/* eslint-enable */



	// Support: IE <=10 - 11, Edge 12 - 13

	// In IE/Edge using regex groups here causes severe slowdowns.

	// See https://connect.microsoft.com/IE/feedback/details/1736512/

	rnoInnerhtml = /<script|<style|<link/i,



	// checked="checked" or checked

	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,

	rscriptTypeMasked = /^true\/(.*)/,

	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;



// Prefer a tbody over its parent table for containing new rows

function manipulationTarget( elem, content ) {

	if ( nodeName( elem, "table" ) &&

		nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {



		return jQuery( ">tbody", elem )[ 0 ] || elem;

	}



	return elem;

}



// Replace/restore the type attribute of script elements for safe DOM manipulation

function disableScript( elem ) {

	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;

	return elem;

}

function restoreScript( elem ) {

	var match = rscriptTypeMasked.exec( elem.type );



	if ( match ) {

		elem.type = match[ 1 ];

	} else {

		elem.removeAttribute( "type" );

	}



	return elem;

}



function cloneCopyEvent( src, dest ) {

	var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;



	if ( dest.nodeType !== 1 ) {

		return;

	}



	// 1. Copy private data: events, handlers, etc.

	if ( dataPriv.hasData( src ) ) {

		pdataOld = dataPriv.access( src );

		pdataCur = dataPriv.set( dest, pdataOld );

		events = pdataOld.events;



		if ( events ) {

			delete pdataCur.handle;

			pdataCur.events = {};



			for ( type in events ) {

				for ( i = 0, l = events[ type ].length; i < l; i++ ) {

					jQuery.event.add( dest, type, events[ type ][ i ] );

				}

			}

		}

	}



	// 2. Copy user data

	if ( dataUser.hasData( src ) ) {

		udataOld = dataUser.access( src );

		udataCur = jQuery.extend( {}, udataOld );



		dataUser.set( dest, udataCur );

	}

}



// Fix IE bugs, see support tests

function fixInput( src, dest ) {

	var nodeName = dest.nodeName.toLowerCase();



	// Fails to persist the checked state of a cloned checkbox or radio button.

	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {

		dest.checked = src.checked;



	// Fails to return the selected option to the default selected state when cloning options

	} else if ( nodeName === "input" || nodeName === "textarea" ) {

		dest.defaultValue = src.defaultValue;

	}

}



function domManip( collection, args, callback, ignored ) {



	// Flatten any nested arrays

	args = concat.apply( [], args );



	var fragment, first, scripts, hasScripts, node, doc,

		i = 0,

		l = collection.length,

		iNoClone = l - 1,

		value = args[ 0 ],

		isFunction = jQuery.isFunction( value );



	// We can't cloneNode fragments that contain checked, in WebKit

	if ( isFunction ||

			( l > 1 && typeof value === "string" &&

				!support.checkClone && rchecked.test( value ) ) ) {

		return collection.each( function( index ) {

			var self = collection.eq( index );

			if ( isFunction ) {

				args[ 0 ] = value.call( this, index, self.html() );

			}

			domManip( self, args, callback, ignored );

		} );

	}



	if ( l ) {

		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );

		first = fragment.firstChild;



		if ( fragment.childNodes.length === 1 ) {

			fragment = first;

		}



		// Require either new content or an interest in ignored elements to invoke the callback

		if ( first || ignored ) {

			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );

			hasScripts = scripts.length;



			// Use the original fragment for the last item

			// instead of the first because it can end up

			// being emptied incorrectly in certain situations (#8070).

			for ( ; i < l; i++ ) {

				node = fragment;



				if ( i !== iNoClone ) {

					node = jQuery.clone( node, true, true );



					// Keep references to cloned scripts for later restoration

					if ( hasScripts ) {



						// Support: Android <=4.0 only, PhantomJS 1 only

						// push.apply(_, arraylike) throws on ancient WebKit

						jQuery.merge( scripts, getAll( node, "script" ) );

					}

				}



				callback.call( collection[ i ], node, i );

			}



			if ( hasScripts ) {

				doc = scripts[ scripts.length - 1 ].ownerDocument;



				// Reenable scripts

				jQuery.map( scripts, restoreScript );



				// Evaluate executable scripts on first document insertion

				for ( i = 0; i < hasScripts; i++ ) {

					node = scripts[ i ];

					if ( rscriptType.test( node.type || "" ) &&

						!dataPriv.access( node, "globalEval" ) &&

						jQuery.contains( doc, node ) ) {



						if ( node.src ) {



							// Optional AJAX dependency, but won't run scripts if not present

							if ( jQuery._evalUrl ) {

								jQuery._evalUrl( node.src );

							}

						} else {

							DOMEval( node.textContent.replace( rcleanScript, "" ), doc );

						}

					}

				}

			}

		}

	}



	return collection;

}



function remove( elem, selector, keepData ) {

	var node,

		nodes = selector ? jQuery.filter( selector, elem ) : elem,

		i = 0;



	for ( ; ( node = nodes[ i ] ) != null; i++ ) {

		if ( !keepData && node.nodeType === 1 ) {

			jQuery.cleanData( getAll( node ) );

		}



		if ( node.parentNode ) {

			if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {

				setGlobalEval( getAll( node, "script" ) );

			}

			node.parentNode.removeChild( node );

		}

	}



	return elem;

}



jQuery.extend( {

	htmlPrefilter: function( html ) {

		return html.replace( rxhtmlTag, "<$1></$2>" );

	},



	clone: function( elem, dataAndEvents, deepDataAndEvents ) {

		var i, l, srcElements, destElements,

			clone = elem.cloneNode( true ),

			inPage = jQuery.contains( elem.ownerDocument, elem );



		// Fix IE cloning issues

		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&

				!jQuery.isXMLDoc( elem ) ) {



			// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2

			destElements = getAll( clone );

			srcElements = getAll( elem );



			for ( i = 0, l = srcElements.length; i < l; i++ ) {

				fixInput( srcElements[ i ], destElements[ i ] );

			}

		}



		// Copy the events from the original to the clone

		if ( dataAndEvents ) {

			if ( deepDataAndEvents ) {

				srcElements = srcElements || getAll( elem );

				destElements = destElements || getAll( clone );



				for ( i = 0, l = srcElements.length; i < l; i++ ) {

					cloneCopyEvent( srcElements[ i ], destElements[ i ] );

				}

			} else {

				cloneCopyEvent( elem, clone );

			}

		}



		// Preserve script evaluation history

		destElements = getAll( clone, "script" );

		if ( destElements.length > 0 ) {

			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );

		}



		// Return the cloned set

		return clone;

	},



	cleanData: function( elems ) {

		var data, elem, type,

			special = jQuery.event.special,

			i = 0;



		for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {

			if ( acceptData( elem ) ) {

				if ( ( data = elem[ dataPriv.expando ] ) ) {

					if ( data.events ) {

						for ( type in data.events ) {

							if ( special[ type ] ) {

								jQuery.event.remove( elem, type );



							// This is a shortcut to avoid jQuery.event.remove's overhead

							} else {

								jQuery.removeEvent( elem, type, data.handle );

							}

						}

					}



					// Support: Chrome <=35 - 45+

					// Assign undefined instead of using delete, see Data#remove

					elem[ dataPriv.expando ] = undefined;

				}

				if ( elem[ dataUser.expando ] ) {



					// Support: Chrome <=35 - 45+

					// Assign undefined instead of using delete, see Data#remove

					elem[ dataUser.expando ] = undefined;

				}

			}

		}

	}

} );



jQuery.fn.extend( {

	detach: function( selector ) {

		return remove( this, selector, true );

	},



	remove: function( selector ) {

		return remove( this, selector );

	},



	text: function( value ) {

		return access( this, function( value ) {

			return value === undefined ?

				jQuery.text( this ) :

				this.empty().each( function() {

					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {

						this.textContent = value;

					}

				} );

		}, null, value, arguments.length );

	},



	append: function() {

		return domManip( this, arguments, function( elem ) {

			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {

				var target = manipulationTarget( this, elem );

				target.appendChild( elem );

			}

		} );

	},



	prepend: function() {

		return domManip( this, arguments, function( elem ) {

			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {

				var target = manipulationTarget( this, elem );

				target.insertBefore( elem, target.firstChild );

			}

		} );

	},



	before: function() {

		return domManip( this, arguments, function( elem ) {

			if ( this.parentNode ) {

				this.parentNode.insertBefore( elem, this );

			}

		} );

	},



	after: function() {

		return domManip( this, arguments, function( elem ) {

			if ( this.parentNode ) {

				this.parentNode.insertBefore( elem, this.nextSibling );

			}

		} );

	},



	empty: function() {

		var elem,

			i = 0;



		for ( ; ( elem = this[ i ] ) != null; i++ ) {

			if ( elem.nodeType === 1 ) {



				// Prevent memory leaks

				jQuery.cleanData( getAll( elem, false ) );



				// Remove any remaining nodes

				elem.textContent = "";

			}

		}



		return this;

	},



	clone: function( dataAndEvents, deepDataAndEvents ) {

		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;

		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;



		return this.map( function() {

			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );

		} );

	},



	html: function( value ) {

		return access( this, function( value ) {

			var elem = this[ 0 ] || {},

				i = 0,

				l = this.length;



			if ( value === undefined && elem.nodeType === 1 ) {

				return elem.innerHTML;

			}



			// See if we can take a shortcut and just use innerHTML

			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&

				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {



				value = jQuery.htmlPrefilter( value );



				try {

					for ( ; i < l; i++ ) {

						elem = this[ i ] || {};



						// Remove element nodes and prevent memory leaks

						if ( elem.nodeType === 1 ) {

							jQuery.cleanData( getAll( elem, false ) );

							elem.innerHTML = value;

						}

					}



					elem = 0;



				// If using innerHTML throws an exception, use the fallback method

				} catch ( e ) {}

			}



			if ( elem ) {

				this.empty().append( value );

			}

		}, null, value, arguments.length );

	},



	replaceWith: function() {

		var ignored = [];



		// Make the changes, replacing each non-ignored context element with the new content

		return domManip( this, arguments, function( elem ) {

			var parent = this.parentNode;



			if ( jQuery.inArray( this, ignored ) < 0 ) {

				jQuery.cleanData( getAll( this ) );

				if ( parent ) {

					parent.replaceChild( elem, this );

				}

			}



		// Force callback invocation

		}, ignored );

	}

} );



jQuery.each( {

	appendTo: "append",

	prependTo: "prepend",

	insertBefore: "before",

	insertAfter: "after",

	replaceAll: "replaceWith"

}, function( name, original ) {

	jQuery.fn[ name ] = function( selector ) {

		var elems,

			ret = [],

			insert = jQuery( selector ),

			last = insert.length - 1,

			i = 0;



		for ( ; i <= last; i++ ) {

			elems = i === last ? this : this.clone( true );

			jQuery( insert[ i ] )[ original ]( elems );



			// Support: Android <=4.0 only, PhantomJS 1 only

			// .get() because push.apply(_, arraylike) throws on ancient WebKit

			push.apply( ret, elems.get() );

		}



		return this.pushStack( ret );

	};

} );

var rmargin = ( /^margin/ );



var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );



var getStyles = function( elem ) {



		// Support: IE <=11 only, Firefox <=30 (#15098, #14150)

		// IE throws on elements created in popups

		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"

		var view = elem.ownerDocument.defaultView;



		if ( !view || !view.opener ) {

			view = window;

		}



		return view.getComputedStyle( elem );

	};







( function() {



	// Executing both pixelPosition & boxSizingReliable tests require only one layout

	// so they're executed at the same time to save the second computation.

	function computeStyleTests() {



		// This is a singleton, we need to execute it only once

		if ( !div ) {

			return;

		}



		div.style.cssText =

			"box-sizing:border-box;" +

			"position:relative;display:block;" +

			"margin:auto;border:1px;padding:1px;" +

			"top:1%;width:50%";

		div.innerHTML = "";

		documentElement.appendChild( container );



		var divStyle = window.getComputedStyle( div );

		pixelPositionVal = divStyle.top !== "1%";



		// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44

		reliableMarginLeftVal = divStyle.marginLeft === "2px";

		boxSizingReliableVal = divStyle.width === "4px";



		// Support: Android 4.0 - 4.3 only

		// Some styles come back with percentage values, even though they shouldn't

		div.style.marginRight = "50%";

		pixelMarginRightVal = divStyle.marginRight === "4px";



		documentElement.removeChild( container );



		// Nullify the div so it wouldn't be stored in the memory and

		// it will also be a sign that checks already performed

		div = null;

	}



	var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,

		container = document.createElement( "div" ),

		div = document.createElement( "div" );



	// Finish early in limited (non-browser) environments

	if ( !div.style ) {

		return;

	}



	// Support: IE <=9 - 11 only

	// Style of cloned element affects source element cloned (#8908)

	div.style.backgroundClip = "content-box";

	div.cloneNode( true ).style.backgroundClip = "";

	support.clearCloneStyle = div.style.backgroundClip === "content-box";



	container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +

		"padding:0;margin-top:1px;position:absolute";

	container.appendChild( div );



	jQuery.extend( support, {

		pixelPosition: function() {

			computeStyleTests();

			return pixelPositionVal;

		},

		boxSizingReliable: function() {

			computeStyleTests();

			return boxSizingReliableVal;

		},

		pixelMarginRight: function() {

			computeStyleTests();

			return pixelMarginRightVal;

		},

		reliableMarginLeft: function() {

			computeStyleTests();

			return reliableMarginLeftVal;

		}

	} );

} )();





function curCSS( elem, name, computed ) {

	var width, minWidth, maxWidth, ret,



		// Support: Firefox 51+

		// Retrieving style before computed somehow

		// fixes an issue with getting wrong values

		// on detached elements

		style = elem.style;



	computed = computed || getStyles( elem );



	// getPropertyValue is needed for:

	//   .css('filter') (IE 9 only, #12537)

	//   .css('--customProperty) (#3144)

	if ( computed ) {

		ret = computed.getPropertyValue( name ) || computed[ name ];



		if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {

			ret = jQuery.style( elem, name );

		}



		// A tribute to the "awesome hack by Dean Edwards"

		// Android Browser returns percentage for some values,

		// but width seems to be reliably pixels.

		// This is against the CSSOM draft spec:

		// https://drafts.csswg.org/cssom/#resolved-values

		if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {



			// Remember the original values

			width = style.width;

			minWidth = style.minWidth;

			maxWidth = style.maxWidth;



			// Put in the new values to get a computed value out

			style.minWidth = style.maxWidth = style.width = ret;

			ret = computed.width;



			// Revert the changed values

			style.width = width;

			style.minWidth = minWidth;

			style.maxWidth = maxWidth;

		}

	}



	return ret !== undefined ?



		// Support: IE <=9 - 11 only

		// IE returns zIndex value as an integer.

		ret + "" :

		ret;

}





function addGetHookIf( conditionFn, hookFn ) {



	// Define the hook, we'll check on the first run if it's really needed.

	return {

		get: function() {

			if ( conditionFn() ) {



				// Hook not needed (or it's not possible to use it due

				// to missing dependency), remove it.

				delete this.get;

				return;

			}



			// Hook needed; redefine it so that the support test is not executed again.

			return ( this.get = hookFn ).apply( this, arguments );

		}

	};

}





var



	// Swappable if display is none or starts with table

	// except "table", "table-cell", or "table-caption"

	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display

	rdisplayswap = /^(none|table(?!-c[ea]).+)/,

	rcustomProp = /^--/,

	cssShow = { position: "absolute", visibility: "hidden", display: "block" },

	cssNormalTransform = {

		letterSpacing: "0",

		fontWeight: "400"

	},



	cssPrefixes = [ "Webkit", "Moz", "ms" ],

	emptyStyle = document.createElement( "div" ).style;



// Return a css property mapped to a potentially vendor prefixed property

function vendorPropName( name ) {



	// Shortcut for names that are not vendor prefixed

	if ( name in emptyStyle ) {

		return name;

	}



	// Check for vendor prefixed names

	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),

		i = cssPrefixes.length;



	while ( i-- ) {

		name = cssPrefixes[ i ] + capName;

		if ( name in emptyStyle ) {

			return name;

		}

	}

}



// Return a property mapped along what jQuery.cssProps suggests or to

// a vendor prefixed property.

function finalPropName( name ) {

	var ret = jQuery.cssProps[ name ];

	if ( !ret ) {

		ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name;

	}

	return ret;

}



function setPositiveNumber( elem, value, subtract ) {



	// Any relative (+/-) values have already been

	// normalized at this point

	var matches = rcssNum.exec( value );

	return matches ?



		// Guard against undefined "subtract", e.g., when used as in cssHooks

		Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :

		value;

}



function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {

	var i,

		val = 0;



	// If we already have the right measurement, avoid augmentation

	if ( extra === ( isBorderBox ? "border" : "content" ) ) {

		i = 4;



	// Otherwise initialize for horizontal or vertical properties

	} else {

		i = name === "width" ? 1 : 0;

	}



	for ( ; i < 4; i += 2 ) {



		// Both box models exclude margin, so add it if we want it

		if ( extra === "margin" ) {

			val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );

		}



		if ( isBorderBox ) {



			// border-box includes padding, so remove it if we want content

			if ( extra === "content" ) {

				val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );

			}



			// At this point, extra isn't border nor margin, so remove border

			if ( extra !== "margin" ) {

				val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );

			}

		} else {



			// At this point, extra isn't content, so add padding

			val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );



			// At this point, extra isn't content nor padding, so add border

			if ( extra !== "padding" ) {

				val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );

			}

		}

	}



	return val;

}



function getWidthOrHeight( elem, name, extra ) {



	// Start with computed style

	var valueIsBorderBox,

		styles = getStyles( elem ),

		val = curCSS( elem, name, styles ),

		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";



	// Computed unit is not pixels. Stop here and return.

	if ( rnumnonpx.test( val ) ) {

		return val;

	}



	// Check for style in case a browser which returns unreliable values

	// for getComputedStyle silently falls back to the reliable elem.style

	valueIsBorderBox = isBorderBox &&

		( support.boxSizingReliable() || val === elem.style[ name ] );



	// Fall back to offsetWidth/Height when value is "auto"

	// This happens for inline elements with no explicit setting (gh-3571)

	if ( val === "auto" ) {

		val = elem[ "offset" + name[ 0 ].toUpperCase() + name.slice( 1 ) ];

	}



	// Normalize "", auto, and prepare for extra

	val = parseFloat( val ) || 0;



	// Use the active box-sizing model to add/subtract irrelevant styles

	return ( val +

		augmentWidthOrHeight(

			elem,

			name,

			extra || ( isBorderBox ? "border" : "content" ),

			valueIsBorderBox,

			styles

		)

	) + "px";

}



jQuery.extend( {



	// Add in style property hooks for overriding the default

	// behavior of getting and setting a style property

	cssHooks: {

		opacity: {

			get: function( elem, computed ) {

				if ( computed ) {



					// We should always get a number back from opacity

					var ret = curCSS( elem, "opacity" );

					return ret === "" ? "1" : ret;

				}

			}

		}

	},



	// Don't automatically add "px" to these possibly-unitless properties

	cssNumber: {

		"animationIterationCount": true,

		"columnCount": true,

		"fillOpacity": true,

		"flexGrow": true,

		"flexShrink": true,

		"fontWeight": true,

		"lineHeight": true,

		"opacity": true,

		"order": true,

		"orphans": true,

		"widows": true,

		"zIndex": true,

		"zoom": true

	},



	// Add in properties whose names you wish to fix before

	// setting or getting the value

	cssProps: {

		"float": "cssFloat"

	},



	// Get and set the style property on a DOM Node

	style: function( elem, name, value, extra ) {



		// Don't set styles on text and comment nodes

		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {

			return;

		}



		// Make sure that we're working with the right name

		var ret, type, hooks,

			origName = jQuery.camelCase( name ),

			isCustomProp = rcustomProp.test( name ),

			style = elem.style;



		// Make sure that we're working with the right name. We don't

		// want to query the value if it is a CSS custom property

		// since they are user-defined.

		if ( !isCustomProp ) {

			name = finalPropName( origName );

		}



		// Gets hook for the prefixed version, then unprefixed version

		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];



		// Check if we're setting a value

		if ( value !== undefined ) {

			type = typeof value;



			// Convert "+=" or "-=" to relative numbers (#7345)

			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {

				value = adjustCSS( elem, name, ret );



				// Fixes bug #9237

				type = "number";

			}



			// Make sure that null and NaN values aren't set (#7116)

			if ( value == null || value !== value ) {

				return;

			}



			// If a number was passed in, add the unit (except for certain CSS properties)

			if ( type === "number" ) {

				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );

			}



			// background-* props affect original clone's values

			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {

				style[ name ] = "inherit";

			}



			// If a hook was provided, use that value, otherwise just set the specified value

			if ( !hooks || !( "set" in hooks ) ||

				( value = hooks.set( elem, value, extra ) ) !== undefined ) {



				if ( isCustomProp ) {

					style.setProperty( name, value );

				} else {

					style[ name ] = value;

				}

			}



		} else {



			// If a hook was provided get the non-computed value from there

			if ( hooks && "get" in hooks &&

				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {



				return ret;

			}



			// Otherwise just get the value from the style object

			return style[ name ];

		}

	},



	css: function( elem, name, extra, styles ) {

		var val, num, hooks,

			origName = jQuery.camelCase( name ),

			isCustomProp = rcustomProp.test( name );



		// Make sure that we're working with the right name. We don't

		// want to modify the value if it is a CSS custom property

		// since they are user-defined.

		if ( !isCustomProp ) {

			name = finalPropName( origName );

		}



		// Try prefixed name followed by the unprefixed name

		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];



		// If a hook was provided get the computed value from there

		if ( hooks && "get" in hooks ) {

			val = hooks.get( elem, true, extra );

		}



		// Otherwise, if a way to get the computed value exists, use that

		if ( val === undefined ) {

			val = curCSS( elem, name, styles );

		}



		// Convert "normal" to computed value

		if ( val === "normal" && name in cssNormalTransform ) {

			val = cssNormalTransform[ name ];

		}



		// Make numeric if forced or a qualifier was provided and val looks numeric

		if ( extra === "" || extra ) {

			num = parseFloat( val );

			return extra === true || isFinite( num ) ? num || 0 : val;

		}



		return val;

	}

} );



jQuery.each( [ "height", "width" ], function( i, name ) {

	jQuery.cssHooks[ name ] = {

		get: function( elem, computed, extra ) {

			if ( computed ) {



				// Certain elements can have dimension info if we invisibly show them

				// but it must have a current display style that would benefit

				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&



					// Support: Safari 8+

					// Table columns in Safari have non-zero offsetWidth & zero

					// getBoundingClientRect().width unless display is changed.

					// Support: IE <=11 only

					// Running getBoundingClientRect on a disconnected node

					// in IE throws an error.

					( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?

						swap( elem, cssShow, function() {

							return getWidthOrHeight( elem, name, extra );

						} ) :

						getWidthOrHeight( elem, name, extra );

			}

		},



		set: function( elem, value, extra ) {

			var matches,

				styles = extra && getStyles( elem ),

				subtract = extra && augmentWidthOrHeight(

					elem,

					name,

					extra,

					jQuery.css( elem, "boxSizing", false, styles ) === "border-box",

					styles

				);



			// Convert to pixels if value adjustment is needed

			if ( subtract && ( matches = rcssNum.exec( value ) ) &&

				( matches[ 3 ] || "px" ) !== "px" ) {



				elem.style[ name ] = value;

				value = jQuery.css( elem, name );

			}



			return setPositiveNumber( elem, value, subtract );

		}

	};

} );



jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,

	function( elem, computed ) {

		if ( computed ) {

			return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||

				elem.getBoundingClientRect().left -

					swap( elem, { marginLeft: 0 }, function() {

						return elem.getBoundingClientRect().left;

					} )

				) + "px";

		}

	}

);



// These hooks are used by animate to expand properties

jQuery.each( {

	margin: "",

	padding: "",

	border: "Width"

}, function( prefix, suffix ) {

	jQuery.cssHooks[ prefix + suffix ] = {

		expand: function( value ) {

			var i = 0,

				expanded = {},



				// Assumes a single number if not a string

				parts = typeof value === "string" ? value.split( " " ) : [ value ];



			for ( ; i < 4; i++ ) {

				expanded[ prefix + cssExpand[ i ] + suffix ] =

					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];

			}



			return expanded;

		}

	};



	if ( !rmargin.test( prefix ) ) {

		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;

	}

} );



jQuery.fn.extend( {

	css: function( name, value ) {

		return access( this, function( elem, name, value ) {

			var styles, len,

				map = {},

				i = 0;



			if ( Array.isArray( name ) ) {

				styles = getStyles( elem );

				len = name.length;



				for ( ; i < len; i++ ) {

					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );

				}



				return map;

			}



			return value !== undefined ?

				jQuery.style( elem, name, value ) :

				jQuery.css( elem, name );

		}, name, value, arguments.length > 1 );

	}

} );





function Tween( elem, options, prop, end, easing ) {

	return new Tween.prototype.init( elem, options, prop, end, easing );

}

jQuery.Tween = Tween;



Tween.prototype = {

	constructor: Tween,

	init: function( elem, options, prop, end, easing, unit ) {

		this.elem = elem;

		this.prop = prop;

		this.easing = easing || jQuery.easing._default;

		this.options = options;

		this.start = this.now = this.cur();

		this.end = end;

		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );

	},

	cur: function() {

		var hooks = Tween.propHooks[ this.prop ];



		return hooks && hooks.get ?

			hooks.get( this ) :

			Tween.propHooks._default.get( this );

	},

	run: function( percent ) {

		var eased,

			hooks = Tween.propHooks[ this.prop ];



		if ( this.options.duration ) {

			this.pos = eased = jQuery.easing[ this.easing ](

				percent, this.options.duration * percent, 0, 1, this.options.duration

			);

		} else {

			this.pos = eased = percent;

		}

		this.now = ( this.end - this.start ) * eased + this.start;



		if ( this.options.step ) {

			this.options.step.call( this.elem, this.now, this );

		}



		if ( hooks && hooks.set ) {

			hooks.set( this );

		} else {

			Tween.propHooks._default.set( this );

		}

		return this;

	}

};



Tween.prototype.init.prototype = Tween.prototype;



Tween.propHooks = {

	_default: {

		get: function( tween ) {

			var result;



			// Use a property on the element directly when it is not a DOM element,

			// or when there is no matching style property that exists.

			if ( tween.elem.nodeType !== 1 ||

				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {

				return tween.elem[ tween.prop ];

			}



			// Passing an empty string as a 3rd parameter to .css will automatically

			// attempt a parseFloat and fallback to a string if the parse fails.

			// Simple values such as "10px" are parsed to Float;

			// complex values such as "rotate(1rad)" are returned as-is.

			result = jQuery.css( tween.elem, tween.prop, "" );



			// Empty strings, null, undefined and "auto" are converted to 0.

			return !result || result === "auto" ? 0 : result;

		},

		set: function( tween ) {



			// Use step hook for back compat.

			// Use cssHook if its there.

			// Use .style if available and use plain properties where available.

			if ( jQuery.fx.step[ tween.prop ] ) {

				jQuery.fx.step[ tween.prop ]( tween );

			} else if ( tween.elem.nodeType === 1 &&

				( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||

					jQuery.cssHooks[ tween.prop ] ) ) {

				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );

			} else {

				tween.elem[ tween.prop ] = tween.now;

			}

		}

	}

};



// Support: IE <=9 only

// Panic based approach to setting things on disconnected nodes

Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {

	set: function( tween ) {

		if ( tween.elem.nodeType && tween.elem.parentNode ) {

			tween.elem[ tween.prop ] = tween.now;

		}

	}

};



jQuery.easing = {

	linear: function( p ) {

		return p;

	},

	swing: function( p ) {

		return 0.5 - Math.cos( p * Math.PI ) / 2;

	},

	_default: "swing"

};



jQuery.fx = Tween.prototype.init;



// Back compat <1.8 extension point

jQuery.fx.step = {};









var

	fxNow, inProgress,

	rfxtypes = /^(?:toggle|show|hide)$/,

	rrun = /queueHooks$/;



function schedule() {

	if ( inProgress ) {

		if ( document.hidden === false && window.requestAnimationFrame ) {

			window.requestAnimationFrame( schedule );

		} else {

			window.setTimeout( schedule, jQuery.fx.interval );

		}



		jQuery.fx.tick();

	}

}



// Animations created synchronously will run synchronously

function createFxNow() {

	window.setTimeout( function() {

		fxNow = undefined;

	} );

	return ( fxNow = jQuery.now() );

}



// Generate parameters to create a standard animation

function genFx( type, includeWidth ) {

	var which,

		i = 0,

		attrs = { height: type };



	// If we include width, step value is 1 to do all cssExpand values,

	// otherwise step value is 2 to skip over Left and Right

	includeWidth = includeWidth ? 1 : 0;

	for ( ; i < 4; i += 2 - includeWidth ) {

		which = cssExpand[ i ];

		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;

	}



	if ( includeWidth ) {

		attrs.opacity = attrs.width = type;

	}



	return attrs;

}



function createTween( value, prop, animation ) {

	var tween,

		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),

		index = 0,

		length = collection.length;

	for ( ; index < length; index++ ) {

		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {



			// We're done with this property

			return tween;

		}

	}

}



function defaultPrefilter( elem, props, opts ) {

	var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,

		isBox = "width" in props || "height" in props,

		anim = this,

		orig = {},

		style = elem.style,

		hidden = elem.nodeType && isHiddenWithinTree( elem ),

		dataShow = dataPriv.get( elem, "fxshow" );



	// Queue-skipping animations hijack the fx hooks

	if ( !opts.queue ) {

		hooks = jQuery._queueHooks( elem, "fx" );

		if ( hooks.unqueued == null ) {

			hooks.unqueued = 0;

			oldfire = hooks.empty.fire;

			hooks.empty.fire = function() {

				if ( !hooks.unqueued ) {

					oldfire();

				}

			};

		}

		hooks.unqueued++;



		anim.always( function() {



			// Ensure the complete handler is called before this completes

			anim.always( function() {

				hooks.unqueued--;

				if ( !jQuery.queue( elem, "fx" ).length ) {

					hooks.empty.fire();

				}

			} );

		} );

	}



	// Detect show/hide animations

	for ( prop in props ) {

		value = props[ prop ];

		if ( rfxtypes.test( value ) ) {

			delete props[ prop ];

			toggle = toggle || value === "toggle";

			if ( value === ( hidden ? "hide" : "show" ) ) {



				// Pretend to be hidden if this is a "show" and

				// there is still data from a stopped show/hide

				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {

					hidden = true;



				// Ignore all other no-op show/hide data

				} else {

					continue;

				}

			}

			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );

		}

	}



	// Bail out if this is a no-op like .hide().hide()

	propTween = !jQuery.isEmptyObject( props );

	if ( !propTween && jQuery.isEmptyObject( orig ) ) {

		return;

	}



	// Restrict "overflow" and "display" styles during box animations

	if ( isBox && elem.nodeType === 1 ) {



		// Support: IE <=9 - 11, Edge 12 - 13

		// Record all 3 overflow attributes because IE does not infer the shorthand

		// from identically-valued overflowX and overflowY

		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];



		// Identify a display type, preferring old show/hide data over the CSS cascade

		restoreDisplay = dataShow && dataShow.display;

		if ( restoreDisplay == null ) {

			restoreDisplay = dataPriv.get( elem, "display" );

		}

		display = jQuery.css( elem, "display" );

		if ( display === "none" ) {

			if ( restoreDisplay ) {

				display = restoreDisplay;

			} else {



				// Get nonempty value(s) by temporarily forcing visibility

				showHide( [ elem ], true );

				restoreDisplay = elem.style.display || restoreDisplay;

				display = jQuery.css( elem, "display" );

				showHide( [ elem ] );

			}

		}



		// Animate inline elements as inline-block

		if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {

			if ( jQuery.css( elem, "float" ) === "none" ) {



				// Restore the original display value at the end of pure show/hide animations

				if ( !propTween ) {

					anim.done( function() {

						style.display = restoreDisplay;

					} );

					if ( restoreDisplay == null ) {

						display = style.display;

						restoreDisplay = display === "none" ? "" : display;

					}

				}

				style.display = "inline-block";

			}

		}

	}



	if ( opts.overflow ) {

		style.overflow = "hidden";

		anim.always( function() {

			style.overflow = opts.overflow[ 0 ];

			style.overflowX = opts.overflow[ 1 ];

			style.overflowY = opts.overflow[ 2 ];

		} );

	}



	// Implement show/hide animations

	propTween = false;

	for ( prop in orig ) {



		// General show/hide setup for this element animation

		if ( !propTween ) {

			if ( dataShow ) {

				if ( "hidden" in dataShow ) {

					hidden = dataShow.hidden;

				}

			} else {

				dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );

			}



			// Store hidden/visible for toggle so `.stop().toggle()` "reverses"

			if ( toggle ) {

				dataShow.hidden = !hidden;

			}



			// Show elements before animating them

			if ( hidden ) {

				showHide( [ elem ], true );

			}



			/* eslint-disable no-loop-func */



			anim.done( function() {



			/* eslint-enable no-loop-func */



				// The final step of a "hide" animation is actually hiding the element

				if ( !hidden ) {

					showHide( [ elem ] );

				}

				dataPriv.remove( elem, "fxshow" );

				for ( prop in orig ) {

					jQuery.style( elem, prop, orig[ prop ] );

				}

			} );

		}



		// Per-property setup

		propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );

		if ( !( prop in dataShow ) ) {

			dataShow[ prop ] = propTween.start;

			if ( hidden ) {

				propTween.end = propTween.start;

				propTween.start = 0;

			}

		}

	}

}



function propFilter( props, specialEasing ) {

	var index, name, easing, value, hooks;



	// camelCase, specialEasing and expand cssHook pass

	for ( index in props ) {

		name = jQuery.camelCase( index );

		easing = specialEasing[ name ];

		value = props[ index ];

		if ( Array.isArray( value ) ) {

			easing = value[ 1 ];

			value = props[ index ] = value[ 0 ];

		}



		if ( index !== name ) {

			props[ name ] = value;

			delete props[ index ];

		}



		hooks = jQuery.cssHooks[ name ];

		if ( hooks && "expand" in hooks ) {

			value = hooks.expand( value );

			delete props[ name ];



			// Not quite $.extend, this won't overwrite existing keys.

			// Reusing 'index' because we have the correct "name"

			for ( index in value ) {

				if ( !( index in props ) ) {

					props[ index ] = value[ index ];

					specialEasing[ index ] = easing;

				}

			}

		} else {

			specialEasing[ name ] = easing;

		}

	}

}



function Animation( elem, properties, options ) {

	var result,

		stopped,

		index = 0,

		length = Animation.prefilters.length,

		deferred = jQuery.Deferred().always( function() {



			// Don't match elem in the :animated selector

			delete tick.elem;

		} ),

		tick = function() {

			if ( stopped ) {

				return false;

			}

			var currentTime = fxNow || createFxNow(),

				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),



				// Support: Android 2.3 only

				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)

				temp = remaining / animation.duration || 0,

				percent = 1 - temp,

				index = 0,

				length = animation.tweens.length;



			for ( ; index < length; index++ ) {

				animation.tweens[ index ].run( percent );

			}



			deferred.notifyWith( elem, [ animation, percent, remaining ] );



			// If there's more to do, yield

			if ( percent < 1 && length ) {

				return remaining;

			}



			// If this was an empty animation, synthesize a final progress notification

			if ( !length ) {

				deferred.notifyWith( elem, [ animation, 1, 0 ] );

			}



			// Resolve the animation and report its conclusion

			deferred.resolveWith( elem, [ animation ] );

			return false;

		},

		animation = deferred.promise( {

			elem: elem,

			props: jQuery.extend( {}, properties ),

			opts: jQuery.extend( true, {

				specialEasing: {},

				easing: jQuery.easing._default

			}, options ),

			originalProperties: properties,

			originalOptions: options,

			startTime: fxNow || createFxNow(),

			duration: options.duration,

			tweens: [],

			createTween: function( prop, end ) {

				var tween = jQuery.Tween( elem, animation.opts, prop, end,

						animation.opts.specialEasing[ prop ] || animation.opts.easing );

				animation.tweens.push( tween );

				return tween;

			},

			stop: function( gotoEnd ) {

				var index = 0,



					// If we are going to the end, we want to run all the tweens

					// otherwise we skip this part

					length = gotoEnd ? animation.tweens.length : 0;

				if ( stopped ) {

					return this;

				}

				stopped = true;

				for ( ; index < length; index++ ) {

					animation.tweens[ index ].run( 1 );

				}



				// Resolve when we played the last frame; otherwise, reject

				if ( gotoEnd ) {

					deferred.notifyWith( elem, [ animation, 1, 0 ] );

					deferred.resolveWith( elem, [ animation, gotoEnd ] );

				} else {

					deferred.rejectWith( elem, [ animation, gotoEnd ] );

				}

				return this;

			}

		} ),

		props = animation.props;



	propFilter( props, animation.opts.specialEasing );



	for ( ; index < length; index++ ) {

		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );

		if ( result ) {

			if ( jQuery.isFunction( result.stop ) ) {

				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =

					jQuery.proxy( result.stop, result );

			}

			return result;

		}

	}



	jQuery.map( props, createTween, animation );



	if ( jQuery.isFunction( animation.opts.start ) ) {

		animation.opts.start.call( elem, animation );

	}



	// Attach callbacks from options

	animation

		.progress( animation.opts.progress )

		.done( animation.opts.done, animation.opts.complete )

		.fail( animation.opts.fail )

		.always( animation.opts.always );



	jQuery.fx.timer(

		jQuery.extend( tick, {

			elem: elem,

			anim: animation,

			queue: animation.opts.queue

		} )

	);



	return animation;

}



jQuery.Animation = jQuery.extend( Animation, {



	tweeners: {

		"*": [ function( prop, value ) {

			var tween = this.createTween( prop, value );

			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );

			return tween;

		} ]

	},



	tweener: function( props, callback ) {

		if ( jQuery.isFunction( props ) ) {

			callback = props;

			props = [ "*" ];

		} else {

			props = props.match( rnothtmlwhite );

		}



		var prop,

			index = 0,

			length = props.length;



		for ( ; index < length; index++ ) {

			prop = props[ index ];

			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];

			Animation.tweeners[ prop ].unshift( callback );

		}

	},



	prefilters: [ defaultPrefilter ],



	prefilter: function( callback, prepend ) {

		if ( prepend ) {

			Animation.prefilters.unshift( callback );

		} else {

			Animation.prefilters.push( callback );

		}

	}

} );



jQuery.speed = function( speed, easing, fn ) {

	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {

		complete: fn || !fn && easing ||

			jQuery.isFunction( speed ) && speed,

		duration: speed,

		easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing

	};



	// Go to the end state if fx are off

	if ( jQuery.fx.off ) {

		opt.duration = 0;



	} else {

		if ( typeof opt.duration !== "number" ) {

			if ( opt.duration in jQuery.fx.speeds ) {

				opt.duration = jQuery.fx.speeds[ opt.duration ];



			} else {

				opt.duration = jQuery.fx.speeds._default;

			}

		}

	}



	// Normalize opt.queue - true/undefined/null -> "fx"

	if ( opt.queue == null || opt.queue === true ) {

		opt.queue = "fx";

	}



	// Queueing

	opt.old = opt.complete;



	opt.complete = function() {

		if ( jQuery.isFunction( opt.old ) ) {

			opt.old.call( this );

		}



		if ( opt.queue ) {

			jQuery.dequeue( this, opt.queue );

		}

	};



	return opt;

};



jQuery.fn.extend( {

	fadeTo: function( speed, to, easing, callback ) {



		// Show any hidden elements after setting opacity to 0

		return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()



			// Animate to the value specified

			.end().animate( { opacity: to }, speed, easing, callback );

	},

	animate: function( prop, speed, easing, callback ) {

		var empty = jQuery.isEmptyObject( prop ),

			optall = jQuery.speed( speed, easing, callback ),

			doAnimation = function() {



				// Operate on a copy of prop so per-property easing won't be lost

				var anim = Animation( this, jQuery.extend( {}, prop ), optall );



				// Empty animations, or finishing resolves immediately

				if ( empty || dataPriv.get( this, "finish" ) ) {

					anim.stop( true );

				}

			};

			doAnimation.finish = doAnimation;



		return empty || optall.queue === false ?

			this.each( doAnimation ) :

			this.queue( optall.queue, doAnimation );

	},

	stop: function( type, clearQueue, gotoEnd ) {

		var stopQueue = function( hooks ) {

			var stop = hooks.stop;

			delete hooks.stop;

			stop( gotoEnd );

		};



		if ( typeof type !== "string" ) {

			gotoEnd = clearQueue;

			clearQueue = type;

			type = undefined;

		}

		if ( clearQueue && type !== false ) {

			this.queue( type || "fx", [] );

		}



		return this.each( function() {

			var dequeue = true,

				index = type != null && type + "queueHooks",

				timers = jQuery.timers,

				data = dataPriv.get( this );



			if ( index ) {

				if ( data[ index ] && data[ index ].stop ) {

					stopQueue( data[ index ] );

				}

			} else {

				for ( index in data ) {

					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {

						stopQueue( data[ index ] );

					}

				}

			}



			for ( index = timers.length; index--; ) {

				if ( timers[ index ].elem === this &&

					( type == null || timers[ index ].queue === type ) ) {



					timers[ index ].anim.stop( gotoEnd );

					dequeue = false;

					timers.splice( index, 1 );

				}

			}



			// Start the next in the queue if the last step wasn't forced.

			// Timers currently will call their complete callbacks, which

			// will dequeue but only if they were gotoEnd.

			if ( dequeue || !gotoEnd ) {

				jQuery.dequeue( this, type );

			}

		} );

	},

	finish: function( type ) {

		if ( type !== false ) {

			type = type || "fx";

		}

		return this.each( function() {

			var index,

				data = dataPriv.get( this ),

				queue = data[ type + "queue" ],

				hooks = data[ type + "queueHooks" ],

				timers = jQuery.timers,

				length = queue ? queue.length : 0;



			// Enable finishing flag on private data

			data.finish = true;



			// Empty the queue first

			jQuery.queue( this, type, [] );



			if ( hooks && hooks.stop ) {

				hooks.stop.call( this, true );

			}



			// Look for any active animations, and finish them

			for ( index = timers.length; index--; ) {

				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {

					timers[ index ].anim.stop( true );

					timers.splice( index, 1 );

				}

			}



			// Look for any animations in the old queue and finish them

			for ( index = 0; index < length; index++ ) {

				if ( queue[ index ] && queue[ index ].finish ) {

					queue[ index ].finish.call( this );

				}

			}



			// Turn off finishing flag

			delete data.finish;

		} );

	}

} );



jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {

	var cssFn = jQuery.fn[ name ];

	jQuery.fn[ name ] = function( speed, easing, callback ) {

		return speed == null || typeof speed === "boolean" ?

			cssFn.apply( this, arguments ) :

			this.animate( genFx( name, true ), speed, easing, callback );

	};

} );



// Generate shortcuts for custom animations

jQuery.each( {

	slideDown: genFx( "show" ),

	slideUp: genFx( "hide" ),

	slideToggle: genFx( "toggle" ),

	fadeIn: { opacity: "show" },

	fadeOut: { opacity: "hide" },

	fadeToggle: { opacity: "toggle" }

}, function( name, props ) {

	jQuery.fn[ name ] = function( speed, easing, callback ) {

		return this.animate( props, speed, easing, callback );

	};

} );



jQuery.timers = [];

jQuery.fx.tick = function() {

	var timer,

		i = 0,

		timers = jQuery.timers;



	fxNow = jQuery.now();



	for ( ; i < timers.length; i++ ) {

		timer = timers[ i ];



		// Run the timer and safely remove it when done (allowing for external removal)

		if ( !timer() && timers[ i ] === timer ) {

			timers.splice( i--, 1 );

		}

	}



	if ( !timers.length ) {

		jQuery.fx.stop();

	}

	fxNow = undefined;

};



jQuery.fx.timer = function( timer ) {

	jQuery.timers.push( timer );

	jQuery.fx.start();

};



jQuery.fx.interval = 13;

jQuery.fx.start = function() {

	if ( inProgress ) {

		return;

	}



	inProgress = true;

	schedule();

};



jQuery.fx.stop = function() {

	inProgress = null;

};



jQuery.fx.speeds = {

	slow: 600,

	fast: 200,



	// Default speed

	_default: 400

};





// Based off of the plugin by Clint Helfers, with permission.

// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/

jQuery.fn.delay = function( time, type ) {

	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;

	type = type || "fx";



	return this.queue( type, function( next, hooks ) {

		var timeout = window.setTimeout( next, time );

		hooks.stop = function() {

			window.clearTimeout( timeout );

		};

	} );

};





( function() {

	var input = document.createElement( "input" ),

		select = document.createElement( "select" ),

		opt = select.appendChild( document.createElement( "option" ) );



	input.type = "checkbox";



	// Support: Android <=4.3 only

	// Default value for a checkbox should be "on"

	support.checkOn = input.value !== "";



	// Support: IE <=11 only

	// Must access selectedIndex to make default options select

	support.optSelected = opt.selected;



	// Support: IE <=11 only

	// An input loses its value after becoming a radio

	input = document.createElement( "input" );

	input.value = "t";

	input.type = "radio";

	support.radioValue = input.value === "t";

} )();





var boolHook,

	attrHandle = jQuery.expr.attrHandle;



jQuery.fn.extend( {

	attr: function( name, value ) {

		return access( this, jQuery.attr, name, value, arguments.length > 1 );

	},



	removeAttr: function( name ) {

		return this.each( function() {

			jQuery.removeAttr( this, name );

		} );

	}

} );



jQuery.extend( {

	attr: function( elem, name, value ) {

		var ret, hooks,

			nType = elem.nodeType;



		// Don't get/set attributes on text, comment and attribute nodes

		if ( nType === 3 || nType === 8 || nType === 2 ) {

			return;

		}



		// Fallback to prop when attributes are not supported

		if ( typeof elem.getAttribute === "undefined" ) {

			return jQuery.prop( elem, name, value );

		}



		// Attribute hooks are determined by the lowercase version

		// Grab necessary hook if one is defined

		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {

			hooks = jQuery.attrHooks[ name.toLowerCase() ] ||

				( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );

		}



		if ( value !== undefined ) {

			if ( value === null ) {

				jQuery.removeAttr( elem, name );

				return;

			}



			if ( hooks && "set" in hooks &&

				( ret = hooks.set( elem, value, name ) ) !== undefined ) {

				return ret;

			}



			elem.setAttribute( name, value + "" );

			return value;

		}



		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {

			return ret;

		}



		ret = jQuery.find.attr( elem, name );



		// Non-existent attributes return null, we normalize to undefined

		return ret == null ? undefined : ret;

	},



	attrHooks: {

		type: {

			set: function( elem, value ) {

				if ( !support.radioValue && value === "radio" &&

					nodeName( elem, "input" ) ) {

					var val = elem.value;

					elem.setAttribute( "type", value );

					if ( val ) {

						elem.value = val;

					}

					return value;

				}

			}

		}

	},



	removeAttr: function( elem, value ) {

		var name,

			i = 0,



			// Attribute names can contain non-HTML whitespace characters

			// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2

			attrNames = value && value.match( rnothtmlwhite );



		if ( attrNames && elem.nodeType === 1 ) {

			while ( ( name = attrNames[ i++ ] ) ) {

				elem.removeAttribute( name );

			}

		}

	}

} );



// Hooks for boolean attributes

boolHook = {

	set: function( elem, value, name ) {

		if ( value === false ) {



			// Remove boolean attributes when set to false

			jQuery.removeAttr( elem, name );

		} else {

			elem.setAttribute( name, name );

		}

		return name;

	}

};



jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {

	var getter = attrHandle[ name ] || jQuery.find.attr;



	attrHandle[ name ] = function( elem, name, isXML ) {

		var ret, handle,

			lowercaseName = name.toLowerCase();



		if ( !isXML ) {



			// Avoid an infinite loop by temporarily removing this function from the getter

			handle = attrHandle[ lowercaseName ];

			attrHandle[ lowercaseName ] = ret;

			ret = getter( elem, name, isXML ) != null ?

				lowercaseName :

				null;

			attrHandle[ lowercaseName ] = handle;

		}

		return ret;

	};

} );









var rfocusable = /^(?:input|select|textarea|button)$/i,

	rclickable = /^(?:a|area)$/i;



jQuery.fn.extend( {

	prop: function( name, value ) {

		return access( this, jQuery.prop, name, value, arguments.length > 1 );

	},



	removeProp: function( name ) {

		return this.each( function() {

			delete this[ jQuery.propFix[ name ] || name ];

		} );

	}

} );



jQuery.extend( {

	prop: function( elem, name, value ) {

		var ret, hooks,

			nType = elem.nodeType;



		// Don't get/set properties on text, comment and attribute nodes

		if ( nType === 3 || nType === 8 || nType === 2 ) {

			return;

		}



		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {



			// Fix name and attach hooks

			name = jQuery.propFix[ name ] || name;

			hooks = jQuery.propHooks[ name ];

		}



		if ( value !== undefined ) {

			if ( hooks && "set" in hooks &&

				( ret = hooks.set( elem, value, name ) ) !== undefined ) {

				return ret;

			}



			return ( elem[ name ] = value );

		}



		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {

			return ret;

		}



		return elem[ name ];

	},



	propHooks: {

		tabIndex: {

			get: function( elem ) {



				// Support: IE <=9 - 11 only

				// elem.tabIndex doesn't always return the

				// correct value when it hasn't been explicitly set

				// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/

				// Use proper attribute retrieval(#12072)

				var tabindex = jQuery.find.attr( elem, "tabindex" );



				if ( tabindex ) {

					return parseInt( tabindex, 10 );

				}



				if (

					rfocusable.test( elem.nodeName ) ||

					rclickable.test( elem.nodeName ) &&

					elem.href

				) {

					return 0;

				}



				return -1;

			}

		}

	},



	propFix: {

		"for": "htmlFor",

		"class": "className"

	}

} );



// Support: IE <=11 only

// Accessing the selectedIndex property

// forces the browser to respect setting selected

// on the option

// The getter ensures a default option is selected

// when in an optgroup

// eslint rule "no-unused-expressions" is disabled for this code

// since it considers such accessions noop

if ( !support.optSelected ) {

	jQuery.propHooks.selected = {

		get: function( elem ) {



			/* eslint no-unused-expressions: "off" */



			var parent = elem.parentNode;

			if ( parent && parent.parentNode ) {

				parent.parentNode.selectedIndex;

			}

			return null;

		},

		set: function( elem ) {



			/* eslint no-unused-expressions: "off" */



			var parent = elem.parentNode;

			if ( parent ) {

				parent.selectedIndex;



				if ( parent.parentNode ) {

					parent.parentNode.selectedIndex;

				}

			}

		}

	};

}



jQuery.each( [

	"tabIndex",

	"readOnly",

	"maxLength",

	"cellSpacing",

	"cellPadding",

	"rowSpan",

	"colSpan",

	"useMap",

	"frameBorder",

	"contentEditable"

], function() {

	jQuery.propFix[ this.toLowerCase() ] = this;

} );









	// Strip and collapse whitespace according to HTML spec

	// https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace

	function stripAndCollapse( value ) {

		var tokens = value.match( rnothtmlwhite ) || [];

		return tokens.join( " " );

	}





function getClass( elem ) {

	return elem.getAttribute && elem.getAttribute( "class" ) || "";

}



jQuery.fn.extend( {

	addClass: function( value ) {

		var classes, elem, cur, curValue, clazz, j, finalValue,

			i = 0;



		if ( jQuery.isFunction( value ) ) {

			return this.each( function( j ) {

				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );

			} );

		}



		if ( typeof value === "string" && value ) {

			classes = value.match( rnothtmlwhite ) || [];



			while ( ( elem = this[ i++ ] ) ) {

				curValue = getClass( elem );

				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );



				if ( cur ) {

					j = 0;

					while ( ( clazz = classes[ j++ ] ) ) {

						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {

							cur += clazz + " ";

						}

					}



					// Only assign if different to avoid unneeded rendering.

					finalValue = stripAndCollapse( cur );

					if ( curValue !== finalValue ) {

						elem.setAttribute( "class", finalValue );

					}

				}

			}

		}



		return this;

	},



	removeClass: function( value ) {

		var classes, elem, cur, curValue, clazz, j, finalValue,

			i = 0;



		if ( jQuery.isFunction( value ) ) {

			return this.each( function( j ) {

				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );

			} );

		}



		if ( !arguments.length ) {

			return this.attr( "class", "" );

		}



		if ( typeof value === "string" && value ) {

			classes = value.match( rnothtmlwhite ) || [];



			while ( ( elem = this[ i++ ] ) ) {

				curValue = getClass( elem );



				// This expression is here for better compressibility (see addClass)

				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );



				if ( cur ) {

					j = 0;

					while ( ( clazz = classes[ j++ ] ) ) {



						// Remove *all* instances

						while ( cur.indexOf( " " + clazz + " " ) > -1 ) {

							cur = cur.replace( " " + clazz + " ", " " );

						}

					}



					// Only assign if different to avoid unneeded rendering.

					finalValue = stripAndCollapse( cur );

					if ( curValue !== finalValue ) {

						elem.setAttribute( "class", finalValue );

					}

				}

			}

		}



		return this;

	},



	toggleClass: function( value, stateVal ) {

		var type = typeof value;



		if ( typeof stateVal === "boolean" && type === "string" ) {

			return stateVal ? this.addClass( value ) : this.removeClass( value );

		}



		if ( jQuery.isFunction( value ) ) {

			return this.each( function( i ) {

				jQuery( this ).toggleClass(

					value.call( this, i, getClass( this ), stateVal ),

					stateVal

				);

			} );

		}



		return this.each( function() {

			var className, i, self, classNames;



			if ( type === "string" ) {



				// Toggle individual class names

				i = 0;

				self = jQuery( this );

				classNames = value.match( rnothtmlwhite ) || [];



				while ( ( className = classNames[ i++ ] ) ) {



					// Check each className given, space separated list

					if ( self.hasClass( className ) ) {

						self.removeClass( className );

					} else {

						self.addClass( className );

					}

				}



			// Toggle whole class name

			} else if ( value === undefined || type === "boolean" ) {

				className = getClass( this );

				if ( className ) {



					// Store className if set

					dataPriv.set( this, "__className__", className );

				}



				// If the element has a class name or if we're passed `false`,

				// then remove the whole classname (if there was one, the above saved it).

				// Otherwise bring back whatever was previously saved (if anything),

				// falling back to the empty string if nothing was stored.

				if ( this.setAttribute ) {

					this.setAttribute( "class",

						className || value === false ?

						"" :

						dataPriv.get( this, "__className__" ) || ""

					);

				}

			}

		} );

	},



	hasClass: function( selector ) {

		var className, elem,

			i = 0;



		className = " " + selector + " ";

		while ( ( elem = this[ i++ ] ) ) {

			if ( elem.nodeType === 1 &&

				( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {

					return true;

			}

		}



		return false;

	}

} );









var rreturn = /\r/g;



jQuery.fn.extend( {

	val: function( value ) {

		var hooks, ret, isFunction,

			elem = this[ 0 ];



		if ( !arguments.length ) {

			if ( elem ) {

				hooks = jQuery.valHooks[ elem.type ] ||

					jQuery.valHooks[ elem.nodeName.toLowerCase() ];



				if ( hooks &&

					"get" in hooks &&

					( ret = hooks.get( elem, "value" ) ) !== undefined

				) {

					return ret;

				}



				ret = elem.value;



				// Handle most common string cases

				if ( typeof ret === "string" ) {

					return ret.replace( rreturn, "" );

				}



				// Handle cases where value is null/undef or number

				return ret == null ? "" : ret;

			}



			return;

		}



		isFunction = jQuery.isFunction( value );



		return this.each( function( i ) {

			var val;



			if ( this.nodeType !== 1 ) {

				return;

			}



			if ( isFunction ) {

				val = value.call( this, i, jQuery( this ).val() );

			} else {

				val = value;

			}



			// Treat null/undefined as ""; convert numbers to string

			if ( val == null ) {

				val = "";



			} else if ( typeof val === "number" ) {

				val += "";



			} else if ( Array.isArray( val ) ) {

				val = jQuery.map( val, function( value ) {

					return value == null ? "" : value + "";

				} );

			}



			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];



			// If set returns undefined, fall back to normal setting

			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {

				this.value = val;

			}

		} );

	}

} );



jQuery.extend( {

	valHooks: {

		option: {

			get: function( elem ) {



				var val = jQuery.find.attr( elem, "value" );

				return val != null ?

					val :



					// Support: IE <=10 - 11 only

					// option.text throws exceptions (#14686, #14858)

					// Strip and collapse whitespace

					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace

					stripAndCollapse( jQuery.text( elem ) );

			}

		},

		select: {

			get: function( elem ) {

				var value, option, i,

					options = elem.options,

					index = elem.selectedIndex,

					one = elem.type === "select-one",

					values = one ? null : [],

					max = one ? index + 1 : options.length;



				if ( index < 0 ) {

					i = max;



				} else {

					i = one ? index : 0;

				}



				// Loop through all the selected options

				for ( ; i < max; i++ ) {

					option = options[ i ];



					// Support: IE <=9 only

					// IE8-9 doesn't update selected after form reset (#2551)

					if ( ( option.selected || i === index ) &&



							// Don't return options that are disabled or in a disabled optgroup

							!option.disabled &&

							( !option.parentNode.disabled ||

								!nodeName( option.parentNode, "optgroup" ) ) ) {



						// Get the specific value for the option

						value = jQuery( option ).val();



						// We don't need an array for one selects

						if ( one ) {

							return value;

						}



						// Multi-Selects return an array

						values.push( value );

					}

				}



				return values;

			},



			set: function( elem, value ) {

				var optionSet, option,

					options = elem.options,

					values = jQuery.makeArray( value ),

					i = options.length;



				while ( i-- ) {

					option = options[ i ];



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



					if ( option.selected =

						jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1

					) {

						optionSet = true;

					}



					/* eslint-enable no-cond-assign */

				}



				// Force browsers to behave consistently when non-matching value is set

				if ( !optionSet ) {

					elem.selectedIndex = -1;

				}

				return values;

			}

		}

	}

} );



// Radios and checkboxes getter/setter

jQuery.each( [ "radio", "checkbox" ], function() {

	jQuery.valHooks[ this ] = {

		set: function( elem, value ) {

			if ( Array.isArray( value ) ) {

				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );

			}

		}

	};

	if ( !support.checkOn ) {

		jQuery.valHooks[ this ].get = function( elem ) {

			return elem.getAttribute( "value" ) === null ? "on" : elem.value;

		};

	}

} );









// Return jQuery for attributes-only inclusion





var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;



jQuery.extend( jQuery.event, {



	trigger: function( event, data, elem, onlyHandlers ) {



		var i, cur, tmp, bubbleType, ontype, handle, special,

			eventPath = [ elem || document ],

			type = hasOwn.call( event, "type" ) ? event.type : event,

			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];



		cur = tmp = elem = elem || document;



		// Don't do events on text and comment nodes

		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {

			return;

		}



		// focus/blur morphs to focusin/out; ensure we're not firing them right now

		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {

			return;

		}



		if ( type.indexOf( "." ) > -1 ) {



			// Namespaced trigger; create a regexp to match event type in handle()

			namespaces = type.split( "." );

			type = namespaces.shift();

			namespaces.sort();

		}

		ontype = type.indexOf( ":" ) < 0 && "on" + type;



		// Caller can pass in a jQuery.Event object, Object, or just an event type string

		event = event[ jQuery.expando ] ?

			event :

			new jQuery.Event( type, typeof event === "object" && event );



		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)

		event.isTrigger = onlyHandlers ? 2 : 3;

		event.namespace = namespaces.join( "." );

		event.rnamespace = event.namespace ?

			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :

			null;



		// Clean up the event in case it is being reused

		event.result = undefined;

		if ( !event.target ) {

			event.target = elem;

		}



		// Clone any incoming data and prepend the event, creating the handler arg list

		data = data == null ?

			[ event ] :

			jQuery.makeArray( data, [ event ] );



		// Allow special events to draw outside the lines

		special = jQuery.event.special[ type ] || {};

		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {

			return;

		}



		// Determine event propagation path in advance, per W3C events spec (#9951)

		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)

		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {



			bubbleType = special.delegateType || type;

			if ( !rfocusMorph.test( bubbleType + type ) ) {

				cur = cur.parentNode;

			}

			for ( ; cur; cur = cur.parentNode ) {

				eventPath.push( cur );

				tmp = cur;

			}



			// Only add window if we got to document (e.g., not plain obj or detached DOM)

			if ( tmp === ( elem.ownerDocument || document ) ) {

				eventPath.push( tmp.defaultView || tmp.parentWindow || window );

			}

		}



		// Fire handlers on the event path

		i = 0;

		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {



			event.type = i > 1 ?

				bubbleType :

				special.bindType || type;



			// jQuery handler

			handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&

				dataPriv.get( cur, "handle" );

			if ( handle ) {

				handle.apply( cur, data );

			}



			// Native handler

			handle = ontype && cur[ ontype ];

			if ( handle && handle.apply && acceptData( cur ) ) {

				event.result = handle.apply( cur, data );

				if ( event.result === false ) {

					event.preventDefault();

				}

			}

		}

		event.type = type;



		// If nobody prevented the default action, do it now

		if ( !onlyHandlers && !event.isDefaultPrevented() ) {



			if ( ( !special._default ||

				special._default.apply( eventPath.pop(), data ) === false ) &&

				acceptData( elem ) ) {



				// Call a native DOM method on the target with the same name as the event.

				// Don't do default actions on window, that's where global variables be (#6170)

				if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {



					// Don't re-trigger an onFOO event when we call its FOO() method

					tmp = elem[ ontype ];



					if ( tmp ) {

						elem[ ontype ] = null;

					}



					// Prevent re-triggering of the same event, since we already bubbled it above

					jQuery.event.triggered = type;

					elem[ type ]();

					jQuery.event.triggered = undefined;



					if ( tmp ) {

						elem[ ontype ] = tmp;

					}

				}

			}

		}



		return event.result;

	},



	// Piggyback on a donor event to simulate a different one

	// Used only for `focus(in | out)` events

	simulate: function( type, elem, event ) {

		var e = jQuery.extend(

			new jQuery.Event(),

			event,

			{

				type: type,

				isSimulated: true

			}

		);



		jQuery.event.trigger( e, null, elem );

	}



} );



jQuery.fn.extend( {



	trigger: function( type, data ) {

		return this.each( function() {

			jQuery.event.trigger( type, data, this );

		} );

	},

	triggerHandler: function( type, data ) {

		var elem = this[ 0 ];

		if ( elem ) {

			return jQuery.event.trigger( type, data, elem, true );

		}

	}

} );





jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +

	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +

	"change select submit keydown keypress keyup contextmenu" ).split( " " ),

	function( i, name ) {



	// Handle event binding

	jQuery.fn[ name ] = function( data, fn ) {

		return arguments.length > 0 ?

			this.on( name, null, data, fn ) :

			this.trigger( name );

	};

} );



jQuery.fn.extend( {

	hover: function( fnOver, fnOut ) {

		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );

	}

} );









support.focusin = "onfocusin" in window;





// Support: Firefox <=44

// Firefox doesn't have focus(in | out) events

// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787

//

// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1

// focus(in | out) events fire after focus & blur events,

// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order

// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857

if ( !support.focusin ) {

	jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {



		// Attach a single capturing handler on the document while someone wants focusin/focusout

		var handler = function( event ) {

			jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );

		};



		jQuery.event.special[ fix ] = {

			setup: function() {

				var doc = this.ownerDocument || this,

					attaches = dataPriv.access( doc, fix );



				if ( !attaches ) {

					doc.addEventListener( orig, handler, true );

				}

				dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );

			},

			teardown: function() {

				var doc = this.ownerDocument || this,

					attaches = dataPriv.access( doc, fix ) - 1;



				if ( !attaches ) {

					doc.removeEventListener( orig, handler, true );

					dataPriv.remove( doc, fix );



				} else {

					dataPriv.access( doc, fix, attaches );

				}

			}

		};

	} );

}

var location = window.location;



var nonce = jQuery.now();



var rquery = ( /\?/ );







// Cross-browser xml parsing

jQuery.parseXML = function( data ) {

	var xml;

	if ( !data || typeof data !== "string" ) {

		return null;

	}



	// Support: IE 9 - 11 only

	// IE throws on parseFromString with invalid input.

	try {

		xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );

	} catch ( e ) {

		xml = undefined;

	}



	if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {

		jQuery.error( "Invalid XML: " + data );

	}

	return xml;

};





var

	rbracket = /\[\]$/,

	rCRLF = /\r?\n/g,

	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,

	rsubmittable = /^(?:input|select|textarea|keygen)/i;



function buildParams( prefix, obj, traditional, add ) {

	var name;



	if ( Array.isArray( obj ) ) {



		// Serialize array item.

		jQuery.each( obj, function( i, v ) {

			if ( traditional || rbracket.test( prefix ) ) {



				// Treat each array item as a scalar.

				add( prefix, v );



			} else {



				// Item is non-scalar (array or object), encode its numeric index.

				buildParams(

					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",

					v,

					traditional,

					add

				);

			}

		} );



	} else if ( !traditional && jQuery.type( obj ) === "object" ) {



		// Serialize object item.

		for ( name in obj ) {

			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );

		}



	} else {



		// Serialize scalar item.

		add( prefix, obj );

	}

}



// Serialize an array of form elements or a set of

// key/values into a query string

jQuery.param = function( a, traditional ) {

	var prefix,

		s = [],

		add = function( key, valueOrFunction ) {



			// If value is a function, invoke it and use its return value

			var value = jQuery.isFunction( valueOrFunction ) ?

				valueOrFunction() :

				valueOrFunction;



			s[ s.length ] = encodeURIComponent( key ) + "=" +

				encodeURIComponent( value == null ? "" : value );

		};



	// If an array was passed in, assume that it is an array of form elements.

	if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {



		// Serialize the form elements

		jQuery.each( a, function() {

			add( this.name, this.value );

		} );



	} else {



		// If traditional, encode the "old" way (the way 1.3.2 or older

		// did it), otherwise encode params recursively.

		for ( prefix in a ) {

			buildParams( prefix, a[ prefix ], traditional, add );

		}

	}



	// Return the resulting serialization

	return s.join( "&" );

};



jQuery.fn.extend( {

	serialize: function() {

		return jQuery.param( this.serializeArray() );

	},

	serializeArray: function() {

		return this.map( function() {



			// Can add propHook for "elements" to filter or add form elements

			var elements = jQuery.prop( this, "elements" );

			return elements ? jQuery.makeArray( elements ) : this;

		} )

		.filter( function() {

			var type = this.type;



			// Use .is( ":disabled" ) so that fieldset[disabled] works

			return this.name && !jQuery( this ).is( ":disabled" ) &&

				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&

				( this.checked || !rcheckableType.test( type ) );

		} )

		.map( function( i, elem ) {

			var val = jQuery( this ).val();



			if ( val == null ) {

				return null;

			}



			if ( Array.isArray( val ) ) {

				return jQuery.map( val, function( val ) {

					return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };

				} );

			}



			return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };

		} ).get();

	}

} );





var

	r20 = /%20/g,

	rhash = /#.*$/,

	rantiCache = /([?&])_=[^&]*/,

	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,



	// #7653, #8125, #8152: local protocol detection

	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,

	rnoContent = /^(?:GET|HEAD)$/,

	rprotocol = /^\/\//,



	/* Prefilters

	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)

	 * 2) These are called:

	 *    - BEFORE asking for a transport

	 *    - AFTER param serialization (s.data is a string if s.processData is true)

	 * 3) key is the dataType

	 * 4) the catchall symbol "*" can be used

	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed

	 */

	prefilters = {},



	/* Transports bindings

	 * 1) key is the dataType

	 * 2) the catchall symbol "*" can be used

	 * 3) selection will start with transport dataType and THEN go to "*" if needed

	 */

	transports = {},



	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression

	allTypes = "*/".concat( "*" ),



	// Anchor tag for parsing the document origin

	originAnchor = document.createElement( "a" );

	originAnchor.href = location.href;



// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport

function addToPrefiltersOrTransports( structure ) {



	// dataTypeExpression is optional and defaults to "*"

	return function( dataTypeExpression, func ) {



		if ( typeof dataTypeExpression !== "string" ) {

			func = dataTypeExpression;

			dataTypeExpression = "*";

		}



		var dataType,

			i = 0,

			dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];



		if ( jQuery.isFunction( func ) ) {



			// For each dataType in the dataTypeExpression

			while ( ( dataType = dataTypes[ i++ ] ) ) {



				// Prepend if requested

				if ( dataType[ 0 ] === "+" ) {

					dataType = dataType.slice( 1 ) || "*";

					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );



				// Otherwise append

				} else {

					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );

				}

			}

		}

	};

}



// Base inspection function for prefilters and transports

function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {



	var inspected = {},

		seekingTransport = ( structure === transports );



	function inspect( dataType ) {

		var selected;

		inspected[ dataType ] = true;

		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {

			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );

			if ( typeof dataTypeOrTransport === "string" &&

				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {



				options.dataTypes.unshift( dataTypeOrTransport );

				inspect( dataTypeOrTransport );

				return false;

			} else if ( seekingTransport ) {

				return !( selected = dataTypeOrTransport );

			}

		} );

		return selected;

	}



	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );

}



// A special extend for ajax options

// that takes "flat" options (not to be deep extended)

// Fixes #9887

function ajaxExtend( target, src ) {

	var key, deep,

		flatOptions = jQuery.ajaxSettings.flatOptions || {};



	for ( key in src ) {

		if ( src[ key ] !== undefined ) {

			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];

		}

	}

	if ( deep ) {

		jQuery.extend( true, target, deep );

	}



	return target;

}



/* Handles responses to an ajax request:

 * - finds the right dataType (mediates between content-type and expected dataType)

 * - returns the corresponding response

 */

function ajaxHandleResponses( s, jqXHR, responses ) {



	var ct, type, finalDataType, firstDataType,

		contents = s.contents,

		dataTypes = s.dataTypes;



	// Remove auto dataType and get content-type in the process

	while ( dataTypes[ 0 ] === "*" ) {

		dataTypes.shift();

		if ( ct === undefined ) {

			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );

		}

	}



	// Check if we're dealing with a known content-type

	if ( ct ) {

		for ( type in contents ) {

			if ( contents[ type ] && contents[ type ].test( ct ) ) {

				dataTypes.unshift( type );

				break;

			}

		}

	}



	// Check to see if we have a response for the expected dataType

	if ( dataTypes[ 0 ] in responses ) {

		finalDataType = dataTypes[ 0 ];

	} else {



		// Try convertible dataTypes

		for ( type in responses ) {

			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {

				finalDataType = type;

				break;

			}

			if ( !firstDataType ) {

				firstDataType = type;

			}

		}



		// Or just use first one

		finalDataType = finalDataType || firstDataType;

	}



	// If we found a dataType

	// We add the dataType to the list if needed

	// and return the corresponding response

	if ( finalDataType ) {

		if ( finalDataType !== dataTypes[ 0 ] ) {

			dataTypes.unshift( finalDataType );

		}

		return responses[ finalDataType ];

	}

}



/* Chain conversions given the request and the original response

 * Also sets the responseXXX fields on the jqXHR instance

 */

function ajaxConvert( s, response, jqXHR, isSuccess ) {

	var conv2, current, conv, tmp, prev,

		converters = {},



		// Work with a copy of dataTypes in case we need to modify it for conversion

		dataTypes = s.dataTypes.slice();



	// Create converters map with lowercased keys

	if ( dataTypes[ 1 ] ) {

		for ( conv in s.converters ) {

			converters[ conv.toLowerCase() ] = s.converters[ conv ];

		}

	}



	current = dataTypes.shift();



	// Convert to each sequential dataType

	while ( current ) {



		if ( s.responseFields[ current ] ) {

			jqXHR[ s.responseFields[ current ] ] = response;

		}



		// Apply the dataFilter if provided

		if ( !prev && isSuccess && s.dataFilter ) {

			response = s.dataFilter( response, s.dataType );

		}



		prev = current;

		current = dataTypes.shift();



		if ( current ) {



			// There's only work to do if current dataType is non-auto

			if ( current === "*" ) {



				current = prev;



			// Convert response if prev dataType is non-auto and differs from current

			} else if ( prev !== "*" && prev !== current ) {



				// Seek a direct converter

				conv = converters[ prev + " " + current ] || converters[ "* " + current ];



				// If none found, seek a pair

				if ( !conv ) {

					for ( conv2 in converters ) {



						// If conv2 outputs current

						tmp = conv2.split( " " );

						if ( tmp[ 1 ] === current ) {



							// If prev can be converted to accepted input

							conv = converters[ prev + " " + tmp[ 0 ] ] ||

								converters[ "* " + tmp[ 0 ] ];

							if ( conv ) {



								// Condense equivalence converters

								if ( conv === true ) {

									conv = converters[ conv2 ];



								// Otherwise, insert the intermediate dataType

								} else if ( converters[ conv2 ] !== true ) {

									current = tmp[ 0 ];

									dataTypes.unshift( tmp[ 1 ] );

								}

								break;

							}

						}

					}

				}



				// Apply converter (if not an equivalence)

				if ( conv !== true ) {



					// Unless errors are allowed to bubble, catch and return them

					if ( conv && s.throws ) {

						response = conv( response );

					} else {

						try {

							response = conv( response );

						} catch ( e ) {

							return {

								state: "parsererror",

								error: conv ? e : "No conversion from " + prev + " to " + current

							};

						}

					}

				}

			}

		}

	}



	return { state: "success", data: response };

}



jQuery.extend( {



	// Counter for holding the number of active queries

	active: 0,



	// Last-Modified header cache for next request

	lastModified: {},

	etag: {},



	ajaxSettings: {

		url: location.href,

		type: "GET",

		isLocal: rlocalProtocol.test( location.protocol ),

		global: true,

		processData: true,

		async: true,

		contentType: "application/x-www-form-urlencoded; charset=UTF-8",



		/*

		timeout: 0,

		data: null,

		dataType: null,

		username: null,

		password: null,

		cache: null,

		throws: false,

		traditional: false,

		headers: {},

		*/



		accepts: {

			"*": allTypes,

			text: "text/plain",

			html: "text/html",

			xml: "application/xml, text/xml",

			json: "application/json, text/javascript"

		},



		contents: {

			xml: /\bxml\b/,

			html: /\bhtml/,

			json: /\bjson\b/

		},



		responseFields: {

			xml: "responseXML",

			text: "responseText",

			json: "responseJSON"

		},



		// Data converters

		// Keys separate source (or catchall "*") and destination types with a single space

		converters: {



			// Convert anything to text

			"* text": String,



			// Text to html (true = no transformation)

			"text html": true,



			// Evaluate text as a json expression

			"text json": JSON.parse,



			// Parse text as xml

			"text xml": jQuery.parseXML

		},



		// For options that shouldn't be deep extended:

		// you can add your own custom options here if

		// and when you create one that shouldn't be

		// deep extended (see ajaxExtend)

		flatOptions: {

			url: true,

			context: true

		}

	},



	// Creates a full fledged settings object into target

	// with both ajaxSettings and settings fields.

	// If target is omitted, writes into ajaxSettings.

	ajaxSetup: function( target, settings ) {

		return settings ?



			// Building a settings object

			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :



			// Extending ajaxSettings

			ajaxExtend( jQuery.ajaxSettings, target );

	},



	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),

	ajaxTransport: addToPrefiltersOrTransports( transports ),



	// Main method

	ajax: function( url, options ) {



		// If url is an object, simulate pre-1.5 signature

		if ( typeof url === "object" ) {

			options = url;

			url = undefined;

		}



		// Force options to be an object

		options = options || {};



		var transport,



			// URL without anti-cache param

			cacheURL,



			// Response headers

			responseHeadersString,

			responseHeaders,



			// timeout handle

			timeoutTimer,



			// Url cleanup var

			urlAnchor,



			// Request state (becomes false upon send and true upon completion)

			completed,



			// To know if global events are to be dispatched

			fireGlobals,



			// Loop variable

			i,



			// uncached part of the url

			uncached,



			// Create the final options object

			s = jQuery.ajaxSetup( {}, options ),



			// Callbacks context

			callbackContext = s.context || s,



			// Context for global events is callbackContext if it is a DOM node or jQuery collection

			globalEventContext = s.context &&

				( callbackContext.nodeType || callbackContext.jquery ) ?

					jQuery( callbackContext ) :

					jQuery.event,



			// Deferreds

			deferred = jQuery.Deferred(),

			completeDeferred = jQuery.Callbacks( "once memory" ),



			// Status-dependent callbacks

			statusCode = s.statusCode || {},



			// Headers (they are sent all at once)

			requestHeaders = {},

			requestHeadersNames = {},



			// Default abort message

			strAbort = "canceled",



			// Fake xhr

			jqXHR = {

				readyState: 0,



				// Builds headers hashtable if needed

				getResponseHeader: function( key ) {

					var match;

					if ( completed ) {

						if ( !responseHeaders ) {

							responseHeaders = {};

							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {

								responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];

							}

						}

						match = responseHeaders[ key.toLowerCase() ];

					}

					return match == null ? null : match;

				},



				// Raw string

				getAllResponseHeaders: function() {

					return completed ? responseHeadersString : null;

				},



				// Caches the header

				setRequestHeader: function( name, value ) {

					if ( completed == null ) {

						name = requestHeadersNames[ name.toLowerCase() ] =

							requestHeadersNames[ name.toLowerCase() ] || name;

						requestHeaders[ name ] = value;

					}

					return this;

				},



				// Overrides response content-type header

				overrideMimeType: function( type ) {

					if ( completed == null ) {

						s.mimeType = type;

					}

					return this;

				},



				// Status-dependent callbacks

				statusCode: function( map ) {

					var code;

					if ( map ) {

						if ( completed ) {



							// Execute the appropriate callbacks

							jqXHR.always( map[ jqXHR.status ] );

						} else {



							// Lazy-add the new callbacks in a way that preserves old ones

							for ( code in map ) {

								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];

							}

						}

					}

					return this;

				},



				// Cancel the request

				abort: function( statusText ) {

					var finalText = statusText || strAbort;

					if ( transport ) {

						transport.abort( finalText );

					}

					done( 0, finalText );

					return this;

				}

			};



		// Attach deferreds

		deferred.promise( jqXHR );



		// Add protocol if not provided (prefilters might expect it)

		// Handle falsy url in the settings object (#10093: consistency with old signature)

		// We also use the url parameter if available

		s.url = ( ( url || s.url || location.href ) + "" )

			.replace( rprotocol, location.protocol + "//" );



		// Alias method option to type as per ticket #12004

		s.type = options.method || options.type || s.method || s.type;



		// Extract dataTypes list

		s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];



		// A cross-domain request is in order when the origin doesn't match the current origin.

		if ( s.crossDomain == null ) {

			urlAnchor = document.createElement( "a" );



			// Support: IE <=8 - 11, Edge 12 - 13

			// IE throws exception on accessing the href property if url is malformed,

			// e.g. http://example.com:80x/

			try {

				urlAnchor.href = s.url;



				// Support: IE <=8 - 11 only

				// Anchor's host property isn't correctly set when s.url is relative

				urlAnchor.href = urlAnchor.href;

				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==

					urlAnchor.protocol + "//" + urlAnchor.host;

			} catch ( e ) {



				// If there is an error parsing the URL, assume it is crossDomain,

				// it can be rejected by the transport if it is invalid

				s.crossDomain = true;

			}

		}



		// Convert data if not already a string

		if ( s.data && s.processData && typeof s.data !== "string" ) {

			s.data = jQuery.param( s.data, s.traditional );

		}



		// Apply prefilters

		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );



		// If request was aborted inside a prefilter, stop there

		if ( completed ) {

			return jqXHR;

		}



		// We can fire global events as of now if asked to

		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)

		fireGlobals = jQuery.event && s.global;



		// Watch for a new set of requests

		if ( fireGlobals && jQuery.active++ === 0 ) {

			jQuery.event.trigger( "ajaxStart" );

		}



		// Uppercase the type

		s.type = s.type.toUpperCase();



		// Determine if request has content

		s.hasContent = !rnoContent.test( s.type );



		// Save the URL in case we're toying with the If-Modified-Since

		// and/or If-None-Match header later on

		// Remove hash to simplify url manipulation

		cacheURL = s.url.replace( rhash, "" );



		// More options handling for requests with no content

		if ( !s.hasContent ) {



			// Remember the hash so we can put it back

			uncached = s.url.slice( cacheURL.length );



			// If data is available, append data to url

			if ( s.data ) {

				cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;



				// #9682: remove data so that it's not used in an eventual retry

				delete s.data;

			}



			// Add or update anti-cache param if needed

			if ( s.cache === false ) {

				cacheURL = cacheURL.replace( rantiCache, "$1" );

				uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached;

			}



			// Put hash and anti-cache on the URL that will be requested (gh-1732)

			s.url = cacheURL + uncached;



		// Change '%20' to '+' if this is encoded form body content (gh-2658)

		} else if ( s.data && s.processData &&

			( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {

			s.data = s.data.replace( r20, "+" );

		}



		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.

		if ( s.ifModified ) {

			if ( jQuery.lastModified[ cacheURL ] ) {

				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );

			}

			if ( jQuery.etag[ cacheURL ] ) {

				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );

			}

		}



		// Set the correct header, if data is being sent

		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {

			jqXHR.setRequestHeader( "Content-Type", s.contentType );

		}



		// Set the Accepts header for the server, depending on the dataType

		jqXHR.setRequestHeader(

			"Accept",

			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?

				s.accepts[ s.dataTypes[ 0 ] ] +

					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :

				s.accepts[ "*" ]

		);



		// Check for headers option

		for ( i in s.headers ) {

			jqXHR.setRequestHeader( i, s.headers[ i ] );

		}



		// Allow custom headers/mimetypes and early abort

		if ( s.beforeSend &&

			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {



			// Abort if not done already and return

			return jqXHR.abort();

		}



		// Aborting is no longer a cancellation

		strAbort = "abort";



		// Install callbacks on deferreds

		completeDeferred.add( s.complete );

		jqXHR.done( s.success );

		jqXHR.fail( s.error );



		// Get transport

		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );



		// If no transport, we auto-abort

		if ( !transport ) {

			done( -1, "No Transport" );

		} else {

			jqXHR.readyState = 1;



			// Send global event

			if ( fireGlobals ) {

				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );

			}



			// If request was aborted inside ajaxSend, stop there

			if ( completed ) {

				return jqXHR;

			}



			// Timeout

			if ( s.async && s.timeout > 0 ) {

				timeoutTimer = window.setTimeout( function() {

					jqXHR.abort( "timeout" );

				}, s.timeout );

			}



			try {

				completed = false;

				transport.send( requestHeaders, done );

			} catch ( e ) {



				// Rethrow post-completion exceptions

				if ( completed ) {

					throw e;

				}



				// Propagate others as results

				done( -1, e );

			}

		}



		// Callback for when everything is done

		function done( status, nativeStatusText, responses, headers ) {

			var isSuccess, success, error, response, modified,

				statusText = nativeStatusText;



			// Ignore repeat invocations

			if ( completed ) {

				return;

			}



			completed = true;



			// Clear timeout if it exists

			if ( timeoutTimer ) {

				window.clearTimeout( timeoutTimer );

			}



			// Dereference transport for early garbage collection

			// (no matter how long the jqXHR object will be used)

			transport = undefined;



			// Cache response headers

			responseHeadersString = headers || "";



			// Set readyState

			jqXHR.readyState = status > 0 ? 4 : 0;



			// Determine if successful

			isSuccess = status >= 200 && status < 300 || status === 304;



			// Get response data

			if ( responses ) {

				response = ajaxHandleResponses( s, jqXHR, responses );

			}



			// Convert no matter what (that way responseXXX fields are always set)

			response = ajaxConvert( s, response, jqXHR, isSuccess );



			// If successful, handle type chaining

			if ( isSuccess ) {



				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.

				if ( s.ifModified ) {

					modified = jqXHR.getResponseHeader( "Last-Modified" );

					if ( modified ) {

						jQuery.lastModified[ cacheURL ] = modified;

					}

					modified = jqXHR.getResponseHeader( "etag" );

					if ( modified ) {

						jQuery.etag[ cacheURL ] = modified;

					}

				}



				// if no content

				if ( status === 204 || s.type === "HEAD" ) {

					statusText = "nocontent";



				// if not modified

				} else if ( status === 304 ) {

					statusText = "notmodified";



				// If we have data, let's convert it

				} else {

					statusText = response.state;

					success = response.data;

					error = response.error;

					isSuccess = !error;

				}

			} else {



				// Extract error from statusText and normalize for non-aborts

				error = statusText;

				if ( status || !statusText ) {

					statusText = "error";

					if ( status < 0 ) {

						status = 0;

					}

				}

			}



			// Set data for the fake xhr object

			jqXHR.status = status;

			jqXHR.statusText = ( nativeStatusText || statusText ) + "";



			// Success/Error

			if ( isSuccess ) {

				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );

			} else {

				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );

			}



			// Status-dependent callbacks

			jqXHR.statusCode( statusCode );

			statusCode = undefined;



			if ( fireGlobals ) {

				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",

					[ jqXHR, s, isSuccess ? success : error ] );

			}



			// Complete

			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );



			if ( fireGlobals ) {

				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );



				// Handle the global AJAX counter

				if ( !( --jQuery.active ) ) {

					jQuery.event.trigger( "ajaxStop" );

				}

			}

		}



		return jqXHR;

	},



	getJSON: function( url, data, callback ) {

		return jQuery.get( url, data, callback, "json" );

	},



	getScript: function( url, callback ) {

		return jQuery.get( url, undefined, callback, "script" );

	}

} );



jQuery.each( [ "get", "post" ], function( i, method ) {

	jQuery[ method ] = function( url, data, callback, type ) {



		// Shift arguments if data argument was omitted

		if ( jQuery.isFunction( data ) ) {

			type = type || callback;

			callback = data;

			data = undefined;

		}



		// The url can be an options object (which then must have .url)

		return jQuery.ajax( jQuery.extend( {

			url: url,

			type: method,

			dataType: type,

			data: data,

			success: callback

		}, jQuery.isPlainObject( url ) && url ) );

	};

} );





jQuery._evalUrl = function( url ) {

	return jQuery.ajax( {

		url: url,



		// Make this explicit, since user can override this through ajaxSetup (#11264)

		type: "GET",

		dataType: "script",

		cache: true,

		async: false,

		global: false,

		"throws": true

	} );

};





jQuery.fn.extend( {

	wrapAll: function( html ) {

		var wrap;



		if ( this[ 0 ] ) {

			if ( jQuery.isFunction( html ) ) {

				html = html.call( this[ 0 ] );

			}



			// The elements to wrap the target around

			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );



			if ( this[ 0 ].parentNode ) {

				wrap.insertBefore( this[ 0 ] );

			}



			wrap.map( function() {

				var elem = this;



				while ( elem.firstElementChild ) {

					elem = elem.firstElementChild;

				}



				return elem;

			} ).append( this );

		}



		return this;

	},



	wrapInner: function( html ) {

		if ( jQuery.isFunction( html ) ) {

			return this.each( function( i ) {

				jQuery( this ).wrapInner( html.call( this, i ) );

			} );

		}



		return this.each( function() {

			var self = jQuery( this ),

				contents = self.contents();



			if ( contents.length ) {

				contents.wrapAll( html );



			} else {

				self.append( html );

			}

		} );

	},



	wrap: function( html ) {

		var isFunction = jQuery.isFunction( html );



		return this.each( function( i ) {

			jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );

		} );

	},



	unwrap: function( selector ) {

		this.parent( selector ).not( "body" ).each( function() {

			jQuery( this ).replaceWith( this.childNodes );

		} );

		return this;

	}

} );





jQuery.expr.pseudos.hidden = function( elem ) {

	return !jQuery.expr.pseudos.visible( elem );

};

jQuery.expr.pseudos.visible = function( elem ) {

	return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );

};









jQuery.ajaxSettings.xhr = function() {

	try {

		return new window.XMLHttpRequest();

	} catch ( e ) {}

};



var xhrSuccessStatus = {



		// File protocol always yields status code 0, assume 200

		0: 200,



		// Support: IE <=9 only

		// #1450: sometimes IE returns 1223 when it should be 204

		1223: 204

	},

	xhrSupported = jQuery.ajaxSettings.xhr();



support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );

support.ajax = xhrSupported = !!xhrSupported;



jQuery.ajaxTransport( function( options ) {

	var callback, errorCallback;



	// Cross domain only allowed if supported through XMLHttpRequest

	if ( support.cors || xhrSupported && !options.crossDomain ) {

		return {

			send: function( headers, complete ) {

				var i,

					xhr = options.xhr();



				xhr.open(

					options.type,

					options.url,

					options.async,

					options.username,

					options.password

				);



				// Apply custom fields if provided

				if ( options.xhrFields ) {

					for ( i in options.xhrFields ) {

						xhr[ i ] = options.xhrFields[ i ];

					}

				}



				// Override mime type if needed

				if ( options.mimeType && xhr.overrideMimeType ) {

					xhr.overrideMimeType( options.mimeType );

				}



				// X-Requested-With header

				// For cross-domain requests, seeing as conditions for a preflight are

				// akin to a jigsaw puzzle, we simply never set it to be sure.

				// (it can always be set on a per-request basis or even using ajaxSetup)

				// For same-domain requests, won't change header if already provided.

				if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {

					headers[ "X-Requested-With" ] = "XMLHttpRequest";

				}



				// Set headers

				for ( i in headers ) {

					xhr.setRequestHeader( i, headers[ i ] );

				}



				// Callback

				callback = function( type ) {

					return function() {

						if ( callback ) {

							callback = errorCallback = xhr.onload =

								xhr.onerror = xhr.onabort = xhr.onreadystatechange = null;



							if ( type === "abort" ) {

								xhr.abort();

							} else if ( type === "error" ) {



								// Support: IE <=9 only

								// On a manual native abort, IE9 throws

								// errors on any property access that is not readyState

								if ( typeof xhr.status !== "number" ) {

									complete( 0, "error" );

								} else {

									complete(



										// File: protocol always yields status 0; see #8605, #14207

										xhr.status,

										xhr.statusText

									);

								}

							} else {

								complete(

									xhrSuccessStatus[ xhr.status ] || xhr.status,

									xhr.statusText,



									// Support: IE <=9 only

									// IE9 has no XHR2 but throws on binary (trac-11426)

									// For XHR2 non-text, let the caller handle it (gh-2498)

									( xhr.responseType || "text" ) !== "text"  ||

									typeof xhr.responseText !== "string" ?

										{ binary: xhr.response } :

										{ text: xhr.responseText },

									xhr.getAllResponseHeaders()

								);

							}

						}

					};

				};



				// Listen to events

				xhr.onload = callback();

				errorCallback = xhr.onerror = callback( "error" );



				// Support: IE 9 only

				// Use onreadystatechange to replace onabort

				// to handle uncaught aborts

				if ( xhr.onabort !== undefined ) {

					xhr.onabort = errorCallback;

				} else {

					xhr.onreadystatechange = function() {



						// Check readyState before timeout as it changes

						if ( xhr.readyState === 4 ) {



							// Allow onerror to be called first,

							// but that will not handle a native abort

							// Also, save errorCallback to a variable

							// as xhr.onerror cannot be accessed

							window.setTimeout( function() {

								if ( callback ) {

									errorCallback();

								}

							} );

						}

					};

				}



				// Create the abort callback

				callback = callback( "abort" );



				try {



					// Do send the request (this may raise an exception)

					xhr.send( options.hasContent && options.data || null );

				} catch ( e ) {



					// #14683: Only rethrow if this hasn't been notified as an error yet

					if ( callback ) {

						throw e;

					}

				}

			},



			abort: function() {

				if ( callback ) {

					callback();

				}

			}

		};

	}

} );









// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)

jQuery.ajaxPrefilter( function( s ) {

	if ( s.crossDomain ) {

		s.contents.script = false;

	}

} );



// Install script dataType

jQuery.ajaxSetup( {

	accepts: {

		script: "text/javascript, application/javascript, " +

			"application/ecmascript, application/x-ecmascript"

	},

	contents: {

		script: /\b(?:java|ecma)script\b/

	},

	converters: {

		"text script": function( text ) {

			jQuery.globalEval( text );

			return text;

		}

	}

} );



// Handle cache's special case and crossDomain

jQuery.ajaxPrefilter( "script", function( s ) {

	if ( s.cache === undefined ) {

		s.cache = false;

	}

	if ( s.crossDomain ) {

		s.type = "GET";

	}

} );



// Bind script tag hack transport

jQuery.ajaxTransport( "script", function( s ) {



	// This transport only deals with cross domain requests

	if ( s.crossDomain ) {

		var script, callback;

		return {

			send: function( _, complete ) {

				script = jQuery( "<script>" ).prop( {

					charset: s.scriptCharset,

					src: s.url

				} ).on(

					"load error",

					callback = function( evt ) {

						script.remove();

						callback = null;

						if ( evt ) {

							complete( evt.type === "error" ? 404 : 200, evt.type );

						}

					}

				);



				// Use native DOM manipulation to avoid our domManip AJAX trickery

				document.head.appendChild( script[ 0 ] );

			},

			abort: function() {

				if ( callback ) {

					callback();

				}

			}

		};

	}

} );









var oldCallbacks = [],

	rjsonp = /(=)\?(?=&|$)|\?\?/;



// Default jsonp settings

jQuery.ajaxSetup( {

	jsonp: "callback",

	jsonpCallback: function() {

		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );

		this[ callback ] = true;

		return callback;

	}

} );



// Detect, normalize options and install callbacks for jsonp requests

jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {



	var callbackName, overwritten, responseContainer,

		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?

			"url" :

			typeof s.data === "string" &&

				( s.contentType || "" )

					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&

				rjsonp.test( s.data ) && "data"

		);



	// Handle iff the expected data type is "jsonp" or we have a parameter to set

	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {



		// Get callback name, remembering preexisting value associated with it

		callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?

			s.jsonpCallback() :

			s.jsonpCallback;



		// Insert callback into url or form data

		if ( jsonProp ) {

			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );

		} else if ( s.jsonp !== false ) {

			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;

		}



		// Use data converter to retrieve json after script execution

		s.converters[ "script json" ] = function() {

			if ( !responseContainer ) {

				jQuery.error( callbackName + " was not called" );

			}

			return responseContainer[ 0 ];

		};



		// Force json dataType

		s.dataTypes[ 0 ] = "json";



		// Install callback

		overwritten = window[ callbackName ];

		window[ callbackName ] = function() {

			responseContainer = arguments;

		};



		// Clean-up function (fires after converters)

		jqXHR.always( function() {



			// If previous value didn't exist - remove it

			if ( overwritten === undefined ) {

				jQuery( window ).removeProp( callbackName );



			// Otherwise restore preexisting value

			} else {

				window[ callbackName ] = overwritten;

			}



			// Save back as free

			if ( s[ callbackName ] ) {



				// Make sure that re-using the options doesn't screw things around

				s.jsonpCallback = originalSettings.jsonpCallback;



				// Save the callback name for future use

				oldCallbacks.push( callbackName );

			}



			// Call if it was a function and we have a response

			if ( responseContainer && jQuery.isFunction( overwritten ) ) {

				overwritten( responseContainer[ 0 ] );

			}



			responseContainer = overwritten = undefined;

		} );



		// Delegate to script

		return "script";

	}

} );









// Support: Safari 8 only

// In Safari 8 documents created via document.implementation.createHTMLDocument

// collapse sibling forms: the second one becomes a child of the first one.

// Because of that, this security measure has to be disabled in Safari 8.

// https://bugs.webkit.org/show_bug.cgi?id=137337

support.createHTMLDocument = ( function() {

	var body = document.implementation.createHTMLDocument( "" ).body;

	body.innerHTML = "<form></form><form></form>";

	return body.childNodes.length === 2;

} )();





// Argument "data" should be string of html

// context (optional): If specified, the fragment will be created in this context,

// defaults to document

// keepScripts (optional): If true, will include scripts passed in the html string

jQuery.parseHTML = function( data, context, keepScripts ) {

	if ( typeof data !== "string" ) {

		return [];

	}

	if ( typeof context === "boolean" ) {

		keepScripts = context;

		context = false;

	}



	var base, parsed, scripts;



	if ( !context ) {



		// Stop scripts or inline event handlers from being executed immediately

		// by using document.implementation

		if ( support.createHTMLDocument ) {

			context = document.implementation.createHTMLDocument( "" );



			// Set the base href for the created document

			// so any parsed elements with URLs

			// are based on the document's URL (gh-2965)

			base = context.createElement( "base" );

			base.href = document.location.href;

			context.head.appendChild( base );

		} else {

			context = document;

		}

	}



	parsed = rsingleTag.exec( data );

	scripts = !keepScripts && [];



	// Single tag

	if ( parsed ) {

		return [ context.createElement( parsed[ 1 ] ) ];

	}



	parsed = buildFragment( [ data ], context, scripts );



	if ( scripts && scripts.length ) {

		jQuery( scripts ).remove();

	}



	return jQuery.merge( [], parsed.childNodes );

};





/**

 * Load a url into a page

 */

jQuery.fn.load = function( url, params, callback ) {

	var selector, type, response,

		self = this,

		off = url.indexOf( " " );



	if ( off > -1 ) {

		selector = stripAndCollapse( url.slice( off ) );

		url = url.slice( 0, off );

	}



	// If it's a function

	if ( jQuery.isFunction( params ) ) {



		// We assume that it's the callback

		callback = params;

		params = undefined;



	// Otherwise, build a param string

	} else if ( params && typeof params === "object" ) {

		type = "POST";

	}



	// If we have elements to modify, make the request

	if ( self.length > 0 ) {

		jQuery.ajax( {

			url: url,



			// If "type" variable is undefined, then "GET" method will be used.

			// Make value of this field explicit since

			// user can override it through ajaxSetup method

			type: type || "GET",

			dataType: "html",

			data: params

		} ).done( function( responseText ) {



			// Save response for use in complete callback

			response = arguments;



			self.html( selector ?



				// If a selector was specified, locate the right elements in a dummy div

				// Exclude scripts to avoid IE 'Permission Denied' errors

				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :



				// Otherwise use the full result

				responseText );



		// If the request succeeds, this function gets "data", "status", "jqXHR"

		// but they are ignored because response was set above.

		// If it fails, this function gets "jqXHR", "status", "error"

		} ).always( callback && function( jqXHR, status ) {

			self.each( function() {

				callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );

			} );

		} );

	}



	return this;

};









// Attach a bunch of functions for handling common AJAX events

jQuery.each( [

	"ajaxStart",

	"ajaxStop",

	"ajaxComplete",

	"ajaxError",

	"ajaxSuccess",

	"ajaxSend"

], function( i, type ) {

	jQuery.fn[ type ] = function( fn ) {

		return this.on( type, fn );

	};

} );









jQuery.expr.pseudos.animated = function( elem ) {

	return jQuery.grep( jQuery.timers, function( fn ) {

		return elem === fn.elem;

	} ).length;

};









jQuery.offset = {

	setOffset: function( elem, options, i ) {

		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,

			position = jQuery.css( elem, "position" ),

			curElem = jQuery( elem ),

			props = {};



		// Set position first, in-case top/left are set even on static elem

		if ( position === "static" ) {

			elem.style.position = "relative";

		}



		curOffset = curElem.offset();

		curCSSTop = jQuery.css( elem, "top" );

		curCSSLeft = jQuery.css( elem, "left" );

		calculatePosition = ( position === "absolute" || position === "fixed" ) &&

			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;



		// Need to be able to calculate position if either

		// top or left is auto and position is either absolute or fixed

		if ( calculatePosition ) {

			curPosition = curElem.position();

			curTop = curPosition.top;

			curLeft = curPosition.left;



		} else {

			curTop = parseFloat( curCSSTop ) || 0;

			curLeft = parseFloat( curCSSLeft ) || 0;

		}



		if ( jQuery.isFunction( options ) ) {



			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)

			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );

		}



		if ( options.top != null ) {

			props.top = ( options.top - curOffset.top ) + curTop;

		}

		if ( options.left != null ) {

			props.left = ( options.left - curOffset.left ) + curLeft;

		}



		if ( "using" in options ) {

			options.using.call( elem, props );



		} else {

			curElem.css( props );

		}

	}

};



jQuery.fn.extend( {

	offset: function( options ) {



		// Preserve chaining for setter

		if ( arguments.length ) {

			return options === undefined ?

				this :

				this.each( function( i ) {

					jQuery.offset.setOffset( this, options, i );

				} );

		}



		var doc, docElem, rect, win,

			elem = this[ 0 ];



		if ( !elem ) {

			return;

		}



		// Return zeros for disconnected and hidden (display: none) elements (gh-2310)

		// Support: IE <=11 only

		// Running getBoundingClientRect on a

		// disconnected node in IE throws an error

		if ( !elem.getClientRects().length ) {

			return { top: 0, left: 0 };

		}



		rect = elem.getBoundingClientRect();



		doc = elem.ownerDocument;

		docElem = doc.documentElement;

		win = doc.defaultView;



		return {

			top: rect.top + win.pageYOffset - docElem.clientTop,

			left: rect.left + win.pageXOffset - docElem.clientLeft

		};

	},



	position: function() {

		if ( !this[ 0 ] ) {

			return;

		}



		var offsetParent, offset,

			elem = this[ 0 ],

			parentOffset = { top: 0, left: 0 };



		// Fixed elements are offset from window (parentOffset = {top:0, left: 0},

		// because it is its only offset parent

		if ( jQuery.css( elem, "position" ) === "fixed" ) {



			// Assume getBoundingClientRect is there when computed position is fixed

			offset = elem.getBoundingClientRect();



		} else {



			// Get *real* offsetParent

			offsetParent = this.offsetParent();



			// Get correct offsets

			offset = this.offset();

			if ( !nodeName( offsetParent[ 0 ], "html" ) ) {

				parentOffset = offsetParent.offset();

			}



			// Add offsetParent borders

			parentOffset = {

				top: parentOffset.top + jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ),

				left: parentOffset.left + jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true )

			};

		}



		// Subtract parent offsets and element margins

		return {

			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),

			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )

		};

	},



	// This method will return documentElement in the following cases:

	// 1) For the element inside the iframe without offsetParent, this method will return

	//    documentElement of the parent window

	// 2) For the hidden or detached element

	// 3) For body or html element, i.e. in case of the html node - it will return itself

	//

	// but those exceptions were never presented as a real life use-cases

	// and might be considered as more preferable results.

	//

	// This logic, however, is not guaranteed and can change at any point in the future

	offsetParent: function() {

		return this.map( function() {

			var offsetParent = this.offsetParent;



			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {

				offsetParent = offsetParent.offsetParent;

			}



			return offsetParent || documentElement;

		} );

	}

} );



// Create scrollLeft and scrollTop methods

jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {

	var top = "pageYOffset" === prop;



	jQuery.fn[ method ] = function( val ) {

		return access( this, function( elem, method, val ) {



			// Coalesce documents and windows

			var win;

			if ( jQuery.isWindow( elem ) ) {

				win = elem;

			} else if ( elem.nodeType === 9 ) {

				win = elem.defaultView;

			}



			if ( val === undefined ) {

				return win ? win[ prop ] : elem[ method ];

			}



			if ( win ) {

				win.scrollTo(

					!top ? val : win.pageXOffset,

					top ? val : win.pageYOffset

				);



			} else {

				elem[ method ] = val;

			}

		}, method, val, arguments.length );

	};

} );



// Support: Safari <=7 - 9.1, Chrome <=37 - 49

// Add the top/left cssHooks using jQuery.fn.position

// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084

// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347

// getComputedStyle returns percent when specified for top/left/bottom/right;

// rather than make the css module depend on the offset module, just check for it here

jQuery.each( [ "top", "left" ], function( i, prop ) {

	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,

		function( elem, computed ) {

			if ( computed ) {

				computed = curCSS( elem, prop );



				// If curCSS returns percentage, fallback to offset

				return rnumnonpx.test( computed ) ?

					jQuery( elem ).position()[ prop ] + "px" :

					computed;

			}

		}

	);

} );





// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods

jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {

	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },

		function( defaultExtra, funcName ) {



		// Margin is only for outerHeight, outerWidth

		jQuery.fn[ funcName ] = function( margin, value ) {

			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),

				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );



			return access( this, function( elem, type, value ) {

				var doc;



				if ( jQuery.isWindow( elem ) ) {



					// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)

					return funcName.indexOf( "outer" ) === 0 ?

						elem[ "inner" + name ] :

						elem.document.documentElement[ "client" + name ];

				}



				// Get document width or height

				if ( elem.nodeType === 9 ) {

					doc = elem.documentElement;



					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],

					// whichever is greatest

					return Math.max(

						elem.body[ "scroll" + name ], doc[ "scroll" + name ],

						elem.body[ "offset" + name ], doc[ "offset" + name ],

						doc[ "client" + name ]

					);

				}



				return value === undefined ?



					// Get width or height on the element, requesting but not forcing parseFloat

					jQuery.css( elem, type, extra ) :



					// Set width or height on the element

					jQuery.style( elem, type, value, extra );

			}, type, chainable ? margin : undefined, chainable );

		};

	} );

} );





jQuery.fn.extend( {



	bind: function( types, data, fn ) {

		return this.on( types, null, data, fn );

	},

	unbind: function( types, fn ) {

		return this.off( types, null, fn );

	},



	delegate: function( selector, types, data, fn ) {

		return this.on( types, selector, data, fn );

	},

	undelegate: function( selector, types, fn ) {



		// ( namespace ) or ( selector, types [, fn] )

		return arguments.length === 1 ?

			this.off( selector, "**" ) :

			this.off( types, selector || "**", fn );

	}

} );



jQuery.holdReady = function( hold ) {

	if ( hold ) {

		jQuery.readyWait++;

	} else {

		jQuery.ready( true );

	}

};

jQuery.isArray = Array.isArray;

jQuery.parseJSON = JSON.parse;

jQuery.nodeName = nodeName;









// Register as a named AMD module, since jQuery can be concatenated with other

// files that may use define, but not via a proper concatenation script that

// understands anonymous AMD modules. A named AMD is safest and most robust

// way to register. Lowercase jquery is used because AMD module names are

// derived from file names, and jQuery is normally delivered in a lowercase

// file name. Do this after creating the global so that if an AMD module wants

// to call noConflict to hide this version of jQuery, it will work.



// Note that for maximum portability, libraries that are not jQuery should

// declare themselves as anonymous modules, and avoid setting a global if an

// AMD loader is present. jQuery is a special case. For more information, see

// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon



if ( true ) {

	!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function() {

		return jQuery;

	}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),

				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));

}









var



	// Map over jQuery in case of overwrite

	_jQuery = window.jQuery,



	// Map over the $ in case of overwrite

	_$ = window.$;



jQuery.noConflict = function( deep ) {

	if ( window.$ === jQuery ) {

		window.$ = _$;

	}



	if ( deep && window.jQuery === jQuery ) {

		window.jQuery = _jQuery;

	}



	return jQuery;

};



// Expose jQuery and $ identifiers, even in AMD

// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)

// and CommonJS for browser emulators (#13566)

if ( !noGlobal ) {

	window.jQuery = window.$ = jQuery;

}









return jQuery;

} );





/***/ }),

/* 4 */

/***/ (function(module, __webpack_exports__, __webpack_require__) {



"use strict";

Object.defineProperty(__webpack_exports__, "__esModule", { value: true });

/* WEBPACK VAR INJECTION */(function(global) {/**!

 * @fileOverview Kickass library to create and place poppers near their reference elements.

 * @version 1.12.9

 * @license

 * Copyright (c) 2016 Federico Zivolo and contributors

 *

 * Permission is hereby granted, free of charge, to any person obtaining a copy

 * of this software and associated documentation files (the "Software"), to deal

 * in the Software without restriction, including without limitation the rights

 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell

 * copies of the Software, and to permit persons to whom the Software is

 * furnished to do so, subject to the following conditions:

 *

 * The above copyright notice and this permission notice shall be included in all

 * copies or substantial portions of the Software.

 *

 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE

 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE

 * SOFTWARE.

 */

var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';

var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox'];

var timeoutDuration = 0;

for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) {

  if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) {

    timeoutDuration = 1;

    break;

  }

}



function microtaskDebounce(fn) {

  var called = false;

  return function () {

    if (called) {

      return;

    }

    called = true;

    window.Promise.resolve().then(function () {

      called = false;

      fn();

    });

  };

}



function taskDebounce(fn) {

  var scheduled = false;

  return function () {

    if (!scheduled) {

      scheduled = true;

      setTimeout(function () {

        scheduled = false;

        fn();

      }, timeoutDuration);

    }

  };

}



var supportsMicroTasks = isBrowser && window.Promise;



/**

* Create a debounced version of a method, that's asynchronously deferred

* but called in the minimum time possible.

*

* @method

* @memberof Popper.Utils

* @argument {Function} fn

* @returns {Function}

*/

var debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce;



/**

 * Check if the given variable is a function

 * @method

 * @memberof Popper.Utils

 * @argument {Any} functionToCheck - variable to check

 * @returns {Boolean} answer to: is a function?

 */

function isFunction(functionToCheck) {

  var getType = {};

  return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';

}



/**

 * Get CSS computed property of the given element

 * @method

 * @memberof Popper.Utils

 * @argument {Eement} element

 * @argument {String} property

 */

function getStyleComputedProperty(element, property) {

  if (element.nodeType !== 1) {

    return [];

  }

  // NOTE: 1 DOM access here

  var css = getComputedStyle(element, null);

  return property ? css[property] : css;

}



/**

 * Returns the parentNode or the host of the element

 * @method

 * @memberof Popper.Utils

 * @argument {Element} element

 * @returns {Element} parent

 */

function getParentNode(element) {

  if (element.nodeName === 'HTML') {

    return element;

  }

  return element.parentNode || element.host;

}



/**

 * Returns the scrolling parent of the given element

 * @method

 * @memberof Popper.Utils

 * @argument {Element} element

 * @returns {Element} scroll parent

 */

function getScrollParent(element) {

  // Return body, `getScroll` will take care to get the correct `scrollTop` from it

  if (!element) {

    return document.body;

  }



  switch (element.nodeName) {

    case 'HTML':

    case 'BODY':

      return element.ownerDocument.body;

    case '#document':

      return element.body;

  }



  // Firefox want us to check `-x` and `-y` variations as well



  var _getStyleComputedProp = getStyleComputedProperty(element),

      overflow = _getStyleComputedProp.overflow,

      overflowX = _getStyleComputedProp.overflowX,

      overflowY = _getStyleComputedProp.overflowY;



  if (/(auto|scroll)/.test(overflow + overflowY + overflowX)) {

    return element;

  }



  return getScrollParent(getParentNode(element));

}



/**

 * Returns the offset parent of the given element

 * @method

 * @memberof Popper.Utils

 * @argument {Element} element

 * @returns {Element} offset parent

 */

function getOffsetParent(element) {

  // NOTE: 1 DOM access here

  var offsetParent = element && element.offsetParent;

  var nodeName = offsetParent && offsetParent.nodeName;



  if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') {

    if (element) {

      return element.ownerDocument.documentElement;

    }



    return document.documentElement;

  }



  // .offsetParent will return the closest TD or TABLE in case

  // no offsetParent is present, I hate this job...

  if (['TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') {

    return getOffsetParent(offsetParent);

  }



  return offsetParent;

}



function isOffsetContainer(element) {

  var nodeName = element.nodeName;



  if (nodeName === 'BODY') {

    return false;

  }

  return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element;

}



/**

 * Finds the root node (document, shadowDOM root) of the given element

 * @method

 * @memberof Popper.Utils

 * @argument {Element} node

 * @returns {Element} root node

 */

function getRoot(node) {

  if (node.parentNode !== null) {

    return getRoot(node.parentNode);

  }



  return node;

}



/**

 * Finds the offset parent common to the two provided nodes

 * @method

 * @memberof Popper.Utils

 * @argument {Element} element1

 * @argument {Element} element2

 * @returns {Element} common offset parent

 */

function findCommonOffsetParent(element1, element2) {

  // This check is needed to avoid errors in case one of the elements isn't defined for any reason

  if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) {

    return document.documentElement;

  }



  // Here we make sure to give as "start" the element that comes first in the DOM

  var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING;

  var start = order ? element1 : element2;

  var end = order ? element2 : element1;



  // Get common ancestor container

  var range = document.createRange();

  range.setStart(start, 0);

  range.setEnd(end, 0);

  var commonAncestorContainer = range.commonAncestorContainer;



  // Both nodes are inside #document



  if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) {

    if (isOffsetContainer(commonAncestorContainer)) {

      return commonAncestorContainer;

    }



    return getOffsetParent(commonAncestorContainer);

  }



  // one of the nodes is inside shadowDOM, find which one

  var element1root = getRoot(element1);

  if (element1root.host) {

    return findCommonOffsetParent(element1root.host, element2);

  } else {

    return findCommonOffsetParent(element1, getRoot(element2).host);

  }

}



/**

 * Gets the scroll value of the given element in the given side (top and left)

 * @method

 * @memberof Popper.Utils

 * @argument {Element} element

 * @argument {String} side `top` or `left`

 * @returns {number} amount of scrolled pixels

 */

function getScroll(element) {

  var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top';



  var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft';

  var nodeName = element.nodeName;



  if (nodeName === 'BODY' || nodeName === 'HTML') {

    var html = element.ownerDocument.documentElement;

    var scrollingElement = element.ownerDocument.scrollingElement || html;

    return scrollingElement[upperSide];

  }



  return element[upperSide];

}



/*

 * Sum or subtract the element scroll values (left and top) from a given rect object

 * @method

 * @memberof Popper.Utils

 * @param {Object} rect - Rect object you want to change

 * @param {HTMLElement} element - The element from the function reads the scroll values

 * @param {Boolean} subtract - set to true if you want to subtract the scroll values

 * @return {Object} rect - The modifier rect object

 */

function includeScroll(rect, element) {

  var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;



  var scrollTop = getScroll(element, 'top');

  var scrollLeft = getScroll(element, 'left');

  var modifier = subtract ? -1 : 1;

  rect.top += scrollTop * modifier;

  rect.bottom += scrollTop * modifier;

  rect.left += scrollLeft * modifier;

  rect.right += scrollLeft * modifier;

  return rect;

}



/*

 * Helper to detect borders of a given element

 * @method

 * @memberof Popper.Utils

 * @param {CSSStyleDeclaration} styles

 * Result of `getStyleComputedProperty` on the given element

 * @param {String} axis - `x` or `y`

 * @return {number} borders - The borders size of the given axis

 */



function getBordersSize(styles, axis) {

  var sideA = axis === 'x' ? 'Left' : 'Top';

  var sideB = sideA === 'Left' ? 'Right' : 'Bottom';



  return parseFloat(styles['border' + sideA + 'Width'], 10) + parseFloat(styles['border' + sideB + 'Width'], 10);

}



/**

 * Tells if you are running Internet Explorer 10

 * @method

 * @memberof Popper.Utils

 * @returns {Boolean} isIE10

 */

var isIE10 = undefined;



var isIE10$1 = function () {

  if (isIE10 === undefined) {

    isIE10 = navigator.appVersion.indexOf('MSIE 10') !== -1;

  }

  return isIE10;

};



function getSize(axis, body, html, computedStyle) {

  return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + axis], html['scroll' + axis], isIE10$1() ? html['offset' + axis] + computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')] + computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')] : 0);

}



function getWindowSizes() {

  var body = document.body;

  var html = document.documentElement;

  var computedStyle = isIE10$1() && getComputedStyle(html);



  return {

    height: getSize('Height', body, html, computedStyle),

    width: getSize('Width', body, html, computedStyle)

  };

}



var classCallCheck = function (instance, Constructor) {

  if (!(instance instanceof Constructor)) {

    throw new TypeError("Cannot call a class as a function");

  }

};



var createClass = function () {

  function defineProperties(target, props) {

    for (var i = 0; i < props.length; i++) {

      var descriptor = props[i];

      descriptor.enumerable = descriptor.enumerable || false;

      descriptor.configurable = true;

      if ("value" in descriptor) descriptor.writable = true;

      Object.defineProperty(target, descriptor.key, descriptor);

    }

  }



  return function (Constructor, protoProps, staticProps) {

    if (protoProps) defineProperties(Constructor.prototype, protoProps);

    if (staticProps) defineProperties(Constructor, staticProps);

    return Constructor;

  };

}();











var defineProperty = function (obj, key, value) {

  if (key in obj) {

    Object.defineProperty(obj, key, {

      value: value,

      enumerable: true,

      configurable: true,

      writable: true

    });

  } else {

    obj[key] = value;

  }



  return obj;

};



var _extends = Object.assign || function (target) {

  for (var i = 1; i < arguments.length; i++) {

    var source = arguments[i];



    for (var key in source) {

      if (Object.prototype.hasOwnProperty.call(source, key)) {

        target[key] = source[key];

      }

    }

  }



  return target;

};



/**

 * Given element offsets, generate an output similar to getBoundingClientRect

 * @method

 * @memberof Popper.Utils

 * @argument {Object} offsets

 * @returns {Object} ClientRect like output

 */

function getClientRect(offsets) {

  return _extends({}, offsets, {

    right: offsets.left + offsets.width,

    bottom: offsets.top + offsets.height

  });

}



/**

 * Get bounding client rect of given element

 * @method

 * @memberof Popper.Utils

 * @param {HTMLElement} element

 * @return {Object} client rect

 */

function getBoundingClientRect(element) {

  var rect = {};



  // IE10 10 FIX: Please, don't ask, the element isn't

  // considered in DOM in some circumstances...

  // This isn't reproducible in IE10 compatibility mode of IE11

  if (isIE10$1()) {

    try {

      rect = element.getBoundingClientRect();

      var scrollTop = getScroll(element, 'top');

      var scrollLeft = getScroll(element, 'left');

      rect.top += scrollTop;

      rect.left += scrollLeft;

      rect.bottom += scrollTop;

      rect.right += scrollLeft;

    } catch (err) {}

  } else {

    rect = element.getBoundingClientRect();

  }



  var result = {

    left: rect.left,

    top: rect.top,

    width: rect.right - rect.left,

    height: rect.bottom - rect.top

  };



  // subtract scrollbar size from sizes

  var sizes = element.nodeName === 'HTML' ? getWindowSizes() : {};

  var width = sizes.width || element.clientWidth || result.right - result.left;

  var height = sizes.height || element.clientHeight || result.bottom - result.top;



  var horizScrollbar = element.offsetWidth - width;

  var vertScrollbar = element.offsetHeight - height;



  // if an hypothetical scrollbar is detected, we must be sure it's not a `border`

  // we make this check conditional for performance reasons

  if (horizScrollbar || vertScrollbar) {

    var styles = getStyleComputedProperty(element);

    horizScrollbar -= getBordersSize(styles, 'x');

    vertScrollbar -= getBordersSize(styles, 'y');



    result.width -= horizScrollbar;

    result.height -= vertScrollbar;

  }



  return getClientRect(result);

}



function getOffsetRectRelativeToArbitraryNode(children, parent) {

  var isIE10 = isIE10$1();

  var isHTML = parent.nodeName === 'HTML';

  var childrenRect = getBoundingClientRect(children);

  var parentRect = getBoundingClientRect(parent);

  var scrollParent = getScrollParent(children);



  var styles = getStyleComputedProperty(parent);

  var borderTopWidth = parseFloat(styles.borderTopWidth, 10);

  var borderLeftWidth = parseFloat(styles.borderLeftWidth, 10);



  var offsets = getClientRect({

    top: childrenRect.top - parentRect.top - borderTopWidth,

    left: childrenRect.left - parentRect.left - borderLeftWidth,

    width: childrenRect.width,

    height: childrenRect.height

  });

  offsets.marginTop = 0;

  offsets.marginLeft = 0;



  // Subtract margins of documentElement in case it's being used as parent

  // we do this only on HTML because it's the only element that behaves

  // differently when margins are applied to it. The margins are included in

  // the box of the documentElement, in the other cases not.

  if (!isIE10 && isHTML) {

    var marginTop = parseFloat(styles.marginTop, 10);

    var marginLeft = parseFloat(styles.marginLeft, 10);



    offsets.top -= borderTopWidth - marginTop;

    offsets.bottom -= borderTopWidth - marginTop;

    offsets.left -= borderLeftWidth - marginLeft;

    offsets.right -= borderLeftWidth - marginLeft;



    // Attach marginTop and marginLeft because in some circumstances we may need them

    offsets.marginTop = marginTop;

    offsets.marginLeft = marginLeft;

  }



  if (isIE10 ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') {

    offsets = includeScroll(offsets, parent);

  }



  return offsets;

}



function getViewportOffsetRectRelativeToArtbitraryNode(element) {

  var html = element.ownerDocument.documentElement;

  var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html);

  var width = Math.max(html.clientWidth, window.innerWidth || 0);

  var height = Math.max(html.clientHeight, window.innerHeight || 0);



  var scrollTop = getScroll(html);

  var scrollLeft = getScroll(html, 'left');



  var offset = {

    top: scrollTop - relativeOffset.top + relativeOffset.marginTop,

    left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft,

    width: width,

    height: height

  };



  return getClientRect(offset);

}



/**

 * Check if the given element is fixed or is inside a fixed parent

 * @method

 * @memberof Popper.Utils

 * @argument {Element} element

 * @argument {Element} customContainer

 * @returns {Boolean} answer to "isFixed?"

 */

function isFixed(element) {

  var nodeName = element.nodeName;

  if (nodeName === 'BODY' || nodeName === 'HTML') {

    return false;

  }

  if (getStyleComputedProperty(element, 'position') === 'fixed') {

    return true;

  }

  return isFixed(getParentNode(element));

}



/**

 * Computed the boundaries limits and return them

 * @method

 * @memberof Popper.Utils

 * @param {HTMLElement} popper

 * @param {HTMLElement} reference

 * @param {number} padding

 * @param {HTMLElement} boundariesElement - Element used to define the boundaries

 * @returns {Object} Coordinates of the boundaries

 */

function getBoundaries(popper, reference, padding, boundariesElement) {

  // NOTE: 1 DOM access here

  var boundaries = { top: 0, left: 0 };

  var offsetParent = findCommonOffsetParent(popper, reference);



  // Handle viewport case

  if (boundariesElement === 'viewport') {

    boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent);

  } else {

    // Handle other cases based on DOM element used as boundaries

    var boundariesNode = void 0;

    if (boundariesElement === 'scrollParent') {

      boundariesNode = getScrollParent(getParentNode(reference));

      if (boundariesNode.nodeName === 'BODY') {

        boundariesNode = popper.ownerDocument.documentElement;

      }

    } else if (boundariesElement === 'window') {

      boundariesNode = popper.ownerDocument.documentElement;

    } else {

      boundariesNode = boundariesElement;

    }



    var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent);



    // In case of HTML, we need a different computation

    if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) {

      var _getWindowSizes = getWindowSizes(),

          height = _getWindowSizes.height,

          width = _getWindowSizes.width;



      boundaries.top += offsets.top - offsets.marginTop;

      boundaries.bottom = height + offsets.top;

      boundaries.left += offsets.left - offsets.marginLeft;

      boundaries.right = width + offsets.left;

    } else {

      // for all the other DOM elements, this one is good

      boundaries = offsets;

    }

  }



  // Add paddings

  boundaries.left += padding;

  boundaries.top += padding;

  boundaries.right -= padding;

  boundaries.bottom -= padding;



  return boundaries;

}



function getArea(_ref) {

  var width = _ref.width,

      height = _ref.height;



  return width * height;

}



/**

 * Utility used to transform the `auto` placement to the placement with more

 * available space.

 * @method

 * @memberof Popper.Utils

 * @argument {Object} data - The data object generated by update method

 * @argument {Object} options - Modifiers configuration and options

 * @returns {Object} The data object, properly modified

 */

function computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) {

  var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;



  if (placement.indexOf('auto') === -1) {

    return placement;

  }



  var boundaries = getBoundaries(popper, reference, padding, boundariesElement);



  var rects = {

    top: {

      width: boundaries.width,

      height: refRect.top - boundaries.top

    },

    right: {

      width: boundaries.right - refRect.right,

      height: boundaries.height

    },

    bottom: {

      width: boundaries.width,

      height: boundaries.bottom - refRect.bottom

    },

    left: {

      width: refRect.left - boundaries.left,

      height: boundaries.height

    }

  };



  var sortedAreas = Object.keys(rects).map(function (key) {

    return _extends({

      key: key

    }, rects[key], {

      area: getArea(rects[key])

    });

  }).sort(function (a, b) {

    return b.area - a.area;

  });



  var filteredAreas = sortedAreas.filter(function (_ref2) {

    var width = _ref2.width,

        height = _ref2.height;

    return width >= popper.clientWidth && height >= popper.clientHeight;

  });



  var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key;



  var variation = placement.split('-')[1];



  return computedPlacement + (variation ? '-' + variation : '');

}



/**

 * Get offsets to the reference element

 * @method

 * @memberof Popper.Utils

 * @param {Object} state

 * @param {Element} popper - the popper element

 * @param {Element} reference - the reference element (the popper will be relative to this)

 * @returns {Object} An object containing the offsets which will be applied to the popper

 */

function getReferenceOffsets(state, popper, reference) {

  var commonOffsetParent = findCommonOffsetParent(popper, reference);

  return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent);

}



/**

 * Get the outer sizes of the given element (offset size + margins)

 * @method

 * @memberof Popper.Utils

 * @argument {Element} element

 * @returns {Object} object containing width and height properties

 */

function getOuterSizes(element) {

  var styles = getComputedStyle(element);

  var x = parseFloat(styles.marginTop) + parseFloat(styles.marginBottom);

  var y = parseFloat(styles.marginLeft) + parseFloat(styles.marginRight);

  var result = {

    width: element.offsetWidth + y,

    height: element.offsetHeight + x

  };

  return result;

}



/**

 * Get the opposite placement of the given one

 * @method

 * @memberof Popper.Utils

 * @argument {String} placement

 * @returns {String} flipped placement

 */

function getOppositePlacement(placement) {

  var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' };

  return placement.replace(/left|right|bottom|top/g, function (matched) {

    return hash[matched];

  });

}



/**

 * Get offsets to the popper

 * @method

 * @memberof Popper.Utils

 * @param {Object} position - CSS position the Popper will get applied

 * @param {HTMLElement} popper - the popper element

 * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this)

 * @param {String} placement - one of the valid placement options

 * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper

 */

function getPopperOffsets(popper, referenceOffsets, placement) {

  placement = placement.split('-')[0];



  // Get popper node sizes

  var popperRect = getOuterSizes(popper);



  // Add position, width and height to our offsets object

  var popperOffsets = {

    width: popperRect.width,

    height: popperRect.height

  };



  // depending by the popper placement we have to compute its offsets slightly differently

  var isHoriz = ['right', 'left'].indexOf(placement) !== -1;

  var mainSide = isHoriz ? 'top' : 'left';

  var secondarySide = isHoriz ? 'left' : 'top';

  var measurement = isHoriz ? 'height' : 'width';

  var secondaryMeasurement = !isHoriz ? 'height' : 'width';



  popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2;

  if (placement === secondarySide) {

    popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement];

  } else {

    popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)];

  }



  return popperOffsets;

}



/**

 * Mimics the `find` method of Array

 * @method

 * @memberof Popper.Utils

 * @argument {Array} arr

 * @argument prop

 * @argument value

 * @returns index or -1

 */

function find(arr, check) {

  // use native find if supported

  if (Array.prototype.find) {

    return arr.find(check);

  }



  // use `filter` to obtain the same behavior of `find`

  return arr.filter(check)[0];

}



/**

 * Return the index of the matching object

 * @method

 * @memberof Popper.Utils

 * @argument {Array} arr

 * @argument prop

 * @argument value

 * @returns index or -1

 */

function findIndex(arr, prop, value) {

  // use native findIndex if supported

  if (Array.prototype.findIndex) {

    return arr.findIndex(function (cur) {

      return cur[prop] === value;

    });

  }



  // use `find` + `indexOf` if `findIndex` isn't supported

  var match = find(arr, function (obj) {

    return obj[prop] === value;

  });

  return arr.indexOf(match);

}



/**

 * Loop trough the list of modifiers and run them in order,

 * each of them will then edit the data object.

 * @method

 * @memberof Popper.Utils

 * @param {dataObject} data

 * @param {Array} modifiers

 * @param {String} ends - Optional modifier name used as stopper

 * @returns {dataObject}

 */

function runModifiers(modifiers, data, ends) {

  var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends));



  modifiersToRun.forEach(function (modifier) {

    if (modifier['function']) {

      // eslint-disable-line dot-notation

      console.warn('`modifier.function` is deprecated, use `modifier.fn`!');

    }

    var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation

    if (modifier.enabled && isFunction(fn)) {

      // Add properties to offsets to make them a complete clientRect object

      // we do this before each modifier to make sure the previous one doesn't

      // mess with these values

      data.offsets.popper = getClientRect(data.offsets.popper);

      data.offsets.reference = getClientRect(data.offsets.reference);



      data = fn(data, modifier);

    }

  });



  return data;

}



/**

 * Updates the position of the popper, computing the new offsets and applying

 * the new style.<br />

 * Prefer `scheduleUpdate` over `update` because of performance reasons.

 * @method

 * @memberof Popper

 */

function update() {

  // if popper is destroyed, don't perform any further update

  if (this.state.isDestroyed) {

    return;

  }



  var data = {

    instance: this,

    styles: {},

    arrowStyles: {},

    attributes: {},

    flipped: false,

    offsets: {}

  };



  // compute reference element offsets

  data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference);



  // compute auto placement, store placement inside the data object,

  // modifiers will be able to edit `placement` if needed

  // and refer to originalPlacement to know the original value

  data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding);



  // store the computed placement inside `originalPlacement`

  data.originalPlacement = data.placement;



  // compute the popper offsets

  data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement);

  data.offsets.popper.position = 'absolute';



  // run the modifiers

  data = runModifiers(this.modifiers, data);



  // the first `update` will call `onCreate` callback

  // the other ones will call `onUpdate` callback

  if (!this.state.isCreated) {

    this.state.isCreated = true;

    this.options.onCreate(data);

  } else {

    this.options.onUpdate(data);

  }

}



/**

 * Helper used to know if the given modifier is enabled.

 * @method

 * @memberof Popper.Utils

 * @returns {Boolean}

 */

function isModifierEnabled(modifiers, modifierName) {

  return modifiers.some(function (_ref) {

    var name = _ref.name,

        enabled = _ref.enabled;

    return enabled && name === modifierName;

  });

}



/**

 * Get the prefixed supported property name

 * @method

 * @memberof Popper.Utils

 * @argument {String} property (camelCase)

 * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix)

 */

function getSupportedPropertyName(property) {

  var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O'];

  var upperProp = property.charAt(0).toUpperCase() + property.slice(1);



  for (var i = 0; i < prefixes.length - 1; i++) {

    var prefix = prefixes[i];

    var toCheck = prefix ? '' + prefix + upperProp : property;

    if (typeof document.body.style[toCheck] !== 'undefined') {

      return toCheck;

    }

  }

  return null;

}



/**

 * Destroy the popper

 * @method

 * @memberof Popper

 */

function destroy() {

  this.state.isDestroyed = true;



  // touch DOM only if `applyStyle` modifier is enabled

  if (isModifierEnabled(this.modifiers, 'applyStyle')) {

    this.popper.removeAttribute('x-placement');

    this.popper.style.left = '';

    this.popper.style.position = '';

    this.popper.style.top = '';

    this.popper.style[getSupportedPropertyName('transform')] = '';

  }



  this.disableEventListeners();



  // remove the popper if user explicity asked for the deletion on destroy

  // do not use `remove` because IE11 doesn't support it

  if (this.options.removeOnDestroy) {

    this.popper.parentNode.removeChild(this.popper);

  }

  return this;

}



/**

 * Get the window associated with the element

 * @argument {Element} element

 * @returns {Window}

 */

function getWindow(element) {

  var ownerDocument = element.ownerDocument;

  return ownerDocument ? ownerDocument.defaultView : window;

}



function attachToScrollParents(scrollParent, event, callback, scrollParents) {

  var isBody = scrollParent.nodeName === 'BODY';

  var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent;

  target.addEventListener(event, callback, { passive: true });



  if (!isBody) {

    attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents);

  }

  scrollParents.push(target);

}



/**

 * Setup needed event listeners used to update the popper position

 * @method

 * @memberof Popper.Utils

 * @private

 */

function setupEventListeners(reference, options, state, updateBound) {

  // Resize event listener on window

  state.updateBound = updateBound;

  getWindow(reference).addEventListener('resize', state.updateBound, { passive: true });



  // Scroll event listener on scroll parents

  var scrollElement = getScrollParent(reference);

  attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents);

  state.scrollElement = scrollElement;

  state.eventsEnabled = true;



  return state;

}



/**

 * It will add resize/scroll events and start recalculating

 * position of the popper element when they are triggered.

 * @method

 * @memberof Popper

 */

function enableEventListeners() {

  if (!this.state.eventsEnabled) {

    this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate);

  }

}



/**

 * Remove event listeners used to update the popper position

 * @method

 * @memberof Popper.Utils

 * @private

 */

function removeEventListeners(reference, state) {

  // Remove resize event listener on window

  getWindow(reference).removeEventListener('resize', state.updateBound);



  // Remove scroll event listener on scroll parents

  state.scrollParents.forEach(function (target) {

    target.removeEventListener('scroll', state.updateBound);

  });



  // Reset state

  state.updateBound = null;

  state.scrollParents = [];

  state.scrollElement = null;

  state.eventsEnabled = false;

  return state;

}



/**

 * It will remove resize/scroll events and won't recalculate popper position

 * when they are triggered. It also won't trigger onUpdate callback anymore,

 * unless you call `update` method manually.

 * @method

 * @memberof Popper

 */

function disableEventListeners() {

  if (this.state.eventsEnabled) {

    cancelAnimationFrame(this.scheduleUpdate);

    this.state = removeEventListeners(this.reference, this.state);

  }

}



/**

 * Tells if a given input is a number

 * @method

 * @memberof Popper.Utils

 * @param {*} input to check

 * @return {Boolean}

 */

function isNumeric(n) {

  return n !== '' && !isNaN(parseFloat(n)) && isFinite(n);

}



/**

 * Set the style to the given popper

 * @method

 * @memberof Popper.Utils

 * @argument {Element} element - Element to apply the style to

 * @argument {Object} styles

 * Object with a list of properties and values which will be applied to the element

 */

function setStyles(element, styles) {

  Object.keys(styles).forEach(function (prop) {

    var unit = '';

    // add unit if the value is numeric and is one of the following

    if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) {

      unit = 'px';

    }

    element.style[prop] = styles[prop] + unit;

  });

}



/**

 * Set the attributes to the given popper

 * @method

 * @memberof Popper.Utils

 * @argument {Element} element - Element to apply the attributes to

 * @argument {Object} styles

 * Object with a list of properties and values which will be applied to the element

 */

function setAttributes(element, attributes) {

  Object.keys(attributes).forEach(function (prop) {

    var value = attributes[prop];

    if (value !== false) {

      element.setAttribute(prop, attributes[prop]);

    } else {

      element.removeAttribute(prop);

    }

  });

}



/**

 * @function

 * @memberof Modifiers

 * @argument {Object} data - The data object generated by `update` method

 * @argument {Object} data.styles - List of style properties - values to apply to popper element

 * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element

 * @argument {Object} options - Modifiers configuration and options

 * @returns {Object} The same data object

 */

function applyStyle(data) {

  // any property present in `data.styles` will be applied to the popper,

  // in this way we can make the 3rd party modifiers add custom styles to it

  // Be aware, modifiers could override the properties defined in the previous

  // lines of this modifier!

  setStyles(data.instance.popper, data.styles);



  // any property present in `data.attributes` will be applied to the popper,

  // they will be set as HTML attributes of the element

  setAttributes(data.instance.popper, data.attributes);



  // if arrowElement is defined and arrowStyles has some properties

  if (data.arrowElement && Object.keys(data.arrowStyles).length) {

    setStyles(data.arrowElement, data.arrowStyles);

  }



  return data;

}



/**

 * Set the x-placement attribute before everything else because it could be used

 * to add margins to the popper margins needs to be calculated to get the

 * correct popper offsets.

 * @method

 * @memberof Popper.modifiers

 * @param {HTMLElement} reference - The reference element used to position the popper

 * @param {HTMLElement} popper - The HTML element used as popper.

 * @param {Object} options - Popper.js options

 */

function applyStyleOnLoad(reference, popper, options, modifierOptions, state) {

  // compute reference element offsets

  var referenceOffsets = getReferenceOffsets(state, popper, reference);



  // compute auto placement, store placement inside the data object,

  // modifiers will be able to edit `placement` if needed

  // and refer to originalPlacement to know the original value

  var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding);



  popper.setAttribute('x-placement', placement);



  // Apply `position` to popper before anything else because

  // without the position applied we can't guarantee correct computations

  setStyles(popper, { position: 'absolute' });



  return options;

}



/**

 * @function

 * @memberof Modifiers

 * @argument {Object} data - The data object generated by `update` method

 * @argument {Object} options - Modifiers configuration and options

 * @returns {Object} The data object, properly modified

 */

function computeStyle(data, options) {

  var x = options.x,

      y = options.y;

  var popper = data.offsets.popper;



  // Remove this legacy support in Popper.js v2



  var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) {

    return modifier.name === 'applyStyle';

  }).gpuAcceleration;

  if (legacyGpuAccelerationOption !== undefined) {

    console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');

  }

  var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration;



  var offsetParent = getOffsetParent(data.instance.popper);

  var offsetParentRect = getBoundingClientRect(offsetParent);



  // Styles

  var styles = {

    position: popper.position

  };



  // floor sides to avoid blurry text

  var offsets = {

    left: Math.floor(popper.left),

    top: Math.floor(popper.top),

    bottom: Math.floor(popper.bottom),

    right: Math.floor(popper.right)

  };



  var sideA = x === 'bottom' ? 'top' : 'bottom';

  var sideB = y === 'right' ? 'left' : 'right';



  // if gpuAcceleration is set to `true` and transform is supported,

  //  we use `translate3d` to apply the position to the popper we

  // automatically use the supported prefixed version if needed

  var prefixedProperty = getSupportedPropertyName('transform');



  // now, let's make a step back and look at this code closely (wtf?)

  // If the content of the popper grows once it's been positioned, it

  // may happen that the popper gets misplaced because of the new content

  // overflowing its reference element

  // To avoid this problem, we provide two options (x and y), which allow

  // the consumer to define the offset origin.

  // If we position a popper on top of a reference element, we can set

  // `x` to `top` to make the popper grow towards its top instead of

  // its bottom.

  var left = void 0,

      top = void 0;

  if (sideA === 'bottom') {

    top = -offsetParentRect.height + offsets.bottom;

  } else {

    top = offsets.top;

  }

  if (sideB === 'right') {

    left = -offsetParentRect.width + offsets.right;

  } else {

    left = offsets.left;

  }

  if (gpuAcceleration && prefixedProperty) {

    styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)';

    styles[sideA] = 0;

    styles[sideB] = 0;

    styles.willChange = 'transform';

  } else {

    // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties

    var invertTop = sideA === 'bottom' ? -1 : 1;

    var invertLeft = sideB === 'right' ? -1 : 1;

    styles[sideA] = top * invertTop;

    styles[sideB] = left * invertLeft;

    styles.willChange = sideA + ', ' + sideB;

  }



  // Attributes

  var attributes = {

    'x-placement': data.placement

  };



  // Update `data` attributes, styles and arrowStyles

  data.attributes = _extends({}, attributes, data.attributes);

  data.styles = _extends({}, styles, data.styles);

  data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles);



  return data;

}



/**

 * Helper used to know if the given modifier depends from another one.<br />

 * It checks if the needed modifier is listed and enabled.

 * @method

 * @memberof Popper.Utils

 * @param {Array} modifiers - list of modifiers

 * @param {String} requestingName - name of requesting modifier

 * @param {String} requestedName - name of requested modifier

 * @returns {Boolean}

 */

function isModifierRequired(modifiers, requestingName, requestedName) {

  var requesting = find(modifiers, function (_ref) {

    var name = _ref.name;

    return name === requestingName;

  });



  var isRequired = !!requesting && modifiers.some(function (modifier) {

    return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order;

  });



  if (!isRequired) {

    var _requesting = '`' + requestingName + '`';

    var requested = '`' + requestedName + '`';

    console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!');

  }

  return isRequired;

}



/**

 * @function

 * @memberof Modifiers

 * @argument {Object} data - The data object generated by update method

 * @argument {Object} options - Modifiers configuration and options

 * @returns {Object} The data object, properly modified

 */

function arrow(data, options) {

  var _data$offsets$arrow;



  // arrow depends on keepTogether in order to work

  if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) {

    return data;

  }



  var arrowElement = options.element;



  // if arrowElement is a string, suppose it's a CSS selector

  if (typeof arrowElement === 'string') {

    arrowElement = data.instance.popper.querySelector(arrowElement);



    // if arrowElement is not found, don't run the modifier

    if (!arrowElement) {

      return data;

    }

  } else {

    // if the arrowElement isn't a query selector we must check that the

    // provided DOM node is child of its popper node

    if (!data.instance.popper.contains(arrowElement)) {

      console.warn('WARNING: `arrow.element` must be child of its popper element!');

      return data;

    }

  }



  var placement = data.placement.split('-')[0];

  var _data$offsets = data.offsets,

      popper = _data$offsets.popper,

      reference = _data$offsets.reference;



  var isVertical = ['left', 'right'].indexOf(placement) !== -1;



  var len = isVertical ? 'height' : 'width';

  var sideCapitalized = isVertical ? 'Top' : 'Left';

  var side = sideCapitalized.toLowerCase();

  var altSide = isVertical ? 'left' : 'top';

  var opSide = isVertical ? 'bottom' : 'right';

  var arrowElementSize = getOuterSizes(arrowElement)[len];



  //

  // extends keepTogether behavior making sure the popper and its

  // reference have enough pixels in conjuction

  //



  // top/left side

  if (reference[opSide] - arrowElementSize < popper[side]) {

    data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize);

  }

  // bottom/right side

  if (reference[side] + arrowElementSize > popper[opSide]) {

    data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide];

  }

  data.offsets.popper = getClientRect(data.offsets.popper);



  // compute center of the popper

  var center = reference[side] + reference[len] / 2 - arrowElementSize / 2;



  // Compute the sideValue using the updated popper offsets

  // take popper margin in account because we don't have this info available

  var css = getStyleComputedProperty(data.instance.popper);

  var popperMarginSide = parseFloat(css['margin' + sideCapitalized], 10);

  var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width'], 10);

  var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide;



  // prevent arrowElement from being placed not contiguously to its popper

  sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0);



  data.arrowElement = arrowElement;

  data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow);



  return data;

}



/**

 * Get the opposite placement variation of the given one

 * @method

 * @memberof Popper.Utils

 * @argument {String} placement variation

 * @returns {String} flipped placement variation

 */

function getOppositeVariation(variation) {

  if (variation === 'end') {

    return 'start';

  } else if (variation === 'start') {

    return 'end';

  }

  return variation;

}



/**

 * List of accepted placements to use as values of the `placement` option.<br />

 * Valid placements are:

 * - `auto`

 * - `top`

 * - `right`

 * - `bottom`

 * - `left`

 *

 * Each placement can have a variation from this list:

 * - `-start`

 * - `-end`

 *

 * Variations are interpreted easily if you think of them as the left to right

 * written languages. Horizontally (`top` and `bottom`), `start` is left and `end`

 * is right.<br />

 * Vertically (`left` and `right`), `start` is top and `end` is bottom.

 *

 * Some valid examples are:

 * - `top-end` (on top of reference, right aligned)

 * - `right-start` (on right of reference, top aligned)

 * - `bottom` (on bottom, centered)

 * - `auto-right` (on the side with more space available, alignment depends by placement)

 *

 * @static

 * @type {Array}

 * @enum {String}

 * @readonly

 * @method placements

 * @memberof Popper

 */

var placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start'];



// Get rid of `auto` `auto-start` and `auto-end`

var validPlacements = placements.slice(3);



/**

 * Given an initial placement, returns all the subsequent placements

 * clockwise (or counter-clockwise).

 *

 * @method

 * @memberof Popper.Utils

 * @argument {String} placement - A valid placement (it accepts variations)

 * @argument {Boolean} counter - Set to true to walk the placements counterclockwise

 * @returns {Array} placements including their variations

 */

function clockwise(placement) {

  var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;



  var index = validPlacements.indexOf(placement);

  var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index));

  return counter ? arr.reverse() : arr;

}



var BEHAVIORS = {

  FLIP: 'flip',

  CLOCKWISE: 'clockwise',

  COUNTERCLOCKWISE: 'counterclockwise'

};



/**

 * @function

 * @memberof Modifiers

 * @argument {Object} data - The data object generated by update method

 * @argument {Object} options - Modifiers configuration and options

 * @returns {Object} The data object, properly modified

 */

function flip(data, options) {

  // if `inner` modifier is enabled, we can't use the `flip` modifier

  if (isModifierEnabled(data.instance.modifiers, 'inner')) {

    return data;

  }



  if (data.flipped && data.placement === data.originalPlacement) {

    // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides

    return data;

  }



  var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement);



  var placement = data.placement.split('-')[0];

  var placementOpposite = getOppositePlacement(placement);

  var variation = data.placement.split('-')[1] || '';



  var flipOrder = [];



  switch (options.behavior) {

    case BEHAVIORS.FLIP:

      flipOrder = [placement, placementOpposite];

      break;

    case BEHAVIORS.CLOCKWISE:

      flipOrder = clockwise(placement);

      break;

    case BEHAVIORS.COUNTERCLOCKWISE:

      flipOrder = clockwise(placement, true);

      break;

    default:

      flipOrder = options.behavior;

  }



  flipOrder.forEach(function (step, index) {

    if (placement !== step || flipOrder.length === index + 1) {

      return data;

    }



    placement = data.placement.split('-')[0];

    placementOpposite = getOppositePlacement(placement);



    var popperOffsets = data.offsets.popper;

    var refOffsets = data.offsets.reference;



    // using floor because the reference offsets may contain decimals we are not going to consider here

    var floor = Math.floor;

    var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom);



    var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left);

    var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right);

    var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top);

    var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom);



    var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom;



    // flip the variation if required

    var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;

    var flippedVariation = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom);



    if (overlapsRef || overflowsBoundaries || flippedVariation) {

      // this boolean to detect any flip loop

      data.flipped = true;



      if (overlapsRef || overflowsBoundaries) {

        placement = flipOrder[index + 1];

      }



      if (flippedVariation) {

        variation = getOppositeVariation(variation);

      }



      data.placement = placement + (variation ? '-' + variation : '');



      // this object contains `position`, we want to preserve it along with

      // any additional property we may add in the future

      data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement));



      data = runModifiers(data.instance.modifiers, data, 'flip');

    }

  });

  return data;

}



/**

 * @function

 * @memberof Modifiers

 * @argument {Object} data - The data object generated by update method

 * @argument {Object} options - Modifiers configuration and options

 * @returns {Object} The data object, properly modified

 */

function keepTogether(data) {

  var _data$offsets = data.offsets,

      popper = _data$offsets.popper,

      reference = _data$offsets.reference;



  var placement = data.placement.split('-')[0];

  var floor = Math.floor;

  var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;

  var side = isVertical ? 'right' : 'bottom';

  var opSide = isVertical ? 'left' : 'top';

  var measurement = isVertical ? 'width' : 'height';



  if (popper[side] < floor(reference[opSide])) {

    data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement];

  }

  if (popper[opSide] > floor(reference[side])) {

    data.offsets.popper[opSide] = floor(reference[side]);

  }



  return data;

}



/**

 * Converts a string containing value + unit into a px value number

 * @function

 * @memberof {modifiers~offset}

 * @private

 * @argument {String} str - Value + unit string

 * @argument {String} measurement - `height` or `width`

 * @argument {Object} popperOffsets

 * @argument {Object} referenceOffsets

 * @returns {Number|String}

 * Value in pixels, or original string if no values were extracted

 */

function toValue(str, measurement, popperOffsets, referenceOffsets) {

  // separate value from unit

  var split = str.match(/((?:\-|\+)?\d*\.?\d*)(.*)/);

  var value = +split[1];

  var unit = split[2];



  // If it's not a number it's an operator, I guess

  if (!value) {

    return str;

  }



  if (unit.indexOf('%') === 0) {

    var element = void 0;

    switch (unit) {

      case '%p':

        element = popperOffsets;

        break;

      case '%':

      case '%r':

      default:

        element = referenceOffsets;

    }



    var rect = getClientRect(element);

    return rect[measurement] / 100 * value;

  } else if (unit === 'vh' || unit === 'vw') {

    // if is a vh or vw, we calculate the size based on the viewport

    var size = void 0;

    if (unit === 'vh') {

      size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);

    } else {

      size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);

    }

    return size / 100 * value;

  } else {

    // if is an explicit pixel unit, we get rid of the unit and keep the value

    // if is an implicit unit, it's px, and we return just the value

    return value;

  }

}



/**

 * Parse an `offset` string to extrapolate `x` and `y` numeric offsets.

 * @function

 * @memberof {modifiers~offset}

 * @private

 * @argument {String} offset

 * @argument {Object} popperOffsets

 * @argument {Object} referenceOffsets

 * @argument {String} basePlacement

 * @returns {Array} a two cells array with x and y offsets in numbers

 */

function parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) {

  var offsets = [0, 0];



  // Use height if placement is left or right and index is 0 otherwise use width

  // in this way the first offset will use an axis and the second one

  // will use the other one

  var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1;



  // Split the offset string to obtain a list of values and operands

  // The regex addresses values with the plus or minus sign in front (+10, -20, etc)

  var fragments = offset.split(/(\+|\-)/).map(function (frag) {

    return frag.trim();

  });



  // Detect if the offset string contains a pair of values or a single one

  // they could be separated by comma or space

  var divider = fragments.indexOf(find(fragments, function (frag) {

    return frag.search(/,|\s/) !== -1;

  }));



  if (fragments[divider] && fragments[divider].indexOf(',') === -1) {

    console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');

  }



  // If divider is found, we divide the list of values and operands to divide

  // them by ofset X and Y.

  var splitRegex = /\s*,\s*|\s+/;

  var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), [fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments];



  // Convert the values with units to absolute pixels to allow our computations

  ops = ops.map(function (op, index) {

    // Most of the units rely on the orientation of the popper

    var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width';

    var mergeWithPrevious = false;

    return op

    // This aggregates any `+` or `-` sign that aren't considered operators

    // e.g.: 10 + +5 => [10, +, +5]

    .reduce(function (a, b) {

      if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) {

        a[a.length - 1] = b;

        mergeWithPrevious = true;

        return a;

      } else if (mergeWithPrevious) {

        a[a.length - 1] += b;

        mergeWithPrevious = false;

        return a;

      } else {

        return a.concat(b);

      }

    }, [])

    // Here we convert the string values into number values (in px)

    .map(function (str) {

      return toValue(str, measurement, popperOffsets, referenceOffsets);

    });

  });



  // Loop trough the offsets arrays and execute the operations

  ops.forEach(function (op, index) {

    op.forEach(function (frag, index2) {

      if (isNumeric(frag)) {

        offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1);

      }

    });

  });

  return offsets;

}



/**

 * @function

 * @memberof Modifiers

 * @argument {Object} data - The data object generated by update method

 * @argument {Object} options - Modifiers configuration and options

 * @argument {Number|String} options.offset=0

 * The offset value as described in the modifier description

 * @returns {Object} The data object, properly modified

 */

function offset(data, _ref) {

  var offset = _ref.offset;

  var placement = data.placement,

      _data$offsets = data.offsets,

      popper = _data$offsets.popper,

      reference = _data$offsets.reference;



  var basePlacement = placement.split('-')[0];



  var offsets = void 0;

  if (isNumeric(+offset)) {

    offsets = [+offset, 0];

  } else {

    offsets = parseOffset(offset, popper, reference, basePlacement);

  }



  if (basePlacement === 'left') {

    popper.top += offsets[0];

    popper.left -= offsets[1];

  } else if (basePlacement === 'right') {

    popper.top += offsets[0];

    popper.left += offsets[1];

  } else if (basePlacement === 'top') {

    popper.left += offsets[0];

    popper.top -= offsets[1];

  } else if (basePlacement === 'bottom') {

    popper.left += offsets[0];

    popper.top += offsets[1];

  }



  data.popper = popper;

  return data;

}



/**

 * @function

 * @memberof Modifiers

 * @argument {Object} data - The data object generated by `update` method

 * @argument {Object} options - Modifiers configuration and options

 * @returns {Object} The data object, properly modified

 */

function preventOverflow(data, options) {

  var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper);



  // If offsetParent is the reference element, we really want to

  // go one step up and use the next offsetParent as reference to

  // avoid to make this modifier completely useless and look like broken

  if (data.instance.reference === boundariesElement) {

    boundariesElement = getOffsetParent(boundariesElement);

  }



  var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement);

  options.boundaries = boundaries;



  var order = options.priority;

  var popper = data.offsets.popper;



  var check = {

    primary: function primary(placement) {

      var value = popper[placement];

      if (popper[placement] < boundaries[placement] && !options.escapeWithReference) {

        value = Math.max(popper[placement], boundaries[placement]);

      }

      return defineProperty({}, placement, value);

    },

    secondary: function secondary(placement) {

      var mainSide = placement === 'right' ? 'left' : 'top';

      var value = popper[mainSide];

      if (popper[placement] > boundaries[placement] && !options.escapeWithReference) {

        value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height));

      }

      return defineProperty({}, mainSide, value);

    }

  };



  order.forEach(function (placement) {

    var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary';

    popper = _extends({}, popper, check[side](placement));

  });



  data.offsets.popper = popper;



  return data;

}



/**

 * @function

 * @memberof Modifiers

 * @argument {Object} data - The data object generated by `update` method

 * @argument {Object} options - Modifiers configuration and options

 * @returns {Object} The data object, properly modified

 */

function shift(data) {

  var placement = data.placement;

  var basePlacement = placement.split('-')[0];

  var shiftvariation = placement.split('-')[1];



  // if shift shiftvariation is specified, run the modifier

  if (shiftvariation) {

    var _data$offsets = data.offsets,

        reference = _data$offsets.reference,

        popper = _data$offsets.popper;



    var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1;

    var side = isVertical ? 'left' : 'top';

    var measurement = isVertical ? 'width' : 'height';



    var shiftOffsets = {

      start: defineProperty({}, side, reference[side]),

      end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement])

    };



    data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]);

  }



  return data;

}



/**

 * @function

 * @memberof Modifiers

 * @argument {Object} data - The data object generated by update method

 * @argument {Object} options - Modifiers configuration and options

 * @returns {Object} The data object, properly modified

 */

function hide(data) {

  if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) {

    return data;

  }



  var refRect = data.offsets.reference;

  var bound = find(data.instance.modifiers, function (modifier) {

    return modifier.name === 'preventOverflow';

  }).boundaries;



  if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) {

    // Avoid unnecessary DOM access if visibility hasn't changed

    if (data.hide === true) {

      return data;

    }



    data.hide = true;

    data.attributes['x-out-of-boundaries'] = '';

  } else {

    // Avoid unnecessary DOM access if visibility hasn't changed

    if (data.hide === false) {

      return data;

    }



    data.hide = false;

    data.attributes['x-out-of-boundaries'] = false;

  }



  return data;

}



/**

 * @function

 * @memberof Modifiers

 * @argument {Object} data - The data object generated by `update` method

 * @argument {Object} options - Modifiers configuration and options

 * @returns {Object} The data object, properly modified

 */

function inner(data) {

  var placement = data.placement;

  var basePlacement = placement.split('-')[0];

  var _data$offsets = data.offsets,

      popper = _data$offsets.popper,

      reference = _data$offsets.reference;



  var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1;



  var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1;



  popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0);



  data.placement = getOppositePlacement(placement);

  data.offsets.popper = getClientRect(popper);



  return data;

}



/**

 * Modifier function, each modifier can have a function of this type assigned

 * to its `fn` property.<br />

 * These functions will be called on each update, this means that you must

 * make sure they are performant enough to avoid performance bottlenecks.

 *

 * @function ModifierFn

 * @argument {dataObject} data - The data object generated by `update` method

 * @argument {Object} options - Modifiers configuration and options

 * @returns {dataObject} The data object, properly modified

 */



/**

 * Modifiers are plugins used to alter the behavior of your poppers.<br />

 * Popper.js uses a set of 9 modifiers to provide all the basic functionalities

 * needed by the library.

 *

 * Usually you don't want to override the `order`, `fn` and `onLoad` props.

 * All the other properties are configurations that could be tweaked.

 * @namespace modifiers

 */

var modifiers = {

  /**

   * Modifier used to shift the popper on the start or end of its reference

   * element.<br />

   * It will read the variation of the `placement` property.<br />

   * It can be one either `-end` or `-start`.

   * @memberof modifiers

   * @inner

   */

  shift: {

    /** @prop {number} order=100 - Index used to define the order of execution */

    order: 100,

    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */

    enabled: true,

    /** @prop {ModifierFn} */

    fn: shift

  },



  /**

   * The `offset` modifier can shift your popper on both its axis.

   *

   * It accepts the following units:

   * - `px` or unitless, interpreted as pixels

   * - `%` or `%r`, percentage relative to the length of the reference element

   * - `%p`, percentage relative to the length of the popper element

   * - `vw`, CSS viewport width unit

   * - `vh`, CSS viewport height unit

   *

   * For length is intended the main axis relative to the placement of the popper.<br />

   * This means that if the placement is `top` or `bottom`, the length will be the

   * `width`. In case of `left` or `right`, it will be the height.

   *

   * You can provide a single value (as `Number` or `String`), or a pair of values

   * as `String` divided by a comma or one (or more) white spaces.<br />

   * The latter is a deprecated method because it leads to confusion and will be

   * removed in v2.<br />

   * Additionally, it accepts additions and subtractions between different units.

   * Note that multiplications and divisions aren't supported.

   *

   * Valid examples are:

   * ```

   * 10

   * '10%'

   * '10, 10'

   * '10%, 10'

   * '10 + 10%'

   * '10 - 5vh + 3%'

   * '-10px + 5vh, 5px - 6%'

   * ```

   * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap

   * > with their reference element, unfortunately, you will have to disable the `flip` modifier.

   * > More on this [reading this issue](https://github.com/FezVrasta/popper.js/issues/373)

   *

   * @memberof modifiers

   * @inner

   */

  offset: {

    /** @prop {number} order=200 - Index used to define the order of execution */

    order: 200,

    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */

    enabled: true,

    /** @prop {ModifierFn} */

    fn: offset,

    /** @prop {Number|String} offset=0

     * The offset value as described in the modifier description

     */

    offset: 0

  },



  /**

   * Modifier used to prevent the popper from being positioned outside the boundary.

   *

   * An scenario exists where the reference itself is not within the boundaries.<br />

   * We can say it has "escaped the boundaries" — or just "escaped".<br />

   * In this case we need to decide whether the popper should either:

   *

   * - detach from the reference and remain "trapped" in the boundaries, or

   * - if it should ignore the boundary and "escape with its reference"

   *

   * When `escapeWithReference` is set to`true` and reference is completely

   * outside its boundaries, the popper will overflow (or completely leave)

   * the boundaries in order to remain attached to the edge of the reference.

   *

   * @memberof modifiers

   * @inner

   */

  preventOverflow: {

    /** @prop {number} order=300 - Index used to define the order of execution */

    order: 300,

    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */

    enabled: true,

    /** @prop {ModifierFn} */

    fn: preventOverflow,

    /**

     * @prop {Array} [priority=['left','right','top','bottom']]

     * Popper will try to prevent overflow following these priorities by default,

     * then, it could overflow on the left and on top of the `boundariesElement`

     */

    priority: ['left', 'right', 'top', 'bottom'],

    /**

     * @prop {number} padding=5

     * Amount of pixel used to define a minimum distance between the boundaries

     * and the popper this makes sure the popper has always a little padding

     * between the edges of its container

     */

    padding: 5,

    /**

     * @prop {String|HTMLElement} boundariesElement='scrollParent'

     * Boundaries used by the modifier, can be `scrollParent`, `window`,

     * `viewport` or any DOM element.

     */

    boundariesElement: 'scrollParent'

  },



  /**

   * Modifier used to make sure the reference and its popper stay near eachothers

   * without leaving any gap between the two. Expecially useful when the arrow is

   * enabled and you want to assure it to point to its reference element.

   * It cares only about the first axis, you can still have poppers with margin

   * between the popper and its reference element.

   * @memberof modifiers

   * @inner

   */

  keepTogether: {

    /** @prop {number} order=400 - Index used to define the order of execution */

    order: 400,

    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */

    enabled: true,

    /** @prop {ModifierFn} */

    fn: keepTogether

  },



  /**

   * This modifier is used to move the `arrowElement` of the popper to make

   * sure it is positioned between the reference element and its popper element.

   * It will read the outer size of the `arrowElement` node to detect how many

   * pixels of conjuction are needed.

   *

   * It has no effect if no `arrowElement` is provided.

   * @memberof modifiers

   * @inner

   */

  arrow: {

    /** @prop {number} order=500 - Index used to define the order of execution */

    order: 500,

    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */

    enabled: true,

    /** @prop {ModifierFn} */

    fn: arrow,

    /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */

    element: '[x-arrow]'

  },



  /**

   * Modifier used to flip the popper's placement when it starts to overlap its

   * reference element.

   *

   * Requires the `preventOverflow` modifier before it in order to work.

   *

   * **NOTE:** this modifier will interrupt the current update cycle and will

   * restart it if it detects the need to flip the placement.

   * @memberof modifiers

   * @inner

   */

  flip: {

    /** @prop {number} order=600 - Index used to define the order of execution */

    order: 600,

    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */

    enabled: true,

    /** @prop {ModifierFn} */

    fn: flip,

    /**

     * @prop {String|Array} behavior='flip'

     * The behavior used to change the popper's placement. It can be one of

     * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid

     * placements (with optional variations).

     */

    behavior: 'flip',

    /**

     * @prop {number} padding=5

     * The popper will flip if it hits the edges of the `boundariesElement`

     */

    padding: 5,

    /**

     * @prop {String|HTMLElement} boundariesElement='viewport'

     * The element which will define the boundaries of the popper position,

     * the popper will never be placed outside of the defined boundaries

     * (except if keepTogether is enabled)

     */

    boundariesElement: 'viewport'

  },



  /**

   * Modifier used to make the popper flow toward the inner of the reference element.

   * By default, when this modifier is disabled, the popper will be placed outside

   * the reference element.

   * @memberof modifiers

   * @inner

   */

  inner: {

    /** @prop {number} order=700 - Index used to define the order of execution */

    order: 700,

    /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */

    enabled: false,

    /** @prop {ModifierFn} */

    fn: inner

  },



  /**

   * Modifier used to hide the popper when its reference element is outside of the

   * popper boundaries. It will set a `x-out-of-boundaries` attribute which can

   * be used to hide with a CSS selector the popper when its reference is

   * out of boundaries.

   *

   * Requires the `preventOverflow` modifier before it in order to work.

   * @memberof modifiers

   * @inner

   */

  hide: {

    /** @prop {number} order=800 - Index used to define the order of execution */

    order: 800,

    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */

    enabled: true,

    /** @prop {ModifierFn} */

    fn: hide

  },



  /**

   * Computes the style that will be applied to the popper element to gets

   * properly positioned.

   *

   * Note that this modifier will not touch the DOM, it just prepares the styles

   * so that `applyStyle` modifier can apply it. This separation is useful

   * in case you need to replace `applyStyle` with a custom implementation.

   *

   * This modifier has `850` as `order` value to maintain backward compatibility

   * with previous versions of Popper.js. Expect the modifiers ordering method

   * to change in future major versions of the library.

   *

   * @memberof modifiers

   * @inner

   */

  computeStyle: {

    /** @prop {number} order=850 - Index used to define the order of execution */

    order: 850,

    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */

    enabled: true,

    /** @prop {ModifierFn} */

    fn: computeStyle,

    /**

     * @prop {Boolean} gpuAcceleration=true

     * If true, it uses the CSS 3d transformation to position the popper.

     * Otherwise, it will use the `top` and `left` properties.

     */

    gpuAcceleration: true,

    /**

     * @prop {string} [x='bottom']

     * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin.

     * Change this if your popper should grow in a direction different from `bottom`

     */

    x: 'bottom',

    /**

     * @prop {string} [x='left']

     * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin.

     * Change this if your popper should grow in a direction different from `right`

     */

    y: 'right'

  },



  /**

   * Applies the computed styles to the popper element.

   *

   * All the DOM manipulations are limited to this modifier. This is useful in case

   * you want to integrate Popper.js inside a framework or view library and you

   * want to delegate all the DOM manipulations to it.

   *

   * Note that if you disable this modifier, you must make sure the popper element

   * has its position set to `absolute` before Popper.js can do its work!

   *

   * Just disable this modifier and define you own to achieve the desired effect.

   *

   * @memberof modifiers

   * @inner

   */

  applyStyle: {

    /** @prop {number} order=900 - Index used to define the order of execution */

    order: 900,

    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */

    enabled: true,

    /** @prop {ModifierFn} */

    fn: applyStyle,

    /** @prop {Function} */

    onLoad: applyStyleOnLoad,

    /**

     * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier

     * @prop {Boolean} gpuAcceleration=true

     * If true, it uses the CSS 3d transformation to position the popper.

     * Otherwise, it will use the `top` and `left` properties.

     */

    gpuAcceleration: undefined

  }

};



/**

 * The `dataObject` is an object containing all the informations used by Popper.js

 * this object get passed to modifiers and to the `onCreate` and `onUpdate` callbacks.

 * @name dataObject

 * @property {Object} data.instance The Popper.js instance

 * @property {String} data.placement Placement applied to popper

 * @property {String} data.originalPlacement Placement originally defined on init

 * @property {Boolean} data.flipped True if popper has been flipped by flip modifier

 * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper.

 * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier

 * @property {Object} data.styles Any CSS property defined here will be applied to the popper, it expects the JavaScript nomenclature (eg. `marginBottom`)

 * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow, it expects the JavaScript nomenclature (eg. `marginBottom`)

 * @property {Object} data.boundaries Offsets of the popper boundaries

 * @property {Object} data.offsets The measurements of popper, reference and arrow elements.

 * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values

 * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values

 * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0

 */



/**

 * Default options provided to Popper.js constructor.<br />

 * These can be overriden using the `options` argument of Popper.js.<br />

 * To override an option, simply pass as 3rd argument an object with the same

 * structure of this object, example:

 * ```

 * new Popper(ref, pop, {

 *   modifiers: {

 *     preventOverflow: { enabled: false }

 *   }

 * })

 * ```

 * @type {Object}

 * @static

 * @memberof Popper

 */

var Defaults = {

  /**

   * Popper's placement

   * @prop {Popper.placements} placement='bottom'

   */

  placement: 'bottom',



  /**

   * Whether events (resize, scroll) are initially enabled

   * @prop {Boolean} eventsEnabled=true

   */

  eventsEnabled: true,



  /**

   * Set to true if you want to automatically remove the popper when

   * you call the `destroy` method.

   * @prop {Boolean} removeOnDestroy=false

   */

  removeOnDestroy: false,



  /**

   * Callback called when the popper is created.<br />

   * By default, is set to no-op.<br />

   * Access Popper.js instance with `data.instance`.

   * @prop {onCreate}

   */

  onCreate: function onCreate() {},



  /**

   * Callback called when the popper is updated, this callback is not called

   * on the initialization/creation of the popper, but only on subsequent

   * updates.<br />

   * By default, is set to no-op.<br />

   * Access Popper.js instance with `data.instance`.

   * @prop {onUpdate}

   */

  onUpdate: function onUpdate() {},



  /**

   * List of modifiers used to modify the offsets before they are applied to the popper.

   * They provide most of the functionalities of Popper.js

   * @prop {modifiers}

   */

  modifiers: modifiers

};



/**

 * @callback onCreate

 * @param {dataObject} data

 */



/**

 * @callback onUpdate

 * @param {dataObject} data

 */



// Utils

// Methods

var Popper = function () {

  /**

   * Create a new Popper.js instance

   * @class Popper

   * @param {HTMLElement|referenceObject} reference - The reference element used to position the popper

   * @param {HTMLElement} popper - The HTML element used as popper.

   * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults)

   * @return {Object} instance - The generated Popper.js instance

   */

  function Popper(reference, popper) {

    var _this = this;



    var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};

    classCallCheck(this, Popper);



    this.scheduleUpdate = function () {

      return requestAnimationFrame(_this.update);

    };



    // make update() debounced, so that it only runs at most once-per-tick

    this.update = debounce(this.update.bind(this));



    // with {} we create a new object with the options inside it

    this.options = _extends({}, Popper.Defaults, options);



    // init state

    this.state = {

      isDestroyed: false,

      isCreated: false,

      scrollParents: []

    };



    // get reference and popper elements (allow jQuery wrappers)

    this.reference = reference && reference.jquery ? reference[0] : reference;

    this.popper = popper && popper.jquery ? popper[0] : popper;



    // Deep merge modifiers options

    this.options.modifiers = {};

    Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) {

      _this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {});

    });



    // Refactoring modifiers' list (Object => Array)

    this.modifiers = Object.keys(this.options.modifiers).map(function (name) {

      return _extends({

        name: name

      }, _this.options.modifiers[name]);

    })

    // sort the modifiers by order

    .sort(function (a, b) {

      return a.order - b.order;

    });



    // modifiers have the ability to execute arbitrary code when Popper.js get inited

    // such code is executed in the same order of its modifier

    // they could add new properties to their options configuration

    // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`!

    this.modifiers.forEach(function (modifierOptions) {

      if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) {

        modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state);

      }

    });



    // fire the first update to position the popper in the right place

    this.update();



    var eventsEnabled = this.options.eventsEnabled;

    if (eventsEnabled) {

      // setup event listeners, they will take care of update the position in specific situations

      this.enableEventListeners();

    }



    this.state.eventsEnabled = eventsEnabled;

  }



  // We can't use class properties because they don't get listed in the

  // class prototype and break stuff like Sinon stubs





  createClass(Popper, [{

    key: 'update',

    value: function update$$1() {

      return update.call(this);

    }

  }, {

    key: 'destroy',

    value: function destroy$$1() {

      return destroy.call(this);

    }

  }, {

    key: 'enableEventListeners',

    value: function enableEventListeners$$1() {

      return enableEventListeners.call(this);

    }

  }, {

    key: 'disableEventListeners',

    value: function disableEventListeners$$1() {

      return disableEventListeners.call(this);

    }



    /**

     * Schedule an update, it will run on the next UI update available

     * @method scheduleUpdate

     * @memberof Popper

     */





    /**

     * Collection of utilities useful when writing custom modifiers.

     * Starting from version 1.7, this method is available only if you

     * include `popper-utils.js` before `popper.js`.

     *

     * **DEPRECATION**: This way to access PopperUtils is deprecated

     * and will be removed in v2! Use the PopperUtils module directly instead.

     * Due to the high instability of the methods contained in Utils, we can't

     * guarantee them to follow semver. Use them at your own risk!

     * @static

     * @private

     * @type {Object}

     * @deprecated since version 1.8

     * @member Utils

     * @memberof Popper

     */



  }]);

  return Popper;

}();



/**

 * The `referenceObject` is an object that provides an interface compatible with Popper.js

 * and lets you use it as replacement of a real DOM node.<br />

 * You can use this method to position a popper relatively to a set of coordinates

 * in case you don't have a DOM node to use as reference.

 *

 * ```

 * new Popper(referenceObject, popperNode);

 * ```

 *

 * NB: This feature isn't supported in Internet Explorer 10

 * @name referenceObject

 * @property {Function} data.getBoundingClientRect

 * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method.

 * @property {number} data.clientWidth

 * An ES6 getter that will return the width of the virtual reference element.

 * @property {number} data.clientHeight

 * An ES6 getter that will return the height of the virtual reference element.

 */





Popper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils;

Popper.placements = placements;

Popper.Defaults = Defaults;



/* harmony default export */ __webpack_exports__["default"] = (Popper);

//# sourceMappingURL=popper.js.map



/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(1)))



/***/ }),

/* 5 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";





module.exports = function bind(fn, thisArg) {

  return function wrap() {

    var args = new Array(arguments.length);

    for (var i = 0; i < args.length; i++) {

      args[i] = arguments[i];

    }

    return fn.apply(thisArg, args);

  };

};





/***/ }),

/* 6 */

/***/ (function(module, exports) {



// shim for using process in browser

var process = module.exports = {};



// cached from whatever global is present so that test runners that stub it

// don't break things.  But we need to wrap it in a try catch in case it is

// wrapped in strict mode code which doesn't define any globals.  It's inside a

// function because try/catches deoptimize in certain engines.



var cachedSetTimeout;

var cachedClearTimeout;



function defaultSetTimout() {

    throw new Error('setTimeout has not been defined');

}

function defaultClearTimeout () {

    throw new Error('clearTimeout has not been defined');

}

(function () {

    try {

        if (typeof setTimeout === 'function') {

            cachedSetTimeout = setTimeout;

        } else {

            cachedSetTimeout = defaultSetTimout;

        }

    } catch (e) {

        cachedSetTimeout = defaultSetTimout;

    }

    try {

        if (typeof clearTimeout === 'function') {

            cachedClearTimeout = clearTimeout;

        } else {

            cachedClearTimeout = defaultClearTimeout;

        }

    } catch (e) {

        cachedClearTimeout = defaultClearTimeout;

    }

} ())

function runTimeout(fun) {

    if (cachedSetTimeout === setTimeout) {

        //normal enviroments in sane situations

        return setTimeout(fun, 0);

    }

    // if setTimeout wasn't available but was latter defined

    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {

        cachedSetTimeout = setTimeout;

        return setTimeout(fun, 0);

    }

    try {

        // when when somebody has screwed with setTimeout but no I.E. maddness

        return cachedSetTimeout(fun, 0);

    } catch(e){

        try {

            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally

            return cachedSetTimeout.call(null, fun, 0);

        } catch(e){

            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error

            return cachedSetTimeout.call(this, fun, 0);

        }

    }





}

function runClearTimeout(marker) {

    if (cachedClearTimeout === clearTimeout) {

        //normal enviroments in sane situations

        return clearTimeout(marker);

    }

    // if clearTimeout wasn't available but was latter defined

    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {

        cachedClearTimeout = clearTimeout;

        return clearTimeout(marker);

    }

    try {

        // when when somebody has screwed with setTimeout but no I.E. maddness

        return cachedClearTimeout(marker);

    } catch (e){

        try {

            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally

            return cachedClearTimeout.call(null, marker);

        } catch (e){

            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.

            // Some versions of I.E. have different rules for clearTimeout vs setTimeout

            return cachedClearTimeout.call(this, marker);

        }

    }







}

var queue = [];

var draining = false;

var currentQueue;

var queueIndex = -1;



function cleanUpNextTick() {

    if (!draining || !currentQueue) {

        return;

    }

    draining = false;

    if (currentQueue.length) {

        queue = currentQueue.concat(queue);

    } else {

        queueIndex = -1;

    }

    if (queue.length) {

        drainQueue();

    }

}



function drainQueue() {

    if (draining) {

        return;

    }

    var timeout = runTimeout(cleanUpNextTick);

    draining = true;



    var len = queue.length;

    while(len) {

        currentQueue = queue;

        queue = [];

        while (++queueIndex < len) {

            if (currentQueue) {

                currentQueue[queueIndex].run();

            }

        }

        queueIndex = -1;

        len = queue.length;

    }

    currentQueue = null;

    draining = false;

    runClearTimeout(timeout);

}



process.nextTick = function (fun) {

    var args = new Array(arguments.length - 1);

    if (arguments.length > 1) {

        for (var i = 1; i < arguments.length; i++) {

            args[i - 1] = arguments[i];

        }

    }

    queue.push(new Item(fun, args));

    if (queue.length === 1 && !draining) {

        runTimeout(drainQueue);

    }

};



// v8 likes predictible objects

function Item(fun, array) {

    this.fun = fun;

    this.array = array;

}

Item.prototype.run = function () {

    this.fun.apply(null, this.array);

};

process.title = 'browser';

process.browser = true;

process.env = {};

process.argv = [];

process.version = ''; // empty string to avoid regexp issues

process.versions = {};



function noop() {}



process.on = noop;

process.addListener = noop;

process.once = noop;

process.off = noop;

process.removeListener = noop;

process.removeAllListeners = noop;

process.emit = noop;

process.prependListener = noop;

process.prependOnceListener = noop;



process.listeners = function (name) { return [] }



process.binding = function (name) {

    throw new Error('process.binding is not supported');

};



process.cwd = function () { return '/' };

process.chdir = function (dir) {

    throw new Error('process.chdir is not supported');

};

process.umask = function() { return 0; };





/***/ }),

/* 7 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";





var utils = __webpack_require__(0);

var settle = __webpack_require__(22);

var buildURL = __webpack_require__(24);

var parseHeaders = __webpack_require__(25);

var isURLSameOrigin = __webpack_require__(26);

var createError = __webpack_require__(8);

var btoa = (typeof window !== 'undefined' && window.btoa && window.btoa.bind(window)) || __webpack_require__(27);



module.exports = function xhrAdapter(config) {

  return new Promise(function dispatchXhrRequest(resolve, reject) {

    var requestData = config.data;

    var requestHeaders = config.headers;



    if (utils.isFormData(requestData)) {

      delete requestHeaders['Content-Type']; // Let the browser set it

    }



    var request = new XMLHttpRequest();

    var loadEvent = 'onreadystatechange';

    var xDomain = false;



    // For IE 8/9 CORS support

    // Only supports POST and GET calls and doesn't returns the response headers.

    // DON'T do this for testing b/c XMLHttpRequest is mocked, not XDomainRequest.

    if ("development" !== 'test' &&

        typeof window !== 'undefined' &&

        window.XDomainRequest && !('withCredentials' in request) &&

        !isURLSameOrigin(config.url)) {

      request = new window.XDomainRequest();

      loadEvent = 'onload';

      xDomain = true;

      request.onprogress = function handleProgress() {};

      request.ontimeout = function handleTimeout() {};

    }



    // HTTP basic authentication

    if (config.auth) {

      var username = config.auth.username || '';

      var password = config.auth.password || '';

      requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password);

    }



    request.open(config.method.toUpperCase(), buildURL(config.url, config.params, config.paramsSerializer), true);



    // Set the request timeout in MS

    request.timeout = config.timeout;



    // Listen for ready state

    request[loadEvent] = function handleLoad() {

      if (!request || (request.readyState !== 4 && !xDomain)) {

        return;

      }



      // The request errored out and we didn't get a response, this will be

      // handled by onerror instead

      // With one exception: request that using file: protocol, most browsers

      // will return status as 0 even though it's a successful request

      if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {

        return;

      }



      // Prepare the response

      var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null;

      var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response;

      var response = {

        data: responseData,

        // IE sends 1223 instead of 204 (https://github.com/mzabriskie/axios/issues/201)

        status: request.status === 1223 ? 204 : request.status,

        statusText: request.status === 1223 ? 'No Content' : request.statusText,

        headers: responseHeaders,

        config: config,

        request: request

      };



      settle(resolve, reject, response);



      // Clean up request

      request = null;

    };



    // Handle low level network errors

    request.onerror = function handleError() {

      // Real errors are hidden from us by the browser

      // onerror should only fire if it's a network error

      reject(createError('Network Error', config, null, request));



      // Clean up request

      request = null;

    };



    // Handle timeout

    request.ontimeout = function handleTimeout() {

      reject(createError('timeout of ' + config.timeout + 'ms exceeded', config, 'ECONNABORTED',

        request));



      // Clean up request

      request = null;

    };



    // Add xsrf header

    // This is only done if running in a standard browser environment.

    // Specifically not if we're in a web worker, or react-native.

    if (utils.isStandardBrowserEnv()) {

      var cookies = __webpack_require__(28);



      // Add xsrf header

      var xsrfValue = (config.withCredentials || isURLSameOrigin(config.url)) && config.xsrfCookieName ?

          cookies.read(config.xsrfCookieName) :

          undefined;



      if (xsrfValue) {

        requestHeaders[config.xsrfHeaderName] = xsrfValue;

      }

    }



    // Add headers to the request

    if ('setRequestHeader' in request) {

      utils.forEach(requestHeaders, function setRequestHeader(val, key) {

        if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') {

          // Remove Content-Type if data is undefined

          delete requestHeaders[key];

        } else {

          // Otherwise add header to the request

          request.setRequestHeader(key, val);

        }

      });

    }



    // Add withCredentials to request if needed

    if (config.withCredentials) {

      request.withCredentials = true;

    }



    // Add responseType to request if needed

    if (config.responseType) {

      try {

        request.responseType = config.responseType;

      } catch (e) {

        // Expected DOMException thrown by browsers not compatible XMLHttpRequest Level 2.

        // But, this can be suppressed for 'json' type as it can be parsed by default 'transformResponse' function.

        if (config.responseType !== 'json') {

          throw e;

        }

      }

    }



    // Handle progress if needed

    if (typeof config.onDownloadProgress === 'function') {

      request.addEventListener('progress', config.onDownloadProgress);

    }



    // Not all browsers support upload events

    if (typeof config.onUploadProgress === 'function' && request.upload) {

      request.upload.addEventListener('progress', config.onUploadProgress);

    }



    if (config.cancelToken) {

      // Handle cancellation

      config.cancelToken.promise.then(function onCanceled(cancel) {

        if (!request) {

          return;

        }



        request.abort();

        reject(cancel);

        // Clean up request

        request = null;

      });

    }



    if (requestData === undefined) {

      requestData = null;

    }



    // Send the request

    request.send(requestData);

  });

};





/***/ }),

/* 8 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";





var enhanceError = __webpack_require__(23);



/**

 * Create an Error with the specified message, config, error code, request and response.

 *

 * @param {string} message The error message.

 * @param {Object} config The config.

 * @param {string} [code] The error code (for example, 'ECONNABORTED').

 * @param {Object} [request] The request.

 * @param {Object} [response] The response.

 * @returns {Error} The created error.

 */

module.exports = function createError(message, config, code, request, response) {

  var error = new Error(message);

  return enhanceError(error, config, code, request, response);

};





/***/ }),

/* 9 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";





module.exports = function isCancel(value) {

  return !!(value && value.__CANCEL__);

};





/***/ }),

/* 10 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";





/**

 * A `Cancel` is an object that is thrown when an operation is canceled.

 *

 * @class

 * @param {string=} message The message.

 */

function Cancel(message) {

  this.message = message;

}



Cancel.prototype.toString = function toString() {

  return 'Cancel' + (this.message ? ': ' + this.message : '');

};



Cancel.prototype.__CANCEL__ = true;



module.exports = Cancel;





/***/ }),

/* 11 */

/***/ (function(module, exports, __webpack_require__) {



__webpack_require__(12);

__webpack_require__(39);

__webpack_require__(40);

module.exports = __webpack_require__(41);





/***/ }),

/* 12 */

/***/ (function(module, exports, __webpack_require__) {



/**

* First we will load all of this project's JavaScript dependencies which

* includes Vue and other libraries. It is a great starting point when

* building robust, powerful web applications using Vue and Laravel.

*/



__webpack_require__(13);



window.Vue = __webpack_require__(36);



/**

* Next, we will create a fresh Vue application instance and attach it to

* the page. Then, you may begin adding components to this application

* or customize the JavaScript scaffolding to fit your unique needs.

*/



/*Vue.component('example', require('./components/Example.vue'));*/



/*const app = new Vue({

    el: '#app'

});*/



/***/ }),

/* 13 */

/***/ (function(module, exports, __webpack_require__) {





window._ = __webpack_require__(14);



/**

 * We'll load jQuery and the Bootstrap jQuery plugin which provides support

 * for JavaScript based Bootstrap features such as modals and tabs. This

 * code may be modified to fit the specific needs of your application.

 */



try {

  window.$ = window.jQuery = __webpack_require__(3);

  window.Popper = __webpack_require__(4).default;



  __webpack_require__(16);

} catch (e) {}



/**

 * We'll load the axios HTTP library which allows us to easily issue requests

 * to our Laravel back-end. This library automatically handles sending the

 * CSRF token as a header based on the value of the "XSRF" token cookie.

 */



window.axios = __webpack_require__(17);



window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';



/**

 * Next we will register the CSRF Token as a common header with Axios so that

 * all outgoing HTTP requests automatically have it attached. This is just

 * a simple convenience so we don't have to attach every token manually.

 */



var token = document.head.querySelector('meta[name="csrf-token"]');



if (token) {

  window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;

} else {

  console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');

}



/**

 * Echo exposes an expressive API for subscribing to channels and listening

 * for events that are broadcast by Laravel. Echo and event broadcasting

 * allows your team to easily build robust real-time web applications.

 */



// import Echo from 'laravel-echo'



// window.Pusher = require('pusher-js');



// window.Echo = new Echo({

//     broadcaster: 'pusher',

//     key: 'your-pusher-key'

// });



/***/ }),

/* 14 */

/***/ (function(module, exports, __webpack_require__) {



/* WEBPACK VAR INJECTION */(function(global, module) {var __WEBPACK_AMD_DEFINE_RESULT__;/**

 * @license

 * Lodash <https://lodash.com/>

 * Copyright JS Foundation and other contributors <https://js.foundation/>

 * Released under MIT license <https://lodash.com/license>

 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>

 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors

 */

;(function() {



  /** Used as a safe reference for `undefined` in pre-ES5 environments. */

  var undefined;



  /** Used as the semantic version number. */

  var VERSION = '4.17.4';



  /** Used as the size to enable large array optimizations. */

  var LARGE_ARRAY_SIZE = 200;



  /** Error message constants. */

  var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',

      FUNC_ERROR_TEXT = 'Expected a function';



  /** Used to stand-in for `undefined` hash values. */

  var HASH_UNDEFINED = '__lodash_hash_undefined__';



  /** Used as the maximum memoize cache size. */

  var MAX_MEMOIZE_SIZE = 500;



  /** Used as the internal argument placeholder. */

  var PLACEHOLDER = '__lodash_placeholder__';



  /** Used to compose bitmasks for cloning. */

  var CLONE_DEEP_FLAG = 1,

      CLONE_FLAT_FLAG = 2,

      CLONE_SYMBOLS_FLAG = 4;



  /** Used to compose bitmasks for value comparisons. */

  var COMPARE_PARTIAL_FLAG = 1,

      COMPARE_UNORDERED_FLAG = 2;



  /** Used to compose bitmasks for function metadata. */

  var WRAP_BIND_FLAG = 1,

      WRAP_BIND_KEY_FLAG = 2,

      WRAP_CURRY_BOUND_FLAG = 4,

      WRAP_CURRY_FLAG = 8,

      WRAP_CURRY_RIGHT_FLAG = 16,

      WRAP_PARTIAL_FLAG = 32,

      WRAP_PARTIAL_RIGHT_FLAG = 64,

      WRAP_ARY_FLAG = 128,

      WRAP_REARG_FLAG = 256,

      WRAP_FLIP_FLAG = 512;



  /** Used as default options for `_.truncate`. */

  var DEFAULT_TRUNC_LENGTH = 30,

      DEFAULT_TRUNC_OMISSION = '...';



  /** Used to detect hot functions by number of calls within a span of milliseconds. */

  var HOT_COUNT = 800,

      HOT_SPAN = 16;



  /** Used to indicate the type of lazy iteratees. */

  var LAZY_FILTER_FLAG = 1,

      LAZY_MAP_FLAG = 2,

      LAZY_WHILE_FLAG = 3;



  /** Used as references for various `Number` constants. */

  var INFINITY = 1 / 0,

      MAX_SAFE_INTEGER = 9007199254740991,

      MAX_INTEGER = 1.7976931348623157e+308,

      NAN = 0 / 0;



  /** Used as references for the maximum length and index of an array. */

  var MAX_ARRAY_LENGTH = 4294967295,

      MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,

      HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;



  /** Used to associate wrap methods with their bit flags. */

  var wrapFlags = [

    ['ary', WRAP_ARY_FLAG],

    ['bind', WRAP_BIND_FLAG],

    ['bindKey', WRAP_BIND_KEY_FLAG],

    ['curry', WRAP_CURRY_FLAG],

    ['curryRight', WRAP_CURRY_RIGHT_FLAG],

    ['flip', WRAP_FLIP_FLAG],

    ['partial', WRAP_PARTIAL_FLAG],

    ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],

    ['rearg', WRAP_REARG_FLAG]

  ];



  /** `Object#toString` result references. */

  var argsTag = '[object Arguments]',

      arrayTag = '[object Array]',

      asyncTag = '[object AsyncFunction]',

      boolTag = '[object Boolean]',

      dateTag = '[object Date]',

      domExcTag = '[object DOMException]',

      errorTag = '[object Error]',

      funcTag = '[object Function]',

      genTag = '[object GeneratorFunction]',

      mapTag = '[object Map]',

      numberTag = '[object Number]',

      nullTag = '[object Null]',

      objectTag = '[object Object]',

      promiseTag = '[object Promise]',

      proxyTag = '[object Proxy]',

      regexpTag = '[object RegExp]',

      setTag = '[object Set]',

      stringTag = '[object String]',

      symbolTag = '[object Symbol]',

      undefinedTag = '[object Undefined]',

      weakMapTag = '[object WeakMap]',

      weakSetTag = '[object WeakSet]';



  var arrayBufferTag = '[object ArrayBuffer]',

      dataViewTag = '[object DataView]',

      float32Tag = '[object Float32Array]',

      float64Tag = '[object Float64Array]',

      int8Tag = '[object Int8Array]',

      int16Tag = '[object Int16Array]',

      int32Tag = '[object Int32Array]',

      uint8Tag = '[object Uint8Array]',

      uint8ClampedTag = '[object Uint8ClampedArray]',

      uint16Tag = '[object Uint16Array]',

      uint32Tag = '[object Uint32Array]';



  /** Used to match empty string literals in compiled template source. */

  var reEmptyStringLeading = /\b__p \+= '';/g,

      reEmptyStringMiddle = /\b(__p \+=) '' \+/g,

      reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;



  /** Used to match HTML entities and HTML characters. */

  var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,

      reUnescapedHtml = /[&<>"']/g,

      reHasEscapedHtml = RegExp(reEscapedHtml.source),

      reHasUnescapedHtml = RegExp(reUnescapedHtml.source);



  /** Used to match template delimiters. */

  var reEscape = /<%-([\s\S]+?)%>/g,

      reEvaluate = /<%([\s\S]+?)%>/g,

      reInterpolate = /<%=([\s\S]+?)%>/g;



  /** Used to match property names within property paths. */

  var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,

      reIsPlainProp = /^\w*$/,

      reLeadingDot = /^\./,

      rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;



  /**

   * Used to match `RegExp`

   * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).

   */

  var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,

      reHasRegExpChar = RegExp(reRegExpChar.source);



  /** Used to match leading and trailing whitespace. */

  var reTrim = /^\s+|\s+$/g,

      reTrimStart = /^\s+/,

      reTrimEnd = /\s+$/;



  /** Used to match wrap detail comments. */

  var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,

      reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,

      reSplitDetails = /,? & /;



  /** Used to match words composed of alphanumeric characters. */

  var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;



  /** Used to match backslashes in property paths. */

  var reEscapeChar = /\\(\\)?/g;



  /**

   * Used to match

   * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).

   */

  var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;



  /** Used to match `RegExp` flags from their coerced string values. */

  var reFlags = /\w*$/;



  /** Used to detect bad signed hexadecimal string values. */

  var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;



  /** Used to detect binary string values. */

  var reIsBinary = /^0b[01]+$/i;



  /** Used to detect host constructors (Safari). */

  var reIsHostCtor = /^\[object .+?Constructor\]$/;



  /** Used to detect octal string values. */

  var reIsOctal = /^0o[0-7]+$/i;



  /** Used to detect unsigned integer values. */

  var reIsUint = /^(?:0|[1-9]\d*)$/;



  /** Used to match Latin Unicode letters (excluding mathematical operators). */

  var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;



  /** Used to ensure capturing order of template delimiters. */

  var reNoMatch = /($^)/;



  /** Used to match unescaped characters in compiled string literals. */

  var reUnescapedString = /['\n\r\u2028\u2029\\]/g;



  /** Used to compose unicode character classes. */

  var rsAstralRange = '\\ud800-\\udfff',

      rsComboMarksRange = '\\u0300-\\u036f',

      reComboHalfMarksRange = '\\ufe20-\\ufe2f',

      rsComboSymbolsRange = '\\u20d0-\\u20ff',

      rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,

      rsDingbatRange = '\\u2700-\\u27bf',

      rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',

      rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',

      rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',

      rsPunctuationRange = '\\u2000-\\u206f',

      rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',

      rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',

      rsVarRange = '\\ufe0e\\ufe0f',

      rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;



  /** Used to compose unicode capture groups. */

  var rsApos = "['\u2019]",

      rsAstral = '[' + rsAstralRange + ']',

      rsBreak = '[' + rsBreakRange + ']',

      rsCombo = '[' + rsComboRange + ']',

      rsDigits = '\\d+',

      rsDingbat = '[' + rsDingbatRange + ']',

      rsLower = '[' + rsLowerRange + ']',

      rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',

      rsFitz = '\\ud83c[\\udffb-\\udfff]',

      rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',

      rsNonAstral = '[^' + rsAstralRange + ']',

      rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',

      rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',

      rsUpper = '[' + rsUpperRange + ']',

      rsZWJ = '\\u200d';



  /** Used to compose unicode regexes. */

  var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',

      rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',

      rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',

      rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',

      reOptMod = rsModifier + '?',

      rsOptVar = '[' + rsVarRange + ']?',

      rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',

      rsOrdLower = '\\d*(?:(?:1st|2nd|3rd|(?![123])\\dth)\\b)',

      rsOrdUpper = '\\d*(?:(?:1ST|2ND|3RD|(?![123])\\dTH)\\b)',

      rsSeq = rsOptVar + reOptMod + rsOptJoin,

      rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,

      rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';



  /** Used to match apostrophes. */

  var reApos = RegExp(rsApos, 'g');



  /**

   * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and

   * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).

   */

  var reComboMark = RegExp(rsCombo, 'g');



  /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */

  var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');



  /** Used to match complex or compound words. */

  var reUnicodeWord = RegExp([

    rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',

    rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',

    rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,

    rsUpper + '+' + rsOptContrUpper,

    rsOrdUpper,

    rsOrdLower,

    rsDigits,

    rsEmoji

  ].join('|'), 'g');



  /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */

  var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange  + rsComboRange + rsVarRange + ']');



  /** Used to detect strings that need a more robust regexp to match words. */

  var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;



  /** Used to assign default `context` object properties. */

  var contextProps = [

    'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',

    'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',

    'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',

    'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',

    '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'

  ];



  /** Used to make template sourceURLs easier to identify. */

  var templateCounter = -1;



  /** Used to identify `toStringTag` values of typed arrays. */

  var typedArrayTags = {};

  typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =

  typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =

  typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =

  typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =

  typedArrayTags[uint32Tag] = true;

  typedArrayTags[argsTag] = typedArrayTags[arrayTag] =

  typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =

  typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =

  typedArrayTags[errorTag] = typedArrayTags[funcTag] =

  typedArrayTags[mapTag] = typedArrayTags[numberTag] =

  typedArrayTags[objectTag] = typedArrayTags[regexpTag] =

  typedArrayTags[setTag] = typedArrayTags[stringTag] =

  typedArrayTags[weakMapTag] = false;



  /** Used to identify `toStringTag` values supported by `_.clone`. */

  var cloneableTags = {};

  cloneableTags[argsTag] = cloneableTags[arrayTag] =

  cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =

  cloneableTags[boolTag] = cloneableTags[dateTag] =

  cloneableTags[float32Tag] = cloneableTags[float64Tag] =

  cloneableTags[int8Tag] = cloneableTags[int16Tag] =

  cloneableTags[int32Tag] = cloneableTags[mapTag] =

  cloneableTags[numberTag] = cloneableTags[objectTag] =

  cloneableTags[regexpTag] = cloneableTags[setTag] =

  cloneableTags[stringTag] = cloneableTags[symbolTag] =

  cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =

  cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;

  cloneableTags[errorTag] = cloneableTags[funcTag] =

  cloneableTags[weakMapTag] = false;



  /** Used to map Latin Unicode letters to basic Latin letters. */

  var deburredLetters = {

    // Latin-1 Supplement block.

    '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',

    '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',

    '\xc7': 'C',  '\xe7': 'c',

    '\xd0': 'D',  '\xf0': 'd',

    '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',

    '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',

    '\xcc': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',

    '\xec': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',

    '\xd1': 'N',  '\xf1': 'n',

    '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',

    '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',

    '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',

    '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',

    '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',

    '\xc6': 'Ae', '\xe6': 'ae',

    '\xde': 'Th', '\xfe': 'th',

    '\xdf': 'ss',

    // Latin Extended-A block.

    '\u0100': 'A',  '\u0102': 'A', '\u0104': 'A',

    '\u0101': 'a',  '\u0103': 'a', '\u0105': 'a',

    '\u0106': 'C',  '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',

    '\u0107': 'c',  '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',

    '\u010e': 'D',  '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',

    '\u0112': 'E',  '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',

    '\u0113': 'e',  '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',

    '\u011c': 'G',  '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',

    '\u011d': 'g',  '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',

    '\u0124': 'H',  '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',

    '\u0128': 'I',  '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',

    '\u0129': 'i',  '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',

    '\u0134': 'J',  '\u0135': 'j',

    '\u0136': 'K',  '\u0137': 'k', '\u0138': 'k',

    '\u0139': 'L',  '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',

    '\u013a': 'l',  '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',

    '\u0143': 'N',  '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',

    '\u0144': 'n',  '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',

    '\u014c': 'O',  '\u014e': 'O', '\u0150': 'O',

    '\u014d': 'o',  '\u014f': 'o', '\u0151': 'o',

    '\u0154': 'R',  '\u0156': 'R', '\u0158': 'R',

    '\u0155': 'r',  '\u0157': 'r', '\u0159': 'r',

    '\u015a': 'S',  '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',

    '\u015b': 's',  '\u015d': 's', '\u015f': 's', '\u0161': 's',

    '\u0162': 'T',  '\u0164': 'T', '\u0166': 'T',

    '\u0163': 't',  '\u0165': 't', '\u0167': 't',

    '\u0168': 'U',  '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',

    '\u0169': 'u',  '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',

    '\u0174': 'W',  '\u0175': 'w',

    '\u0176': 'Y',  '\u0177': 'y', '\u0178': 'Y',

    '\u0179': 'Z',  '\u017b': 'Z', '\u017d': 'Z',

    '\u017a': 'z',  '\u017c': 'z', '\u017e': 'z',

    '\u0132': 'IJ', '\u0133': 'ij',

    '\u0152': 'Oe', '\u0153': 'oe',

    '\u0149': "'n", '\u017f': 's'

  };



  /** Used to map characters to HTML entities. */

  var htmlEscapes = {

    '&': '&amp;',

    '<': '&lt;',

    '>': '&gt;',

    '"': '&quot;',

    "'": '&#39;'

  };



  /** Used to map HTML entities to characters. */

  var htmlUnescapes = {

    '&amp;': '&',

    '&lt;': '<',

    '&gt;': '>',

    '&quot;': '"',

    '&#39;': "'"

  };



  /** Used to escape characters for inclusion in compiled string literals. */

  var stringEscapes = {

    '\\': '\\',

    "'": "'",

    '\n': 'n',

    '\r': 'r',

    '\u2028': 'u2028',

    '\u2029': 'u2029'

  };



  /** Built-in method references without a dependency on `root`. */

  var freeParseFloat = parseFloat,

      freeParseInt = parseInt;



  /** Detect free variable `global` from Node.js. */

  var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;



  /** Detect free variable `self`. */

  var freeSelf = typeof self == 'object' && self && self.Object === Object && self;



  /** Used as a reference to the global object. */

  var root = freeGlobal || freeSelf || Function('return this')();



  /** Detect free variable `exports`. */

  var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;



  /** Detect free variable `module`. */

  var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;



  /** Detect the popular CommonJS extension `module.exports`. */

  var moduleExports = freeModule && freeModule.exports === freeExports;



  /** Detect free variable `process` from Node.js. */

  var freeProcess = moduleExports && freeGlobal.process;



  /** Used to access faster Node.js helpers. */

  var nodeUtil = (function() {

    try {

      return freeProcess && freeProcess.binding && freeProcess.binding('util');

    } catch (e) {}

  }());



  /* Node.js helper references. */

  var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,

      nodeIsDate = nodeUtil && nodeUtil.isDate,

      nodeIsMap = nodeUtil && nodeUtil.isMap,

      nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,

      nodeIsSet = nodeUtil && nodeUtil.isSet,

      nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;



  /*--------------------------------------------------------------------------*/



  /**

   * Adds the key-value `pair` to `map`.

   *

   * @private

   * @param {Object} map The map to modify.

   * @param {Array} pair The key-value pair to add.

   * @returns {Object} Returns `map`.

   */

  function addMapEntry(map, pair) {

    // Don't return `map.set` because it's not chainable in IE 11.

    map.set(pair[0], pair[1]);

    return map;

  }



  /**

   * Adds `value` to `set`.

   *

   * @private

   * @param {Object} set The set to modify.

   * @param {*} value The value to add.

   * @returns {Object} Returns `set`.

   */

  function addSetEntry(set, value) {

    // Don't return `set.add` because it's not chainable in IE 11.

    set.add(value);

    return set;

  }



  /**

   * A faster alternative to `Function#apply`, this function invokes `func`

   * with the `this` binding of `thisArg` and the arguments of `args`.

   *

   * @private

   * @param {Function} func The function to invoke.

   * @param {*} thisArg The `this` binding of `func`.

   * @param {Array} args The arguments to invoke `func` with.

   * @returns {*} Returns the result of `func`.

   */

  function apply(func, thisArg, args) {

    switch (args.length) {

      case 0: return func.call(thisArg);

      case 1: return func.call(thisArg, args[0]);

      case 2: return func.call(thisArg, args[0], args[1]);

      case 3: return func.call(thisArg, args[0], args[1], args[2]);

    }

    return func.apply(thisArg, args);

  }



  /**

   * A specialized version of `baseAggregator` for arrays.

   *

   * @private

   * @param {Array} [array] The array to iterate over.

   * @param {Function} setter The function to set `accumulator` values.

   * @param {Function} iteratee The iteratee to transform keys.

   * @param {Object} accumulator The initial aggregated object.

   * @returns {Function} Returns `accumulator`.

   */

  function arrayAggregator(array, setter, iteratee, accumulator) {

    var index = -1,

        length = array == null ? 0 : array.length;



    while (++index < length) {

      var value = array[index];

      setter(accumulator, value, iteratee(value), array);

    }

    return accumulator;

  }



  /**

   * A specialized version of `_.forEach` for arrays without support for

   * iteratee shorthands.

   *

   * @private

   * @param {Array} [array] The array to iterate over.

   * @param {Function} iteratee The function invoked per iteration.

   * @returns {Array} Returns `array`.

   */

  function arrayEach(array, iteratee) {

    var index = -1,

        length = array == null ? 0 : array.length;



    while (++index < length) {

      if (iteratee(array[index], index, array) === false) {

        break;

      }

    }

    return array;

  }



  /**

   * A specialized version of `_.forEachRight` for arrays without support for

   * iteratee shorthands.

   *

   * @private

   * @param {Array} [array] The array to iterate over.

   * @param {Function} iteratee The function invoked per iteration.

   * @returns {Array} Returns `array`.

   */

  function arrayEachRight(array, iteratee) {

    var length = array == null ? 0 : array.length;



    while (length--) {

      if (iteratee(array[length], length, array) === false) {

        break;

      }

    }

    return array;

  }



  /**

   * A specialized version of `_.every` for arrays without support for

   * iteratee shorthands.

   *

   * @private

   * @param {Array} [array] The array to iterate over.

   * @param {Function} predicate The function invoked per iteration.

   * @returns {boolean} Returns `true` if all elements pass the predicate check,

   *  else `false`.

   */

  function arrayEvery(array, predicate) {

    var index = -1,

        length = array == null ? 0 : array.length;



    while (++index < length) {

      if (!predicate(array[index], index, array)) {

        return false;

      }

    }

    return true;

  }



  /**

   * A specialized version of `_.filter` for arrays without support for

   * iteratee shorthands.

   *

   * @private

   * @param {Array} [array] The array to iterate over.

   * @param {Function} predicate The function invoked per iteration.

   * @returns {Array} Returns the new filtered array.

   */

  function arrayFilter(array, predicate) {

    var index = -1,

        length = array == null ? 0 : array.length,

        resIndex = 0,

        result = [];



    while (++index < length) {

      var value = array[index];

      if (predicate(value, index, array)) {

        result[resIndex++] = value;

      }

    }

    return result;

  }



  /**

   * A specialized version of `_.includes` for arrays without support for

   * specifying an index to search from.

   *

   * @private

   * @param {Array} [array] The array to inspect.

   * @param {*} target The value to search for.

   * @returns {boolean} Returns `true` if `target` is found, else `false`.

   */

  function arrayIncludes(array, value) {

    var length = array == null ? 0 : array.length;

    return !!length && baseIndexOf(array, value, 0) > -1;

  }



  /**

   * This function is like `arrayIncludes` except that it accepts a comparator.

   *

   * @private

   * @param {Array} [array] The array to inspect.

   * @param {*} target The value to search for.

   * @param {Function} comparator The comparator invoked per element.

   * @returns {boolean} Returns `true` if `target` is found, else `false`.

   */

  function arrayIncludesWith(array, value, comparator) {

    var index = -1,

        length = array == null ? 0 : array.length;



    while (++index < length) {

      if (comparator(value, array[index])) {

        return true;

      }

    }

    return false;

  }



  /**

   * A specialized version of `_.map` for arrays without support for iteratee

   * shorthands.

   *

   * @private

   * @param {Array} [array] The array to iterate over.

   * @param {Function} iteratee The function invoked per iteration.

   * @returns {Array} Returns the new mapped array.

   */

  function arrayMap(array, iteratee) {

    var index = -1,

        length = array == null ? 0 : array.length,

        result = Array(length);



    while (++index < length) {

      result[index] = iteratee(array[index], index, array);

    }

    return result;

  }



  /**

   * Appends the elements of `values` to `array`.

   *

   * @private

   * @param {Array} array The array to modify.

   * @param {Array} values The values to append.

   * @returns {Array} Returns `array`.

   */

  function arrayPush(array, values) {

    var index = -1,

        length = values.length,

        offset = array.length;



    while (++index < length) {

      array[offset + index] = values[index];

    }

    return array;

  }



  /**

   * A specialized version of `_.reduce` for arrays without support for

   * iteratee shorthands.

   *

   * @private

   * @param {Array} [array] The array to iterate over.

   * @param {Function} iteratee The function invoked per iteration.

   * @param {*} [accumulator] The initial value.

   * @param {boolean} [initAccum] Specify using the first element of `array` as

   *  the initial value.

   * @returns {*} Returns the accumulated value.

   */

  function arrayReduce(array, iteratee, accumulator, initAccum) {

    var index = -1,

        length = array == null ? 0 : array.length;



    if (initAccum && length) {

      accumulator = array[++index];

    }

    while (++index < length) {

      accumulator = iteratee(accumulator, array[index], index, array);

    }

    return accumulator;

  }



  /**

   * A specialized version of `_.reduceRight` for arrays without support for

   * iteratee shorthands.

   *

   * @private

   * @param {Array} [array] The array to iterate over.

   * @param {Function} iteratee The function invoked per iteration.

   * @param {*} [accumulator] The initial value.

   * @param {boolean} [initAccum] Specify using the last element of `array` as

   *  the initial value.

   * @returns {*} Returns the accumulated value.

   */

  function arrayReduceRight(array, iteratee, accumulator, initAccum) {

    var length = array == null ? 0 : array.length;

    if (initAccum && length) {

      accumulator = array[--length];

    }

    while (length--) {

      accumulator = iteratee(accumulator, array[length], length, array);

    }

    return accumulator;

  }



  /**

   * A specialized version of `_.some` for arrays without support for iteratee

   * shorthands.

   *

   * @private

   * @param {Array} [array] The array to iterate over.

   * @param {Function} predicate The function invoked per iteration.

   * @returns {boolean} Returns `true` if any element passes the predicate check,

   *  else `false`.

   */

  function arraySome(array, predicate) {

    var index = -1,

        length = array == null ? 0 : array.length;



    while (++index < length) {

      if (predicate(array[index], index, array)) {

        return true;

      }

    }

    return false;

  }



  /**

   * Gets the size of an ASCII `string`.

   *

   * @private

   * @param {string} string The string inspect.

   * @returns {number} Returns the string size.

   */

  var asciiSize = baseProperty('length');



  /**

   * Converts an ASCII `string` to an array.

   *

   * @private

   * @param {string} string The string to convert.

   * @returns {Array} Returns the converted array.

   */

  function asciiToArray(string) {

    return string.split('');

  }



  /**

   * Splits an ASCII `string` into an array of its words.

   *

   * @private

   * @param {string} The string to inspect.

   * @returns {Array} Returns the words of `string`.

   */

  function asciiWords(string) {

    return string.match(reAsciiWord) || [];

  }



  /**

   * The base implementation of methods like `_.findKey` and `_.findLastKey`,

   * without support for iteratee shorthands, which iterates over `collection`

   * using `eachFunc`.

   *

   * @private

   * @param {Array|Object} collection The collection to inspect.

   * @param {Function} predicate The function invoked per iteration.

   * @param {Function} eachFunc The function to iterate over `collection`.

   * @returns {*} Returns the found element or its key, else `undefined`.

   */

  function baseFindKey(collection, predicate, eachFunc) {

    var result;

    eachFunc(collection, function(value, key, collection) {

      if (predicate(value, key, collection)) {

        result = key;

        return false;

      }

    });

    return result;

  }



  /**

   * The base implementation of `_.findIndex` and `_.findLastIndex` without

   * support for iteratee shorthands.

   *

   * @private

   * @param {Array} array The array to inspect.

   * @param {Function} predicate The function invoked per iteration.

   * @param {number} fromIndex The index to search from.

   * @param {boolean} [fromRight] Specify iterating from right to left.

   * @returns {number} Returns the index of the matched value, else `-1`.

   */

  function baseFindIndex(array, predicate, fromIndex, fromRight) {

    var length = array.length,

        index = fromIndex + (fromRight ? 1 : -1);



    while ((fromRight ? index-- : ++index < length)) {

      if (predicate(array[index], index, array)) {

        return index;

      }

    }

    return -1;

  }



  /**

   * The base implementation of `_.indexOf` without `fromIndex` bounds checks.

   *

   * @private

   * @param {Array} array The array to inspect.

   * @param {*} value The value to search for.

   * @param {number} fromIndex The index to search from.

   * @returns {number} Returns the index of the matched value, else `-1`.

   */

  function baseIndexOf(array, value, fromIndex) {

    return value === value

      ? strictIndexOf(array, value, fromIndex)

      : baseFindIndex(array, baseIsNaN, fromIndex);

  }



  /**

   * This function is like `baseIndexOf` except that it accepts a comparator.

   *

   * @private

   * @param {Array} array The array to inspect.

   * @param {*} value The value to search for.

   * @param {number} fromIndex The index to search from.

   * @param {Function} comparator The comparator invoked per element.

   * @returns {number} Returns the index of the matched value, else `-1`.

   */

  function baseIndexOfWith(array, value, fromIndex, comparator) {

    var index = fromIndex - 1,

        length = array.length;



    while (++index < length) {

      if (comparator(array[index], value)) {

        return index;

      }

    }

    return -1;

  }



  /**

   * The base implementation of `_.isNaN` without support for number objects.

   *

   * @private

   * @param {*} value The value to check.

   * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.

   */

  function baseIsNaN(value) {

    return value !== value;

  }



  /**

   * The base implementation of `_.mean` and `_.meanBy` without support for

   * iteratee shorthands.

   *

   * @private

   * @param {Array} array The array to iterate over.

   * @param {Function} iteratee The function invoked per iteration.

   * @returns {number} Returns the mean.

   */

  function baseMean(array, iteratee) {

    var length = array == null ? 0 : array.length;

    return length ? (baseSum(array, iteratee) / length) : NAN;

  }



  /**

   * The base implementation of `_.property` without support for deep paths.

   *

   * @private

   * @param {string} key The key of the property to get.

   * @returns {Function} Returns the new accessor function.

   */

  function baseProperty(key) {

    return function(object) {

      return object == null ? undefined : object[key];

    };

  }



  /**

   * The base implementation of `_.propertyOf` without support for deep paths.

   *

   * @private

   * @param {Object} object The object to query.

   * @returns {Function} Returns the new accessor function.

   */

  function basePropertyOf(object) {

    return function(key) {

      return object == null ? undefined : object[key];

    };

  }



  /**

   * The base implementation of `_.reduce` and `_.reduceRight`, without support

   * for iteratee shorthands, which iterates over `collection` using `eachFunc`.

   *

   * @private

   * @param {Array|Object} collection The collection to iterate over.

   * @param {Function} iteratee The function invoked per iteration.

   * @param {*} accumulator The initial value.

   * @param {boolean} initAccum Specify using the first or last element of

   *  `collection` as the initial value.

   * @param {Function} eachFunc The function to iterate over `collection`.

   * @returns {*} Returns the accumulated value.

   */

  function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {

    eachFunc(collection, function(value, index, collection) {

      accumulator = initAccum

        ? (initAccum = false, value)

        : iteratee(accumulator, value, index, collection);

    });

    return accumulator;

  }



  /**

   * The base implementation of `_.sortBy` which uses `comparer` to define the

   * sort order of `array` and replaces criteria objects with their corresponding

   * values.

   *

   * @private

   * @param {Array} array The array to sort.

   * @param {Function} comparer The function to define sort order.

   * @returns {Array} Returns `array`.

   */

  function baseSortBy(array, comparer) {

    var length = array.length;



    array.sort(comparer);

    while (length--) {

      array[length] = array[length].value;

    }

    return array;

  }



  /**

   * The base implementation of `_.sum` and `_.sumBy` without support for

   * iteratee shorthands.

   *

   * @private

   * @param {Array} array The array to iterate over.

   * @param {Function} iteratee The function invoked per iteration.

   * @returns {number} Returns the sum.

   */

  function baseSum(array, iteratee) {

    var result,

        index = -1,

        length = array.length;



    while (++index < length) {

      var current = iteratee(array[index]);

      if (current !== undefined) {

        result = result === undefined ? current : (result + current);

      }

    }

    return result;

  }



  /**

   * The base implementation of `_.times` without support for iteratee shorthands

   * or max array length checks.

   *

   * @private

   * @param {number} n The number of times to invoke `iteratee`.

   * @param {Function} iteratee The function invoked per iteration.

   * @returns {Array} Returns the array of results.

   */

  function baseTimes(n, iteratee) {

    var index = -1,

        result = Array(n);



    while (++index < n) {

      result[index] = iteratee(index);

    }

    return result;

  }



  /**

   * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array

   * of key-value pairs for `object` corresponding to the property names of `props`.

   *

   * @private

   * @param {Object} object The object to query.

   * @param {Array} props The property names to get values for.

   * @returns {Object} Returns the key-value pairs.

   */

  function baseToPairs(object, props) {

    return arrayMap(props, function(key) {

      return [key, object[key]];

    });

  }



  /**

   * The base implementation of `_.unary` without support for storing metadata.

   *

   * @private

   * @param {Function} func The function to cap arguments for.

   * @returns {Function} Returns the new capped function.

   */

  function baseUnary(func) {

    return function(value) {

      return func(value);

    };

  }



  /**

   * The base implementation of `_.values` and `_.valuesIn` which creates an

   * array of `object` property values corresponding to the property names

   * of `props`.

   *

   * @private

   * @param {Object} object The object to query.

   * @param {Array} props The property names to get values for.

   * @returns {Object} Returns the array of property values.

   */

  function baseValues(object, props) {

    return arrayMap(props, function(key) {

      return object[key];

    });

  }



  /**

   * Checks if a `cache` value for `key` exists.

   *

   * @private

   * @param {Object} cache The cache to query.

   * @param {string} key The key of the entry to check.

   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.

   */

  function cacheHas(cache, key) {

    return cache.has(key);

  }



  /**

   * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol

   * that is not found in the character symbols.

   *

   * @private

   * @param {Array} strSymbols The string symbols to inspect.

   * @param {Array} chrSymbols The character symbols to find.

   * @returns {number} Returns the index of the first unmatched string symbol.

   */

  function charsStartIndex(strSymbols, chrSymbols) {

    var index = -1,

        length = strSymbols.length;



    while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}

    return index;

  }



  /**

   * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol

   * that is not found in the character symbols.

   *

   * @private

   * @param {Array} strSymbols The string symbols to inspect.

   * @param {Array} chrSymbols The character symbols to find.

   * @returns {number} Returns the index of the last unmatched string symbol.

   */

  function charsEndIndex(strSymbols, chrSymbols) {

    var index = strSymbols.length;



    while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}

    return index;

  }



  /**

   * Gets the number of `placeholder` occurrences in `array`.

   *

   * @private

   * @param {Array} array The array to inspect.

   * @param {*} placeholder The placeholder to search for.

   * @returns {number} Returns the placeholder count.

   */

  function countHolders(array, placeholder) {

    var length = array.length,

        result = 0;



    while (length--) {

      if (array[length] === placeholder) {

        ++result;

      }

    }

    return result;

  }



  /**

   * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A

   * letters to basic Latin letters.

   *

   * @private

   * @param {string} letter The matched letter to deburr.

   * @returns {string} Returns the deburred letter.

   */

  var deburrLetter = basePropertyOf(deburredLetters);



  /**

   * Used by `_.escape` to convert characters to HTML entities.

   *

   * @private

   * @param {string} chr The matched character to escape.

   * @returns {string} Returns the escaped character.

   */

  var escapeHtmlChar = basePropertyOf(htmlEscapes);



  /**

   * Used by `_.template` to escape characters for inclusion in compiled string literals.

   *

   * @private

   * @param {string} chr The matched character to escape.

   * @returns {string} Returns the escaped character.

   */

  function escapeStringChar(chr) {

    return '\\' + stringEscapes[chr];

  }



  /**

   * Gets the value at `key` of `object`.

   *

   * @private

   * @param {Object} [object] The object to query.

   * @param {string} key The key of the property to get.

   * @returns {*} Returns the property value.

   */

  function getValue(object, key) {

    return object == null ? undefined : object[key];

  }



  /**

   * Checks if `string` contains Unicode symbols.

   *

   * @private

   * @param {string} string The string to inspect.

   * @returns {boolean} Returns `true` if a symbol is found, else `false`.

   */

  function hasUnicode(string) {

    return reHasUnicode.test(string);

  }



  /**

   * Checks if `string` contains a word composed of Unicode symbols.

   *

   * @private

   * @param {string} string The string to inspect.

   * @returns {boolean} Returns `true` if a word is found, else `false`.

   */

  function hasUnicodeWord(string) {

    return reHasUnicodeWord.test(string);

  }



  /**

   * Converts `iterator` to an array.

   *

   * @private

   * @param {Object} iterator The iterator to convert.

   * @returns {Array} Returns the converted array.

   */

  function iteratorToArray(iterator) {

    var data,

        result = [];



    while (!(data = iterator.next()).done) {

      result.push(data.value);

    }

    return result;

  }



  /**

   * Converts `map` to its key-value pairs.

   *

   * @private

   * @param {Object} map The map to convert.

   * @returns {Array} Returns the key-value pairs.

   */

  function mapToArray(map) {

    var index = -1,

        result = Array(map.size);



    map.forEach(function(value, key) {

      result[++index] = [key, value];

    });

    return result;

  }



  /**

   * Creates a unary function that invokes `func` with its argument transformed.

   *

   * @private

   * @param {Function} func The function to wrap.

   * @param {Function} transform The argument transform.

   * @returns {Function} Returns the new function.

   */

  function overArg(func, transform) {

    return function(arg) {

      return func(transform(arg));

    };

  }



  /**

   * Replaces all `placeholder` elements in `array` with an internal placeholder

   * and returns an array of their indexes.

   *

   * @private

   * @param {Array} array The array to modify.

   * @param {*} placeholder The placeholder to replace.

   * @returns {Array} Returns the new array of placeholder indexes.

   */

  function replaceHolders(array, placeholder) {

    var index = -1,

        length = array.length,

        resIndex = 0,

        result = [];



    while (++index < length) {

      var value = array[index];

      if (value === placeholder || value === PLACEHOLDER) {

        array[index] = PLACEHOLDER;

        result[resIndex++] = index;

      }

    }

    return result;

  }



  /**

   * Converts `set` to an array of its values.

   *

   * @private

   * @param {Object} set The set to convert.

   * @returns {Array} Returns the values.

   */

  function setToArray(set) {

    var index = -1,

        result = Array(set.size);



    set.forEach(function(value) {

      result[++index] = value;

    });

    return result;

  }



  /**

   * Converts `set` to its value-value pairs.

   *

   * @private

   * @param {Object} set The set to convert.

   * @returns {Array} Returns the value-value pairs.

   */

  function setToPairs(set) {

    var index = -1,

        result = Array(set.size);



    set.forEach(function(value) {

      result[++index] = [value, value];

    });

    return result;

  }



  /**

   * A specialized version of `_.indexOf` which performs strict equality

   * comparisons of values, i.e. `===`.

   *

   * @private

   * @param {Array} array The array to inspect.

   * @param {*} value The value to search for.

   * @param {number} fromIndex The index to search from.

   * @returns {number} Returns the index of the matched value, else `-1`.

   */

  function strictIndexOf(array, value, fromIndex) {

    var index = fromIndex - 1,

        length = array.length;



    while (++index < length) {

      if (array[index] === value) {

        return index;

      }

    }

    return -1;

  }



  /**

   * A specialized version of `_.lastIndexOf` which performs strict equality

   * comparisons of values, i.e. `===`.

   *

   * @private

   * @param {Array} array The array to inspect.

   * @param {*} value The value to search for.

   * @param {number} fromIndex The index to search from.

   * @returns {number} Returns the index of the matched value, else `-1`.

   */

  function strictLastIndexOf(array, value, fromIndex) {

    var index = fromIndex + 1;

    while (index--) {

      if (array[index] === value) {

        return index;

      }

    }

    return index;

  }



  /**

   * Gets the number of symbols in `string`.

   *

   * @private

   * @param {string} string The string to inspect.

   * @returns {number} Returns the string size.

   */

  function stringSize(string) {

    return hasUnicode(string)

      ? unicodeSize(string)

      : asciiSize(string);

  }



  /**

   * Converts `string` to an array.

   *

   * @private

   * @param {string} string The string to convert.

   * @returns {Array} Returns the converted array.

   */

  function stringToArray(string) {

    return hasUnicode(string)

      ? unicodeToArray(string)

      : asciiToArray(string);

  }



  /**

   * Used by `_.unescape` to convert HTML entities to characters.

   *

   * @private

   * @param {string} chr The matched character to unescape.

   * @returns {string} Returns the unescaped character.

   */

  var unescapeHtmlChar = basePropertyOf(htmlUnescapes);



  /**

   * Gets the size of a Unicode `string`.

   *

   * @private

   * @param {string} string The string inspect.

   * @returns {number} Returns the string size.

   */

  function unicodeSize(string) {

    var result = reUnicode.lastIndex = 0;

    while (reUnicode.test(string)) {

      ++result;

    }

    return result;

  }



  /**

   * Converts a Unicode `string` to an array.

   *

   * @private

   * @param {string} string The string to convert.

   * @returns {Array} Returns the converted array.

   */

  function unicodeToArray(string) {

    return string.match(reUnicode) || [];

  }



  /**

   * Splits a Unicode `string` into an array of its words.

   *

   * @private

   * @param {string} The string to inspect.

   * @returns {Array} Returns the words of `string`.

   */

  function unicodeWords(string) {

    return string.match(reUnicodeWord) || [];

  }



  /*--------------------------------------------------------------------------*/



  /**

   * Create a new pristine `lodash` function using the `context` object.

   *

   * @static

   * @memberOf _

   * @since 1.1.0

   * @category Util

   * @param {Object} [context=root] The context object.

   * @returns {Function} Returns a new `lodash` function.

   * @example

   *

   * _.mixin({ 'foo': _.constant('foo') });

   *

   * var lodash = _.runInContext();

   * lodash.mixin({ 'bar': lodash.constant('bar') });

   *

   * _.isFunction(_.foo);

   * // => true

   * _.isFunction(_.bar);

   * // => false

   *

   * lodash.isFunction(lodash.foo);

   * // => false

   * lodash.isFunction(lodash.bar);

   * // => true

   *

   * // Create a suped-up `defer` in Node.js.

   * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;

   */

  var runInContext = (function runInContext(context) {

    context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));



    /** Built-in constructor references. */

    var Array = context.Array,

        Date = context.Date,

        Error = context.Error,

        Function = context.Function,

        Math = context.Math,

        Object = context.Object,

        RegExp = context.RegExp,

        String = context.String,

        TypeError = context.TypeError;



    /** Used for built-in method references. */

    var arrayProto = Array.prototype,

        funcProto = Function.prototype,

        objectProto = Object.prototype;



    /** Used to detect overreaching core-js shims. */

    var coreJsData = context['__core-js_shared__'];



    /** Used to resolve the decompiled source of functions. */

    var funcToString = funcProto.toString;



    /** Used to check objects for own properties. */

    var hasOwnProperty = objectProto.hasOwnProperty;



    /** Used to generate unique IDs. */

    var idCounter = 0;



    /** Used to detect methods masquerading as native. */

    var maskSrcKey = (function() {

      var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');

      return uid ? ('Symbol(src)_1.' + uid) : '';

    }());



    /**

     * Used to resolve the

     * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)

     * of values.

     */

    var nativeObjectToString = objectProto.toString;



    /** Used to infer the `Object` constructor. */

    var objectCtorString = funcToString.call(Object);



    /** Used to restore the original `_` reference in `_.noConflict`. */

    var oldDash = root._;



    /** Used to detect if a method is native. */

    var reIsNative = RegExp('^' +

      funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')

      .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'

    );



    /** Built-in value references. */

    var Buffer = moduleExports ? context.Buffer : undefined,

        Symbol = context.Symbol,

        Uint8Array = context.Uint8Array,

        allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,

        getPrototype = overArg(Object.getPrototypeOf, Object),

        objectCreate = Object.create,

        propertyIsEnumerable = objectProto.propertyIsEnumerable,

        splice = arrayProto.splice,

        spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,

        symIterator = Symbol ? Symbol.iterator : undefined,

        symToStringTag = Symbol ? Symbol.toStringTag : undefined;



    var defineProperty = (function() {

      try {

        var func = getNative(Object, 'defineProperty');

        func({}, '', {});

        return func;

      } catch (e) {}

    }());



    /** Mocked built-ins. */

    var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,

        ctxNow = Date && Date.now !== root.Date.now && Date.now,

        ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;



    /* Built-in method references for those with the same name as other `lodash` methods. */

    var nativeCeil = Math.ceil,

        nativeFloor = Math.floor,

        nativeGetSymbols = Object.getOwnPropertySymbols,

        nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,

        nativeIsFinite = context.isFinite,

        nativeJoin = arrayProto.join,

        nativeKeys = overArg(Object.keys, Object),

        nativeMax = Math.max,

        nativeMin = Math.min,

        nativeNow = Date.now,

        nativeParseInt = context.parseInt,

        nativeRandom = Math.random,

        nativeReverse = arrayProto.reverse;



    /* Built-in method references that are verified to be native. */

    var DataView = getNative(context, 'DataView'),

        Map = getNative(context, 'Map'),

        Promise = getNative(context, 'Promise'),

        Set = getNative(context, 'Set'),

        WeakMap = getNative(context, 'WeakMap'),

        nativeCreate = getNative(Object, 'create');



    /** Used to store function metadata. */

    var metaMap = WeakMap && new WeakMap;



    /** Used to lookup unminified function names. */

    var realNames = {};



    /** Used to detect maps, sets, and weakmaps. */

    var dataViewCtorString = toSource(DataView),

        mapCtorString = toSource(Map),

        promiseCtorString = toSource(Promise),

        setCtorString = toSource(Set),

        weakMapCtorString = toSource(WeakMap);



    /** Used to convert symbols to primitives and strings. */

    var symbolProto = Symbol ? Symbol.prototype : undefined,

        symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,

        symbolToString = symbolProto ? symbolProto.toString : undefined;



    /*------------------------------------------------------------------------*/



    /**

     * Creates a `lodash` object which wraps `value` to enable implicit method

     * chain sequences. Methods that operate on and return arrays, collections,

     * and functions can be chained together. Methods that retrieve a single value

     * or may return a primitive value will automatically end the chain sequence

     * and return the unwrapped value. Otherwise, the value must be unwrapped

     * with `_#value`.

     *

     * Explicit chain sequences, which must be unwrapped with `_#value`, may be

     * enabled using `_.chain`.

     *

     * The execution of chained methods is lazy, that is, it's deferred until

     * `_#value` is implicitly or explicitly called.

     *

     * Lazy evaluation allows several methods to support shortcut fusion.

     * Shortcut fusion is an optimization to merge iteratee calls; this avoids

     * the creation of intermediate arrays and can greatly reduce the number of

     * iteratee executions. Sections of a chain sequence qualify for shortcut

     * fusion if the section is applied to an array and iteratees accept only

     * one argument. The heuristic for whether a section qualifies for shortcut

     * fusion is subject to change.

     *

     * Chaining is supported in custom builds as long as the `_#value` method is

     * directly or indirectly included in the build.

     *

     * In addition to lodash methods, wrappers have `Array` and `String` methods.

     *

     * The wrapper `Array` methods are:

     * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`

     *

     * The wrapper `String` methods are:

     * `replace` and `split`

     *

     * The wrapper methods that support shortcut fusion are:

     * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,

     * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,

     * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`

     *

     * The chainable wrapper methods are:

     * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,

     * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,

     * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,

     * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,

     * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,

     * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,

     * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,

     * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,

     * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,

     * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,

     * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,

     * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,

     * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,

     * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,

     * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,

     * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,

     * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,

     * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,

     * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,

     * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,

     * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,

     * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,

     * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,

     * `zipObject`, `zipObjectDeep`, and `zipWith`

     *

     * The wrapper methods that are **not** chainable by default are:

     * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,

     * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,

     * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,

     * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,

     * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,

     * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,

     * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,

     * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,

     * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,

     * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,

     * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,

     * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,

     * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,

     * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,

     * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,

     * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,

     * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,

     * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,

     * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,

     * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,

     * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,

     * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,

     * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,

     * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,

     * `upperFirst`, `value`, and `words`

     *

     * @name _

     * @constructor

     * @category Seq

     * @param {*} value The value to wrap in a `lodash` instance.

     * @returns {Object} Returns the new `lodash` wrapper instance.

     * @example

     *

     * function square(n) {

     *   return n * n;

     * }

     *

     * var wrapped = _([1, 2, 3]);

     *

     * // Returns an unwrapped value.

     * wrapped.reduce(_.add);

     * // => 6

     *

     * // Returns a wrapped value.

     * var squares = wrapped.map(square);

     *

     * _.isArray(squares);

     * // => false

     *

     * _.isArray(squares.value());

     * // => true

     */

    function lodash(value) {

      if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {

        if (value instanceof LodashWrapper) {

          return value;

        }

        if (hasOwnProperty.call(value, '__wrapped__')) {

          return wrapperClone(value);

        }

      }

      return new LodashWrapper(value);

    }



    /**

     * The base implementation of `_.create` without support for assigning

     * properties to the created object.

     *

     * @private

     * @param {Object} proto The object to inherit from.

     * @returns {Object} Returns the new object.

     */

    var baseCreate = (function() {

      function object() {}

      return function(proto) {

        if (!isObject(proto)) {

          return {};

        }

        if (objectCreate) {

          return objectCreate(proto);

        }

        object.prototype = proto;

        var result = new object;

        object.prototype = undefined;

        return result;

      };

    }());



    /**

     * The function whose prototype chain sequence wrappers inherit from.

     *

     * @private

     */

    function baseLodash() {

      // No operation performed.

    }



    /**

     * The base constructor for creating `lodash` wrapper objects.

     *

     * @private

     * @param {*} value The value to wrap.

     * @param {boolean} [chainAll] Enable explicit method chain sequences.

     */

    function LodashWrapper(value, chainAll) {

      this.__wrapped__ = value;

      this.__actions__ = [];

      this.__chain__ = !!chainAll;

      this.__index__ = 0;

      this.__values__ = undefined;

    }



    /**

     * By default, the template delimiters used by lodash are like those in

     * embedded Ruby (ERB) as well as ES2015 template strings. Change the

     * following template settings to use alternative delimiters.

     *

     * @static

     * @memberOf _

     * @type {Object}

     */

    lodash.templateSettings = {



      /**

       * Used to detect `data` property values to be HTML-escaped.

       *

       * @memberOf _.templateSettings

       * @type {RegExp}

       */

      'escape': reEscape,



      /**

       * Used to detect code to be evaluated.

       *

       * @memberOf _.templateSettings

       * @type {RegExp}

       */

      'evaluate': reEvaluate,



      /**

       * Used to detect `data` property values to inject.

       *

       * @memberOf _.templateSettings

       * @type {RegExp}

       */

      'interpolate': reInterpolate,



      /**

       * Used to reference the data object in the template text.

       *

       * @memberOf _.templateSettings

       * @type {string}

       */

      'variable': '',



      /**

       * Used to import variables into the compiled template.

       *

       * @memberOf _.templateSettings

       * @type {Object}

       */

      'imports': {



        /**

         * A reference to the `lodash` function.

         *

         * @memberOf _.templateSettings.imports

         * @type {Function}

         */

        '_': lodash

      }

    };



    // Ensure wrappers are instances of `baseLodash`.

    lodash.prototype = baseLodash.prototype;

    lodash.prototype.constructor = lodash;



    LodashWrapper.prototype = baseCreate(baseLodash.prototype);

    LodashWrapper.prototype.constructor = LodashWrapper;



    /*------------------------------------------------------------------------*/



    /**

     * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.

     *

     * @private

     * @constructor

     * @param {*} value The value to wrap.

     */

    function LazyWrapper(value) {

      this.__wrapped__ = value;

      this.__actions__ = [];

      this.__dir__ = 1;

      this.__filtered__ = false;

      this.__iteratees__ = [];

      this.__takeCount__ = MAX_ARRAY_LENGTH;

      this.__views__ = [];

    }



    /**

     * Creates a clone of the lazy wrapper object.

     *

     * @private

     * @name clone

     * @memberOf LazyWrapper

     * @returns {Object} Returns the cloned `LazyWrapper` object.

     */

    function lazyClone() {

      var result = new LazyWrapper(this.__wrapped__);

      result.__actions__ = copyArray(this.__actions__);

      result.__dir__ = this.__dir__;

      result.__filtered__ = this.__filtered__;

      result.__iteratees__ = copyArray(this.__iteratees__);

      result.__takeCount__ = this.__takeCount__;

      result.__views__ = copyArray(this.__views__);

      return result;

    }



    /**

     * Reverses the direction of lazy iteration.

     *

     * @private

     * @name reverse

     * @memberOf LazyWrapper

     * @returns {Object} Returns the new reversed `LazyWrapper` object.

     */

    function lazyReverse() {

      if (this.__filtered__) {

        var result = new LazyWrapper(this);

        result.__dir__ = -1;

        result.__filtered__ = true;

      } else {

        result = this.clone();

        result.__dir__ *= -1;

      }

      return result;

    }



    /**

     * Extracts the unwrapped value from its lazy wrapper.

     *

     * @private

     * @name value

     * @memberOf LazyWrapper

     * @returns {*} Returns the unwrapped value.

     */

    function lazyValue() {

      var array = this.__wrapped__.value(),

          dir = this.__dir__,

          isArr = isArray(array),

          isRight = dir < 0,

          arrLength = isArr ? array.length : 0,

          view = getView(0, arrLength, this.__views__),

          start = view.start,

          end = view.end,

          length = end - start,

          index = isRight ? end : (start - 1),

          iteratees = this.__iteratees__,

          iterLength = iteratees.length,

          resIndex = 0,

          takeCount = nativeMin(length, this.__takeCount__);



      if (!isArr || (!isRight && arrLength == length && takeCount == length)) {

        return baseWrapperValue(array, this.__actions__);

      }

      var result = [];



      outer:

      while (length-- && resIndex < takeCount) {

        index += dir;



        var iterIndex = -1,

            value = array[index];



        while (++iterIndex < iterLength) {

          var data = iteratees[iterIndex],

              iteratee = data.iteratee,

              type = data.type,

              computed = iteratee(value);



          if (type == LAZY_MAP_FLAG) {

            value = computed;

          } else if (!computed) {

            if (type == LAZY_FILTER_FLAG) {

              continue outer;

            } else {

              break outer;

            }

          }

        }

        result[resIndex++] = value;

      }

      return result;

    }



    // Ensure `LazyWrapper` is an instance of `baseLodash`.

    LazyWrapper.prototype = baseCreate(baseLodash.prototype);

    LazyWrapper.prototype.constructor = LazyWrapper;



    /*------------------------------------------------------------------------*/



    /**

     * Creates a hash object.

     *

     * @private

     * @constructor

     * @param {Array} [entries] The key-value pairs to cache.

     */

    function Hash(entries) {

      var index = -1,

          length = entries == null ? 0 : entries.length;



      this.clear();

      while (++index < length) {

        var entry = entries[index];

        this.set(entry[0], entry[1]);

      }

    }



    /**

     * Removes all key-value entries from the hash.

     *

     * @private

     * @name clear

     * @memberOf Hash

     */

    function hashClear() {

      this.__data__ = nativeCreate ? nativeCreate(null) : {};

      this.size = 0;

    }



    /**

     * Removes `key` and its value from the hash.

     *

     * @private

     * @name delete

     * @memberOf Hash

     * @param {Object} hash The hash to modify.

     * @param {string} key The key of the value to remove.

     * @returns {boolean} Returns `true` if the entry was removed, else `false`.

     */

    function hashDelete(key) {

      var result = this.has(key) && delete this.__data__[key];

      this.size -= result ? 1 : 0;

      return result;

    }



    /**

     * Gets the hash value for `key`.

     *

     * @private

     * @name get

     * @memberOf Hash

     * @param {string} key The key of the value to get.

     * @returns {*} Returns the entry value.

     */

    function hashGet(key) {

      var data = this.__data__;

      if (nativeCreate) {

        var result = data[key];

        return result === HASH_UNDEFINED ? undefined : result;

      }

      return hasOwnProperty.call(data, key) ? data[key] : undefined;

    }



    /**

     * Checks if a hash value for `key` exists.

     *

     * @private

     * @name has

     * @memberOf Hash

     * @param {string} key The key of the entry to check.

     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.

     */

    function hashHas(key) {

      var data = this.__data__;

      return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);

    }



    /**

     * Sets the hash `key` to `value`.

     *

     * @private

     * @name set

     * @memberOf Hash

     * @param {string} key The key of the value to set.

     * @param {*} value The value to set.

     * @returns {Object} Returns the hash instance.

     */

    function hashSet(key, value) {

      var data = this.__data__;

      this.size += this.has(key) ? 0 : 1;

      data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;

      return this;

    }



    // Add methods to `Hash`.

    Hash.prototype.clear = hashClear;

    Hash.prototype['delete'] = hashDelete;

    Hash.prototype.get = hashGet;

    Hash.prototype.has = hashHas;

    Hash.prototype.set = hashSet;



    /*------------------------------------------------------------------------*/



    /**

     * Creates an list cache object.

     *

     * @private

     * @constructor

     * @param {Array} [entries] The key-value pairs to cache.

     */

    function ListCache(entries) {

      var index = -1,

          length = entries == null ? 0 : entries.length;



      this.clear();

      while (++index < length) {

        var entry = entries[index];

        this.set(entry[0], entry[1]);

      }

    }



    /**

     * Removes all key-value entries from the list cache.

     *

     * @private

     * @name clear

     * @memberOf ListCache

     */

    function listCacheClear() {

      this.__data__ = [];

      this.size = 0;

    }



    /**

     * Removes `key` and its value from the list cache.

     *

     * @private

     * @name delete

     * @memberOf ListCache

     * @param {string} key The key of the value to remove.

     * @returns {boolean} Returns `true` if the entry was removed, else `false`.

     */

    function listCacheDelete(key) {

      var data = this.__data__,

          index = assocIndexOf(data, key);



      if (index < 0) {

        return false;

      }

      var lastIndex = data.length - 1;

      if (index == lastIndex) {

        data.pop();

      } else {

        splice.call(data, index, 1);

      }

      --this.size;

      return true;

    }



    /**

     * Gets the list cache value for `key`.

     *

     * @private

     * @name get

     * @memberOf ListCache

     * @param {string} key The key of the value to get.

     * @returns {*} Returns the entry value.

     */

    function listCacheGet(key) {

      var data = this.__data__,

          index = assocIndexOf(data, key);



      return index < 0 ? undefined : data[index][1];

    }



    /**

     * Checks if a list cache value for `key` exists.

     *

     * @private

     * @name has

     * @memberOf ListCache

     * @param {string} key The key of the entry to check.

     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.

     */

    function listCacheHas(key) {

      return assocIndexOf(this.__data__, key) > -1;

    }



    /**

     * Sets the list cache `key` to `value`.

     *

     * @private

     * @name set

     * @memberOf ListCache

     * @param {string} key The key of the value to set.

     * @param {*} value The value to set.

     * @returns {Object} Returns the list cache instance.

     */

    function listCacheSet(key, value) {

      var data = this.__data__,

          index = assocIndexOf(data, key);



      if (index < 0) {

        ++this.size;

        data.push([key, value]);

      } else {

        data[index][1] = value;

      }

      return this;

    }



    // Add methods to `ListCache`.

    ListCache.prototype.clear = listCacheClear;

    ListCache.prototype['delete'] = listCacheDelete;

    ListCache.prototype.get = listCacheGet;

    ListCache.prototype.has = listCacheHas;

    ListCache.prototype.set = listCacheSet;



    /*------------------------------------------------------------------------*/



    /**

     * Creates a map cache object to store key-value pairs.

     *

     * @private

     * @constructor

     * @param {Array} [entries] The key-value pairs to cache.

     */

    function MapCache(entries) {

      var index = -1,

          length = entries == null ? 0 : entries.length;



      this.clear();

      while (++index < length) {

        var entry = entries[index];

        this.set(entry[0], entry[1]);

      }

    }



    /**

     * Removes all key-value entries from the map.

     *

     * @private

     * @name clear

     * @memberOf MapCache

     */

    function mapCacheClear() {

      this.size = 0;

      this.__data__ = {

        'hash': new Hash,

        'map': new (Map || ListCache),

        'string': new Hash

      };

    }



    /**

     * Removes `key` and its value from the map.

     *

     * @private

     * @name delete

     * @memberOf MapCache

     * @param {string} key The key of the value to remove.

     * @returns {boolean} Returns `true` if the entry was removed, else `false`.

     */

    function mapCacheDelete(key) {

      var result = getMapData(this, key)['delete'](key);

      this.size -= result ? 1 : 0;

      return result;

    }



    /**

     * Gets the map value for `key`.

     *

     * @private

     * @name get

     * @memberOf MapCache

     * @param {string} key The key of the value to get.

     * @returns {*} Returns the entry value.

     */

    function mapCacheGet(key) {

      return getMapData(this, key).get(key);

    }



    /**

     * Checks if a map value for `key` exists.

     *

     * @private

     * @name has

     * @memberOf MapCache

     * @param {string} key The key of the entry to check.

     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.

     */

    function mapCacheHas(key) {

      return getMapData(this, key).has(key);

    }



    /**

     * Sets the map `key` to `value`.

     *

     * @private

     * @name set

     * @memberOf MapCache

     * @param {string} key The key of the value to set.

     * @param {*} value The value to set.

     * @returns {Object} Returns the map cache instance.

     */

    function mapCacheSet(key, value) {

      var data = getMapData(this, key),

          size = data.size;



      data.set(key, value);

      this.size += data.size == size ? 0 : 1;

      return this;

    }



    // Add methods to `MapCache`.

    MapCache.prototype.clear = mapCacheClear;

    MapCache.prototype['delete'] = mapCacheDelete;

    MapCache.prototype.get = mapCacheGet;

    MapCache.prototype.has = mapCacheHas;

    MapCache.prototype.set = mapCacheSet;



    /*------------------------------------------------------------------------*/



    /**

     *

     * Creates an array cache object to store unique values.

     *

     * @private

     * @constructor

     * @param {Array} [values] The values to cache.

     */

    function SetCache(values) {

      var index = -1,

          length = values == null ? 0 : values.length;



      this.__data__ = new MapCache;

      while (++index < length) {

        this.add(values[index]);

      }

    }



    /**

     * Adds `value` to the array cache.

     *

     * @private

     * @name add

     * @memberOf SetCache

     * @alias push

     * @param {*} value The value to cache.

     * @returns {Object} Returns the cache instance.

     */

    function setCacheAdd(value) {

      this.__data__.set(value, HASH_UNDEFINED);

      return this;

    }



    /**

     * Checks if `value` is in the array cache.

     *

     * @private

     * @name has

     * @memberOf SetCache

     * @param {*} value The value to search for.

     * @returns {number} Returns `true` if `value` is found, else `false`.

     */

    function setCacheHas(value) {

      return this.__data__.has(value);

    }



    // Add methods to `SetCache`.

    SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;

    SetCache.prototype.has = setCacheHas;



    /*------------------------------------------------------------------------*/



    /**

     * Creates a stack cache object to store key-value pairs.

     *

     * @private

     * @constructor

     * @param {Array} [entries] The key-value pairs to cache.

     */

    function Stack(entries) {

      var data = this.__data__ = new ListCache(entries);

      this.size = data.size;

    }



    /**

     * Removes all key-value entries from the stack.

     *

     * @private

     * @name clear

     * @memberOf Stack

     */

    function stackClear() {

      this.__data__ = new ListCache;

      this.size = 0;

    }



    /**

     * Removes `key` and its value from the stack.

     *

     * @private

     * @name delete

     * @memberOf Stack

     * @param {string} key The key of the value to remove.

     * @returns {boolean} Returns `true` if the entry was removed, else `false`.

     */

    function stackDelete(key) {

      var data = this.__data__,

          result = data['delete'](key);



      this.size = data.size;

      return result;

    }



    /**

     * Gets the stack value for `key`.

     *

     * @private

     * @name get

     * @memberOf Stack

     * @param {string} key The key of the value to get.

     * @returns {*} Returns the entry value.

     */

    function stackGet(key) {

      return this.__data__.get(key);

    }



    /**

     * Checks if a stack value for `key` exists.

     *

     * @private

     * @name has

     * @memberOf Stack

     * @param {string} key The key of the entry to check.

     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.

     */

    function stackHas(key) {

      return this.__data__.has(key);

    }



    /**

     * Sets the stack `key` to `value`.

     *

     * @private

     * @name set

     * @memberOf Stack

     * @param {string} key The key of the value to set.

     * @param {*} value The value to set.

     * @returns {Object} Returns the stack cache instance.

     */

    function stackSet(key, value) {

      var data = this.__data__;

      if (data instanceof ListCache) {

        var pairs = data.__data__;

        if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {

          pairs.push([key, value]);

          this.size = ++data.size;

          return this;

        }

        data = this.__data__ = new MapCache(pairs);

      }

      data.set(key, value);

      this.size = data.size;

      return this;

    }



    // Add methods to `Stack`.

    Stack.prototype.clear = stackClear;

    Stack.prototype['delete'] = stackDelete;

    Stack.prototype.get = stackGet;

    Stack.prototype.has = stackHas;

    Stack.prototype.set = stackSet;



    /*------------------------------------------------------------------------*/



    /**

     * Creates an array of the enumerable property names of the array-like `value`.

     *

     * @private

     * @param {*} value The value to query.

     * @param {boolean} inherited Specify returning inherited property names.

     * @returns {Array} Returns the array of property names.

     */

    function arrayLikeKeys(value, inherited) {

      var isArr = isArray(value),

          isArg = !isArr && isArguments(value),

          isBuff = !isArr && !isArg && isBuffer(value),

          isType = !isArr && !isArg && !isBuff && isTypedArray(value),

          skipIndexes = isArr || isArg || isBuff || isType,

          result = skipIndexes ? baseTimes(value.length, String) : [],

          length = result.length;



      for (var key in value) {

        if ((inherited || hasOwnProperty.call(value, key)) &&

            !(skipIndexes && (

               // Safari 9 has enumerable `arguments.length` in strict mode.

               key == 'length' ||

               // Node.js 0.10 has enumerable non-index properties on buffers.

               (isBuff && (key == 'offset' || key == 'parent')) ||

               // PhantomJS 2 has enumerable non-index properties on typed arrays.

               (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||

               // Skip index properties.

               isIndex(key, length)

            ))) {

          result.push(key);

        }

      }

      return result;

    }



    /**

     * A specialized version of `_.sample` for arrays.

     *

     * @private

     * @param {Array} array The array to sample.

     * @returns {*} Returns the random element.

     */

    function arraySample(array) {

      var length = array.length;

      return length ? array[baseRandom(0, length - 1)] : undefined;

    }



    /**

     * A specialized version of `_.sampleSize` for arrays.

     *

     * @private

     * @param {Array} array The array to sample.

     * @param {number} n The number of elements to sample.

     * @returns {Array} Returns the random elements.

     */

    function arraySampleSize(array, n) {

      return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));

    }



    /**

     * A specialized version of `_.shuffle` for arrays.

     *

     * @private

     * @param {Array} array The array to shuffle.

     * @returns {Array} Returns the new shuffled array.

     */

    function arrayShuffle(array) {

      return shuffleSelf(copyArray(array));

    }



    /**

     * This function is like `assignValue` except that it doesn't assign

     * `undefined` values.

     *

     * @private

     * @param {Object} object The object to modify.

     * @param {string} key The key of the property to assign.

     * @param {*} value The value to assign.

     */

    function assignMergeValue(object, key, value) {

      if ((value !== undefined && !eq(object[key], value)) ||

          (value === undefined && !(key in object))) {

        baseAssignValue(object, key, value);

      }

    }



    /**

     * Assigns `value` to `key` of `object` if the existing value is not equivalent

     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)

     * for equality comparisons.

     *

     * @private

     * @param {Object} object The object to modify.

     * @param {string} key The key of the property to assign.

     * @param {*} value The value to assign.

     */

    function assignValue(object, key, value) {

      var objValue = object[key];

      if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||

          (value === undefined && !(key in object))) {

        baseAssignValue(object, key, value);

      }

    }



    /**

     * Gets the index at which the `key` is found in `array` of key-value pairs.

     *

     * @private

     * @param {Array} array The array to inspect.

     * @param {*} key The key to search for.

     * @returns {number} Returns the index of the matched value, else `-1`.

     */

    function assocIndexOf(array, key) {

      var length = array.length;

      while (length--) {

        if (eq(array[length][0], key)) {

          return length;

        }

      }

      return -1;

    }



    /**

     * Aggregates elements of `collection` on `accumulator` with keys transformed

     * by `iteratee` and values set by `setter`.

     *

     * @private

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Function} setter The function to set `accumulator` values.

     * @param {Function} iteratee The iteratee to transform keys.

     * @param {Object} accumulator The initial aggregated object.

     * @returns {Function} Returns `accumulator`.

     */

    function baseAggregator(collection, setter, iteratee, accumulator) {

      baseEach(collection, function(value, key, collection) {

        setter(accumulator, value, iteratee(value), collection);

      });

      return accumulator;

    }



    /**

     * The base implementation of `_.assign` without support for multiple sources

     * or `customizer` functions.

     *

     * @private

     * @param {Object} object The destination object.

     * @param {Object} source The source object.

     * @returns {Object} Returns `object`.

     */

    function baseAssign(object, source) {

      return object && copyObject(source, keys(source), object);

    }



    /**

     * The base implementation of `_.assignIn` without support for multiple sources

     * or `customizer` functions.

     *

     * @private

     * @param {Object} object The destination object.

     * @param {Object} source The source object.

     * @returns {Object} Returns `object`.

     */

    function baseAssignIn(object, source) {

      return object && copyObject(source, keysIn(source), object);

    }



    /**

     * The base implementation of `assignValue` and `assignMergeValue` without

     * value checks.

     *

     * @private

     * @param {Object} object The object to modify.

     * @param {string} key The key of the property to assign.

     * @param {*} value The value to assign.

     */

    function baseAssignValue(object, key, value) {

      if (key == '__proto__' && defineProperty) {

        defineProperty(object, key, {

          'configurable': true,

          'enumerable': true,

          'value': value,

          'writable': true

        });

      } else {

        object[key] = value;

      }

    }



    /**

     * The base implementation of `_.at` without support for individual paths.

     *

     * @private

     * @param {Object} object The object to iterate over.

     * @param {string[]} paths The property paths to pick.

     * @returns {Array} Returns the picked elements.

     */

    function baseAt(object, paths) {

      var index = -1,

          length = paths.length,

          result = Array(length),

          skip = object == null;



      while (++index < length) {

        result[index] = skip ? undefined : get(object, paths[index]);

      }

      return result;

    }



    /**

     * The base implementation of `_.clamp` which doesn't coerce arguments.

     *

     * @private

     * @param {number} number The number to clamp.

     * @param {number} [lower] The lower bound.

     * @param {number} upper The upper bound.

     * @returns {number} Returns the clamped number.

     */

    function baseClamp(number, lower, upper) {

      if (number === number) {

        if (upper !== undefined) {

          number = number <= upper ? number : upper;

        }

        if (lower !== undefined) {

          number = number >= lower ? number : lower;

        }

      }

      return number;

    }



    /**

     * The base implementation of `_.clone` and `_.cloneDeep` which tracks

     * traversed objects.

     *

     * @private

     * @param {*} value The value to clone.

     * @param {boolean} bitmask The bitmask flags.

     *  1 - Deep clone

     *  2 - Flatten inherited properties

     *  4 - Clone symbols

     * @param {Function} [customizer] The function to customize cloning.

     * @param {string} [key] The key of `value`.

     * @param {Object} [object] The parent object of `value`.

     * @param {Object} [stack] Tracks traversed objects and their clone counterparts.

     * @returns {*} Returns the cloned value.

     */

    function baseClone(value, bitmask, customizer, key, object, stack) {

      var result,

          isDeep = bitmask & CLONE_DEEP_FLAG,

          isFlat = bitmask & CLONE_FLAT_FLAG,

          isFull = bitmask & CLONE_SYMBOLS_FLAG;



      if (customizer) {

        result = object ? customizer(value, key, object, stack) : customizer(value);

      }

      if (result !== undefined) {

        return result;

      }

      if (!isObject(value)) {

        return value;

      }

      var isArr = isArray(value);

      if (isArr) {

        result = initCloneArray(value);

        if (!isDeep) {

          return copyArray(value, result);

        }

      } else {

        var tag = getTag(value),

            isFunc = tag == funcTag || tag == genTag;



        if (isBuffer(value)) {

          return cloneBuffer(value, isDeep);

        }

        if (tag == objectTag || tag == argsTag || (isFunc && !object)) {

          result = (isFlat || isFunc) ? {} : initCloneObject(value);

          if (!isDeep) {

            return isFlat

              ? copySymbolsIn(value, baseAssignIn(result, value))

              : copySymbols(value, baseAssign(result, value));

          }

        } else {

          if (!cloneableTags[tag]) {

            return object ? value : {};

          }

          result = initCloneByTag(value, tag, baseClone, isDeep);

        }

      }

      // Check for circular references and return its corresponding clone.

      stack || (stack = new Stack);

      var stacked = stack.get(value);

      if (stacked) {

        return stacked;

      }

      stack.set(value, result);



      var keysFunc = isFull

        ? (isFlat ? getAllKeysIn : getAllKeys)

        : (isFlat ? keysIn : keys);



      var props = isArr ? undefined : keysFunc(value);

      arrayEach(props || value, function(subValue, key) {

        if (props) {

          key = subValue;

          subValue = value[key];

        }

        // Recursively populate clone (susceptible to call stack limits).

        assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));

      });

      return result;

    }



    /**

     * The base implementation of `_.conforms` which doesn't clone `source`.

     *

     * @private

     * @param {Object} source The object of property predicates to conform to.

     * @returns {Function} Returns the new spec function.

     */

    function baseConforms(source) {

      var props = keys(source);

      return function(object) {

        return baseConformsTo(object, source, props);

      };

    }



    /**

     * The base implementation of `_.conformsTo` which accepts `props` to check.

     *

     * @private

     * @param {Object} object The object to inspect.

     * @param {Object} source The object of property predicates to conform to.

     * @returns {boolean} Returns `true` if `object` conforms, else `false`.

     */

    function baseConformsTo(object, source, props) {

      var length = props.length;

      if (object == null) {

        return !length;

      }

      object = Object(object);

      while (length--) {

        var key = props[length],

            predicate = source[key],

            value = object[key];



        if ((value === undefined && !(key in object)) || !predicate(value)) {

          return false;

        }

      }

      return true;

    }



    /**

     * The base implementation of `_.delay` and `_.defer` which accepts `args`

     * to provide to `func`.

     *

     * @private

     * @param {Function} func The function to delay.

     * @param {number} wait The number of milliseconds to delay invocation.

     * @param {Array} args The arguments to provide to `func`.

     * @returns {number|Object} Returns the timer id or timeout object.

     */

    function baseDelay(func, wait, args) {

      if (typeof func != 'function') {

        throw new TypeError(FUNC_ERROR_TEXT);

      }

      return setTimeout(function() { func.apply(undefined, args); }, wait);

    }



    /**

     * The base implementation of methods like `_.difference` without support

     * for excluding multiple arrays or iteratee shorthands.

     *

     * @private

     * @param {Array} array The array to inspect.

     * @param {Array} values The values to exclude.

     * @param {Function} [iteratee] The iteratee invoked per element.

     * @param {Function} [comparator] The comparator invoked per element.

     * @returns {Array} Returns the new array of filtered values.

     */

    function baseDifference(array, values, iteratee, comparator) {

      var index = -1,

          includes = arrayIncludes,

          isCommon = true,

          length = array.length,

          result = [],

          valuesLength = values.length;



      if (!length) {

        return result;

      }

      if (iteratee) {

        values = arrayMap(values, baseUnary(iteratee));

      }

      if (comparator) {

        includes = arrayIncludesWith;

        isCommon = false;

      }

      else if (values.length >= LARGE_ARRAY_SIZE) {

        includes = cacheHas;

        isCommon = false;

        values = new SetCache(values);

      }

      outer:

      while (++index < length) {

        var value = array[index],

            computed = iteratee == null ? value : iteratee(value);



        value = (comparator || value !== 0) ? value : 0;

        if (isCommon && computed === computed) {

          var valuesIndex = valuesLength;

          while (valuesIndex--) {

            if (values[valuesIndex] === computed) {

              continue outer;

            }

          }

          result.push(value);

        }

        else if (!includes(values, computed, comparator)) {

          result.push(value);

        }

      }

      return result;

    }



    /**

     * The base implementation of `_.forEach` without support for iteratee shorthands.

     *

     * @private

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Function} iteratee The function invoked per iteration.

     * @returns {Array|Object} Returns `collection`.

     */

    var baseEach = createBaseEach(baseForOwn);



    /**

     * The base implementation of `_.forEachRight` without support for iteratee shorthands.

     *

     * @private

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Function} iteratee The function invoked per iteration.

     * @returns {Array|Object} Returns `collection`.

     */

    var baseEachRight = createBaseEach(baseForOwnRight, true);



    /**

     * The base implementation of `_.every` without support for iteratee shorthands.

     *

     * @private

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Function} predicate The function invoked per iteration.

     * @returns {boolean} Returns `true` if all elements pass the predicate check,

     *  else `false`

     */

    function baseEvery(collection, predicate) {

      var result = true;

      baseEach(collection, function(value, index, collection) {

        result = !!predicate(value, index, collection);

        return result;

      });

      return result;

    }



    /**

     * The base implementation of methods like `_.max` and `_.min` which accepts a

     * `comparator` to determine the extremum value.

     *

     * @private

     * @param {Array} array The array to iterate over.

     * @param {Function} iteratee The iteratee invoked per iteration.

     * @param {Function} comparator The comparator used to compare values.

     * @returns {*} Returns the extremum value.

     */

    function baseExtremum(array, iteratee, comparator) {

      var index = -1,

          length = array.length;



      while (++index < length) {

        var value = array[index],

            current = iteratee(value);



        if (current != null && (computed === undefined

              ? (current === current && !isSymbol(current))

              : comparator(current, computed)

            )) {

          var computed = current,

              result = value;

        }

      }

      return result;

    }



    /**

     * The base implementation of `_.fill` without an iteratee call guard.

     *

     * @private

     * @param {Array} array The array to fill.

     * @param {*} value The value to fill `array` with.

     * @param {number} [start=0] The start position.

     * @param {number} [end=array.length] The end position.

     * @returns {Array} Returns `array`.

     */

    function baseFill(array, value, start, end) {

      var length = array.length;



      start = toInteger(start);

      if (start < 0) {

        start = -start > length ? 0 : (length + start);

      }

      end = (end === undefined || end > length) ? length : toInteger(end);

      if (end < 0) {

        end += length;

      }

      end = start > end ? 0 : toLength(end);

      while (start < end) {

        array[start++] = value;

      }

      return array;

    }



    /**

     * The base implementation of `_.filter` without support for iteratee shorthands.

     *

     * @private

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Function} predicate The function invoked per iteration.

     * @returns {Array} Returns the new filtered array.

     */

    function baseFilter(collection, predicate) {

      var result = [];

      baseEach(collection, function(value, index, collection) {

        if (predicate(value, index, collection)) {

          result.push(value);

        }

      });

      return result;

    }



    /**

     * The base implementation of `_.flatten` with support for restricting flattening.

     *

     * @private

     * @param {Array} array The array to flatten.

     * @param {number} depth The maximum recursion depth.

     * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.

     * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.

     * @param {Array} [result=[]] The initial result value.

     * @returns {Array} Returns the new flattened array.

     */

    function baseFlatten(array, depth, predicate, isStrict, result) {

      var index = -1,

          length = array.length;



      predicate || (predicate = isFlattenable);

      result || (result = []);



      while (++index < length) {

        var value = array[index];

        if (depth > 0 && predicate(value)) {

          if (depth > 1) {

            // Recursively flatten arrays (susceptible to call stack limits).

            baseFlatten(value, depth - 1, predicate, isStrict, result);

          } else {

            arrayPush(result, value);

          }

        } else if (!isStrict) {

          result[result.length] = value;

        }

      }

      return result;

    }



    /**

     * The base implementation of `baseForOwn` which iterates over `object`

     * properties returned by `keysFunc` and invokes `iteratee` for each property.

     * Iteratee functions may exit iteration early by explicitly returning `false`.

     *

     * @private

     * @param {Object} object The object to iterate over.

     * @param {Function} iteratee The function invoked per iteration.

     * @param {Function} keysFunc The function to get the keys of `object`.

     * @returns {Object} Returns `object`.

     */

    var baseFor = createBaseFor();



    /**

     * This function is like `baseFor` except that it iterates over properties

     * in the opposite order.

     *

     * @private

     * @param {Object} object The object to iterate over.

     * @param {Function} iteratee The function invoked per iteration.

     * @param {Function} keysFunc The function to get the keys of `object`.

     * @returns {Object} Returns `object`.

     */

    var baseForRight = createBaseFor(true);



    /**

     * The base implementation of `_.forOwn` without support for iteratee shorthands.

     *

     * @private

     * @param {Object} object The object to iterate over.

     * @param {Function} iteratee The function invoked per iteration.

     * @returns {Object} Returns `object`.

     */

    function baseForOwn(object, iteratee) {

      return object && baseFor(object, iteratee, keys);

    }



    /**

     * The base implementation of `_.forOwnRight` without support for iteratee shorthands.

     *

     * @private

     * @param {Object} object The object to iterate over.

     * @param {Function} iteratee The function invoked per iteration.

     * @returns {Object} Returns `object`.

     */

    function baseForOwnRight(object, iteratee) {

      return object && baseForRight(object, iteratee, keys);

    }



    /**

     * The base implementation of `_.functions` which creates an array of

     * `object` function property names filtered from `props`.

     *

     * @private

     * @param {Object} object The object to inspect.

     * @param {Array} props The property names to filter.

     * @returns {Array} Returns the function names.

     */

    function baseFunctions(object, props) {

      return arrayFilter(props, function(key) {

        return isFunction(object[key]);

      });

    }



    /**

     * The base implementation of `_.get` without support for default values.

     *

     * @private

     * @param {Object} object The object to query.

     * @param {Array|string} path The path of the property to get.

     * @returns {*} Returns the resolved value.

     */

    function baseGet(object, path) {

      path = castPath(path, object);



      var index = 0,

          length = path.length;



      while (object != null && index < length) {

        object = object[toKey(path[index++])];

      }

      return (index && index == length) ? object : undefined;

    }



    /**

     * The base implementation of `getAllKeys` and `getAllKeysIn` which uses

     * `keysFunc` and `symbolsFunc` to get the enumerable property names and

     * symbols of `object`.

     *

     * @private

     * @param {Object} object The object to query.

     * @param {Function} keysFunc The function to get the keys of `object`.

     * @param {Function} symbolsFunc The function to get the symbols of `object`.

     * @returns {Array} Returns the array of property names and symbols.

     */

    function baseGetAllKeys(object, keysFunc, symbolsFunc) {

      var result = keysFunc(object);

      return isArray(object) ? result : arrayPush(result, symbolsFunc(object));

    }



    /**

     * The base implementation of `getTag` without fallbacks for buggy environments.

     *

     * @private

     * @param {*} value The value to query.

     * @returns {string} Returns the `toStringTag`.

     */

    function baseGetTag(value) {

      if (value == null) {

        return value === undefined ? undefinedTag : nullTag;

      }

      return (symToStringTag && symToStringTag in Object(value))

        ? getRawTag(value)

        : objectToString(value);

    }



    /**

     * The base implementation of `_.gt` which doesn't coerce arguments.

     *

     * @private

     * @param {*} value The value to compare.

     * @param {*} other The other value to compare.

     * @returns {boolean} Returns `true` if `value` is greater than `other`,

     *  else `false`.

     */

    function baseGt(value, other) {

      return value > other;

    }



    /**

     * The base implementation of `_.has` without support for deep paths.

     *

     * @private

     * @param {Object} [object] The object to query.

     * @param {Array|string} key The key to check.

     * @returns {boolean} Returns `true` if `key` exists, else `false`.

     */

    function baseHas(object, key) {

      return object != null && hasOwnProperty.call(object, key);

    }



    /**

     * The base implementation of `_.hasIn` without support for deep paths.

     *

     * @private

     * @param {Object} [object] The object to query.

     * @param {Array|string} key The key to check.

     * @returns {boolean} Returns `true` if `key` exists, else `false`.

     */

    function baseHasIn(object, key) {

      return object != null && key in Object(object);

    }



    /**

     * The base implementation of `_.inRange` which doesn't coerce arguments.

     *

     * @private

     * @param {number} number The number to check.

     * @param {number} start The start of the range.

     * @param {number} end The end of the range.

     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.

     */

    function baseInRange(number, start, end) {

      return number >= nativeMin(start, end) && number < nativeMax(start, end);

    }



    /**

     * The base implementation of methods like `_.intersection`, without support

     * for iteratee shorthands, that accepts an array of arrays to inspect.

     *

     * @private

     * @param {Array} arrays The arrays to inspect.

     * @param {Function} [iteratee] The iteratee invoked per element.

     * @param {Function} [comparator] The comparator invoked per element.

     * @returns {Array} Returns the new array of shared values.

     */

    function baseIntersection(arrays, iteratee, comparator) {

      var includes = comparator ? arrayIncludesWith : arrayIncludes,

          length = arrays[0].length,

          othLength = arrays.length,

          othIndex = othLength,

          caches = Array(othLength),

          maxLength = Infinity,

          result = [];



      while (othIndex--) {

        var array = arrays[othIndex];

        if (othIndex && iteratee) {

          array = arrayMap(array, baseUnary(iteratee));

        }

        maxLength = nativeMin(array.length, maxLength);

        caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))

          ? new SetCache(othIndex && array)

          : undefined;

      }

      array = arrays[0];



      var index = -1,

          seen = caches[0];



      outer:

      while (++index < length && result.length < maxLength) {

        var value = array[index],

            computed = iteratee ? iteratee(value) : value;



        value = (comparator || value !== 0) ? value : 0;

        if (!(seen

              ? cacheHas(seen, computed)

              : includes(result, computed, comparator)

            )) {

          othIndex = othLength;

          while (--othIndex) {

            var cache = caches[othIndex];

            if (!(cache

                  ? cacheHas(cache, computed)

                  : includes(arrays[othIndex], computed, comparator))

                ) {

              continue outer;

            }

          }

          if (seen) {

            seen.push(computed);

          }

          result.push(value);

        }

      }

      return result;

    }



    /**

     * The base implementation of `_.invert` and `_.invertBy` which inverts

     * `object` with values transformed by `iteratee` and set by `setter`.

     *

     * @private

     * @param {Object} object The object to iterate over.

     * @param {Function} setter The function to set `accumulator` values.

     * @param {Function} iteratee The iteratee to transform values.

     * @param {Object} accumulator The initial inverted object.

     * @returns {Function} Returns `accumulator`.

     */

    function baseInverter(object, setter, iteratee, accumulator) {

      baseForOwn(object, function(value, key, object) {

        setter(accumulator, iteratee(value), key, object);

      });

      return accumulator;

    }



    /**

     * The base implementation of `_.invoke` without support for individual

     * method arguments.

     *

     * @private

     * @param {Object} object The object to query.

     * @param {Array|string} path The path of the method to invoke.

     * @param {Array} args The arguments to invoke the method with.

     * @returns {*} Returns the result of the invoked method.

     */

    function baseInvoke(object, path, args) {

      path = castPath(path, object);

      object = parent(object, path);

      var func = object == null ? object : object[toKey(last(path))];

      return func == null ? undefined : apply(func, object, args);

    }



    /**

     * The base implementation of `_.isArguments`.

     *

     * @private

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is an `arguments` object,

     */

    function baseIsArguments(value) {

      return isObjectLike(value) && baseGetTag(value) == argsTag;

    }



    /**

     * The base implementation of `_.isArrayBuffer` without Node.js optimizations.

     *

     * @private

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.

     */

    function baseIsArrayBuffer(value) {

      return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;

    }



    /**

     * The base implementation of `_.isDate` without Node.js optimizations.

     *

     * @private

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.

     */

    function baseIsDate(value) {

      return isObjectLike(value) && baseGetTag(value) == dateTag;

    }



    /**

     * The base implementation of `_.isEqual` which supports partial comparisons

     * and tracks traversed objects.

     *

     * @private

     * @param {*} value The value to compare.

     * @param {*} other The other value to compare.

     * @param {boolean} bitmask The bitmask flags.

     *  1 - Unordered comparison

     *  2 - Partial comparison

     * @param {Function} [customizer] The function to customize comparisons.

     * @param {Object} [stack] Tracks traversed `value` and `other` objects.

     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.

     */

    function baseIsEqual(value, other, bitmask, customizer, stack) {

      if (value === other) {

        return true;

      }

      if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {

        return value !== value && other !== other;

      }

      return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);

    }



    /**

     * A specialized version of `baseIsEqual` for arrays and objects which performs

     * deep comparisons and tracks traversed objects enabling objects with circular

     * references to be compared.

     *

     * @private

     * @param {Object} object The object to compare.

     * @param {Object} other The other object to compare.

     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.

     * @param {Function} customizer The function to customize comparisons.

     * @param {Function} equalFunc The function to determine equivalents of values.

     * @param {Object} [stack] Tracks traversed `object` and `other` objects.

     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.

     */

    function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {

      var objIsArr = isArray(object),

          othIsArr = isArray(other),

          objTag = objIsArr ? arrayTag : getTag(object),

          othTag = othIsArr ? arrayTag : getTag(other);



      objTag = objTag == argsTag ? objectTag : objTag;

      othTag = othTag == argsTag ? objectTag : othTag;



      var objIsObj = objTag == objectTag,

          othIsObj = othTag == objectTag,

          isSameTag = objTag == othTag;



      if (isSameTag && isBuffer(object)) {

        if (!isBuffer(other)) {

          return false;

        }

        objIsArr = true;

        objIsObj = false;

      }

      if (isSameTag && !objIsObj) {

        stack || (stack = new Stack);

        return (objIsArr || isTypedArray(object))

          ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)

          : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);

      }

      if (!(bitmask & COMPARE_PARTIAL_FLAG)) {

        var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),

            othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');



        if (objIsWrapped || othIsWrapped) {

          var objUnwrapped = objIsWrapped ? object.value() : object,

              othUnwrapped = othIsWrapped ? other.value() : other;



          stack || (stack = new Stack);

          return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);

        }

      }

      if (!isSameTag) {

        return false;

      }

      stack || (stack = new Stack);

      return equalObjects(object, other, bitmask, customizer, equalFunc, stack);

    }



    /**

     * The base implementation of `_.isMap` without Node.js optimizations.

     *

     * @private

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a map, else `false`.

     */

    function baseIsMap(value) {

      return isObjectLike(value) && getTag(value) == mapTag;

    }



    /**

     * The base implementation of `_.isMatch` without support for iteratee shorthands.

     *

     * @private

     * @param {Object} object The object to inspect.

     * @param {Object} source The object of property values to match.

     * @param {Array} matchData The property names, values, and compare flags to match.

     * @param {Function} [customizer] The function to customize comparisons.

     * @returns {boolean} Returns `true` if `object` is a match, else `false`.

     */

    function baseIsMatch(object, source, matchData, customizer) {

      var index = matchData.length,

          length = index,

          noCustomizer = !customizer;



      if (object == null) {

        return !length;

      }

      object = Object(object);

      while (index--) {

        var data = matchData[index];

        if ((noCustomizer && data[2])

              ? data[1] !== object[data[0]]

              : !(data[0] in object)

            ) {

          return false;

        }

      }

      while (++index < length) {

        data = matchData[index];

        var key = data[0],

            objValue = object[key],

            srcValue = data[1];



        if (noCustomizer && data[2]) {

          if (objValue === undefined && !(key in object)) {

            return false;

          }

        } else {

          var stack = new Stack;

          if (customizer) {

            var result = customizer(objValue, srcValue, key, object, source, stack);

          }

          if (!(result === undefined

                ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)

                : result

              )) {

            return false;

          }

        }

      }

      return true;

    }



    /**

     * The base implementation of `_.isNative` without bad shim checks.

     *

     * @private

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a native function,

     *  else `false`.

     */

    function baseIsNative(value) {

      if (!isObject(value) || isMasked(value)) {

        return false;

      }

      var pattern = isFunction(value) ? reIsNative : reIsHostCtor;

      return pattern.test(toSource(value));

    }



    /**

     * The base implementation of `_.isRegExp` without Node.js optimizations.

     *

     * @private

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.

     */

    function baseIsRegExp(value) {

      return isObjectLike(value) && baseGetTag(value) == regexpTag;

    }



    /**

     * The base implementation of `_.isSet` without Node.js optimizations.

     *

     * @private

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a set, else `false`.

     */

    function baseIsSet(value) {

      return isObjectLike(value) && getTag(value) == setTag;

    }



    /**

     * The base implementation of `_.isTypedArray` without Node.js optimizations.

     *

     * @private

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.

     */

    function baseIsTypedArray(value) {

      return isObjectLike(value) &&

        isLength(value.length) && !!typedArrayTags[baseGetTag(value)];

    }



    /**

     * The base implementation of `_.iteratee`.

     *

     * @private

     * @param {*} [value=_.identity] The value to convert to an iteratee.

     * @returns {Function} Returns the iteratee.

     */

    function baseIteratee(value) {

      // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.

      // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.

      if (typeof value == 'function') {

        return value;

      }

      if (value == null) {

        return identity;

      }

      if (typeof value == 'object') {

        return isArray(value)

          ? baseMatchesProperty(value[0], value[1])

          : baseMatches(value);

      }

      return property(value);

    }



    /**

     * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.

     *

     * @private

     * @param {Object} object The object to query.

     * @returns {Array} Returns the array of property names.

     */

    function baseKeys(object) {

      if (!isPrototype(object)) {

        return nativeKeys(object);

      }

      var result = [];

      for (var key in Object(object)) {

        if (hasOwnProperty.call(object, key) && key != 'constructor') {

          result.push(key);

        }

      }

      return result;

    }



    /**

     * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.

     *

     * @private

     * @param {Object} object The object to query.

     * @returns {Array} Returns the array of property names.

     */

    function baseKeysIn(object) {

      if (!isObject(object)) {

        return nativeKeysIn(object);

      }

      var isProto = isPrototype(object),

          result = [];



      for (var key in object) {

        if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {

          result.push(key);

        }

      }

      return result;

    }



    /**

     * The base implementation of `_.lt` which doesn't coerce arguments.

     *

     * @private

     * @param {*} value The value to compare.

     * @param {*} other The other value to compare.

     * @returns {boolean} Returns `true` if `value` is less than `other`,

     *  else `false`.

     */

    function baseLt(value, other) {

      return value < other;

    }



    /**

     * The base implementation of `_.map` without support for iteratee shorthands.

     *

     * @private

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Function} iteratee The function invoked per iteration.

     * @returns {Array} Returns the new mapped array.

     */

    function baseMap(collection, iteratee) {

      var index = -1,

          result = isArrayLike(collection) ? Array(collection.length) : [];



      baseEach(collection, function(value, key, collection) {

        result[++index] = iteratee(value, key, collection);

      });

      return result;

    }



    /**

     * The base implementation of `_.matches` which doesn't clone `source`.

     *

     * @private

     * @param {Object} source The object of property values to match.

     * @returns {Function} Returns the new spec function.

     */

    function baseMatches(source) {

      var matchData = getMatchData(source);

      if (matchData.length == 1 && matchData[0][2]) {

        return matchesStrictComparable(matchData[0][0], matchData[0][1]);

      }

      return function(object) {

        return object === source || baseIsMatch(object, source, matchData);

      };

    }



    /**

     * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.

     *

     * @private

     * @param {string} path The path of the property to get.

     * @param {*} srcValue The value to match.

     * @returns {Function} Returns the new spec function.

     */

    function baseMatchesProperty(path, srcValue) {

      if (isKey(path) && isStrictComparable(srcValue)) {

        return matchesStrictComparable(toKey(path), srcValue);

      }

      return function(object) {

        var objValue = get(object, path);

        return (objValue === undefined && objValue === srcValue)

          ? hasIn(object, path)

          : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);

      };

    }



    /**

     * The base implementation of `_.merge` without support for multiple sources.

     *

     * @private

     * @param {Object} object The destination object.

     * @param {Object} source The source object.

     * @param {number} srcIndex The index of `source`.

     * @param {Function} [customizer] The function to customize merged values.

     * @param {Object} [stack] Tracks traversed source values and their merged

     *  counterparts.

     */

    function baseMerge(object, source, srcIndex, customizer, stack) {

      if (object === source) {

        return;

      }

      baseFor(source, function(srcValue, key) {

        if (isObject(srcValue)) {

          stack || (stack = new Stack);

          baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);

        }

        else {

          var newValue = customizer

            ? customizer(object[key], srcValue, (key + ''), object, source, stack)

            : undefined;



          if (newValue === undefined) {

            newValue = srcValue;

          }

          assignMergeValue(object, key, newValue);

        }

      }, keysIn);

    }



    /**

     * A specialized version of `baseMerge` for arrays and objects which performs

     * deep merges and tracks traversed objects enabling objects with circular

     * references to be merged.

     *

     * @private

     * @param {Object} object The destination object.

     * @param {Object} source The source object.

     * @param {string} key The key of the value to merge.

     * @param {number} srcIndex The index of `source`.

     * @param {Function} mergeFunc The function to merge values.

     * @param {Function} [customizer] The function to customize assigned values.

     * @param {Object} [stack] Tracks traversed source values and their merged

     *  counterparts.

     */

    function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {

      var objValue = object[key],

          srcValue = source[key],

          stacked = stack.get(srcValue);



      if (stacked) {

        assignMergeValue(object, key, stacked);

        return;

      }

      var newValue = customizer

        ? customizer(objValue, srcValue, (key + ''), object, source, stack)

        : undefined;



      var isCommon = newValue === undefined;



      if (isCommon) {

        var isArr = isArray(srcValue),

            isBuff = !isArr && isBuffer(srcValue),

            isTyped = !isArr && !isBuff && isTypedArray(srcValue);



        newValue = srcValue;

        if (isArr || isBuff || isTyped) {

          if (isArray(objValue)) {

            newValue = objValue;

          }

          else if (isArrayLikeObject(objValue)) {

            newValue = copyArray(objValue);

          }

          else if (isBuff) {

            isCommon = false;

            newValue = cloneBuffer(srcValue, true);

          }

          else if (isTyped) {

            isCommon = false;

            newValue = cloneTypedArray(srcValue, true);

          }

          else {

            newValue = [];

          }

        }

        else if (isPlainObject(srcValue) || isArguments(srcValue)) {

          newValue = objValue;

          if (isArguments(objValue)) {

            newValue = toPlainObject(objValue);

          }

          else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {

            newValue = initCloneObject(srcValue);

          }

        }

        else {

          isCommon = false;

        }

      }

      if (isCommon) {

        // Recursively merge objects and arrays (susceptible to call stack limits).

        stack.set(srcValue, newValue);

        mergeFunc(newValue, srcValue, srcIndex, customizer, stack);

        stack['delete'](srcValue);

      }

      assignMergeValue(object, key, newValue);

    }



    /**

     * The base implementation of `_.nth` which doesn't coerce arguments.

     *

     * @private

     * @param {Array} array The array to query.

     * @param {number} n The index of the element to return.

     * @returns {*} Returns the nth element of `array`.

     */

    function baseNth(array, n) {

      var length = array.length;

      if (!length) {

        return;

      }

      n += n < 0 ? length : 0;

      return isIndex(n, length) ? array[n] : undefined;

    }



    /**

     * The base implementation of `_.orderBy` without param guards.

     *

     * @private

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.

     * @param {string[]} orders The sort orders of `iteratees`.

     * @returns {Array} Returns the new sorted array.

     */

    function baseOrderBy(collection, iteratees, orders) {

      var index = -1;

      iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee()));



      var result = baseMap(collection, function(value, key, collection) {

        var criteria = arrayMap(iteratees, function(iteratee) {

          return iteratee(value);

        });

        return { 'criteria': criteria, 'index': ++index, 'value': value };

      });



      return baseSortBy(result, function(object, other) {

        return compareMultiple(object, other, orders);

      });

    }



    /**

     * The base implementation of `_.pick` without support for individual

     * property identifiers.

     *

     * @private

     * @param {Object} object The source object.

     * @param {string[]} paths The property paths to pick.

     * @returns {Object} Returns the new object.

     */

    function basePick(object, paths) {

      return basePickBy(object, paths, function(value, path) {

        return hasIn(object, path);

      });

    }



    /**

     * The base implementation of  `_.pickBy` without support for iteratee shorthands.

     *

     * @private

     * @param {Object} object The source object.

     * @param {string[]} paths The property paths to pick.

     * @param {Function} predicate The function invoked per property.

     * @returns {Object} Returns the new object.

     */

    function basePickBy(object, paths, predicate) {

      var index = -1,

          length = paths.length,

          result = {};



      while (++index < length) {

        var path = paths[index],

            value = baseGet(object, path);



        if (predicate(value, path)) {

          baseSet(result, castPath(path, object), value);

        }

      }

      return result;

    }



    /**

     * A specialized version of `baseProperty` which supports deep paths.

     *

     * @private

     * @param {Array|string} path The path of the property to get.

     * @returns {Function} Returns the new accessor function.

     */

    function basePropertyDeep(path) {

      return function(object) {

        return baseGet(object, path);

      };

    }



    /**

     * The base implementation of `_.pullAllBy` without support for iteratee

     * shorthands.

     *

     * @private

     * @param {Array} array The array to modify.

     * @param {Array} values The values to remove.

     * @param {Function} [iteratee] The iteratee invoked per element.

     * @param {Function} [comparator] The comparator invoked per element.

     * @returns {Array} Returns `array`.

     */

    function basePullAll(array, values, iteratee, comparator) {

      var indexOf = comparator ? baseIndexOfWith : baseIndexOf,

          index = -1,

          length = values.length,

          seen = array;



      if (array === values) {

        values = copyArray(values);

      }

      if (iteratee) {

        seen = arrayMap(array, baseUnary(iteratee));

      }

      while (++index < length) {

        var fromIndex = 0,

            value = values[index],

            computed = iteratee ? iteratee(value) : value;



        while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {

          if (seen !== array) {

            splice.call(seen, fromIndex, 1);

          }

          splice.call(array, fromIndex, 1);

        }

      }

      return array;

    }



    /**

     * The base implementation of `_.pullAt` without support for individual

     * indexes or capturing the removed elements.

     *

     * @private

     * @param {Array} array The array to modify.

     * @param {number[]} indexes The indexes of elements to remove.

     * @returns {Array} Returns `array`.

     */

    function basePullAt(array, indexes) {

      var length = array ? indexes.length : 0,

          lastIndex = length - 1;



      while (length--) {

        var index = indexes[length];

        if (length == lastIndex || index !== previous) {

          var previous = index;

          if (isIndex(index)) {

            splice.call(array, index, 1);

          } else {

            baseUnset(array, index);

          }

        }

      }

      return array;

    }



    /**

     * The base implementation of `_.random` without support for returning

     * floating-point numbers.

     *

     * @private

     * @param {number} lower The lower bound.

     * @param {number} upper The upper bound.

     * @returns {number} Returns the random number.

     */

    function baseRandom(lower, upper) {

      return lower + nativeFloor(nativeRandom() * (upper - lower + 1));

    }



    /**

     * The base implementation of `_.range` and `_.rangeRight` which doesn't

     * coerce arguments.

     *

     * @private

     * @param {number} start The start of the range.

     * @param {number} end The end of the range.

     * @param {number} step The value to increment or decrement by.

     * @param {boolean} [fromRight] Specify iterating from right to left.

     * @returns {Array} Returns the range of numbers.

     */

    function baseRange(start, end, step, fromRight) {

      var index = -1,

          length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),

          result = Array(length);



      while (length--) {

        result[fromRight ? length : ++index] = start;

        start += step;

      }

      return result;

    }



    /**

     * The base implementation of `_.repeat` which doesn't coerce arguments.

     *

     * @private

     * @param {string} string The string to repeat.

     * @param {number} n The number of times to repeat the string.

     * @returns {string} Returns the repeated string.

     */

    function baseRepeat(string, n) {

      var result = '';

      if (!string || n < 1 || n > MAX_SAFE_INTEGER) {

        return result;

      }

      // Leverage the exponentiation by squaring algorithm for a faster repeat.

      // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.

      do {

        if (n % 2) {

          result += string;

        }

        n = nativeFloor(n / 2);

        if (n) {

          string += string;

        }

      } while (n);



      return result;

    }



    /**

     * The base implementation of `_.rest` which doesn't validate or coerce arguments.

     *

     * @private

     * @param {Function} func The function to apply a rest parameter to.

     * @param {number} [start=func.length-1] The start position of the rest parameter.

     * @returns {Function} Returns the new function.

     */

    function baseRest(func, start) {

      return setToString(overRest(func, start, identity), func + '');

    }



    /**

     * The base implementation of `_.sample`.

     *

     * @private

     * @param {Array|Object} collection The collection to sample.

     * @returns {*} Returns the random element.

     */

    function baseSample(collection) {

      return arraySample(values(collection));

    }



    /**

     * The base implementation of `_.sampleSize` without param guards.

     *

     * @private

     * @param {Array|Object} collection The collection to sample.

     * @param {number} n The number of elements to sample.

     * @returns {Array} Returns the random elements.

     */

    function baseSampleSize(collection, n) {

      var array = values(collection);

      return shuffleSelf(array, baseClamp(n, 0, array.length));

    }



    /**

     * The base implementation of `_.set`.

     *

     * @private

     * @param {Object} object The object to modify.

     * @param {Array|string} path The path of the property to set.

     * @param {*} value The value to set.

     * @param {Function} [customizer] The function to customize path creation.

     * @returns {Object} Returns `object`.

     */

    function baseSet(object, path, value, customizer) {

      if (!isObject(object)) {

        return object;

      }

      path = castPath(path, object);



      var index = -1,

          length = path.length,

          lastIndex = length - 1,

          nested = object;



      while (nested != null && ++index < length) {

        var key = toKey(path[index]),

            newValue = value;



        if (index != lastIndex) {

          var objValue = nested[key];

          newValue = customizer ? customizer(objValue, key, nested) : undefined;

          if (newValue === undefined) {

            newValue = isObject(objValue)

              ? objValue

              : (isIndex(path[index + 1]) ? [] : {});

          }

        }

        assignValue(nested, key, newValue);

        nested = nested[key];

      }

      return object;

    }



    /**

     * The base implementation of `setData` without support for hot loop shorting.

     *

     * @private

     * @param {Function} func The function to associate metadata with.

     * @param {*} data The metadata.

     * @returns {Function} Returns `func`.

     */

    var baseSetData = !metaMap ? identity : function(func, data) {

      metaMap.set(func, data);

      return func;

    };



    /**

     * The base implementation of `setToString` without support for hot loop shorting.

     *

     * @private

     * @param {Function} func The function to modify.

     * @param {Function} string The `toString` result.

     * @returns {Function} Returns `func`.

     */

    var baseSetToString = !defineProperty ? identity : function(func, string) {

      return defineProperty(func, 'toString', {

        'configurable': true,

        'enumerable': false,

        'value': constant(string),

        'writable': true

      });

    };



    /**

     * The base implementation of `_.shuffle`.

     *

     * @private

     * @param {Array|Object} collection The collection to shuffle.

     * @returns {Array} Returns the new shuffled array.

     */

    function baseShuffle(collection) {

      return shuffleSelf(values(collection));

    }



    /**

     * The base implementation of `_.slice` without an iteratee call guard.

     *

     * @private

     * @param {Array} array The array to slice.

     * @param {number} [start=0] The start position.

     * @param {number} [end=array.length] The end position.

     * @returns {Array} Returns the slice of `array`.

     */

    function baseSlice(array, start, end) {

      var index = -1,

          length = array.length;



      if (start < 0) {

        start = -start > length ? 0 : (length + start);

      }

      end = end > length ? length : end;

      if (end < 0) {

        end += length;

      }

      length = start > end ? 0 : ((end - start) >>> 0);

      start >>>= 0;



      var result = Array(length);

      while (++index < length) {

        result[index] = array[index + start];

      }

      return result;

    }



    /**

     * The base implementation of `_.some` without support for iteratee shorthands.

     *

     * @private

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Function} predicate The function invoked per iteration.

     * @returns {boolean} Returns `true` if any element passes the predicate check,

     *  else `false`.

     */

    function baseSome(collection, predicate) {

      var result;



      baseEach(collection, function(value, index, collection) {

        result = predicate(value, index, collection);

        return !result;

      });

      return !!result;

    }



    /**

     * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which

     * performs a binary search of `array` to determine the index at which `value`

     * should be inserted into `array` in order to maintain its sort order.

     *

     * @private

     * @param {Array} array The sorted array to inspect.

     * @param {*} value The value to evaluate.

     * @param {boolean} [retHighest] Specify returning the highest qualified index.

     * @returns {number} Returns the index at which `value` should be inserted

     *  into `array`.

     */

    function baseSortedIndex(array, value, retHighest) {

      var low = 0,

          high = array == null ? low : array.length;



      if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {

        while (low < high) {

          var mid = (low + high) >>> 1,

              computed = array[mid];



          if (computed !== null && !isSymbol(computed) &&

              (retHighest ? (computed <= value) : (computed < value))) {

            low = mid + 1;

          } else {

            high = mid;

          }

        }

        return high;

      }

      return baseSortedIndexBy(array, value, identity, retHighest);

    }



    /**

     * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`

     * which invokes `iteratee` for `value` and each element of `array` to compute

     * their sort ranking. The iteratee is invoked with one argument; (value).

     *

     * @private

     * @param {Array} array The sorted array to inspect.

     * @param {*} value The value to evaluate.

     * @param {Function} iteratee The iteratee invoked per element.

     * @param {boolean} [retHighest] Specify returning the highest qualified index.

     * @returns {number} Returns the index at which `value` should be inserted

     *  into `array`.

     */

    function baseSortedIndexBy(array, value, iteratee, retHighest) {

      value = iteratee(value);



      var low = 0,

          high = array == null ? 0 : array.length,

          valIsNaN = value !== value,

          valIsNull = value === null,

          valIsSymbol = isSymbol(value),

          valIsUndefined = value === undefined;



      while (low < high) {

        var mid = nativeFloor((low + high) / 2),

            computed = iteratee(array[mid]),

            othIsDefined = computed !== undefined,

            othIsNull = computed === null,

            othIsReflexive = computed === computed,

            othIsSymbol = isSymbol(computed);



        if (valIsNaN) {

          var setLow = retHighest || othIsReflexive;

        } else if (valIsUndefined) {

          setLow = othIsReflexive && (retHighest || othIsDefined);

        } else if (valIsNull) {

          setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);

        } else if (valIsSymbol) {

          setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);

        } else if (othIsNull || othIsSymbol) {

          setLow = false;

        } else {

          setLow = retHighest ? (computed <= value) : (computed < value);

        }

        if (setLow) {

          low = mid + 1;

        } else {

          high = mid;

        }

      }

      return nativeMin(high, MAX_ARRAY_INDEX);

    }



    /**

     * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without

     * support for iteratee shorthands.

     *

     * @private

     * @param {Array} array The array to inspect.

     * @param {Function} [iteratee] The iteratee invoked per element.

     * @returns {Array} Returns the new duplicate free array.

     */

    function baseSortedUniq(array, iteratee) {

      var index = -1,

          length = array.length,

          resIndex = 0,

          result = [];



      while (++index < length) {

        var value = array[index],

            computed = iteratee ? iteratee(value) : value;



        if (!index || !eq(computed, seen)) {

          var seen = computed;

          result[resIndex++] = value === 0 ? 0 : value;

        }

      }

      return result;

    }



    /**

     * The base implementation of `_.toNumber` which doesn't ensure correct

     * conversions of binary, hexadecimal, or octal string values.

     *

     * @private

     * @param {*} value The value to process.

     * @returns {number} Returns the number.

     */

    function baseToNumber(value) {

      if (typeof value == 'number') {

        return value;

      }

      if (isSymbol(value)) {

        return NAN;

      }

      return +value;

    }



    /**

     * The base implementation of `_.toString` which doesn't convert nullish

     * values to empty strings.

     *

     * @private

     * @param {*} value The value to process.

     * @returns {string} Returns the string.

     */

    function baseToString(value) {

      // Exit early for strings to avoid a performance hit in some environments.

      if (typeof value == 'string') {

        return value;

      }

      if (isArray(value)) {

        // Recursively convert values (susceptible to call stack limits).

        return arrayMap(value, baseToString) + '';

      }

      if (isSymbol(value)) {

        return symbolToString ? symbolToString.call(value) : '';

      }

      var result = (value + '');

      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;

    }



    /**

     * The base implementation of `_.uniqBy` without support for iteratee shorthands.

     *

     * @private

     * @param {Array} array The array to inspect.

     * @param {Function} [iteratee] The iteratee invoked per element.

     * @param {Function} [comparator] The comparator invoked per element.

     * @returns {Array} Returns the new duplicate free array.

     */

    function baseUniq(array, iteratee, comparator) {

      var index = -1,

          includes = arrayIncludes,

          length = array.length,

          isCommon = true,

          result = [],

          seen = result;



      if (comparator) {

        isCommon = false;

        includes = arrayIncludesWith;

      }

      else if (length >= LARGE_ARRAY_SIZE) {

        var set = iteratee ? null : createSet(array);

        if (set) {

          return setToArray(set);

        }

        isCommon = false;

        includes = cacheHas;

        seen = new SetCache;

      }

      else {

        seen = iteratee ? [] : result;

      }

      outer:

      while (++index < length) {

        var value = array[index],

            computed = iteratee ? iteratee(value) : value;



        value = (comparator || value !== 0) ? value : 0;

        if (isCommon && computed === computed) {

          var seenIndex = seen.length;

          while (seenIndex--) {

            if (seen[seenIndex] === computed) {

              continue outer;

            }

          }

          if (iteratee) {

            seen.push(computed);

          }

          result.push(value);

        }

        else if (!includes(seen, computed, comparator)) {

          if (seen !== result) {

            seen.push(computed);

          }

          result.push(value);

        }

      }

      return result;

    }



    /**

     * The base implementation of `_.unset`.

     *

     * @private

     * @param {Object} object The object to modify.

     * @param {Array|string} path The property path to unset.

     * @returns {boolean} Returns `true` if the property is deleted, else `false`.

     */

    function baseUnset(object, path) {

      path = castPath(path, object);

      object = parent(object, path);

      return object == null || delete object[toKey(last(path))];

    }



    /**

     * The base implementation of `_.update`.

     *

     * @private

     * @param {Object} object The object to modify.

     * @param {Array|string} path The path of the property to update.

     * @param {Function} updater The function to produce the updated value.

     * @param {Function} [customizer] The function to customize path creation.

     * @returns {Object} Returns `object`.

     */

    function baseUpdate(object, path, updater, customizer) {

      return baseSet(object, path, updater(baseGet(object, path)), customizer);

    }



    /**

     * The base implementation of methods like `_.dropWhile` and `_.takeWhile`

     * without support for iteratee shorthands.

     *

     * @private

     * @param {Array} array The array to query.

     * @param {Function} predicate The function invoked per iteration.

     * @param {boolean} [isDrop] Specify dropping elements instead of taking them.

     * @param {boolean} [fromRight] Specify iterating from right to left.

     * @returns {Array} Returns the slice of `array`.

     */

    function baseWhile(array, predicate, isDrop, fromRight) {

      var length = array.length,

          index = fromRight ? length : -1;



      while ((fromRight ? index-- : ++index < length) &&

        predicate(array[index], index, array)) {}



      return isDrop

        ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))

        : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));

    }



    /**

     * The base implementation of `wrapperValue` which returns the result of

     * performing a sequence of actions on the unwrapped `value`, where each

     * successive action is supplied the return value of the previous.

     *

     * @private

     * @param {*} value The unwrapped value.

     * @param {Array} actions Actions to perform to resolve the unwrapped value.

     * @returns {*} Returns the resolved value.

     */

    function baseWrapperValue(value, actions) {

      var result = value;

      if (result instanceof LazyWrapper) {

        result = result.value();

      }

      return arrayReduce(actions, function(result, action) {

        return action.func.apply(action.thisArg, arrayPush([result], action.args));

      }, result);

    }



    /**

     * The base implementation of methods like `_.xor`, without support for

     * iteratee shorthands, that accepts an array of arrays to inspect.

     *

     * @private

     * @param {Array} arrays The arrays to inspect.

     * @param {Function} [iteratee] The iteratee invoked per element.

     * @param {Function} [comparator] The comparator invoked per element.

     * @returns {Array} Returns the new array of values.

     */

    function baseXor(arrays, iteratee, comparator) {

      var length = arrays.length;

      if (length < 2) {

        return length ? baseUniq(arrays[0]) : [];

      }

      var index = -1,

          result = Array(length);



      while (++index < length) {

        var array = arrays[index],

            othIndex = -1;



        while (++othIndex < length) {

          if (othIndex != index) {

            result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);

          }

        }

      }

      return baseUniq(baseFlatten(result, 1), iteratee, comparator);

    }



    /**

     * This base implementation of `_.zipObject` which assigns values using `assignFunc`.

     *

     * @private

     * @param {Array} props The property identifiers.

     * @param {Array} values The property values.

     * @param {Function} assignFunc The function to assign values.

     * @returns {Object} Returns the new object.

     */

    function baseZipObject(props, values, assignFunc) {

      var index = -1,

          length = props.length,

          valsLength = values.length,

          result = {};



      while (++index < length) {

        var value = index < valsLength ? values[index] : undefined;

        assignFunc(result, props[index], value);

      }

      return result;

    }



    /**

     * Casts `value` to an empty array if it's not an array like object.

     *

     * @private

     * @param {*} value The value to inspect.

     * @returns {Array|Object} Returns the cast array-like object.

     */

    function castArrayLikeObject(value) {

      return isArrayLikeObject(value) ? value : [];

    }



    /**

     * Casts `value` to `identity` if it's not a function.

     *

     * @private

     * @param {*} value The value to inspect.

     * @returns {Function} Returns cast function.

     */

    function castFunction(value) {

      return typeof value == 'function' ? value : identity;

    }



    /**

     * Casts `value` to a path array if it's not one.

     *

     * @private

     * @param {*} value The value to inspect.

     * @param {Object} [object] The object to query keys on.

     * @returns {Array} Returns the cast property path array.

     */

    function castPath(value, object) {

      if (isArray(value)) {

        return value;

      }

      return isKey(value, object) ? [value] : stringToPath(toString(value));

    }



    /**

     * A `baseRest` alias which can be replaced with `identity` by module

     * replacement plugins.

     *

     * @private

     * @type {Function}

     * @param {Function} func The function to apply a rest parameter to.

     * @returns {Function} Returns the new function.

     */

    var castRest = baseRest;



    /**

     * Casts `array` to a slice if it's needed.

     *

     * @private

     * @param {Array} array The array to inspect.

     * @param {number} start The start position.

     * @param {number} [end=array.length] The end position.

     * @returns {Array} Returns the cast slice.

     */

    function castSlice(array, start, end) {

      var length = array.length;

      end = end === undefined ? length : end;

      return (!start && end >= length) ? array : baseSlice(array, start, end);

    }



    /**

     * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).

     *

     * @private

     * @param {number|Object} id The timer id or timeout object of the timer to clear.

     */

    var clearTimeout = ctxClearTimeout || function(id) {

      return root.clearTimeout(id);

    };



    /**

     * Creates a clone of  `buffer`.

     *

     * @private

     * @param {Buffer} buffer The buffer to clone.

     * @param {boolean} [isDeep] Specify a deep clone.

     * @returns {Buffer} Returns the cloned buffer.

     */

    function cloneBuffer(buffer, isDeep) {

      if (isDeep) {

        return buffer.slice();

      }

      var length = buffer.length,

          result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);



      buffer.copy(result);

      return result;

    }



    /**

     * Creates a clone of `arrayBuffer`.

     *

     * @private

     * @param {ArrayBuffer} arrayBuffer The array buffer to clone.

     * @returns {ArrayBuffer} Returns the cloned array buffer.

     */

    function cloneArrayBuffer(arrayBuffer) {

      var result = new arrayBuffer.constructor(arrayBuffer.byteLength);

      new Uint8Array(result).set(new Uint8Array(arrayBuffer));

      return result;

    }



    /**

     * Creates a clone of `dataView`.

     *

     * @private

     * @param {Object} dataView The data view to clone.

     * @param {boolean} [isDeep] Specify a deep clone.

     * @returns {Object} Returns the cloned data view.

     */

    function cloneDataView(dataView, isDeep) {

      var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;

      return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);

    }



    /**

     * Creates a clone of `map`.

     *

     * @private

     * @param {Object} map The map to clone.

     * @param {Function} cloneFunc The function to clone values.

     * @param {boolean} [isDeep] Specify a deep clone.

     * @returns {Object} Returns the cloned map.

     */

    function cloneMap(map, isDeep, cloneFunc) {

      var array = isDeep ? cloneFunc(mapToArray(map), CLONE_DEEP_FLAG) : mapToArray(map);

      return arrayReduce(array, addMapEntry, new map.constructor);

    }



    /**

     * Creates a clone of `regexp`.

     *

     * @private

     * @param {Object} regexp The regexp to clone.

     * @returns {Object} Returns the cloned regexp.

     */

    function cloneRegExp(regexp) {

      var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));

      result.lastIndex = regexp.lastIndex;

      return result;

    }



    /**

     * Creates a clone of `set`.

     *

     * @private

     * @param {Object} set The set to clone.

     * @param {Function} cloneFunc The function to clone values.

     * @param {boolean} [isDeep] Specify a deep clone.

     * @returns {Object} Returns the cloned set.

     */

    function cloneSet(set, isDeep, cloneFunc) {

      var array = isDeep ? cloneFunc(setToArray(set), CLONE_DEEP_FLAG) : setToArray(set);

      return arrayReduce(array, addSetEntry, new set.constructor);

    }



    /**

     * Creates a clone of the `symbol` object.

     *

     * @private

     * @param {Object} symbol The symbol object to clone.

     * @returns {Object} Returns the cloned symbol object.

     */

    function cloneSymbol(symbol) {

      return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};

    }



    /**

     * Creates a clone of `typedArray`.

     *

     * @private

     * @param {Object} typedArray The typed array to clone.

     * @param {boolean} [isDeep] Specify a deep clone.

     * @returns {Object} Returns the cloned typed array.

     */

    function cloneTypedArray(typedArray, isDeep) {

      var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;

      return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);

    }



    /**

     * Compares values to sort them in ascending order.

     *

     * @private

     * @param {*} value The value to compare.

     * @param {*} other The other value to compare.

     * @returns {number} Returns the sort order indicator for `value`.

     */

    function compareAscending(value, other) {

      if (value !== other) {

        var valIsDefined = value !== undefined,

            valIsNull = value === null,

            valIsReflexive = value === value,

            valIsSymbol = isSymbol(value);



        var othIsDefined = other !== undefined,

            othIsNull = other === null,

            othIsReflexive = other === other,

            othIsSymbol = isSymbol(other);



        if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||

            (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||

            (valIsNull && othIsDefined && othIsReflexive) ||

            (!valIsDefined && othIsReflexive) ||

            !valIsReflexive) {

          return 1;

        }

        if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||

            (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||

            (othIsNull && valIsDefined && valIsReflexive) ||

            (!othIsDefined && valIsReflexive) ||

            !othIsReflexive) {

          return -1;

        }

      }

      return 0;

    }



    /**

     * Used by `_.orderBy` to compare multiple properties of a value to another

     * and stable sort them.

     *

     * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,

     * specify an order of "desc" for descending or "asc" for ascending sort order

     * of corresponding values.

     *

     * @private

     * @param {Object} object The object to compare.

     * @param {Object} other The other object to compare.

     * @param {boolean[]|string[]} orders The order to sort by for each property.

     * @returns {number} Returns the sort order indicator for `object`.

     */

    function compareMultiple(object, other, orders) {

      var index = -1,

          objCriteria = object.criteria,

          othCriteria = other.criteria,

          length = objCriteria.length,

          ordersLength = orders.length;



      while (++index < length) {

        var result = compareAscending(objCriteria[index], othCriteria[index]);

        if (result) {

          if (index >= ordersLength) {

            return result;

          }

          var order = orders[index];

          return result * (order == 'desc' ? -1 : 1);

        }

      }

      // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications

      // that causes it, under certain circumstances, to provide the same value for

      // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247

      // for more details.

      //

      // This also ensures a stable sort in V8 and other engines.

      // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.

      return object.index - other.index;

    }



    /**

     * Creates an array that is the composition of partially applied arguments,

     * placeholders, and provided arguments into a single array of arguments.

     *

     * @private

     * @param {Array} args The provided arguments.

     * @param {Array} partials The arguments to prepend to those provided.

     * @param {Array} holders The `partials` placeholder indexes.

     * @params {boolean} [isCurried] Specify composing for a curried function.

     * @returns {Array} Returns the new array of composed arguments.

     */

    function composeArgs(args, partials, holders, isCurried) {

      var argsIndex = -1,

          argsLength = args.length,

          holdersLength = holders.length,

          leftIndex = -1,

          leftLength = partials.length,

          rangeLength = nativeMax(argsLength - holdersLength, 0),

          result = Array(leftLength + rangeLength),

          isUncurried = !isCurried;



      while (++leftIndex < leftLength) {

        result[leftIndex] = partials[leftIndex];

      }

      while (++argsIndex < holdersLength) {

        if (isUncurried || argsIndex < argsLength) {

          result[holders[argsIndex]] = args[argsIndex];

        }

      }

      while (rangeLength--) {

        result[leftIndex++] = args[argsIndex++];

      }

      return result;

    }



    /**

     * This function is like `composeArgs` except that the arguments composition

     * is tailored for `_.partialRight`.

     *

     * @private

     * @param {Array} args The provided arguments.

     * @param {Array} partials The arguments to append to those provided.

     * @param {Array} holders The `partials` placeholder indexes.

     * @params {boolean} [isCurried] Specify composing for a curried function.

     * @returns {Array} Returns the new array of composed arguments.

     */

    function composeArgsRight(args, partials, holders, isCurried) {

      var argsIndex = -1,

          argsLength = args.length,

          holdersIndex = -1,

          holdersLength = holders.length,

          rightIndex = -1,

          rightLength = partials.length,

          rangeLength = nativeMax(argsLength - holdersLength, 0),

          result = Array(rangeLength + rightLength),

          isUncurried = !isCurried;



      while (++argsIndex < rangeLength) {

        result[argsIndex] = args[argsIndex];

      }

      var offset = argsIndex;

      while (++rightIndex < rightLength) {

        result[offset + rightIndex] = partials[rightIndex];

      }

      while (++holdersIndex < holdersLength) {

        if (isUncurried || argsIndex < argsLength) {

          result[offset + holders[holdersIndex]] = args[argsIndex++];

        }

      }

      return result;

    }



    /**

     * Copies the values of `source` to `array`.

     *

     * @private

     * @param {Array} source The array to copy values from.

     * @param {Array} [array=[]] The array to copy values to.

     * @returns {Array} Returns `array`.

     */

    function copyArray(source, array) {

      var index = -1,

          length = source.length;



      array || (array = Array(length));

      while (++index < length) {

        array[index] = source[index];

      }

      return array;

    }



    /**

     * Copies properties of `source` to `object`.

     *

     * @private

     * @param {Object} source The object to copy properties from.

     * @param {Array} props The property identifiers to copy.

     * @param {Object} [object={}] The object to copy properties to.

     * @param {Function} [customizer] The function to customize copied values.

     * @returns {Object} Returns `object`.

     */

    function copyObject(source, props, object, customizer) {

      var isNew = !object;

      object || (object = {});



      var index = -1,

          length = props.length;



      while (++index < length) {

        var key = props[index];



        var newValue = customizer

          ? customizer(object[key], source[key], key, object, source)

          : undefined;



        if (newValue === undefined) {

          newValue = source[key];

        }

        if (isNew) {

          baseAssignValue(object, key, newValue);

        } else {

          assignValue(object, key, newValue);

        }

      }

      return object;

    }



    /**

     * Copies own symbols of `source` to `object`.

     *

     * @private

     * @param {Object} source The object to copy symbols from.

     * @param {Object} [object={}] The object to copy symbols to.

     * @returns {Object} Returns `object`.

     */

    function copySymbols(source, object) {

      return copyObject(source, getSymbols(source), object);

    }



    /**

     * Copies own and inherited symbols of `source` to `object`.

     *

     * @private

     * @param {Object} source The object to copy symbols from.

     * @param {Object} [object={}] The object to copy symbols to.

     * @returns {Object} Returns `object`.

     */

    function copySymbolsIn(source, object) {

      return copyObject(source, getSymbolsIn(source), object);

    }



    /**

     * Creates a function like `_.groupBy`.

     *

     * @private

     * @param {Function} setter The function to set accumulator values.

     * @param {Function} [initializer] The accumulator object initializer.

     * @returns {Function} Returns the new aggregator function.

     */

    function createAggregator(setter, initializer) {

      return function(collection, iteratee) {

        var func = isArray(collection) ? arrayAggregator : baseAggregator,

            accumulator = initializer ? initializer() : {};



        return func(collection, setter, getIteratee(iteratee, 2), accumulator);

      };

    }



    /**

     * Creates a function like `_.assign`.

     *

     * @private

     * @param {Function} assigner The function to assign values.

     * @returns {Function} Returns the new assigner function.

     */

    function createAssigner(assigner) {

      return baseRest(function(object, sources) {

        var index = -1,

            length = sources.length,

            customizer = length > 1 ? sources[length - 1] : undefined,

            guard = length > 2 ? sources[2] : undefined;



        customizer = (assigner.length > 3 && typeof customizer == 'function')

          ? (length--, customizer)

          : undefined;



        if (guard && isIterateeCall(sources[0], sources[1], guard)) {

          customizer = length < 3 ? undefined : customizer;

          length = 1;

        }

        object = Object(object);

        while (++index < length) {

          var source = sources[index];

          if (source) {

            assigner(object, source, index, customizer);

          }

        }

        return object;

      });

    }



    /**

     * Creates a `baseEach` or `baseEachRight` function.

     *

     * @private

     * @param {Function} eachFunc The function to iterate over a collection.

     * @param {boolean} [fromRight] Specify iterating from right to left.

     * @returns {Function} Returns the new base function.

     */

    function createBaseEach(eachFunc, fromRight) {

      return function(collection, iteratee) {

        if (collection == null) {

          return collection;

        }

        if (!isArrayLike(collection)) {

          return eachFunc(collection, iteratee);

        }

        var length = collection.length,

            index = fromRight ? length : -1,

            iterable = Object(collection);



        while ((fromRight ? index-- : ++index < length)) {

          if (iteratee(iterable[index], index, iterable) === false) {

            break;

          }

        }

        return collection;

      };

    }



    /**

     * Creates a base function for methods like `_.forIn` and `_.forOwn`.

     *

     * @private

     * @param {boolean} [fromRight] Specify iterating from right to left.

     * @returns {Function} Returns the new base function.

     */

    function createBaseFor(fromRight) {

      return function(object, iteratee, keysFunc) {

        var index = -1,

            iterable = Object(object),

            props = keysFunc(object),

            length = props.length;



        while (length--) {

          var key = props[fromRight ? length : ++index];

          if (iteratee(iterable[key], key, iterable) === false) {

            break;

          }

        }

        return object;

      };

    }



    /**

     * Creates a function that wraps `func` to invoke it with the optional `this`

     * binding of `thisArg`.

     *

     * @private

     * @param {Function} func The function to wrap.

     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.

     * @param {*} [thisArg] The `this` binding of `func`.

     * @returns {Function} Returns the new wrapped function.

     */

    function createBind(func, bitmask, thisArg) {

      var isBind = bitmask & WRAP_BIND_FLAG,

          Ctor = createCtor(func);



      function wrapper() {

        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;

        return fn.apply(isBind ? thisArg : this, arguments);

      }

      return wrapper;

    }



    /**

     * Creates a function like `_.lowerFirst`.

     *

     * @private

     * @param {string} methodName The name of the `String` case method to use.

     * @returns {Function} Returns the new case function.

     */

    function createCaseFirst(methodName) {

      return function(string) {

        string = toString(string);



        var strSymbols = hasUnicode(string)

          ? stringToArray(string)

          : undefined;



        var chr = strSymbols

          ? strSymbols[0]

          : string.charAt(0);



        var trailing = strSymbols

          ? castSlice(strSymbols, 1).join('')

          : string.slice(1);



        return chr[methodName]() + trailing;

      };

    }



    /**

     * Creates a function like `_.camelCase`.

     *

     * @private

     * @param {Function} callback The function to combine each word.

     * @returns {Function} Returns the new compounder function.

     */

    function createCompounder(callback) {

      return function(string) {

        return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');

      };

    }



    /**

     * Creates a function that produces an instance of `Ctor` regardless of

     * whether it was invoked as part of a `new` expression or by `call` or `apply`.

     *

     * @private

     * @param {Function} Ctor The constructor to wrap.

     * @returns {Function} Returns the new wrapped function.

     */

    function createCtor(Ctor) {

      return function() {

        // Use a `switch` statement to work with class constructors. See

        // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist

        // for more details.

        var args = arguments;

        switch (args.length) {

          case 0: return new Ctor;

          case 1: return new Ctor(args[0]);

          case 2: return new Ctor(args[0], args[1]);

          case 3: return new Ctor(args[0], args[1], args[2]);

          case 4: return new Ctor(args[0], args[1], args[2], args[3]);

          case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);

          case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);

          case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);

        }

        var thisBinding = baseCreate(Ctor.prototype),

            result = Ctor.apply(thisBinding, args);



        // Mimic the constructor's `return` behavior.

        // See https://es5.github.io/#x13.2.2 for more details.

        return isObject(result) ? result : thisBinding;

      };

    }



    /**

     * Creates a function that wraps `func` to enable currying.

     *

     * @private

     * @param {Function} func The function to wrap.

     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.

     * @param {number} arity The arity of `func`.

     * @returns {Function} Returns the new wrapped function.

     */

    function createCurry(func, bitmask, arity) {

      var Ctor = createCtor(func);



      function wrapper() {

        var length = arguments.length,

            args = Array(length),

            index = length,

            placeholder = getHolder(wrapper);



        while (index--) {

          args[index] = arguments[index];

        }

        var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)

          ? []

          : replaceHolders(args, placeholder);



        length -= holders.length;

        if (length < arity) {

          return createRecurry(

            func, bitmask, createHybrid, wrapper.placeholder, undefined,

            args, holders, undefined, undefined, arity - length);

        }

        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;

        return apply(fn, this, args);

      }

      return wrapper;

    }



    /**

     * Creates a `_.find` or `_.findLast` function.

     *

     * @private

     * @param {Function} findIndexFunc The function to find the collection index.

     * @returns {Function} Returns the new find function.

     */

    function createFind(findIndexFunc) {

      return function(collection, predicate, fromIndex) {

        var iterable = Object(collection);

        if (!isArrayLike(collection)) {

          var iteratee = getIteratee(predicate, 3);

          collection = keys(collection);

          predicate = function(key) { return iteratee(iterable[key], key, iterable); };

        }

        var index = findIndexFunc(collection, predicate, fromIndex);

        return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;

      };

    }



    /**

     * Creates a `_.flow` or `_.flowRight` function.

     *

     * @private

     * @param {boolean} [fromRight] Specify iterating from right to left.

     * @returns {Function} Returns the new flow function.

     */

    function createFlow(fromRight) {

      return flatRest(function(funcs) {

        var length = funcs.length,

            index = length,

            prereq = LodashWrapper.prototype.thru;



        if (fromRight) {

          funcs.reverse();

        }

        while (index--) {

          var func = funcs[index];

          if (typeof func != 'function') {

            throw new TypeError(FUNC_ERROR_TEXT);

          }

          if (prereq && !wrapper && getFuncName(func) == 'wrapper') {

            var wrapper = new LodashWrapper([], true);

          }

        }

        index = wrapper ? index : length;

        while (++index < length) {

          func = funcs[index];



          var funcName = getFuncName(func),

              data = funcName == 'wrapper' ? getData(func) : undefined;



          if (data && isLaziable(data[0]) &&

                data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&

                !data[4].length && data[9] == 1

              ) {

            wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);

          } else {

            wrapper = (func.length == 1 && isLaziable(func))

              ? wrapper[funcName]()

              : wrapper.thru(func);

          }

        }

        return function() {

          var args = arguments,

              value = args[0];



          if (wrapper && args.length == 1 && isArray(value)) {

            return wrapper.plant(value).value();

          }

          var index = 0,

              result = length ? funcs[index].apply(this, args) : value;



          while (++index < length) {

            result = funcs[index].call(this, result);

          }

          return result;

        };

      });

    }



    /**

     * Creates a function that wraps `func` to invoke it with optional `this`

     * binding of `thisArg`, partial application, and currying.

     *

     * @private

     * @param {Function|string} func The function or method name to wrap.

     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.

     * @param {*} [thisArg] The `this` binding of `func`.

     * @param {Array} [partials] The arguments to prepend to those provided to

     *  the new function.

     * @param {Array} [holders] The `partials` placeholder indexes.

     * @param {Array} [partialsRight] The arguments to append to those provided

     *  to the new function.

     * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.

     * @param {Array} [argPos] The argument positions of the new function.

     * @param {number} [ary] The arity cap of `func`.

     * @param {number} [arity] The arity of `func`.

     * @returns {Function} Returns the new wrapped function.

     */

    function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {

      var isAry = bitmask & WRAP_ARY_FLAG,

          isBind = bitmask & WRAP_BIND_FLAG,

          isBindKey = bitmask & WRAP_BIND_KEY_FLAG,

          isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),

          isFlip = bitmask & WRAP_FLIP_FLAG,

          Ctor = isBindKey ? undefined : createCtor(func);



      function wrapper() {

        var length = arguments.length,

            args = Array(length),

            index = length;



        while (index--) {

          args[index] = arguments[index];

        }

        if (isCurried) {

          var placeholder = getHolder(wrapper),

              holdersCount = countHolders(args, placeholder);

        }

        if (partials) {

          args = composeArgs(args, partials, holders, isCurried);

        }

        if (partialsRight) {

          args = composeArgsRight(args, partialsRight, holdersRight, isCurried);

        }

        length -= holdersCount;

        if (isCurried && length < arity) {

          var newHolders = replaceHolders(args, placeholder);

          return createRecurry(

            func, bitmask, createHybrid, wrapper.placeholder, thisArg,

            args, newHolders, argPos, ary, arity - length

          );

        }

        var thisBinding = isBind ? thisArg : this,

            fn = isBindKey ? thisBinding[func] : func;



        length = args.length;

        if (argPos) {

          args = reorder(args, argPos);

        } else if (isFlip && length > 1) {

          args.reverse();

        }

        if (isAry && ary < length) {

          args.length = ary;

        }

        if (this && this !== root && this instanceof wrapper) {

          fn = Ctor || createCtor(fn);

        }

        return fn.apply(thisBinding, args);

      }

      return wrapper;

    }



    /**

     * Creates a function like `_.invertBy`.

     *

     * @private

     * @param {Function} setter The function to set accumulator values.

     * @param {Function} toIteratee The function to resolve iteratees.

     * @returns {Function} Returns the new inverter function.

     */

    function createInverter(setter, toIteratee) {

      return function(object, iteratee) {

        return baseInverter(object, setter, toIteratee(iteratee), {});

      };

    }



    /**

     * Creates a function that performs a mathematical operation on two values.

     *

     * @private

     * @param {Function} operator The function to perform the operation.

     * @param {number} [defaultValue] The value used for `undefined` arguments.

     * @returns {Function} Returns the new mathematical operation function.

     */

    function createMathOperation(operator, defaultValue) {

      return function(value, other) {

        var result;

        if (value === undefined && other === undefined) {

          return defaultValue;

        }

        if (value !== undefined) {

          result = value;

        }

        if (other !== undefined) {

          if (result === undefined) {

            return other;

          }

          if (typeof value == 'string' || typeof other == 'string') {

            value = baseToString(value);

            other = baseToString(other);

          } else {

            value = baseToNumber(value);

            other = baseToNumber(other);

          }

          result = operator(value, other);

        }

        return result;

      };

    }



    /**

     * Creates a function like `_.over`.

     *

     * @private

     * @param {Function} arrayFunc The function to iterate over iteratees.

     * @returns {Function} Returns the new over function.

     */

    function createOver(arrayFunc) {

      return flatRest(function(iteratees) {

        iteratees = arrayMap(iteratees, baseUnary(getIteratee()));

        return baseRest(function(args) {

          var thisArg = this;

          return arrayFunc(iteratees, function(iteratee) {

            return apply(iteratee, thisArg, args);

          });

        });

      });

    }



    /**

     * Creates the padding for `string` based on `length`. The `chars` string

     * is truncated if the number of characters exceeds `length`.

     *

     * @private

     * @param {number} length The padding length.

     * @param {string} [chars=' '] The string used as padding.

     * @returns {string} Returns the padding for `string`.

     */

    function createPadding(length, chars) {

      chars = chars === undefined ? ' ' : baseToString(chars);



      var charsLength = chars.length;

      if (charsLength < 2) {

        return charsLength ? baseRepeat(chars, length) : chars;

      }

      var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));

      return hasUnicode(chars)

        ? castSlice(stringToArray(result), 0, length).join('')

        : result.slice(0, length);

    }



    /**

     * Creates a function that wraps `func` to invoke it with the `this` binding

     * of `thisArg` and `partials` prepended to the arguments it receives.

     *

     * @private

     * @param {Function} func The function to wrap.

     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.

     * @param {*} thisArg The `this` binding of `func`.

     * @param {Array} partials The arguments to prepend to those provided to

     *  the new function.

     * @returns {Function} Returns the new wrapped function.

     */

    function createPartial(func, bitmask, thisArg, partials) {

      var isBind = bitmask & WRAP_BIND_FLAG,

          Ctor = createCtor(func);



      function wrapper() {

        var argsIndex = -1,

            argsLength = arguments.length,

            leftIndex = -1,

            leftLength = partials.length,

            args = Array(leftLength + argsLength),

            fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;



        while (++leftIndex < leftLength) {

          args[leftIndex] = partials[leftIndex];

        }

        while (argsLength--) {

          args[leftIndex++] = arguments[++argsIndex];

        }

        return apply(fn, isBind ? thisArg : this, args);

      }

      return wrapper;

    }



    /**

     * Creates a `_.range` or `_.rangeRight` function.

     *

     * @private

     * @param {boolean} [fromRight] Specify iterating from right to left.

     * @returns {Function} Returns the new range function.

     */

    function createRange(fromRight) {

      return function(start, end, step) {

        if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {

          end = step = undefined;

        }

        // Ensure the sign of `-0` is preserved.

        start = toFinite(start);

        if (end === undefined) {

          end = start;

          start = 0;

        } else {

          end = toFinite(end);

        }

        step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);

        return baseRange(start, end, step, fromRight);

      };

    }



    /**

     * Creates a function that performs a relational operation on two values.

     *

     * @private

     * @param {Function} operator The function to perform the operation.

     * @returns {Function} Returns the new relational operation function.

     */

    function createRelationalOperation(operator) {

      return function(value, other) {

        if (!(typeof value == 'string' && typeof other == 'string')) {

          value = toNumber(value);

          other = toNumber(other);

        }

        return operator(value, other);

      };

    }



    /**

     * Creates a function that wraps `func` to continue currying.

     *

     * @private

     * @param {Function} func The function to wrap.

     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.

     * @param {Function} wrapFunc The function to create the `func` wrapper.

     * @param {*} placeholder The placeholder value.

     * @param {*} [thisArg] The `this` binding of `func`.

     * @param {Array} [partials] The arguments to prepend to those provided to

     *  the new function.

     * @param {Array} [holders] The `partials` placeholder indexes.

     * @param {Array} [argPos] The argument positions of the new function.

     * @param {number} [ary] The arity cap of `func`.

     * @param {number} [arity] The arity of `func`.

     * @returns {Function} Returns the new wrapped function.

     */

    function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {

      var isCurry = bitmask & WRAP_CURRY_FLAG,

          newHolders = isCurry ? holders : undefined,

          newHoldersRight = isCurry ? undefined : holders,

          newPartials = isCurry ? partials : undefined,

          newPartialsRight = isCurry ? undefined : partials;



      bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);

      bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);



      if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {

        bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);

      }

      var newData = [

        func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,

        newHoldersRight, argPos, ary, arity

      ];



      var result = wrapFunc.apply(undefined, newData);

      if (isLaziable(func)) {

        setData(result, newData);

      }

      result.placeholder = placeholder;

      return setWrapToString(result, func, bitmask);

    }



    /**

     * Creates a function like `_.round`.

     *

     * @private

     * @param {string} methodName The name of the `Math` method to use when rounding.

     * @returns {Function} Returns the new round function.

     */

    function createRound(methodName) {

      var func = Math[methodName];

      return function(number, precision) {

        number = toNumber(number);

        precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);

        if (precision) {

          // Shift with exponential notation to avoid floating-point issues.

          // See [MDN](https://mdn.io/round#Examples) for more details.

          var pair = (toString(number) + 'e').split('e'),

              value = func(pair[0] + 'e' + (+pair[1] + precision));



          pair = (toString(value) + 'e').split('e');

          return +(pair[0] + 'e' + (+pair[1] - precision));

        }

        return func(number);

      };

    }



    /**

     * Creates a set object of `values`.

     *

     * @private

     * @param {Array} values The values to add to the set.

     * @returns {Object} Returns the new set.

     */

    var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {

      return new Set(values);

    };



    /**

     * Creates a `_.toPairs` or `_.toPairsIn` function.

     *

     * @private

     * @param {Function} keysFunc The function to get the keys of a given object.

     * @returns {Function} Returns the new pairs function.

     */

    function createToPairs(keysFunc) {

      return function(object) {

        var tag = getTag(object);

        if (tag == mapTag) {

          return mapToArray(object);

        }

        if (tag == setTag) {

          return setToPairs(object);

        }

        return baseToPairs(object, keysFunc(object));

      };

    }



    /**

     * Creates a function that either curries or invokes `func` with optional

     * `this` binding and partially applied arguments.

     *

     * @private

     * @param {Function|string} func The function or method name to wrap.

     * @param {number} bitmask The bitmask flags.

     *    1 - `_.bind`

     *    2 - `_.bindKey`

     *    4 - `_.curry` or `_.curryRight` of a bound function

     *    8 - `_.curry`

     *   16 - `_.curryRight`

     *   32 - `_.partial`

     *   64 - `_.partialRight`

     *  128 - `_.rearg`

     *  256 - `_.ary`

     *  512 - `_.flip`

     * @param {*} [thisArg] The `this` binding of `func`.

     * @param {Array} [partials] The arguments to be partially applied.

     * @param {Array} [holders] The `partials` placeholder indexes.

     * @param {Array} [argPos] The argument positions of the new function.

     * @param {number} [ary] The arity cap of `func`.

     * @param {number} [arity] The arity of `func`.

     * @returns {Function} Returns the new wrapped function.

     */

    function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {

      var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;

      if (!isBindKey && typeof func != 'function') {

        throw new TypeError(FUNC_ERROR_TEXT);

      }

      var length = partials ? partials.length : 0;

      if (!length) {

        bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);

        partials = holders = undefined;

      }

      ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);

      arity = arity === undefined ? arity : toInteger(arity);

      length -= holders ? holders.length : 0;



      if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {

        var partialsRight = partials,

            holdersRight = holders;



        partials = holders = undefined;

      }

      var data = isBindKey ? undefined : getData(func);



      var newData = [

        func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,

        argPos, ary, arity

      ];



      if (data) {

        mergeData(newData, data);

      }

      func = newData[0];

      bitmask = newData[1];

      thisArg = newData[2];

      partials = newData[3];

      holders = newData[4];

      arity = newData[9] = newData[9] === undefined

        ? (isBindKey ? 0 : func.length)

        : nativeMax(newData[9] - length, 0);



      if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {

        bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);

      }

      if (!bitmask || bitmask == WRAP_BIND_FLAG) {

        var result = createBind(func, bitmask, thisArg);

      } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {

        result = createCurry(func, bitmask, arity);

      } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {

        result = createPartial(func, bitmask, thisArg, partials);

      } else {

        result = createHybrid.apply(undefined, newData);

      }

      var setter = data ? baseSetData : setData;

      return setWrapToString(setter(result, newData), func, bitmask);

    }



    /**

     * Used by `_.defaults` to customize its `_.assignIn` use to assign properties

     * of source objects to the destination object for all destination properties

     * that resolve to `undefined`.

     *

     * @private

     * @param {*} objValue The destination value.

     * @param {*} srcValue The source value.

     * @param {string} key The key of the property to assign.

     * @param {Object} object The parent object of `objValue`.

     * @returns {*} Returns the value to assign.

     */

    function customDefaultsAssignIn(objValue, srcValue, key, object) {

      if (objValue === undefined ||

          (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {

        return srcValue;

      }

      return objValue;

    }



    /**

     * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source

     * objects into destination objects that are passed thru.

     *

     * @private

     * @param {*} objValue The destination value.

     * @param {*} srcValue The source value.

     * @param {string} key The key of the property to merge.

     * @param {Object} object The parent object of `objValue`.

     * @param {Object} source The parent object of `srcValue`.

     * @param {Object} [stack] Tracks traversed source values and their merged

     *  counterparts.

     * @returns {*} Returns the value to assign.

     */

    function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {

      if (isObject(objValue) && isObject(srcValue)) {

        // Recursively merge objects and arrays (susceptible to call stack limits).

        stack.set(srcValue, objValue);

        baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);

        stack['delete'](srcValue);

      }

      return objValue;

    }



    /**

     * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain

     * objects.

     *

     * @private

     * @param {*} value The value to inspect.

     * @param {string} key The key of the property to inspect.

     * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.

     */

    function customOmitClone(value) {

      return isPlainObject(value) ? undefined : value;

    }



    /**

     * A specialized version of `baseIsEqualDeep` for arrays with support for

     * partial deep comparisons.

     *

     * @private

     * @param {Array} array The array to compare.

     * @param {Array} other The other array to compare.

     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.

     * @param {Function} customizer The function to customize comparisons.

     * @param {Function} equalFunc The function to determine equivalents of values.

     * @param {Object} stack Tracks traversed `array` and `other` objects.

     * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.

     */

    function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {

      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,

          arrLength = array.length,

          othLength = other.length;



      if (arrLength != othLength && !(isPartial && othLength > arrLength)) {

        return false;

      }

      // Assume cyclic values are equal.

      var stacked = stack.get(array);

      if (stacked && stack.get(other)) {

        return stacked == other;

      }

      var index = -1,

          result = true,

          seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;



      stack.set(array, other);

      stack.set(other, array);



      // Ignore non-index properties.

      while (++index < arrLength) {

        var arrValue = array[index],

            othValue = other[index];



        if (customizer) {

          var compared = isPartial

            ? customizer(othValue, arrValue, index, other, array, stack)

            : customizer(arrValue, othValue, index, array, other, stack);

        }

        if (compared !== undefined) {

          if (compared) {

            continue;

          }

          result = false;

          break;

        }

        // Recursively compare arrays (susceptible to call stack limits).

        if (seen) {

          if (!arraySome(other, function(othValue, othIndex) {

                if (!cacheHas(seen, othIndex) &&

                    (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {

                  return seen.push(othIndex);

                }

              })) {

            result = false;

            break;

          }

        } else if (!(

              arrValue === othValue ||

                equalFunc(arrValue, othValue, bitmask, customizer, stack)

            )) {

          result = false;

          break;

        }

      }

      stack['delete'](array);

      stack['delete'](other);

      return result;

    }



    /**

     * A specialized version of `baseIsEqualDeep` for comparing objects of

     * the same `toStringTag`.

     *

     * **Note:** This function only supports comparing values with tags of

     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.

     *

     * @private

     * @param {Object} object The object to compare.

     * @param {Object} other The other object to compare.

     * @param {string} tag The `toStringTag` of the objects to compare.

     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.

     * @param {Function} customizer The function to customize comparisons.

     * @param {Function} equalFunc The function to determine equivalents of values.

     * @param {Object} stack Tracks traversed `object` and `other` objects.

     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.

     */

    function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {

      switch (tag) {

        case dataViewTag:

          if ((object.byteLength != other.byteLength) ||

              (object.byteOffset != other.byteOffset)) {

            return false;

          }

          object = object.buffer;

          other = other.buffer;



        case arrayBufferTag:

          if ((object.byteLength != other.byteLength) ||

              !equalFunc(new Uint8Array(object), new Uint8Array(other))) {

            return false;

          }

          return true;



        case boolTag:

        case dateTag:

        case numberTag:

          // Coerce booleans to `1` or `0` and dates to milliseconds.

          // Invalid dates are coerced to `NaN`.

          return eq(+object, +other);



        case errorTag:

          return object.name == other.name && object.message == other.message;



        case regexpTag:

        case stringTag:

          // Coerce regexes to strings and treat strings, primitives and objects,

          // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring

          // for more details.

          return object == (other + '');



        case mapTag:

          var convert = mapToArray;



        case setTag:

          var isPartial = bitmask & COMPARE_PARTIAL_FLAG;

          convert || (convert = setToArray);



          if (object.size != other.size && !isPartial) {

            return false;

          }

          // Assume cyclic values are equal.

          var stacked = stack.get(object);

          if (stacked) {

            return stacked == other;

          }

          bitmask |= COMPARE_UNORDERED_FLAG;



          // Recursively compare objects (susceptible to call stack limits).

          stack.set(object, other);

          var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);

          stack['delete'](object);

          return result;



        case symbolTag:

          if (symbolValueOf) {

            return symbolValueOf.call(object) == symbolValueOf.call(other);

          }

      }

      return false;

    }



    /**

     * A specialized version of `baseIsEqualDeep` for objects with support for

     * partial deep comparisons.

     *

     * @private

     * @param {Object} object The object to compare.

     * @param {Object} other The other object to compare.

     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.

     * @param {Function} customizer The function to customize comparisons.

     * @param {Function} equalFunc The function to determine equivalents of values.

     * @param {Object} stack Tracks traversed `object` and `other` objects.

     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.

     */

    function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {

      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,

          objProps = getAllKeys(object),

          objLength = objProps.length,

          othProps = getAllKeys(other),

          othLength = othProps.length;



      if (objLength != othLength && !isPartial) {

        return false;

      }

      var index = objLength;

      while (index--) {

        var key = objProps[index];

        if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {

          return false;

        }

      }

      // Assume cyclic values are equal.

      var stacked = stack.get(object);

      if (stacked && stack.get(other)) {

        return stacked == other;

      }

      var result = true;

      stack.set(object, other);

      stack.set(other, object);



      var skipCtor = isPartial;

      while (++index < objLength) {

        key = objProps[index];

        var objValue = object[key],

            othValue = other[key];



        if (customizer) {

          var compared = isPartial

            ? customizer(othValue, objValue, key, other, object, stack)

            : customizer(objValue, othValue, key, object, other, stack);

        }

        // Recursively compare objects (susceptible to call stack limits).

        if (!(compared === undefined

              ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))

              : compared

            )) {

          result = false;

          break;

        }

        skipCtor || (skipCtor = key == 'constructor');

      }

      if (result && !skipCtor) {

        var objCtor = object.constructor,

            othCtor = other.constructor;



        // Non `Object` object instances with different constructors are not equal.

        if (objCtor != othCtor &&

            ('constructor' in object && 'constructor' in other) &&

            !(typeof objCtor == 'function' && objCtor instanceof objCtor &&

              typeof othCtor == 'function' && othCtor instanceof othCtor)) {

          result = false;

        }

      }

      stack['delete'](object);

      stack['delete'](other);

      return result;

    }



    /**

     * A specialized version of `baseRest` which flattens the rest array.

     *

     * @private

     * @param {Function} func The function to apply a rest parameter to.

     * @returns {Function} Returns the new function.

     */

    function flatRest(func) {

      return setToString(overRest(func, undefined, flatten), func + '');

    }



    /**

     * Creates an array of own enumerable property names and symbols of `object`.

     *

     * @private

     * @param {Object} object The object to query.

     * @returns {Array} Returns the array of property names and symbols.

     */

    function getAllKeys(object) {

      return baseGetAllKeys(object, keys, getSymbols);

    }



    /**

     * Creates an array of own and inherited enumerable property names and

     * symbols of `object`.

     *

     * @private

     * @param {Object} object The object to query.

     * @returns {Array} Returns the array of property names and symbols.

     */

    function getAllKeysIn(object) {

      return baseGetAllKeys(object, keysIn, getSymbolsIn);

    }



    /**

     * Gets metadata for `func`.

     *

     * @private

     * @param {Function} func The function to query.

     * @returns {*} Returns the metadata for `func`.

     */

    var getData = !metaMap ? noop : function(func) {

      return metaMap.get(func);

    };



    /**

     * Gets the name of `func`.

     *

     * @private

     * @param {Function} func The function to query.

     * @returns {string} Returns the function name.

     */

    function getFuncName(func) {

      var result = (func.name + ''),

          array = realNames[result],

          length = hasOwnProperty.call(realNames, result) ? array.length : 0;



      while (length--) {

        var data = array[length],

            otherFunc = data.func;

        if (otherFunc == null || otherFunc == func) {

          return data.name;

        }

      }

      return result;

    }



    /**

     * Gets the argument placeholder value for `func`.

     *

     * @private

     * @param {Function} func The function to inspect.

     * @returns {*} Returns the placeholder value.

     */

    function getHolder(func) {

      var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;

      return object.placeholder;

    }



    /**

     * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,

     * this function returns the custom method, otherwise it returns `baseIteratee`.

     * If arguments are provided, the chosen function is invoked with them and

     * its result is returned.

     *

     * @private

     * @param {*} [value] The value to convert to an iteratee.

     * @param {number} [arity] The arity of the created iteratee.

     * @returns {Function} Returns the chosen function or its result.

     */

    function getIteratee() {

      var result = lodash.iteratee || iteratee;

      result = result === iteratee ? baseIteratee : result;

      return arguments.length ? result(arguments[0], arguments[1]) : result;

    }



    /**

     * Gets the data for `map`.

     *

     * @private

     * @param {Object} map The map to query.

     * @param {string} key The reference key.

     * @returns {*} Returns the map data.

     */

    function getMapData(map, key) {

      var data = map.__data__;

      return isKeyable(key)

        ? data[typeof key == 'string' ? 'string' : 'hash']

        : data.map;

    }



    /**

     * Gets the property names, values, and compare flags of `object`.

     *

     * @private

     * @param {Object} object The object to query.

     * @returns {Array} Returns the match data of `object`.

     */

    function getMatchData(object) {

      var result = keys(object),

          length = result.length;



      while (length--) {

        var key = result[length],

            value = object[key];



        result[length] = [key, value, isStrictComparable(value)];

      }

      return result;

    }



    /**

     * Gets the native function at `key` of `object`.

     *

     * @private

     * @param {Object} object The object to query.

     * @param {string} key The key of the method to get.

     * @returns {*} Returns the function if it's native, else `undefined`.

     */

    function getNative(object, key) {

      var value = getValue(object, key);

      return baseIsNative(value) ? value : undefined;

    }



    /**

     * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.

     *

     * @private

     * @param {*} value The value to query.

     * @returns {string} Returns the raw `toStringTag`.

     */

    function getRawTag(value) {

      var isOwn = hasOwnProperty.call(value, symToStringTag),

          tag = value[symToStringTag];



      try {

        value[symToStringTag] = undefined;

        var unmasked = true;

      } catch (e) {}



      var result = nativeObjectToString.call(value);

      if (unmasked) {

        if (isOwn) {

          value[symToStringTag] = tag;

        } else {

          delete value[symToStringTag];

        }

      }

      return result;

    }



    /**

     * Creates an array of the own enumerable symbols of `object`.

     *

     * @private

     * @param {Object} object The object to query.

     * @returns {Array} Returns the array of symbols.

     */

    var getSymbols = !nativeGetSymbols ? stubArray : function(object) {

      if (object == null) {

        return [];

      }

      object = Object(object);

      return arrayFilter(nativeGetSymbols(object), function(symbol) {

        return propertyIsEnumerable.call(object, symbol);

      });

    };



    /**

     * Creates an array of the own and inherited enumerable symbols of `object`.

     *

     * @private

     * @param {Object} object The object to query.

     * @returns {Array} Returns the array of symbols.

     */

    var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {

      var result = [];

      while (object) {

        arrayPush(result, getSymbols(object));

        object = getPrototype(object);

      }

      return result;

    };



    /**

     * Gets the `toStringTag` of `value`.

     *

     * @private

     * @param {*} value The value to query.

     * @returns {string} Returns the `toStringTag`.

     */

    var getTag = baseGetTag;



    // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.

    if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||

        (Map && getTag(new Map) != mapTag) ||

        (Promise && getTag(Promise.resolve()) != promiseTag) ||

        (Set && getTag(new Set) != setTag) ||

        (WeakMap && getTag(new WeakMap) != weakMapTag)) {

      getTag = function(value) {

        var result = baseGetTag(value),

            Ctor = result == objectTag ? value.constructor : undefined,

            ctorString = Ctor ? toSource(Ctor) : '';



        if (ctorString) {

          switch (ctorString) {

            case dataViewCtorString: return dataViewTag;

            case mapCtorString: return mapTag;

            case promiseCtorString: return promiseTag;

            case setCtorString: return setTag;

            case weakMapCtorString: return weakMapTag;

          }

        }

        return result;

      };

    }



    /**

     * Gets the view, applying any `transforms` to the `start` and `end` positions.

     *

     * @private

     * @param {number} start The start of the view.

     * @param {number} end The end of the view.

     * @param {Array} transforms The transformations to apply to the view.

     * @returns {Object} Returns an object containing the `start` and `end`

     *  positions of the view.

     */

    function getView(start, end, transforms) {

      var index = -1,

          length = transforms.length;



      while (++index < length) {

        var data = transforms[index],

            size = data.size;



        switch (data.type) {

          case 'drop':      start += size; break;

          case 'dropRight': end -= size; break;

          case 'take':      end = nativeMin(end, start + size); break;

          case 'takeRight': start = nativeMax(start, end - size); break;

        }

      }

      return { 'start': start, 'end': end };

    }



    /**

     * Extracts wrapper details from the `source` body comment.

     *

     * @private

     * @param {string} source The source to inspect.

     * @returns {Array} Returns the wrapper details.

     */

    function getWrapDetails(source) {

      var match = source.match(reWrapDetails);

      return match ? match[1].split(reSplitDetails) : [];

    }



    /**

     * Checks if `path` exists on `object`.

     *

     * @private

     * @param {Object} object The object to query.

     * @param {Array|string} path The path to check.

     * @param {Function} hasFunc The function to check properties.

     * @returns {boolean} Returns `true` if `path` exists, else `false`.

     */

    function hasPath(object, path, hasFunc) {

      path = castPath(path, object);



      var index = -1,

          length = path.length,

          result = false;



      while (++index < length) {

        var key = toKey(path[index]);

        if (!(result = object != null && hasFunc(object, key))) {

          break;

        }

        object = object[key];

      }

      if (result || ++index != length) {

        return result;

      }

      length = object == null ? 0 : object.length;

      return !!length && isLength(length) && isIndex(key, length) &&

        (isArray(object) || isArguments(object));

    }



    /**

     * Initializes an array clone.

     *

     * @private

     * @param {Array} array The array to clone.

     * @returns {Array} Returns the initialized clone.

     */

    function initCloneArray(array) {

      var length = array.length,

          result = array.constructor(length);



      // Add properties assigned by `RegExp#exec`.

      if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {

        result.index = array.index;

        result.input = array.input;

      }

      return result;

    }



    /**

     * Initializes an object clone.

     *

     * @private

     * @param {Object} object The object to clone.

     * @returns {Object} Returns the initialized clone.

     */

    function initCloneObject(object) {

      return (typeof object.constructor == 'function' && !isPrototype(object))

        ? baseCreate(getPrototype(object))

        : {};

    }



    /**

     * Initializes an object clone based on its `toStringTag`.

     *

     * **Note:** This function only supports cloning values with tags of

     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.

     *

     * @private

     * @param {Object} object The object to clone.

     * @param {string} tag The `toStringTag` of the object to clone.

     * @param {Function} cloneFunc The function to clone values.

     * @param {boolean} [isDeep] Specify a deep clone.

     * @returns {Object} Returns the initialized clone.

     */

    function initCloneByTag(object, tag, cloneFunc, isDeep) {

      var Ctor = object.constructor;

      switch (tag) {

        case arrayBufferTag:

          return cloneArrayBuffer(object);



        case boolTag:

        case dateTag:

          return new Ctor(+object);



        case dataViewTag:

          return cloneDataView(object, isDeep);



        case float32Tag: case float64Tag:

        case int8Tag: case int16Tag: case int32Tag:

        case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:

          return cloneTypedArray(object, isDeep);



        case mapTag:

          return cloneMap(object, isDeep, cloneFunc);



        case numberTag:

        case stringTag:

          return new Ctor(object);



        case regexpTag:

          return cloneRegExp(object);



        case setTag:

          return cloneSet(object, isDeep, cloneFunc);



        case symbolTag:

          return cloneSymbol(object);

      }

    }



    /**

     * Inserts wrapper `details` in a comment at the top of the `source` body.

     *

     * @private

     * @param {string} source The source to modify.

     * @returns {Array} details The details to insert.

     * @returns {string} Returns the modified source.

     */

    function insertWrapDetails(source, details) {

      var length = details.length;

      if (!length) {

        return source;

      }

      var lastIndex = length - 1;

      details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];

      details = details.join(length > 2 ? ', ' : ' ');

      return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');

    }



    /**

     * Checks if `value` is a flattenable `arguments` object or array.

     *

     * @private

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.

     */

    function isFlattenable(value) {

      return isArray(value) || isArguments(value) ||

        !!(spreadableSymbol && value && value[spreadableSymbol]);

    }



    /**

     * Checks if `value` is a valid array-like index.

     *

     * @private

     * @param {*} value The value to check.

     * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.

     * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.

     */

    function isIndex(value, length) {

      length = length == null ? MAX_SAFE_INTEGER : length;

      return !!length &&

        (typeof value == 'number' || reIsUint.test(value)) &&

        (value > -1 && value % 1 == 0 && value < length);

    }



    /**

     * Checks if the given arguments are from an iteratee call.

     *

     * @private

     * @param {*} value The potential iteratee value argument.

     * @param {*} index The potential iteratee index or key argument.

     * @param {*} object The potential iteratee object argument.

     * @returns {boolean} Returns `true` if the arguments are from an iteratee call,

     *  else `false`.

     */

    function isIterateeCall(value, index, object) {

      if (!isObject(object)) {

        return false;

      }

      var type = typeof index;

      if (type == 'number'

            ? (isArrayLike(object) && isIndex(index, object.length))

            : (type == 'string' && index in object)

          ) {

        return eq(object[index], value);

      }

      return false;

    }



    /**

     * Checks if `value` is a property name and not a property path.

     *

     * @private

     * @param {*} value The value to check.

     * @param {Object} [object] The object to query keys on.

     * @returns {boolean} Returns `true` if `value` is a property name, else `false`.

     */

    function isKey(value, object) {

      if (isArray(value)) {

        return false;

      }

      var type = typeof value;

      if (type == 'number' || type == 'symbol' || type == 'boolean' ||

          value == null || isSymbol(value)) {

        return true;

      }

      return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||

        (object != null && value in Object(object));

    }



    /**

     * Checks if `value` is suitable for use as unique object key.

     *

     * @private

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is suitable, else `false`.

     */

    function isKeyable(value) {

      var type = typeof value;

      return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')

        ? (value !== '__proto__')

        : (value === null);

    }



    /**

     * Checks if `func` has a lazy counterpart.

     *

     * @private

     * @param {Function} func The function to check.

     * @returns {boolean} Returns `true` if `func` has a lazy counterpart,

     *  else `false`.

     */

    function isLaziable(func) {

      var funcName = getFuncName(func),

          other = lodash[funcName];



      if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {

        return false;

      }

      if (func === other) {

        return true;

      }

      var data = getData(other);

      return !!data && func === data[0];

    }



    /**

     * Checks if `func` has its source masked.

     *

     * @private

     * @param {Function} func The function to check.

     * @returns {boolean} Returns `true` if `func` is masked, else `false`.

     */

    function isMasked(func) {

      return !!maskSrcKey && (maskSrcKey in func);

    }



    /**

     * Checks if `func` is capable of being masked.

     *

     * @private

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `func` is maskable, else `false`.

     */

    var isMaskable = coreJsData ? isFunction : stubFalse;



    /**

     * Checks if `value` is likely a prototype object.

     *

     * @private

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.

     */

    function isPrototype(value) {

      var Ctor = value && value.constructor,

          proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;



      return value === proto;

    }



    /**

     * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.

     *

     * @private

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` if suitable for strict

     *  equality comparisons, else `false`.

     */

    function isStrictComparable(value) {

      return value === value && !isObject(value);

    }



    /**

     * A specialized version of `matchesProperty` for source values suitable

     * for strict equality comparisons, i.e. `===`.

     *

     * @private

     * @param {string} key The key of the property to get.

     * @param {*} srcValue The value to match.

     * @returns {Function} Returns the new spec function.

     */

    function matchesStrictComparable(key, srcValue) {

      return function(object) {

        if (object == null) {

          return false;

        }

        return object[key] === srcValue &&

          (srcValue !== undefined || (key in Object(object)));

      };

    }



    /**

     * A specialized version of `_.memoize` which clears the memoized function's

     * cache when it exceeds `MAX_MEMOIZE_SIZE`.

     *

     * @private

     * @param {Function} func The function to have its output memoized.

     * @returns {Function} Returns the new memoized function.

     */

    function memoizeCapped(func) {

      var result = memoize(func, function(key) {

        if (cache.size === MAX_MEMOIZE_SIZE) {

          cache.clear();

        }

        return key;

      });



      var cache = result.cache;

      return result;

    }



    /**

     * Merges the function metadata of `source` into `data`.

     *

     * Merging metadata reduces the number of wrappers used to invoke a function.

     * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`

     * may be applied regardless of execution order. Methods like `_.ary` and

     * `_.rearg` modify function arguments, making the order in which they are

     * executed important, preventing the merging of metadata. However, we make

     * an exception for a safe combined case where curried functions have `_.ary`

     * and or `_.rearg` applied.

     *

     * @private

     * @param {Array} data The destination metadata.

     * @param {Array} source The source metadata.

     * @returns {Array} Returns `data`.

     */

    function mergeData(data, source) {

      var bitmask = data[1],

          srcBitmask = source[1],

          newBitmask = bitmask | srcBitmask,

          isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);



      var isCombo =

        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||

        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||

        ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));



      // Exit early if metadata can't be merged.

      if (!(isCommon || isCombo)) {

        return data;

      }

      // Use source `thisArg` if available.

      if (srcBitmask & WRAP_BIND_FLAG) {

        data[2] = source[2];

        // Set when currying a bound function.

        newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;

      }

      // Compose partial arguments.

      var value = source[3];

      if (value) {

        var partials = data[3];

        data[3] = partials ? composeArgs(partials, value, source[4]) : value;

        data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];

      }

      // Compose partial right arguments.

      value = source[5];

      if (value) {

        partials = data[5];

        data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;

        data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];

      }

      // Use source `argPos` if available.

      value = source[7];

      if (value) {

        data[7] = value;

      }

      // Use source `ary` if it's smaller.

      if (srcBitmask & WRAP_ARY_FLAG) {

        data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);

      }

      // Use source `arity` if one is not provided.

      if (data[9] == null) {

        data[9] = source[9];

      }

      // Use source `func` and merge bitmasks.

      data[0] = source[0];

      data[1] = newBitmask;



      return data;

    }



    /**

     * This function is like

     * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)

     * except that it includes inherited enumerable properties.

     *

     * @private

     * @param {Object} object The object to query.

     * @returns {Array} Returns the array of property names.

     */

    function nativeKeysIn(object) {

      var result = [];

      if (object != null) {

        for (var key in Object(object)) {

          result.push(key);

        }

      }

      return result;

    }



    /**

     * Converts `value` to a string using `Object.prototype.toString`.

     *

     * @private

     * @param {*} value The value to convert.

     * @returns {string} Returns the converted string.

     */

    function objectToString(value) {

      return nativeObjectToString.call(value);

    }



    /**

     * A specialized version of `baseRest` which transforms the rest array.

     *

     * @private

     * @param {Function} func The function to apply a rest parameter to.

     * @param {number} [start=func.length-1] The start position of the rest parameter.

     * @param {Function} transform The rest array transform.

     * @returns {Function} Returns the new function.

     */

    function overRest(func, start, transform) {

      start = nativeMax(start === undefined ? (func.length - 1) : start, 0);

      return function() {

        var args = arguments,

            index = -1,

            length = nativeMax(args.length - start, 0),

            array = Array(length);



        while (++index < length) {

          array[index] = args[start + index];

        }

        index = -1;

        var otherArgs = Array(start + 1);

        while (++index < start) {

          otherArgs[index] = args[index];

        }

        otherArgs[start] = transform(array);

        return apply(func, this, otherArgs);

      };

    }



    /**

     * Gets the parent value at `path` of `object`.

     *

     * @private

     * @param {Object} object The object to query.

     * @param {Array} path The path to get the parent value of.

     * @returns {*} Returns the parent value.

     */

    function parent(object, path) {

      return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));

    }



    /**

     * Reorder `array` according to the specified indexes where the element at

     * the first index is assigned as the first element, the element at

     * the second index is assigned as the second element, and so on.

     *

     * @private

     * @param {Array} array The array to reorder.

     * @param {Array} indexes The arranged array indexes.

     * @returns {Array} Returns `array`.

     */

    function reorder(array, indexes) {

      var arrLength = array.length,

          length = nativeMin(indexes.length, arrLength),

          oldArray = copyArray(array);



      while (length--) {

        var index = indexes[length];

        array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;

      }

      return array;

    }



    /**

     * Sets metadata for `func`.

     *

     * **Note:** If this function becomes hot, i.e. is invoked a lot in a short

     * period of time, it will trip its breaker and transition to an identity

     * function to avoid garbage collection pauses in V8. See

     * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)

     * for more details.

     *

     * @private

     * @param {Function} func The function to associate metadata with.

     * @param {*} data The metadata.

     * @returns {Function} Returns `func`.

     */

    var setData = shortOut(baseSetData);



    /**

     * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).

     *

     * @private

     * @param {Function} func The function to delay.

     * @param {number} wait The number of milliseconds to delay invocation.

     * @returns {number|Object} Returns the timer id or timeout object.

     */

    var setTimeout = ctxSetTimeout || function(func, wait) {

      return root.setTimeout(func, wait);

    };



    /**

     * Sets the `toString` method of `func` to return `string`.

     *

     * @private

     * @param {Function} func The function to modify.

     * @param {Function} string The `toString` result.

     * @returns {Function} Returns `func`.

     */

    var setToString = shortOut(baseSetToString);



    /**

     * Sets the `toString` method of `wrapper` to mimic the source of `reference`

     * with wrapper details in a comment at the top of the source body.

     *

     * @private

     * @param {Function} wrapper The function to modify.

     * @param {Function} reference The reference function.

     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.

     * @returns {Function} Returns `wrapper`.

     */

    function setWrapToString(wrapper, reference, bitmask) {

      var source = (reference + '');

      return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));

    }



    /**

     * Creates a function that'll short out and invoke `identity` instead

     * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`

     * milliseconds.

     *

     * @private

     * @param {Function} func The function to restrict.

     * @returns {Function} Returns the new shortable function.

     */

    function shortOut(func) {

      var count = 0,

          lastCalled = 0;



      return function() {

        var stamp = nativeNow(),

            remaining = HOT_SPAN - (stamp - lastCalled);



        lastCalled = stamp;

        if (remaining > 0) {

          if (++count >= HOT_COUNT) {

            return arguments[0];

          }

        } else {

          count = 0;

        }

        return func.apply(undefined, arguments);

      };

    }



    /**

     * A specialized version of `_.shuffle` which mutates and sets the size of `array`.

     *

     * @private

     * @param {Array} array The array to shuffle.

     * @param {number} [size=array.length] The size of `array`.

     * @returns {Array} Returns `array`.

     */

    function shuffleSelf(array, size) {

      var index = -1,

          length = array.length,

          lastIndex = length - 1;



      size = size === undefined ? length : size;

      while (++index < size) {

        var rand = baseRandom(index, lastIndex),

            value = array[rand];



        array[rand] = array[index];

        array[index] = value;

      }

      array.length = size;

      return array;

    }



    /**

     * Converts `string` to a property path array.

     *

     * @private

     * @param {string} string The string to convert.

     * @returns {Array} Returns the property path array.

     */

    var stringToPath = memoizeCapped(function(string) {

      var result = [];

      if (reLeadingDot.test(string)) {

        result.push('');

      }

      string.replace(rePropName, function(match, number, quote, string) {

        result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));

      });

      return result;

    });



    /**

     * Converts `value` to a string key if it's not a string or symbol.

     *

     * @private

     * @param {*} value The value to inspect.

     * @returns {string|symbol} Returns the key.

     */

    function toKey(value) {

      if (typeof value == 'string' || isSymbol(value)) {

        return value;

      }

      var result = (value + '');

      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;

    }



    /**

     * Converts `func` to its source code.

     *

     * @private

     * @param {Function} func The function to convert.

     * @returns {string} Returns the source code.

     */

    function toSource(func) {

      if (func != null) {

        try {

          return funcToString.call(func);

        } catch (e) {}

        try {

          return (func + '');

        } catch (e) {}

      }

      return '';

    }



    /**

     * Updates wrapper `details` based on `bitmask` flags.

     *

     * @private

     * @returns {Array} details The details to modify.

     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.

     * @returns {Array} Returns `details`.

     */

    function updateWrapDetails(details, bitmask) {

      arrayEach(wrapFlags, function(pair) {

        var value = '_.' + pair[0];

        if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {

          details.push(value);

        }

      });

      return details.sort();

    }



    /**

     * Creates a clone of `wrapper`.

     *

     * @private

     * @param {Object} wrapper The wrapper to clone.

     * @returns {Object} Returns the cloned wrapper.

     */

    function wrapperClone(wrapper) {

      if (wrapper instanceof LazyWrapper) {

        return wrapper.clone();

      }

      var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);

      result.__actions__ = copyArray(wrapper.__actions__);

      result.__index__  = wrapper.__index__;

      result.__values__ = wrapper.__values__;

      return result;

    }



    /*------------------------------------------------------------------------*/



    /**

     * Creates an array of elements split into groups the length of `size`.

     * If `array` can't be split evenly, the final chunk will be the remaining

     * elements.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Array

     * @param {Array} array The array to process.

     * @param {number} [size=1] The length of each chunk

     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.

     * @returns {Array} Returns the new array of chunks.

     * @example

     *

     * _.chunk(['a', 'b', 'c', 'd'], 2);

     * // => [['a', 'b'], ['c', 'd']]

     *

     * _.chunk(['a', 'b', 'c', 'd'], 3);

     * // => [['a', 'b', 'c'], ['d']]

     */

    function chunk(array, size, guard) {

      if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {

        size = 1;

      } else {

        size = nativeMax(toInteger(size), 0);

      }

      var length = array == null ? 0 : array.length;

      if (!length || size < 1) {

        return [];

      }

      var index = 0,

          resIndex = 0,

          result = Array(nativeCeil(length / size));



      while (index < length) {

        result[resIndex++] = baseSlice(array, index, (index += size));

      }

      return result;

    }



    /**

     * Creates an array with all falsey values removed. The values `false`, `null`,

     * `0`, `""`, `undefined`, and `NaN` are falsey.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Array

     * @param {Array} array The array to compact.

     * @returns {Array} Returns the new array of filtered values.

     * @example

     *

     * _.compact([0, 1, false, 2, '', 3]);

     * // => [1, 2, 3]

     */

    function compact(array) {

      var index = -1,

          length = array == null ? 0 : array.length,

          resIndex = 0,

          result = [];



      while (++index < length) {

        var value = array[index];

        if (value) {

          result[resIndex++] = value;

        }

      }

      return result;

    }



    /**

     * Creates a new array concatenating `array` with any additional arrays

     * and/or values.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Array

     * @param {Array} array The array to concatenate.

     * @param {...*} [values] The values to concatenate.

     * @returns {Array} Returns the new concatenated array.

     * @example

     *

     * var array = [1];

     * var other = _.concat(array, 2, [3], [[4]]);

     *

     * console.log(other);

     * // => [1, 2, 3, [4]]

     *

     * console.log(array);

     * // => [1]

     */

    function concat() {

      var length = arguments.length;

      if (!length) {

        return [];

      }

      var args = Array(length - 1),

          array = arguments[0],

          index = length;



      while (index--) {

        args[index - 1] = arguments[index];

      }

      return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));

    }



    /**

     * Creates an array of `array` values not included in the other given arrays

     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)

     * for equality comparisons. The order and references of result values are

     * determined by the first array.

     *

     * **Note:** Unlike `_.pullAll`, this method returns a new array.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Array

     * @param {Array} array The array to inspect.

     * @param {...Array} [values] The values to exclude.

     * @returns {Array} Returns the new array of filtered values.

     * @see _.without, _.xor

     * @example

     *

     * _.difference([2, 1], [2, 3]);

     * // => [1]

     */

    var difference = baseRest(function(array, values) {

      return isArrayLikeObject(array)

        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))

        : [];

    });



    /**

     * This method is like `_.difference` except that it accepts `iteratee` which

     * is invoked for each element of `array` and `values` to generate the criterion

     * by which they're compared. The order and references of result values are

     * determined by the first array. The iteratee is invoked with one argument:

     * (value).

     *

     * **Note:** Unlike `_.pullAllBy`, this method returns a new array.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Array

     * @param {Array} array The array to inspect.

     * @param {...Array} [values] The values to exclude.

     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.

     * @returns {Array} Returns the new array of filtered values.

     * @example

     *

     * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);

     * // => [1.2]

     *

     * // The `_.property` iteratee shorthand.

     * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');

     * // => [{ 'x': 2 }]

     */

    var differenceBy = baseRest(function(array, values) {

      var iteratee = last(values);

      if (isArrayLikeObject(iteratee)) {

        iteratee = undefined;

      }

      return isArrayLikeObject(array)

        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))

        : [];

    });



    /**

     * This method is like `_.difference` except that it accepts `comparator`

     * which is invoked to compare elements of `array` to `values`. The order and

     * references of result values are determined by the first array. The comparator

     * is invoked with two arguments: (arrVal, othVal).

     *

     * **Note:** Unlike `_.pullAllWith`, this method returns a new array.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Array

     * @param {Array} array The array to inspect.

     * @param {...Array} [values] The values to exclude.

     * @param {Function} [comparator] The comparator invoked per element.

     * @returns {Array} Returns the new array of filtered values.

     * @example

     *

     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];

     *

     * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);

     * // => [{ 'x': 2, 'y': 1 }]

     */

    var differenceWith = baseRest(function(array, values) {

      var comparator = last(values);

      if (isArrayLikeObject(comparator)) {

        comparator = undefined;

      }

      return isArrayLikeObject(array)

        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)

        : [];

    });



    /**

     * Creates a slice of `array` with `n` elements dropped from the beginning.

     *

     * @static

     * @memberOf _

     * @since 0.5.0

     * @category Array

     * @param {Array} array The array to query.

     * @param {number} [n=1] The number of elements to drop.

     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.

     * @returns {Array} Returns the slice of `array`.

     * @example

     *

     * _.drop([1, 2, 3]);

     * // => [2, 3]

     *

     * _.drop([1, 2, 3], 2);

     * // => [3]

     *

     * _.drop([1, 2, 3], 5);

     * // => []

     *

     * _.drop([1, 2, 3], 0);

     * // => [1, 2, 3]

     */

    function drop(array, n, guard) {

      var length = array == null ? 0 : array.length;

      if (!length) {

        return [];

      }

      n = (guard || n === undefined) ? 1 : toInteger(n);

      return baseSlice(array, n < 0 ? 0 : n, length);

    }



    /**

     * Creates a slice of `array` with `n` elements dropped from the end.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Array

     * @param {Array} array The array to query.

     * @param {number} [n=1] The number of elements to drop.

     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.

     * @returns {Array} Returns the slice of `array`.

     * @example

     *

     * _.dropRight([1, 2, 3]);

     * // => [1, 2]

     *

     * _.dropRight([1, 2, 3], 2);

     * // => [1]

     *

     * _.dropRight([1, 2, 3], 5);

     * // => []

     *

     * _.dropRight([1, 2, 3], 0);

     * // => [1, 2, 3]

     */

    function dropRight(array, n, guard) {

      var length = array == null ? 0 : array.length;

      if (!length) {

        return [];

      }

      n = (guard || n === undefined) ? 1 : toInteger(n);

      n = length - n;

      return baseSlice(array, 0, n < 0 ? 0 : n);

    }



    /**

     * Creates a slice of `array` excluding elements dropped from the end.

     * Elements are dropped until `predicate` returns falsey. The predicate is

     * invoked with three arguments: (value, index, array).

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Array

     * @param {Array} array The array to query.

     * @param {Function} [predicate=_.identity] The function invoked per iteration.

     * @returns {Array} Returns the slice of `array`.

     * @example

     *

     * var users = [

     *   { 'user': 'barney',  'active': true },

     *   { 'user': 'fred',    'active': false },

     *   { 'user': 'pebbles', 'active': false }

     * ];

     *

     * _.dropRightWhile(users, function(o) { return !o.active; });

     * // => objects for ['barney']

     *

     * // The `_.matches` iteratee shorthand.

     * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });

     * // => objects for ['barney', 'fred']

     *

     * // The `_.matchesProperty` iteratee shorthand.

     * _.dropRightWhile(users, ['active', false]);

     * // => objects for ['barney']

     *

     * // The `_.property` iteratee shorthand.

     * _.dropRightWhile(users, 'active');

     * // => objects for ['barney', 'fred', 'pebbles']

     */

    function dropRightWhile(array, predicate) {

      return (array && array.length)

        ? baseWhile(array, getIteratee(predicate, 3), true, true)

        : [];

    }



    /**

     * Creates a slice of `array` excluding elements dropped from the beginning.

     * Elements are dropped until `predicate` returns falsey. The predicate is

     * invoked with three arguments: (value, index, array).

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Array

     * @param {Array} array The array to query.

     * @param {Function} [predicate=_.identity] The function invoked per iteration.

     * @returns {Array} Returns the slice of `array`.

     * @example

     *

     * var users = [

     *   { 'user': 'barney',  'active': false },

     *   { 'user': 'fred',    'active': false },

     *   { 'user': 'pebbles', 'active': true }

     * ];

     *

     * _.dropWhile(users, function(o) { return !o.active; });

     * // => objects for ['pebbles']

     *

     * // The `_.matches` iteratee shorthand.

     * _.dropWhile(users, { 'user': 'barney', 'active': false });

     * // => objects for ['fred', 'pebbles']

     *

     * // The `_.matchesProperty` iteratee shorthand.

     * _.dropWhile(users, ['active', false]);

     * // => objects for ['pebbles']

     *

     * // The `_.property` iteratee shorthand.

     * _.dropWhile(users, 'active');

     * // => objects for ['barney', 'fred', 'pebbles']

     */

    function dropWhile(array, predicate) {

      return (array && array.length)

        ? baseWhile(array, getIteratee(predicate, 3), true)

        : [];

    }



    /**

     * Fills elements of `array` with `value` from `start` up to, but not

     * including, `end`.

     *

     * **Note:** This method mutates `array`.

     *

     * @static

     * @memberOf _

     * @since 3.2.0

     * @category Array

     * @param {Array} array The array to fill.

     * @param {*} value The value to fill `array` with.

     * @param {number} [start=0] The start position.

     * @param {number} [end=array.length] The end position.

     * @returns {Array} Returns `array`.

     * @example

     *

     * var array = [1, 2, 3];

     *

     * _.fill(array, 'a');

     * console.log(array);

     * // => ['a', 'a', 'a']

     *

     * _.fill(Array(3), 2);

     * // => [2, 2, 2]

     *

     * _.fill([4, 6, 8, 10], '*', 1, 3);

     * // => [4, '*', '*', 10]

     */

    function fill(array, value, start, end) {

      var length = array == null ? 0 : array.length;

      if (!length) {

        return [];

      }

      if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {

        start = 0;

        end = length;

      }

      return baseFill(array, value, start, end);

    }



    /**

     * This method is like `_.find` except that it returns the index of the first

     * element `predicate` returns truthy for instead of the element itself.

     *

     * @static

     * @memberOf _

     * @since 1.1.0

     * @category Array

     * @param {Array} array The array to inspect.

     * @param {Function} [predicate=_.identity] The function invoked per iteration.

     * @param {number} [fromIndex=0] The index to search from.

     * @returns {number} Returns the index of the found element, else `-1`.

     * @example

     *

     * var users = [

     *   { 'user': 'barney',  'active': false },

     *   { 'user': 'fred',    'active': false },

     *   { 'user': 'pebbles', 'active': true }

     * ];

     *

     * _.findIndex(users, function(o) { return o.user == 'barney'; });

     * // => 0

     *

     * // The `_.matches` iteratee shorthand.

     * _.findIndex(users, { 'user': 'fred', 'active': false });

     * // => 1

     *

     * // The `_.matchesProperty` iteratee shorthand.

     * _.findIndex(users, ['active', false]);

     * // => 0

     *

     * // The `_.property` iteratee shorthand.

     * _.findIndex(users, 'active');

     * // => 2

     */

    function findIndex(array, predicate, fromIndex) {

      var length = array == null ? 0 : array.length;

      if (!length) {

        return -1;

      }

      var index = fromIndex == null ? 0 : toInteger(fromIndex);

      if (index < 0) {

        index = nativeMax(length + index, 0);

      }

      return baseFindIndex(array, getIteratee(predicate, 3), index);

    }



    /**

     * This method is like `_.findIndex` except that it iterates over elements

     * of `collection` from right to left.

     *

     * @static

     * @memberOf _

     * @since 2.0.0

     * @category Array

     * @param {Array} array The array to inspect.

     * @param {Function} [predicate=_.identity] The function invoked per iteration.

     * @param {number} [fromIndex=array.length-1] The index to search from.

     * @returns {number} Returns the index of the found element, else `-1`.

     * @example

     *

     * var users = [

     *   { 'user': 'barney',  'active': true },

     *   { 'user': 'fred',    'active': false },

     *   { 'user': 'pebbles', 'active': false }

     * ];

     *

     * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });

     * // => 2

     *

     * // The `_.matches` iteratee shorthand.

     * _.findLastIndex(users, { 'user': 'barney', 'active': true });

     * // => 0

     *

     * // The `_.matchesProperty` iteratee shorthand.

     * _.findLastIndex(users, ['active', false]);

     * // => 2

     *

     * // The `_.property` iteratee shorthand.

     * _.findLastIndex(users, 'active');

     * // => 0

     */

    function findLastIndex(array, predicate, fromIndex) {

      var length = array == null ? 0 : array.length;

      if (!length) {

        return -1;

      }

      var index = length - 1;

      if (fromIndex !== undefined) {

        index = toInteger(fromIndex);

        index = fromIndex < 0

          ? nativeMax(length + index, 0)

          : nativeMin(index, length - 1);

      }

      return baseFindIndex(array, getIteratee(predicate, 3), index, true);

    }



    /**

     * Flattens `array` a single level deep.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Array

     * @param {Array} array The array to flatten.

     * @returns {Array} Returns the new flattened array.

     * @example

     *

     * _.flatten([1, [2, [3, [4]], 5]]);

     * // => [1, 2, [3, [4]], 5]

     */

    function flatten(array) {

      var length = array == null ? 0 : array.length;

      return length ? baseFlatten(array, 1) : [];

    }



    /**

     * Recursively flattens `array`.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Array

     * @param {Array} array The array to flatten.

     * @returns {Array} Returns the new flattened array.

     * @example

     *

     * _.flattenDeep([1, [2, [3, [4]], 5]]);

     * // => [1, 2, 3, 4, 5]

     */

    function flattenDeep(array) {

      var length = array == null ? 0 : array.length;

      return length ? baseFlatten(array, INFINITY) : [];

    }



    /**

     * Recursively flatten `array` up to `depth` times.

     *

     * @static

     * @memberOf _

     * @since 4.4.0

     * @category Array

     * @param {Array} array The array to flatten.

     * @param {number} [depth=1] The maximum recursion depth.

     * @returns {Array} Returns the new flattened array.

     * @example

     *

     * var array = [1, [2, [3, [4]], 5]];

     *

     * _.flattenDepth(array, 1);

     * // => [1, 2, [3, [4]], 5]

     *

     * _.flattenDepth(array, 2);

     * // => [1, 2, 3, [4], 5]

     */

    function flattenDepth(array, depth) {

      var length = array == null ? 0 : array.length;

      if (!length) {

        return [];

      }

      depth = depth === undefined ? 1 : toInteger(depth);

      return baseFlatten(array, depth);

    }



    /**

     * The inverse of `_.toPairs`; this method returns an object composed

     * from key-value `pairs`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Array

     * @param {Array} pairs The key-value pairs.

     * @returns {Object} Returns the new object.

     * @example

     *

     * _.fromPairs([['a', 1], ['b', 2]]);

     * // => { 'a': 1, 'b': 2 }

     */

    function fromPairs(pairs) {

      var index = -1,

          length = pairs == null ? 0 : pairs.length,

          result = {};



      while (++index < length) {

        var pair = pairs[index];

        result[pair[0]] = pair[1];

      }

      return result;

    }



    /**

     * Gets the first element of `array`.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @alias first

     * @category Array

     * @param {Array} array The array to query.

     * @returns {*} Returns the first element of `array`.

     * @example

     *

     * _.head([1, 2, 3]);

     * // => 1

     *

     * _.head([]);

     * // => undefined

     */

    function head(array) {

      return (array && array.length) ? array[0] : undefined;

    }



    /**

     * Gets the index at which the first occurrence of `value` is found in `array`

     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)

     * for equality comparisons. If `fromIndex` is negative, it's used as the

     * offset from the end of `array`.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Array

     * @param {Array} array The array to inspect.

     * @param {*} value The value to search for.

     * @param {number} [fromIndex=0] The index to search from.

     * @returns {number} Returns the index of the matched value, else `-1`.

     * @example

     *

     * _.indexOf([1, 2, 1, 2], 2);

     * // => 1

     *

     * // Search from the `fromIndex`.

     * _.indexOf([1, 2, 1, 2], 2, 2);

     * // => 3

     */

    function indexOf(array, value, fromIndex) {

      var length = array == null ? 0 : array.length;

      if (!length) {

        return -1;

      }

      var index = fromIndex == null ? 0 : toInteger(fromIndex);

      if (index < 0) {

        index = nativeMax(length + index, 0);

      }

      return baseIndexOf(array, value, index);

    }



    /**

     * Gets all but the last element of `array`.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Array

     * @param {Array} array The array to query.

     * @returns {Array} Returns the slice of `array`.

     * @example

     *

     * _.initial([1, 2, 3]);

     * // => [1, 2]

     */

    function initial(array) {

      var length = array == null ? 0 : array.length;

      return length ? baseSlice(array, 0, -1) : [];

    }



    /**

     * Creates an array of unique values that are included in all given arrays

     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)

     * for equality comparisons. The order and references of result values are

     * determined by the first array.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Array

     * @param {...Array} [arrays] The arrays to inspect.

     * @returns {Array} Returns the new array of intersecting values.

     * @example

     *

     * _.intersection([2, 1], [2, 3]);

     * // => [2]

     */

    var intersection = baseRest(function(arrays) {

      var mapped = arrayMap(arrays, castArrayLikeObject);

      return (mapped.length && mapped[0] === arrays[0])

        ? baseIntersection(mapped)

        : [];

    });



    /**

     * This method is like `_.intersection` except that it accepts `iteratee`

     * which is invoked for each element of each `arrays` to generate the criterion

     * by which they're compared. The order and references of result values are

     * determined by the first array. The iteratee is invoked with one argument:

     * (value).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Array

     * @param {...Array} [arrays] The arrays to inspect.

     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.

     * @returns {Array} Returns the new array of intersecting values.

     * @example

     *

     * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);

     * // => [2.1]

     *

     * // The `_.property` iteratee shorthand.

     * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');

     * // => [{ 'x': 1 }]

     */

    var intersectionBy = baseRest(function(arrays) {

      var iteratee = last(arrays),

          mapped = arrayMap(arrays, castArrayLikeObject);



      if (iteratee === last(mapped)) {

        iteratee = undefined;

      } else {

        mapped.pop();

      }

      return (mapped.length && mapped[0] === arrays[0])

        ? baseIntersection(mapped, getIteratee(iteratee, 2))

        : [];

    });



    /**

     * This method is like `_.intersection` except that it accepts `comparator`

     * which is invoked to compare elements of `arrays`. The order and references

     * of result values are determined by the first array. The comparator is

     * invoked with two arguments: (arrVal, othVal).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Array

     * @param {...Array} [arrays] The arrays to inspect.

     * @param {Function} [comparator] The comparator invoked per element.

     * @returns {Array} Returns the new array of intersecting values.

     * @example

     *

     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];

     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];

     *

     * _.intersectionWith(objects, others, _.isEqual);

     * // => [{ 'x': 1, 'y': 2 }]

     */

    var intersectionWith = baseRest(function(arrays) {

      var comparator = last(arrays),

          mapped = arrayMap(arrays, castArrayLikeObject);



      comparator = typeof comparator == 'function' ? comparator : undefined;

      if (comparator) {

        mapped.pop();

      }

      return (mapped.length && mapped[0] === arrays[0])

        ? baseIntersection(mapped, undefined, comparator)

        : [];

    });



    /**

     * Converts all elements in `array` into a string separated by `separator`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Array

     * @param {Array} array The array to convert.

     * @param {string} [separator=','] The element separator.

     * @returns {string} Returns the joined string.

     * @example

     *

     * _.join(['a', 'b', 'c'], '~');

     * // => 'a~b~c'

     */

    function join(array, separator) {

      return array == null ? '' : nativeJoin.call(array, separator);

    }



    /**

     * Gets the last element of `array`.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Array

     * @param {Array} array The array to query.

     * @returns {*} Returns the last element of `array`.

     * @example

     *

     * _.last([1, 2, 3]);

     * // => 3

     */

    function last(array) {

      var length = array == null ? 0 : array.length;

      return length ? array[length - 1] : undefined;

    }



    /**

     * This method is like `_.indexOf` except that it iterates over elements of

     * `array` from right to left.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Array

     * @param {Array} array The array to inspect.

     * @param {*} value The value to search for.

     * @param {number} [fromIndex=array.length-1] The index to search from.

     * @returns {number} Returns the index of the matched value, else `-1`.

     * @example

     *

     * _.lastIndexOf([1, 2, 1, 2], 2);

     * // => 3

     *

     * // Search from the `fromIndex`.

     * _.lastIndexOf([1, 2, 1, 2], 2, 2);

     * // => 1

     */

    function lastIndexOf(array, value, fromIndex) {

      var length = array == null ? 0 : array.length;

      if (!length) {

        return -1;

      }

      var index = length;

      if (fromIndex !== undefined) {

        index = toInteger(fromIndex);

        index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);

      }

      return value === value

        ? strictLastIndexOf(array, value, index)

        : baseFindIndex(array, baseIsNaN, index, true);

    }



    /**

     * Gets the element at index `n` of `array`. If `n` is negative, the nth

     * element from the end is returned.

     *

     * @static

     * @memberOf _

     * @since 4.11.0

     * @category Array

     * @param {Array} array The array to query.

     * @param {number} [n=0] The index of the element to return.

     * @returns {*} Returns the nth element of `array`.

     * @example

     *

     * var array = ['a', 'b', 'c', 'd'];

     *

     * _.nth(array, 1);

     * // => 'b'

     *

     * _.nth(array, -2);

     * // => 'c';

     */

    function nth(array, n) {

      return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;

    }



    /**

     * Removes all given values from `array` using

     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)

     * for equality comparisons.

     *

     * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`

     * to remove elements from an array by predicate.

     *

     * @static

     * @memberOf _

     * @since 2.0.0

     * @category Array

     * @param {Array} array The array to modify.

     * @param {...*} [values] The values to remove.

     * @returns {Array} Returns `array`.

     * @example

     *

     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];

     *

     * _.pull(array, 'a', 'c');

     * console.log(array);

     * // => ['b', 'b']

     */

    var pull = baseRest(pullAll);



    /**

     * This method is like `_.pull` except that it accepts an array of values to remove.

     *

     * **Note:** Unlike `_.difference`, this method mutates `array`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Array

     * @param {Array} array The array to modify.

     * @param {Array} values The values to remove.

     * @returns {Array} Returns `array`.

     * @example

     *

     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];

     *

     * _.pullAll(array, ['a', 'c']);

     * console.log(array);

     * // => ['b', 'b']

     */

    function pullAll(array, values) {

      return (array && array.length && values && values.length)

        ? basePullAll(array, values)

        : array;

    }



    /**

     * This method is like `_.pullAll` except that it accepts `iteratee` which is

     * invoked for each element of `array` and `values` to generate the criterion

     * by which they're compared. The iteratee is invoked with one argument: (value).

     *

     * **Note:** Unlike `_.differenceBy`, this method mutates `array`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Array

     * @param {Array} array The array to modify.

     * @param {Array} values The values to remove.

     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.

     * @returns {Array} Returns `array`.

     * @example

     *

     * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];

     *

     * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');

     * console.log(array);

     * // => [{ 'x': 2 }]

     */

    function pullAllBy(array, values, iteratee) {

      return (array && array.length && values && values.length)

        ? basePullAll(array, values, getIteratee(iteratee, 2))

        : array;

    }



    /**

     * This method is like `_.pullAll` except that it accepts `comparator` which

     * is invoked to compare elements of `array` to `values`. The comparator is

     * invoked with two arguments: (arrVal, othVal).

     *

     * **Note:** Unlike `_.differenceWith`, this method mutates `array`.

     *

     * @static

     * @memberOf _

     * @since 4.6.0

     * @category Array

     * @param {Array} array The array to modify.

     * @param {Array} values The values to remove.

     * @param {Function} [comparator] The comparator invoked per element.

     * @returns {Array} Returns `array`.

     * @example

     *

     * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];

     *

     * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);

     * console.log(array);

     * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]

     */

    function pullAllWith(array, values, comparator) {

      return (array && array.length && values && values.length)

        ? basePullAll(array, values, undefined, comparator)

        : array;

    }



    /**

     * Removes elements from `array` corresponding to `indexes` and returns an

     * array of removed elements.

     *

     * **Note:** Unlike `_.at`, this method mutates `array`.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Array

     * @param {Array} array The array to modify.

     * @param {...(number|number[])} [indexes] The indexes of elements to remove.

     * @returns {Array} Returns the new array of removed elements.

     * @example

     *

     * var array = ['a', 'b', 'c', 'd'];

     * var pulled = _.pullAt(array, [1, 3]);

     *

     * console.log(array);

     * // => ['a', 'c']

     *

     * console.log(pulled);

     * // => ['b', 'd']

     */

    var pullAt = flatRest(function(array, indexes) {

      var length = array == null ? 0 : array.length,

          result = baseAt(array, indexes);



      basePullAt(array, arrayMap(indexes, function(index) {

        return isIndex(index, length) ? +index : index;

      }).sort(compareAscending));



      return result;

    });



    /**

     * Removes all elements from `array` that `predicate` returns truthy for

     * and returns an array of the removed elements. The predicate is invoked

     * with three arguments: (value, index, array).

     *

     * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`

     * to pull elements from an array by value.

     *

     * @static

     * @memberOf _

     * @since 2.0.0

     * @category Array

     * @param {Array} array The array to modify.

     * @param {Function} [predicate=_.identity] The function invoked per iteration.

     * @returns {Array} Returns the new array of removed elements.

     * @example

     *

     * var array = [1, 2, 3, 4];

     * var evens = _.remove(array, function(n) {

     *   return n % 2 == 0;

     * });

     *

     * console.log(array);

     * // => [1, 3]

     *

     * console.log(evens);

     * // => [2, 4]

     */

    function remove(array, predicate) {

      var result = [];

      if (!(array && array.length)) {

        return result;

      }

      var index = -1,

          indexes = [],

          length = array.length;



      predicate = getIteratee(predicate, 3);

      while (++index < length) {

        var value = array[index];

        if (predicate(value, index, array)) {

          result.push(value);

          indexes.push(index);

        }

      }

      basePullAt(array, indexes);

      return result;

    }



    /**

     * Reverses `array` so that the first element becomes the last, the second

     * element becomes the second to last, and so on.

     *

     * **Note:** This method mutates `array` and is based on

     * [`Array#reverse`](https://mdn.io/Array/reverse).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Array

     * @param {Array} array The array to modify.

     * @returns {Array} Returns `array`.

     * @example

     *

     * var array = [1, 2, 3];

     *

     * _.reverse(array);

     * // => [3, 2, 1]

     *

     * console.log(array);

     * // => [3, 2, 1]

     */

    function reverse(array) {

      return array == null ? array : nativeReverse.call(array);

    }



    /**

     * Creates a slice of `array` from `start` up to, but not including, `end`.

     *

     * **Note:** This method is used instead of

     * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are

     * returned.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Array

     * @param {Array} array The array to slice.

     * @param {number} [start=0] The start position.

     * @param {number} [end=array.length] The end position.

     * @returns {Array} Returns the slice of `array`.

     */

    function slice(array, start, end) {

      var length = array == null ? 0 : array.length;

      if (!length) {

        return [];

      }

      if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {

        start = 0;

        end = length;

      }

      else {

        start = start == null ? 0 : toInteger(start);

        end = end === undefined ? length : toInteger(end);

      }

      return baseSlice(array, start, end);

    }



    /**

     * Uses a binary search to determine the lowest index at which `value`

     * should be inserted into `array` in order to maintain its sort order.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Array

     * @param {Array} array The sorted array to inspect.

     * @param {*} value The value to evaluate.

     * @returns {number} Returns the index at which `value` should be inserted

     *  into `array`.

     * @example

     *

     * _.sortedIndex([30, 50], 40);

     * // => 1

     */

    function sortedIndex(array, value) {

      return baseSortedIndex(array, value);

    }



    /**

     * This method is like `_.sortedIndex` except that it accepts `iteratee`

     * which is invoked for `value` and each element of `array` to compute their

     * sort ranking. The iteratee is invoked with one argument: (value).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Array

     * @param {Array} array The sorted array to inspect.

     * @param {*} value The value to evaluate.

     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.

     * @returns {number} Returns the index at which `value` should be inserted

     *  into `array`.

     * @example

     *

     * var objects = [{ 'x': 4 }, { 'x': 5 }];

     *

     * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });

     * // => 0

     *

     * // The `_.property` iteratee shorthand.

     * _.sortedIndexBy(objects, { 'x': 4 }, 'x');

     * // => 0

     */

    function sortedIndexBy(array, value, iteratee) {

      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));

    }



    /**

     * This method is like `_.indexOf` except that it performs a binary

     * search on a sorted `array`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Array

     * @param {Array} array The array to inspect.

     * @param {*} value The value to search for.

     * @returns {number} Returns the index of the matched value, else `-1`.

     * @example

     *

     * _.sortedIndexOf([4, 5, 5, 5, 6], 5);

     * // => 1

     */

    function sortedIndexOf(array, value) {

      var length = array == null ? 0 : array.length;

      if (length) {

        var index = baseSortedIndex(array, value);

        if (index < length && eq(array[index], value)) {

          return index;

        }

      }

      return -1;

    }



    /**

     * This method is like `_.sortedIndex` except that it returns the highest

     * index at which `value` should be inserted into `array` in order to

     * maintain its sort order.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Array

     * @param {Array} array The sorted array to inspect.

     * @param {*} value The value to evaluate.

     * @returns {number} Returns the index at which `value` should be inserted

     *  into `array`.

     * @example

     *

     * _.sortedLastIndex([4, 5, 5, 5, 6], 5);

     * // => 4

     */

    function sortedLastIndex(array, value) {

      return baseSortedIndex(array, value, true);

    }



    /**

     * This method is like `_.sortedLastIndex` except that it accepts `iteratee`

     * which is invoked for `value` and each element of `array` to compute their

     * sort ranking. The iteratee is invoked with one argument: (value).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Array

     * @param {Array} array The sorted array to inspect.

     * @param {*} value The value to evaluate.

     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.

     * @returns {number} Returns the index at which `value` should be inserted

     *  into `array`.

     * @example

     *

     * var objects = [{ 'x': 4 }, { 'x': 5 }];

     *

     * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });

     * // => 1

     *

     * // The `_.property` iteratee shorthand.

     * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');

     * // => 1

     */

    function sortedLastIndexBy(array, value, iteratee) {

      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);

    }



    /**

     * This method is like `_.lastIndexOf` except that it performs a binary

     * search on a sorted `array`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Array

     * @param {Array} array The array to inspect.

     * @param {*} value The value to search for.

     * @returns {number} Returns the index of the matched value, else `-1`.

     * @example

     *

     * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);

     * // => 3

     */

    function sortedLastIndexOf(array, value) {

      var length = array == null ? 0 : array.length;

      if (length) {

        var index = baseSortedIndex(array, value, true) - 1;

        if (eq(array[index], value)) {

          return index;

        }

      }

      return -1;

    }



    /**

     * This method is like `_.uniq` except that it's designed and optimized

     * for sorted arrays.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Array

     * @param {Array} array The array to inspect.

     * @returns {Array} Returns the new duplicate free array.

     * @example

     *

     * _.sortedUniq([1, 1, 2]);

     * // => [1, 2]

     */

    function sortedUniq(array) {

      return (array && array.length)

        ? baseSortedUniq(array)

        : [];

    }



    /**

     * This method is like `_.uniqBy` except that it's designed and optimized

     * for sorted arrays.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Array

     * @param {Array} array The array to inspect.

     * @param {Function} [iteratee] The iteratee invoked per element.

     * @returns {Array} Returns the new duplicate free array.

     * @example

     *

     * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);

     * // => [1.1, 2.3]

     */

    function sortedUniqBy(array, iteratee) {

      return (array && array.length)

        ? baseSortedUniq(array, getIteratee(iteratee, 2))

        : [];

    }



    /**

     * Gets all but the first element of `array`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Array

     * @param {Array} array The array to query.

     * @returns {Array} Returns the slice of `array`.

     * @example

     *

     * _.tail([1, 2, 3]);

     * // => [2, 3]

     */

    function tail(array) {

      var length = array == null ? 0 : array.length;

      return length ? baseSlice(array, 1, length) : [];

    }



    /**

     * Creates a slice of `array` with `n` elements taken from the beginning.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Array

     * @param {Array} array The array to query.

     * @param {number} [n=1] The number of elements to take.

     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.

     * @returns {Array} Returns the slice of `array`.

     * @example

     *

     * _.take([1, 2, 3]);

     * // => [1]

     *

     * _.take([1, 2, 3], 2);

     * // => [1, 2]

     *

     * _.take([1, 2, 3], 5);

     * // => [1, 2, 3]

     *

     * _.take([1, 2, 3], 0);

     * // => []

     */

    function take(array, n, guard) {

      if (!(array && array.length)) {

        return [];

      }

      n = (guard || n === undefined) ? 1 : toInteger(n);

      return baseSlice(array, 0, n < 0 ? 0 : n);

    }



    /**

     * Creates a slice of `array` with `n` elements taken from the end.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Array

     * @param {Array} array The array to query.

     * @param {number} [n=1] The number of elements to take.

     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.

     * @returns {Array} Returns the slice of `array`.

     * @example

     *

     * _.takeRight([1, 2, 3]);

     * // => [3]

     *

     * _.takeRight([1, 2, 3], 2);

     * // => [2, 3]

     *

     * _.takeRight([1, 2, 3], 5);

     * // => [1, 2, 3]

     *

     * _.takeRight([1, 2, 3], 0);

     * // => []

     */

    function takeRight(array, n, guard) {

      var length = array == null ? 0 : array.length;

      if (!length) {

        return [];

      }

      n = (guard || n === undefined) ? 1 : toInteger(n);

      n = length - n;

      return baseSlice(array, n < 0 ? 0 : n, length);

    }



    /**

     * Creates a slice of `array` with elements taken from the end. Elements are

     * taken until `predicate` returns falsey. The predicate is invoked with

     * three arguments: (value, index, array).

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Array

     * @param {Array} array The array to query.

     * @param {Function} [predicate=_.identity] The function invoked per iteration.

     * @returns {Array} Returns the slice of `array`.

     * @example

     *

     * var users = [

     *   { 'user': 'barney',  'active': true },

     *   { 'user': 'fred',    'active': false },

     *   { 'user': 'pebbles', 'active': false }

     * ];

     *

     * _.takeRightWhile(users, function(o) { return !o.active; });

     * // => objects for ['fred', 'pebbles']

     *

     * // The `_.matches` iteratee shorthand.

     * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });

     * // => objects for ['pebbles']

     *

     * // The `_.matchesProperty` iteratee shorthand.

     * _.takeRightWhile(users, ['active', false]);

     * // => objects for ['fred', 'pebbles']

     *

     * // The `_.property` iteratee shorthand.

     * _.takeRightWhile(users, 'active');

     * // => []

     */

    function takeRightWhile(array, predicate) {

      return (array && array.length)

        ? baseWhile(array, getIteratee(predicate, 3), false, true)

        : [];

    }



    /**

     * Creates a slice of `array` with elements taken from the beginning. Elements

     * are taken until `predicate` returns falsey. The predicate is invoked with

     * three arguments: (value, index, array).

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Array

     * @param {Array} array The array to query.

     * @param {Function} [predicate=_.identity] The function invoked per iteration.

     * @returns {Array} Returns the slice of `array`.

     * @example

     *

     * var users = [

     *   { 'user': 'barney',  'active': false },

     *   { 'user': 'fred',    'active': false },

     *   { 'user': 'pebbles', 'active': true }

     * ];

     *

     * _.takeWhile(users, function(o) { return !o.active; });

     * // => objects for ['barney', 'fred']

     *

     * // The `_.matches` iteratee shorthand.

     * _.takeWhile(users, { 'user': 'barney', 'active': false });

     * // => objects for ['barney']

     *

     * // The `_.matchesProperty` iteratee shorthand.

     * _.takeWhile(users, ['active', false]);

     * // => objects for ['barney', 'fred']

     *

     * // The `_.property` iteratee shorthand.

     * _.takeWhile(users, 'active');

     * // => []

     */

    function takeWhile(array, predicate) {

      return (array && array.length)

        ? baseWhile(array, getIteratee(predicate, 3))

        : [];

    }



    /**

     * Creates an array of unique values, in order, from all given arrays using

     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)

     * for equality comparisons.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Array

     * @param {...Array} [arrays] The arrays to inspect.

     * @returns {Array} Returns the new array of combined values.

     * @example

     *

     * _.union([2], [1, 2]);

     * // => [2, 1]

     */

    var union = baseRest(function(arrays) {

      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));

    });



    /**

     * This method is like `_.union` except that it accepts `iteratee` which is

     * invoked for each element of each `arrays` to generate the criterion by

     * which uniqueness is computed. Result values are chosen from the first

     * array in which the value occurs. The iteratee is invoked with one argument:

     * (value).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Array

     * @param {...Array} [arrays] The arrays to inspect.

     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.

     * @returns {Array} Returns the new array of combined values.

     * @example

     *

     * _.unionBy([2.1], [1.2, 2.3], Math.floor);

     * // => [2.1, 1.2]

     *

     * // The `_.property` iteratee shorthand.

     * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');

     * // => [{ 'x': 1 }, { 'x': 2 }]

     */

    var unionBy = baseRest(function(arrays) {

      var iteratee = last(arrays);

      if (isArrayLikeObject(iteratee)) {

        iteratee = undefined;

      }

      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));

    });



    /**

     * This method is like `_.union` except that it accepts `comparator` which

     * is invoked to compare elements of `arrays`. Result values are chosen from

     * the first array in which the value occurs. The comparator is invoked

     * with two arguments: (arrVal, othVal).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Array

     * @param {...Array} [arrays] The arrays to inspect.

     * @param {Function} [comparator] The comparator invoked per element.

     * @returns {Array} Returns the new array of combined values.

     * @example

     *

     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];

     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];

     *

     * _.unionWith(objects, others, _.isEqual);

     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]

     */

    var unionWith = baseRest(function(arrays) {

      var comparator = last(arrays);

      comparator = typeof comparator == 'function' ? comparator : undefined;

      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);

    });



    /**

     * Creates a duplicate-free version of an array, using

     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)

     * for equality comparisons, in which only the first occurrence of each element

     * is kept. The order of result values is determined by the order they occur

     * in the array.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Array

     * @param {Array} array The array to inspect.

     * @returns {Array} Returns the new duplicate free array.

     * @example

     *

     * _.uniq([2, 1, 2]);

     * // => [2, 1]

     */

    function uniq(array) {

      return (array && array.length) ? baseUniq(array) : [];

    }



    /**

     * This method is like `_.uniq` except that it accepts `iteratee` which is

     * invoked for each element in `array` to generate the criterion by which

     * uniqueness is computed. The order of result values is determined by the

     * order they occur in the array. The iteratee is invoked with one argument:

     * (value).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Array

     * @param {Array} array The array to inspect.

     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.

     * @returns {Array} Returns the new duplicate free array.

     * @example

     *

     * _.uniqBy([2.1, 1.2, 2.3], Math.floor);

     * // => [2.1, 1.2]

     *

     * // The `_.property` iteratee shorthand.

     * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');

     * // => [{ 'x': 1 }, { 'x': 2 }]

     */

    function uniqBy(array, iteratee) {

      return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];

    }



    /**

     * This method is like `_.uniq` except that it accepts `comparator` which

     * is invoked to compare elements of `array`. The order of result values is

     * determined by the order they occur in the array.The comparator is invoked

     * with two arguments: (arrVal, othVal).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Array

     * @param {Array} array The array to inspect.

     * @param {Function} [comparator] The comparator invoked per element.

     * @returns {Array} Returns the new duplicate free array.

     * @example

     *

     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];

     *

     * _.uniqWith(objects, _.isEqual);

     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]

     */

    function uniqWith(array, comparator) {

      comparator = typeof comparator == 'function' ? comparator : undefined;

      return (array && array.length) ? baseUniq(array, undefined, comparator) : [];

    }



    /**

     * This method is like `_.zip` except that it accepts an array of grouped

     * elements and creates an array regrouping the elements to their pre-zip

     * configuration.

     *

     * @static

     * @memberOf _

     * @since 1.2.0

     * @category Array

     * @param {Array} array The array of grouped elements to process.

     * @returns {Array} Returns the new array of regrouped elements.

     * @example

     *

     * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);

     * // => [['a', 1, true], ['b', 2, false]]

     *

     * _.unzip(zipped);

     * // => [['a', 'b'], [1, 2], [true, false]]

     */

    function unzip(array) {

      if (!(array && array.length)) {

        return [];

      }

      var length = 0;

      array = arrayFilter(array, function(group) {

        if (isArrayLikeObject(group)) {

          length = nativeMax(group.length, length);

          return true;

        }

      });

      return baseTimes(length, function(index) {

        return arrayMap(array, baseProperty(index));

      });

    }



    /**

     * This method is like `_.unzip` except that it accepts `iteratee` to specify

     * how regrouped values should be combined. The iteratee is invoked with the

     * elements of each group: (...group).

     *

     * @static

     * @memberOf _

     * @since 3.8.0

     * @category Array

     * @param {Array} array The array of grouped elements to process.

     * @param {Function} [iteratee=_.identity] The function to combine

     *  regrouped values.

     * @returns {Array} Returns the new array of regrouped elements.

     * @example

     *

     * var zipped = _.zip([1, 2], [10, 20], [100, 200]);

     * // => [[1, 10, 100], [2, 20, 200]]

     *

     * _.unzipWith(zipped, _.add);

     * // => [3, 30, 300]

     */

    function unzipWith(array, iteratee) {

      if (!(array && array.length)) {

        return [];

      }

      var result = unzip(array);

      if (iteratee == null) {

        return result;

      }

      return arrayMap(result, function(group) {

        return apply(iteratee, undefined, group);

      });

    }



    /**

     * Creates an array excluding all given values using

     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)

     * for equality comparisons.

     *

     * **Note:** Unlike `_.pull`, this method returns a new array.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Array

     * @param {Array} array The array to inspect.

     * @param {...*} [values] The values to exclude.

     * @returns {Array} Returns the new array of filtered values.

     * @see _.difference, _.xor

     * @example

     *

     * _.without([2, 1, 2, 3], 1, 2);

     * // => [3]

     */

    var without = baseRest(function(array, values) {

      return isArrayLikeObject(array)

        ? baseDifference(array, values)

        : [];

    });



    /**

     * Creates an array of unique values that is the

     * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)

     * of the given arrays. The order of result values is determined by the order

     * they occur in the arrays.

     *

     * @static

     * @memberOf _

     * @since 2.4.0

     * @category Array

     * @param {...Array} [arrays] The arrays to inspect.

     * @returns {Array} Returns the new array of filtered values.

     * @see _.difference, _.without

     * @example

     *

     * _.xor([2, 1], [2, 3]);

     * // => [1, 3]

     */

    var xor = baseRest(function(arrays) {

      return baseXor(arrayFilter(arrays, isArrayLikeObject));

    });



    /**

     * This method is like `_.xor` except that it accepts `iteratee` which is

     * invoked for each element of each `arrays` to generate the criterion by

     * which by which they're compared. The order of result values is determined

     * by the order they occur in the arrays. The iteratee is invoked with one

     * argument: (value).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Array

     * @param {...Array} [arrays] The arrays to inspect.

     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.

     * @returns {Array} Returns the new array of filtered values.

     * @example

     *

     * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);

     * // => [1.2, 3.4]

     *

     * // The `_.property` iteratee shorthand.

     * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');

     * // => [{ 'x': 2 }]

     */

    var xorBy = baseRest(function(arrays) {

      var iteratee = last(arrays);

      if (isArrayLikeObject(iteratee)) {

        iteratee = undefined;

      }

      return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));

    });



    /**

     * This method is like `_.xor` except that it accepts `comparator` which is

     * invoked to compare elements of `arrays`. The order of result values is

     * determined by the order they occur in the arrays. The comparator is invoked

     * with two arguments: (arrVal, othVal).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Array

     * @param {...Array} [arrays] The arrays to inspect.

     * @param {Function} [comparator] The comparator invoked per element.

     * @returns {Array} Returns the new array of filtered values.

     * @example

     *

     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];

     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];

     *

     * _.xorWith(objects, others, _.isEqual);

     * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]

     */

    var xorWith = baseRest(function(arrays) {

      var comparator = last(arrays);

      comparator = typeof comparator == 'function' ? comparator : undefined;

      return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);

    });



    /**

     * Creates an array of grouped elements, the first of which contains the

     * first elements of the given arrays, the second of which contains the

     * second elements of the given arrays, and so on.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Array

     * @param {...Array} [arrays] The arrays to process.

     * @returns {Array} Returns the new array of grouped elements.

     * @example

     *

     * _.zip(['a', 'b'], [1, 2], [true, false]);

     * // => [['a', 1, true], ['b', 2, false]]

     */

    var zip = baseRest(unzip);



    /**

     * This method is like `_.fromPairs` except that it accepts two arrays,

     * one of property identifiers and one of corresponding values.

     *

     * @static

     * @memberOf _

     * @since 0.4.0

     * @category Array

     * @param {Array} [props=[]] The property identifiers.

     * @param {Array} [values=[]] The property values.

     * @returns {Object} Returns the new object.

     * @example

     *

     * _.zipObject(['a', 'b'], [1, 2]);

     * // => { 'a': 1, 'b': 2 }

     */

    function zipObject(props, values) {

      return baseZipObject(props || [], values || [], assignValue);

    }



    /**

     * This method is like `_.zipObject` except that it supports property paths.

     *

     * @static

     * @memberOf _

     * @since 4.1.0

     * @category Array

     * @param {Array} [props=[]] The property identifiers.

     * @param {Array} [values=[]] The property values.

     * @returns {Object} Returns the new object.

     * @example

     *

     * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);

     * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }

     */

    function zipObjectDeep(props, values) {

      return baseZipObject(props || [], values || [], baseSet);

    }



    /**

     * This method is like `_.zip` except that it accepts `iteratee` to specify

     * how grouped values should be combined. The iteratee is invoked with the

     * elements of each group: (...group).

     *

     * @static

     * @memberOf _

     * @since 3.8.0

     * @category Array

     * @param {...Array} [arrays] The arrays to process.

     * @param {Function} [iteratee=_.identity] The function to combine

     *  grouped values.

     * @returns {Array} Returns the new array of grouped elements.

     * @example

     *

     * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {

     *   return a + b + c;

     * });

     * // => [111, 222]

     */

    var zipWith = baseRest(function(arrays) {

      var length = arrays.length,

          iteratee = length > 1 ? arrays[length - 1] : undefined;



      iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;

      return unzipWith(arrays, iteratee);

    });



    /*------------------------------------------------------------------------*/



    /**

     * Creates a `lodash` wrapper instance that wraps `value` with explicit method

     * chain sequences enabled. The result of such sequences must be unwrapped

     * with `_#value`.

     *

     * @static

     * @memberOf _

     * @since 1.3.0

     * @category Seq

     * @param {*} value The value to wrap.

     * @returns {Object} Returns the new `lodash` wrapper instance.

     * @example

     *

     * var users = [

     *   { 'user': 'barney',  'age': 36 },

     *   { 'user': 'fred',    'age': 40 },

     *   { 'user': 'pebbles', 'age': 1 }

     * ];

     *

     * var youngest = _

     *   .chain(users)

     *   .sortBy('age')

     *   .map(function(o) {

     *     return o.user + ' is ' + o.age;

     *   })

     *   .head()

     *   .value();

     * // => 'pebbles is 1'

     */

    function chain(value) {

      var result = lodash(value);

      result.__chain__ = true;

      return result;

    }



    /**

     * This method invokes `interceptor` and returns `value`. The interceptor

     * is invoked with one argument; (value). The purpose of this method is to

     * "tap into" a method chain sequence in order to modify intermediate results.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Seq

     * @param {*} value The value to provide to `interceptor`.

     * @param {Function} interceptor The function to invoke.

     * @returns {*} Returns `value`.

     * @example

     *

     * _([1, 2, 3])

     *  .tap(function(array) {

     *    // Mutate input array.

     *    array.pop();

     *  })

     *  .reverse()

     *  .value();

     * // => [2, 1]

     */

    function tap(value, interceptor) {

      interceptor(value);

      return value;

    }



    /**

     * This method is like `_.tap` except that it returns the result of `interceptor`.

     * The purpose of this method is to "pass thru" values replacing intermediate

     * results in a method chain sequence.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Seq

     * @param {*} value The value to provide to `interceptor`.

     * @param {Function} interceptor The function to invoke.

     * @returns {*} Returns the result of `interceptor`.

     * @example

     *

     * _('  abc  ')

     *  .chain()

     *  .trim()

     *  .thru(function(value) {

     *    return [value];

     *  })

     *  .value();

     * // => ['abc']

     */

    function thru(value, interceptor) {

      return interceptor(value);

    }



    /**

     * This method is the wrapper version of `_.at`.

     *

     * @name at

     * @memberOf _

     * @since 1.0.0

     * @category Seq

     * @param {...(string|string[])} [paths] The property paths to pick.

     * @returns {Object} Returns the new `lodash` wrapper instance.

     * @example

     *

     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };

     *

     * _(object).at(['a[0].b.c', 'a[1]']).value();

     * // => [3, 4]

     */

    var wrapperAt = flatRest(function(paths) {

      var length = paths.length,

          start = length ? paths[0] : 0,

          value = this.__wrapped__,

          interceptor = function(object) { return baseAt(object, paths); };



      if (length > 1 || this.__actions__.length ||

          !(value instanceof LazyWrapper) || !isIndex(start)) {

        return this.thru(interceptor);

      }

      value = value.slice(start, +start + (length ? 1 : 0));

      value.__actions__.push({

        'func': thru,

        'args': [interceptor],

        'thisArg': undefined

      });

      return new LodashWrapper(value, this.__chain__).thru(function(array) {

        if (length && !array.length) {

          array.push(undefined);

        }

        return array;

      });

    });



    /**

     * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.

     *

     * @name chain

     * @memberOf _

     * @since 0.1.0

     * @category Seq

     * @returns {Object} Returns the new `lodash` wrapper instance.

     * @example

     *

     * var users = [

     *   { 'user': 'barney', 'age': 36 },

     *   { 'user': 'fred',   'age': 40 }

     * ];

     *

     * // A sequence without explicit chaining.

     * _(users).head();

     * // => { 'user': 'barney', 'age': 36 }

     *

     * // A sequence with explicit chaining.

     * _(users)

     *   .chain()

     *   .head()

     *   .pick('user')

     *   .value();

     * // => { 'user': 'barney' }

     */

    function wrapperChain() {

      return chain(this);

    }



    /**

     * Executes the chain sequence and returns the wrapped result.

     *

     * @name commit

     * @memberOf _

     * @since 3.2.0

     * @category Seq

     * @returns {Object} Returns the new `lodash` wrapper instance.

     * @example

     *

     * var array = [1, 2];

     * var wrapped = _(array).push(3);

     *

     * console.log(array);

     * // => [1, 2]

     *

     * wrapped = wrapped.commit();

     * console.log(array);

     * // => [1, 2, 3]

     *

     * wrapped.last();

     * // => 3

     *

     * console.log(array);

     * // => [1, 2, 3]

     */

    function wrapperCommit() {

      return new LodashWrapper(this.value(), this.__chain__);

    }



    /**

     * Gets the next value on a wrapped object following the

     * [iterator protocol](https://mdn.io/iteration_protocols#iterator).

     *

     * @name next

     * @memberOf _

     * @since 4.0.0

     * @category Seq

     * @returns {Object} Returns the next iterator value.

     * @example

     *

     * var wrapped = _([1, 2]);

     *

     * wrapped.next();

     * // => { 'done': false, 'value': 1 }

     *

     * wrapped.next();

     * // => { 'done': false, 'value': 2 }

     *

     * wrapped.next();

     * // => { 'done': true, 'value': undefined }

     */

    function wrapperNext() {

      if (this.__values__ === undefined) {

        this.__values__ = toArray(this.value());

      }

      var done = this.__index__ >= this.__values__.length,

          value = done ? undefined : this.__values__[this.__index__++];



      return { 'done': done, 'value': value };

    }



    /**

     * Enables the wrapper to be iterable.

     *

     * @name Symbol.iterator

     * @memberOf _

     * @since 4.0.0

     * @category Seq

     * @returns {Object} Returns the wrapper object.

     * @example

     *

     * var wrapped = _([1, 2]);

     *

     * wrapped[Symbol.iterator]() === wrapped;

     * // => true

     *

     * Array.from(wrapped);

     * // => [1, 2]

     */

    function wrapperToIterator() {

      return this;

    }



    /**

     * Creates a clone of the chain sequence planting `value` as the wrapped value.

     *

     * @name plant

     * @memberOf _

     * @since 3.2.0

     * @category Seq

     * @param {*} value The value to plant.

     * @returns {Object} Returns the new `lodash` wrapper instance.

     * @example

     *

     * function square(n) {

     *   return n * n;

     * }

     *

     * var wrapped = _([1, 2]).map(square);

     * var other = wrapped.plant([3, 4]);

     *

     * other.value();

     * // => [9, 16]

     *

     * wrapped.value();

     * // => [1, 4]

     */

    function wrapperPlant(value) {

      var result,

          parent = this;



      while (parent instanceof baseLodash) {

        var clone = wrapperClone(parent);

        clone.__index__ = 0;

        clone.__values__ = undefined;

        if (result) {

          previous.__wrapped__ = clone;

        } else {

          result = clone;

        }

        var previous = clone;

        parent = parent.__wrapped__;

      }

      previous.__wrapped__ = value;

      return result;

    }



    /**

     * This method is the wrapper version of `_.reverse`.

     *

     * **Note:** This method mutates the wrapped array.

     *

     * @name reverse

     * @memberOf _

     * @since 0.1.0

     * @category Seq

     * @returns {Object} Returns the new `lodash` wrapper instance.

     * @example

     *

     * var array = [1, 2, 3];

     *

     * _(array).reverse().value()

     * // => [3, 2, 1]

     *

     * console.log(array);

     * // => [3, 2, 1]

     */

    function wrapperReverse() {

      var value = this.__wrapped__;

      if (value instanceof LazyWrapper) {

        var wrapped = value;

        if (this.__actions__.length) {

          wrapped = new LazyWrapper(this);

        }

        wrapped = wrapped.reverse();

        wrapped.__actions__.push({

          'func': thru,

          'args': [reverse],

          'thisArg': undefined

        });

        return new LodashWrapper(wrapped, this.__chain__);

      }

      return this.thru(reverse);

    }



    /**

     * Executes the chain sequence to resolve the unwrapped value.

     *

     * @name value

     * @memberOf _

     * @since 0.1.0

     * @alias toJSON, valueOf

     * @category Seq

     * @returns {*} Returns the resolved unwrapped value.

     * @example

     *

     * _([1, 2, 3]).value();

     * // => [1, 2, 3]

     */

    function wrapperValue() {

      return baseWrapperValue(this.__wrapped__, this.__actions__);

    }



    /*------------------------------------------------------------------------*/



    /**

     * Creates an object composed of keys generated from the results of running

     * each element of `collection` thru `iteratee`. The corresponding value of

     * each key is the number of times the key was returned by `iteratee`. The

     * iteratee is invoked with one argument: (value).

     *

     * @static

     * @memberOf _

     * @since 0.5.0

     * @category Collection

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.

     * @returns {Object} Returns the composed aggregate object.

     * @example

     *

     * _.countBy([6.1, 4.2, 6.3], Math.floor);

     * // => { '4': 1, '6': 2 }

     *

     * // The `_.property` iteratee shorthand.

     * _.countBy(['one', 'two', 'three'], 'length');

     * // => { '3': 2, '5': 1 }

     */

    var countBy = createAggregator(function(result, value, key) {

      if (hasOwnProperty.call(result, key)) {

        ++result[key];

      } else {

        baseAssignValue(result, key, 1);

      }

    });



    /**

     * Checks if `predicate` returns truthy for **all** elements of `collection`.

     * Iteration is stopped once `predicate` returns falsey. The predicate is

     * invoked with three arguments: (value, index|key, collection).

     *

     * **Note:** This method returns `true` for

     * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because

     * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of

     * elements of empty collections.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Collection

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Function} [predicate=_.identity] The function invoked per iteration.

     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.

     * @returns {boolean} Returns `true` if all elements pass the predicate check,

     *  else `false`.

     * @example

     *

     * _.every([true, 1, null, 'yes'], Boolean);

     * // => false

     *

     * var users = [

     *   { 'user': 'barney', 'age': 36, 'active': false },

     *   { 'user': 'fred',   'age': 40, 'active': false }

     * ];

     *

     * // The `_.matches` iteratee shorthand.

     * _.every(users, { 'user': 'barney', 'active': false });

     * // => false

     *

     * // The `_.matchesProperty` iteratee shorthand.

     * _.every(users, ['active', false]);

     * // => true

     *

     * // The `_.property` iteratee shorthand.

     * _.every(users, 'active');

     * // => false

     */

    function every(collection, predicate, guard) {

      var func = isArray(collection) ? arrayEvery : baseEvery;

      if (guard && isIterateeCall(collection, predicate, guard)) {

        predicate = undefined;

      }

      return func(collection, getIteratee(predicate, 3));

    }



    /**

     * Iterates over elements of `collection`, returning an array of all elements

     * `predicate` returns truthy for. The predicate is invoked with three

     * arguments: (value, index|key, collection).

     *

     * **Note:** Unlike `_.remove`, this method returns a new array.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Collection

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Function} [predicate=_.identity] The function invoked per iteration.

     * @returns {Array} Returns the new filtered array.

     * @see _.reject

     * @example

     *

     * var users = [

     *   { 'user': 'barney', 'age': 36, 'active': true },

     *   { 'user': 'fred',   'age': 40, 'active': false }

     * ];

     *

     * _.filter(users, function(o) { return !o.active; });

     * // => objects for ['fred']

     *

     * // The `_.matches` iteratee shorthand.

     * _.filter(users, { 'age': 36, 'active': true });

     * // => objects for ['barney']

     *

     * // The `_.matchesProperty` iteratee shorthand.

     * _.filter(users, ['active', false]);

     * // => objects for ['fred']

     *

     * // The `_.property` iteratee shorthand.

     * _.filter(users, 'active');

     * // => objects for ['barney']

     */

    function filter(collection, predicate) {

      var func = isArray(collection) ? arrayFilter : baseFilter;

      return func(collection, getIteratee(predicate, 3));

    }



    /**

     * Iterates over elements of `collection`, returning the first element

     * `predicate` returns truthy for. The predicate is invoked with three

     * arguments: (value, index|key, collection).

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Collection

     * @param {Array|Object} collection The collection to inspect.

     * @param {Function} [predicate=_.identity] The function invoked per iteration.

     * @param {number} [fromIndex=0] The index to search from.

     * @returns {*} Returns the matched element, else `undefined`.

     * @example

     *

     * var users = [

     *   { 'user': 'barney',  'age': 36, 'active': true },

     *   { 'user': 'fred',    'age': 40, 'active': false },

     *   { 'user': 'pebbles', 'age': 1,  'active': true }

     * ];

     *

     * _.find(users, function(o) { return o.age < 40; });

     * // => object for 'barney'

     *

     * // The `_.matches` iteratee shorthand.

     * _.find(users, { 'age': 1, 'active': true });

     * // => object for 'pebbles'

     *

     * // The `_.matchesProperty` iteratee shorthand.

     * _.find(users, ['active', false]);

     * // => object for 'fred'

     *

     * // The `_.property` iteratee shorthand.

     * _.find(users, 'active');

     * // => object for 'barney'

     */

    var find = createFind(findIndex);



    /**

     * This method is like `_.find` except that it iterates over elements of

     * `collection` from right to left.

     *

     * @static

     * @memberOf _

     * @since 2.0.0

     * @category Collection

     * @param {Array|Object} collection The collection to inspect.

     * @param {Function} [predicate=_.identity] The function invoked per iteration.

     * @param {number} [fromIndex=collection.length-1] The index to search from.

     * @returns {*} Returns the matched element, else `undefined`.

     * @example

     *

     * _.findLast([1, 2, 3, 4], function(n) {

     *   return n % 2 == 1;

     * });

     * // => 3

     */

    var findLast = createFind(findLastIndex);



    /**

     * Creates a flattened array of values by running each element in `collection`

     * thru `iteratee` and flattening the mapped results. The iteratee is invoked

     * with three arguments: (value, index|key, collection).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Collection

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Function} [iteratee=_.identity] The function invoked per iteration.

     * @returns {Array} Returns the new flattened array.

     * @example

     *

     * function duplicate(n) {

     *   return [n, n];

     * }

     *

     * _.flatMap([1, 2], duplicate);

     * // => [1, 1, 2, 2]

     */

    function flatMap(collection, iteratee) {

      return baseFlatten(map(collection, iteratee), 1);

    }



    /**

     * This method is like `_.flatMap` except that it recursively flattens the

     * mapped results.

     *

     * @static

     * @memberOf _

     * @since 4.7.0

     * @category Collection

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Function} [iteratee=_.identity] The function invoked per iteration.

     * @returns {Array} Returns the new flattened array.

     * @example

     *

     * function duplicate(n) {

     *   return [[[n, n]]];

     * }

     *

     * _.flatMapDeep([1, 2], duplicate);

     * // => [1, 1, 2, 2]

     */

    function flatMapDeep(collection, iteratee) {

      return baseFlatten(map(collection, iteratee), INFINITY);

    }



    /**

     * This method is like `_.flatMap` except that it recursively flattens the

     * mapped results up to `depth` times.

     *

     * @static

     * @memberOf _

     * @since 4.7.0

     * @category Collection

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Function} [iteratee=_.identity] The function invoked per iteration.

     * @param {number} [depth=1] The maximum recursion depth.

     * @returns {Array} Returns the new flattened array.

     * @example

     *

     * function duplicate(n) {

     *   return [[[n, n]]];

     * }

     *

     * _.flatMapDepth([1, 2], duplicate, 2);

     * // => [[1, 1], [2, 2]]

     */

    function flatMapDepth(collection, iteratee, depth) {

      depth = depth === undefined ? 1 : toInteger(depth);

      return baseFlatten(map(collection, iteratee), depth);

    }



    /**

     * Iterates over elements of `collection` and invokes `iteratee` for each element.

     * The iteratee is invoked with three arguments: (value, index|key, collection).

     * Iteratee functions may exit iteration early by explicitly returning `false`.

     *

     * **Note:** As with other "Collections" methods, objects with a "length"

     * property are iterated like arrays. To avoid this behavior use `_.forIn`

     * or `_.forOwn` for object iteration.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @alias each

     * @category Collection

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Function} [iteratee=_.identity] The function invoked per iteration.

     * @returns {Array|Object} Returns `collection`.

     * @see _.forEachRight

     * @example

     *

     * _.forEach([1, 2], function(value) {

     *   console.log(value);

     * });

     * // => Logs `1` then `2`.

     *

     * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {

     *   console.log(key);

     * });

     * // => Logs 'a' then 'b' (iteration order is not guaranteed).

     */

    function forEach(collection, iteratee) {

      var func = isArray(collection) ? arrayEach : baseEach;

      return func(collection, getIteratee(iteratee, 3));

    }



    /**

     * This method is like `_.forEach` except that it iterates over elements of

     * `collection` from right to left.

     *

     * @static

     * @memberOf _

     * @since 2.0.0

     * @alias eachRight

     * @category Collection

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Function} [iteratee=_.identity] The function invoked per iteration.

     * @returns {Array|Object} Returns `collection`.

     * @see _.forEach

     * @example

     *

     * _.forEachRight([1, 2], function(value) {

     *   console.log(value);

     * });

     * // => Logs `2` then `1`.

     */

    function forEachRight(collection, iteratee) {

      var func = isArray(collection) ? arrayEachRight : baseEachRight;

      return func(collection, getIteratee(iteratee, 3));

    }



    /**

     * Creates an object composed of keys generated from the results of running

     * each element of `collection` thru `iteratee`. The order of grouped values

     * is determined by the order they occur in `collection`. The corresponding

     * value of each key is an array of elements responsible for generating the

     * key. The iteratee is invoked with one argument: (value).

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Collection

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.

     * @returns {Object} Returns the composed aggregate object.

     * @example

     *

     * _.groupBy([6.1, 4.2, 6.3], Math.floor);

     * // => { '4': [4.2], '6': [6.1, 6.3] }

     *

     * // The `_.property` iteratee shorthand.

     * _.groupBy(['one', 'two', 'three'], 'length');

     * // => { '3': ['one', 'two'], '5': ['three'] }

     */

    var groupBy = createAggregator(function(result, value, key) {

      if (hasOwnProperty.call(result, key)) {

        result[key].push(value);

      } else {

        baseAssignValue(result, key, [value]);

      }

    });



    /**

     * Checks if `value` is in `collection`. If `collection` is a string, it's

     * checked for a substring of `value`, otherwise

     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)

     * is used for equality comparisons. If `fromIndex` is negative, it's used as

     * the offset from the end of `collection`.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Collection

     * @param {Array|Object|string} collection The collection to inspect.

     * @param {*} value The value to search for.

     * @param {number} [fromIndex=0] The index to search from.

     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.

     * @returns {boolean} Returns `true` if `value` is found, else `false`.

     * @example

     *

     * _.includes([1, 2, 3], 1);

     * // => true

     *

     * _.includes([1, 2, 3], 1, 2);

     * // => false

     *

     * _.includes({ 'a': 1, 'b': 2 }, 1);

     * // => true

     *

     * _.includes('abcd', 'bc');

     * // => true

     */

    function includes(collection, value, fromIndex, guard) {

      collection = isArrayLike(collection) ? collection : values(collection);

      fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;



      var length = collection.length;

      if (fromIndex < 0) {

        fromIndex = nativeMax(length + fromIndex, 0);

      }

      return isString(collection)

        ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)

        : (!!length && baseIndexOf(collection, value, fromIndex) > -1);

    }



    /**

     * Invokes the method at `path` of each element in `collection`, returning

     * an array of the results of each invoked method. Any additional arguments

     * are provided to each invoked method. If `path` is a function, it's invoked

     * for, and `this` bound to, each element in `collection`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Collection

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Array|Function|string} path The path of the method to invoke or

     *  the function invoked per iteration.

     * @param {...*} [args] The arguments to invoke each method with.

     * @returns {Array} Returns the array of results.

     * @example

     *

     * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');

     * // => [[1, 5, 7], [1, 2, 3]]

     *

     * _.invokeMap([123, 456], String.prototype.split, '');

     * // => [['1', '2', '3'], ['4', '5', '6']]

     */

    var invokeMap = baseRest(function(collection, path, args) {

      var index = -1,

          isFunc = typeof path == 'function',

          result = isArrayLike(collection) ? Array(collection.length) : [];



      baseEach(collection, function(value) {

        result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);

      });

      return result;

    });



    /**

     * Creates an object composed of keys generated from the results of running

     * each element of `collection` thru `iteratee`. The corresponding value of

     * each key is the last element responsible for generating the key. The

     * iteratee is invoked with one argument: (value).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Collection

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.

     * @returns {Object} Returns the composed aggregate object.

     * @example

     *

     * var array = [

     *   { 'dir': 'left', 'code': 97 },

     *   { 'dir': 'right', 'code': 100 }

     * ];

     *

     * _.keyBy(array, function(o) {

     *   return String.fromCharCode(o.code);

     * });

     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }

     *

     * _.keyBy(array, 'dir');

     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }

     */

    var keyBy = createAggregator(function(result, value, key) {

      baseAssignValue(result, key, value);

    });



    /**

     * Creates an array of values by running each element in `collection` thru

     * `iteratee`. The iteratee is invoked with three arguments:

     * (value, index|key, collection).

     *

     * Many lodash methods are guarded to work as iteratees for methods like

     * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.

     *

     * The guarded methods are:

     * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,

     * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,

     * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,

     * `template`, `trim`, `trimEnd`, `trimStart`, and `words`

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Collection

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Function} [iteratee=_.identity] The function invoked per iteration.

     * @returns {Array} Returns the new mapped array.

     * @example

     *

     * function square(n) {

     *   return n * n;

     * }

     *

     * _.map([4, 8], square);

     * // => [16, 64]

     *

     * _.map({ 'a': 4, 'b': 8 }, square);

     * // => [16, 64] (iteration order is not guaranteed)

     *

     * var users = [

     *   { 'user': 'barney' },

     *   { 'user': 'fred' }

     * ];

     *

     * // The `_.property` iteratee shorthand.

     * _.map(users, 'user');

     * // => ['barney', 'fred']

     */

    function map(collection, iteratee) {

      var func = isArray(collection) ? arrayMap : baseMap;

      return func(collection, getIteratee(iteratee, 3));

    }



    /**

     * This method is like `_.sortBy` except that it allows specifying the sort

     * orders of the iteratees to sort by. If `orders` is unspecified, all values

     * are sorted in ascending order. Otherwise, specify an order of "desc" for

     * descending or "asc" for ascending sort order of corresponding values.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Collection

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]

     *  The iteratees to sort by.

     * @param {string[]} [orders] The sort orders of `iteratees`.

     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.

     * @returns {Array} Returns the new sorted array.

     * @example

     *

     * var users = [

     *   { 'user': 'fred',   'age': 48 },

     *   { 'user': 'barney', 'age': 34 },

     *   { 'user': 'fred',   'age': 40 },

     *   { 'user': 'barney', 'age': 36 }

     * ];

     *

     * // Sort by `user` in ascending order and by `age` in descending order.

     * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);

     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]

     */

    function orderBy(collection, iteratees, orders, guard) {

      if (collection == null) {

        return [];

      }

      if (!isArray(iteratees)) {

        iteratees = iteratees == null ? [] : [iteratees];

      }

      orders = guard ? undefined : orders;

      if (!isArray(orders)) {

        orders = orders == null ? [] : [orders];

      }

      return baseOrderBy(collection, iteratees, orders);

    }



    /**

     * Creates an array of elements split into two groups, the first of which

     * contains elements `predicate` returns truthy for, the second of which

     * contains elements `predicate` returns falsey for. The predicate is

     * invoked with one argument: (value).

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Collection

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Function} [predicate=_.identity] The function invoked per iteration.

     * @returns {Array} Returns the array of grouped elements.

     * @example

     *

     * var users = [

     *   { 'user': 'barney',  'age': 36, 'active': false },

     *   { 'user': 'fred',    'age': 40, 'active': true },

     *   { 'user': 'pebbles', 'age': 1,  'active': false }

     * ];

     *

     * _.partition(users, function(o) { return o.active; });

     * // => objects for [['fred'], ['barney', 'pebbles']]

     *

     * // The `_.matches` iteratee shorthand.

     * _.partition(users, { 'age': 1, 'active': false });

     * // => objects for [['pebbles'], ['barney', 'fred']]

     *

     * // The `_.matchesProperty` iteratee shorthand.

     * _.partition(users, ['active', false]);

     * // => objects for [['barney', 'pebbles'], ['fred']]

     *

     * // The `_.property` iteratee shorthand.

     * _.partition(users, 'active');

     * // => objects for [['fred'], ['barney', 'pebbles']]

     */

    var partition = createAggregator(function(result, value, key) {

      result[key ? 0 : 1].push(value);

    }, function() { return [[], []]; });



    /**

     * Reduces `collection` to a value which is the accumulated result of running

     * each element in `collection` thru `iteratee`, where each successive

     * invocation is supplied the return value of the previous. If `accumulator`

     * is not given, the first element of `collection` is used as the initial

     * value. The iteratee is invoked with four arguments:

     * (accumulator, value, index|key, collection).

     *

     * Many lodash methods are guarded to work as iteratees for methods like

     * `_.reduce`, `_.reduceRight`, and `_.transform`.

     *

     * The guarded methods are:

     * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,

     * and `sortBy`

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Collection

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Function} [iteratee=_.identity] The function invoked per iteration.

     * @param {*} [accumulator] The initial value.

     * @returns {*} Returns the accumulated value.

     * @see _.reduceRight

     * @example

     *

     * _.reduce([1, 2], function(sum, n) {

     *   return sum + n;

     * }, 0);

     * // => 3

     *

     * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {

     *   (result[value] || (result[value] = [])).push(key);

     *   return result;

     * }, {});

     * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)

     */

    function reduce(collection, iteratee, accumulator) {

      var func = isArray(collection) ? arrayReduce : baseReduce,

          initAccum = arguments.length < 3;



      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);

    }



    /**

     * This method is like `_.reduce` except that it iterates over elements of

     * `collection` from right to left.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Collection

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Function} [iteratee=_.identity] The function invoked per iteration.

     * @param {*} [accumulator] The initial value.

     * @returns {*} Returns the accumulated value.

     * @see _.reduce

     * @example

     *

     * var array = [[0, 1], [2, 3], [4, 5]];

     *

     * _.reduceRight(array, function(flattened, other) {

     *   return flattened.concat(other);

     * }, []);

     * // => [4, 5, 2, 3, 0, 1]

     */

    function reduceRight(collection, iteratee, accumulator) {

      var func = isArray(collection) ? arrayReduceRight : baseReduce,

          initAccum = arguments.length < 3;



      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);

    }



    /**

     * The opposite of `_.filter`; this method returns the elements of `collection`

     * that `predicate` does **not** return truthy for.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Collection

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Function} [predicate=_.identity] The function invoked per iteration.

     * @returns {Array} Returns the new filtered array.

     * @see _.filter

     * @example

     *

     * var users = [

     *   { 'user': 'barney', 'age': 36, 'active': false },

     *   { 'user': 'fred',   'age': 40, 'active': true }

     * ];

     *

     * _.reject(users, function(o) { return !o.active; });

     * // => objects for ['fred']

     *

     * // The `_.matches` iteratee shorthand.

     * _.reject(users, { 'age': 40, 'active': true });

     * // => objects for ['barney']

     *

     * // The `_.matchesProperty` iteratee shorthand.

     * _.reject(users, ['active', false]);

     * // => objects for ['fred']

     *

     * // The `_.property` iteratee shorthand.

     * _.reject(users, 'active');

     * // => objects for ['barney']

     */

    function reject(collection, predicate) {

      var func = isArray(collection) ? arrayFilter : baseFilter;

      return func(collection, negate(getIteratee(predicate, 3)));

    }



    /**

     * Gets a random element from `collection`.

     *

     * @static

     * @memberOf _

     * @since 2.0.0

     * @category Collection

     * @param {Array|Object} collection The collection to sample.

     * @returns {*} Returns the random element.

     * @example

     *

     * _.sample([1, 2, 3, 4]);

     * // => 2

     */

    function sample(collection) {

      var func = isArray(collection) ? arraySample : baseSample;

      return func(collection);

    }



    /**

     * Gets `n` random elements at unique keys from `collection` up to the

     * size of `collection`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Collection

     * @param {Array|Object} collection The collection to sample.

     * @param {number} [n=1] The number of elements to sample.

     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.

     * @returns {Array} Returns the random elements.

     * @example

     *

     * _.sampleSize([1, 2, 3], 2);

     * // => [3, 1]

     *

     * _.sampleSize([1, 2, 3], 4);

     * // => [2, 3, 1]

     */

    function sampleSize(collection, n, guard) {

      if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {

        n = 1;

      } else {

        n = toInteger(n);

      }

      var func = isArray(collection) ? arraySampleSize : baseSampleSize;

      return func(collection, n);

    }



    /**

     * Creates an array of shuffled values, using a version of the

     * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Collection

     * @param {Array|Object} collection The collection to shuffle.

     * @returns {Array} Returns the new shuffled array.

     * @example

     *

     * _.shuffle([1, 2, 3, 4]);

     * // => [4, 1, 3, 2]

     */

    function shuffle(collection) {

      var func = isArray(collection) ? arrayShuffle : baseShuffle;

      return func(collection);

    }



    /**

     * Gets the size of `collection` by returning its length for array-like

     * values or the number of own enumerable string keyed properties for objects.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Collection

     * @param {Array|Object|string} collection The collection to inspect.

     * @returns {number} Returns the collection size.

     * @example

     *

     * _.size([1, 2, 3]);

     * // => 3

     *

     * _.size({ 'a': 1, 'b': 2 });

     * // => 2

     *

     * _.size('pebbles');

     * // => 7

     */

    function size(collection) {

      if (collection == null) {

        return 0;

      }

      if (isArrayLike(collection)) {

        return isString(collection) ? stringSize(collection) : collection.length;

      }

      var tag = getTag(collection);

      if (tag == mapTag || tag == setTag) {

        return collection.size;

      }

      return baseKeys(collection).length;

    }



    /**

     * Checks if `predicate` returns truthy for **any** element of `collection`.

     * Iteration is stopped once `predicate` returns truthy. The predicate is

     * invoked with three arguments: (value, index|key, collection).

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Collection

     * @param {Array|Object} collection The collection to iterate over.

     * @param {Function} [predicate=_.identity] The function invoked per iteration.

     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.

     * @returns {boolean} Returns `true` if any element passes the predicate check,

     *  else `false`.

     * @example

     *

     * _.some([null, 0, 'yes', false], Boolean);

     * // => true

     *

     * var users = [

     *   { 'user': 'barney', 'active': true },

     *   { 'user': 'fred',   'active': false }

     * ];

     *

     * // The `_.matches` iteratee shorthand.

     * _.some(users, { 'user': 'barney', 'active': false });

     * // => false

     *

     * // The `_.matchesProperty` iteratee shorthand.

     * _.some(users, ['active', false]);

     * // => true

     *

     * // The `_.property` iteratee shorthand.

     * _.some(users, 'active');

     * // => true

     */

    function some(collection, predicate, guard) {

      var func = isArray(collection) ? arraySome : baseSome;

      if (guard && isIterateeCall(collection, predicate, guard)) {

        predicate = undefined;

      }

      return func(collection, getIteratee(predicate, 3));

    }



    /**

     * Creates an array of elements, sorted in ascending order by the results of

     * running each element in a collection thru each iteratee. This method

     * performs a stable sort, that is, it preserves the original sort order of

     * equal elements. The iteratees are invoked with one argument: (value).

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Collection

     * @param {Array|Object} collection The collection to iterate over.

     * @param {...(Function|Function[])} [iteratees=[_.identity]]

     *  The iteratees to sort by.

     * @returns {Array} Returns the new sorted array.

     * @example

     *

     * var users = [

     *   { 'user': 'fred',   'age': 48 },

     *   { 'user': 'barney', 'age': 36 },

     *   { 'user': 'fred',   'age': 40 },

     *   { 'user': 'barney', 'age': 34 }

     * ];

     *

     * _.sortBy(users, [function(o) { return o.user; }]);

     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]

     *

     * _.sortBy(users, ['user', 'age']);

     * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]

     */

    var sortBy = baseRest(function(collection, iteratees) {

      if (collection == null) {

        return [];

      }

      var length = iteratees.length;

      if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {

        iteratees = [];

      } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {

        iteratees = [iteratees[0]];

      }

      return baseOrderBy(collection, baseFlatten(iteratees, 1), []);

    });



    /*------------------------------------------------------------------------*/



    /**

     * Gets the timestamp of the number of milliseconds that have elapsed since

     * the Unix epoch (1 January 1970 00:00:00 UTC).

     *

     * @static

     * @memberOf _

     * @since 2.4.0

     * @category Date

     * @returns {number} Returns the timestamp.

     * @example

     *

     * _.defer(function(stamp) {

     *   console.log(_.now() - stamp);

     * }, _.now());

     * // => Logs the number of milliseconds it took for the deferred invocation.

     */

    var now = ctxNow || function() {

      return root.Date.now();

    };



    /*------------------------------------------------------------------------*/



    /**

     * The opposite of `_.before`; this method creates a function that invokes

     * `func` once it's called `n` or more times.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Function

     * @param {number} n The number of calls before `func` is invoked.

     * @param {Function} func The function to restrict.

     * @returns {Function} Returns the new restricted function.

     * @example

     *

     * var saves = ['profile', 'settings'];

     *

     * var done = _.after(saves.length, function() {

     *   console.log('done saving!');

     * });

     *

     * _.forEach(saves, function(type) {

     *   asyncSave({ 'type': type, 'complete': done });

     * });

     * // => Logs 'done saving!' after the two async saves have completed.

     */

    function after(n, func) {

      if (typeof func != 'function') {

        throw new TypeError(FUNC_ERROR_TEXT);

      }

      n = toInteger(n);

      return function() {

        if (--n < 1) {

          return func.apply(this, arguments);

        }

      };

    }



    /**

     * Creates a function that invokes `func`, with up to `n` arguments,

     * ignoring any additional arguments.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Function

     * @param {Function} func The function to cap arguments for.

     * @param {number} [n=func.length] The arity cap.

     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.

     * @returns {Function} Returns the new capped function.

     * @example

     *

     * _.map(['6', '8', '10'], _.ary(parseInt, 1));

     * // => [6, 8, 10]

     */

    function ary(func, n, guard) {

      n = guard ? undefined : n;

      n = (func && n == null) ? func.length : n;

      return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);

    }



    /**

     * Creates a function that invokes `func`, with the `this` binding and arguments

     * of the created function, while it's called less than `n` times. Subsequent

     * calls to the created function return the result of the last `func` invocation.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Function

     * @param {number} n The number of calls at which `func` is no longer invoked.

     * @param {Function} func The function to restrict.

     * @returns {Function} Returns the new restricted function.

     * @example

     *

     * jQuery(element).on('click', _.before(5, addContactToList));

     * // => Allows adding up to 4 contacts to the list.

     */

    function before(n, func) {

      var result;

      if (typeof func != 'function') {

        throw new TypeError(FUNC_ERROR_TEXT);

      }

      n = toInteger(n);

      return function() {

        if (--n > 0) {

          result = func.apply(this, arguments);

        }

        if (n <= 1) {

          func = undefined;

        }

        return result;

      };

    }



    /**

     * Creates a function that invokes `func` with the `this` binding of `thisArg`

     * and `partials` prepended to the arguments it receives.

     *

     * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,

     * may be used as a placeholder for partially applied arguments.

     *

     * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"

     * property of bound functions.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Function

     * @param {Function} func The function to bind.

     * @param {*} thisArg The `this` binding of `func`.

     * @param {...*} [partials] The arguments to be partially applied.

     * @returns {Function} Returns the new bound function.

     * @example

     *

     * function greet(greeting, punctuation) {

     *   return greeting + ' ' + this.user + punctuation;

     * }

     *

     * var object = { 'user': 'fred' };

     *

     * var bound = _.bind(greet, object, 'hi');

     * bound('!');

     * // => 'hi fred!'

     *

     * // Bound with placeholders.

     * var bound = _.bind(greet, object, _, '!');

     * bound('hi');

     * // => 'hi fred!'

     */

    var bind = baseRest(function(func, thisArg, partials) {

      var bitmask = WRAP_BIND_FLAG;

      if (partials.length) {

        var holders = replaceHolders(partials, getHolder(bind));

        bitmask |= WRAP_PARTIAL_FLAG;

      }

      return createWrap(func, bitmask, thisArg, partials, holders);

    });



    /**

     * Creates a function that invokes the method at `object[key]` with `partials`

     * prepended to the arguments it receives.

     *

     * This method differs from `_.bind` by allowing bound functions to reference

     * methods that may be redefined or don't yet exist. See

     * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)

     * for more details.

     *

     * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic

     * builds, may be used as a placeholder for partially applied arguments.

     *

     * @static

     * @memberOf _

     * @since 0.10.0

     * @category Function

     * @param {Object} object The object to invoke the method on.

     * @param {string} key The key of the method.

     * @param {...*} [partials] The arguments to be partially applied.

     * @returns {Function} Returns the new bound function.

     * @example

     *

     * var object = {

     *   'user': 'fred',

     *   'greet': function(greeting, punctuation) {

     *     return greeting + ' ' + this.user + punctuation;

     *   }

     * };

     *

     * var bound = _.bindKey(object, 'greet', 'hi');

     * bound('!');

     * // => 'hi fred!'

     *

     * object.greet = function(greeting, punctuation) {

     *   return greeting + 'ya ' + this.user + punctuation;

     * };

     *

     * bound('!');

     * // => 'hiya fred!'

     *

     * // Bound with placeholders.

     * var bound = _.bindKey(object, 'greet', _, '!');

     * bound('hi');

     * // => 'hiya fred!'

     */

    var bindKey = baseRest(function(object, key, partials) {

      var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;

      if (partials.length) {

        var holders = replaceHolders(partials, getHolder(bindKey));

        bitmask |= WRAP_PARTIAL_FLAG;

      }

      return createWrap(key, bitmask, object, partials, holders);

    });



    /**

     * Creates a function that accepts arguments of `func` and either invokes

     * `func` returning its result, if at least `arity` number of arguments have

     * been provided, or returns a function that accepts the remaining `func`

     * arguments, and so on. The arity of `func` may be specified if `func.length`

     * is not sufficient.

     *

     * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,

     * may be used as a placeholder for provided arguments.

     *

     * **Note:** This method doesn't set the "length" property of curried functions.

     *

     * @static

     * @memberOf _

     * @since 2.0.0

     * @category Function

     * @param {Function} func The function to curry.

     * @param {number} [arity=func.length] The arity of `func`.

     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.

     * @returns {Function} Returns the new curried function.

     * @example

     *

     * var abc = function(a, b, c) {

     *   return [a, b, c];

     * };

     *

     * var curried = _.curry(abc);

     *

     * curried(1)(2)(3);

     * // => [1, 2, 3]

     *

     * curried(1, 2)(3);

     * // => [1, 2, 3]

     *

     * curried(1, 2, 3);

     * // => [1, 2, 3]

     *

     * // Curried with placeholders.

     * curried(1)(_, 3)(2);

     * // => [1, 2, 3]

     */

    function curry(func, arity, guard) {

      arity = guard ? undefined : arity;

      var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);

      result.placeholder = curry.placeholder;

      return result;

    }



    /**

     * This method is like `_.curry` except that arguments are applied to `func`

     * in the manner of `_.partialRight` instead of `_.partial`.

     *

     * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic

     * builds, may be used as a placeholder for provided arguments.

     *

     * **Note:** This method doesn't set the "length" property of curried functions.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Function

     * @param {Function} func The function to curry.

     * @param {number} [arity=func.length] The arity of `func`.

     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.

     * @returns {Function} Returns the new curried function.

     * @example

     *

     * var abc = function(a, b, c) {

     *   return [a, b, c];

     * };

     *

     * var curried = _.curryRight(abc);

     *

     * curried(3)(2)(1);

     * // => [1, 2, 3]

     *

     * curried(2, 3)(1);

     * // => [1, 2, 3]

     *

     * curried(1, 2, 3);

     * // => [1, 2, 3]

     *

     * // Curried with placeholders.

     * curried(3)(1, _)(2);

     * // => [1, 2, 3]

     */

    function curryRight(func, arity, guard) {

      arity = guard ? undefined : arity;

      var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);

      result.placeholder = curryRight.placeholder;

      return result;

    }



    /**

     * Creates a debounced function that delays invoking `func` until after `wait`

     * milliseconds have elapsed since the last time the debounced function was

     * invoked. The debounced function comes with a `cancel` method to cancel

     * delayed `func` invocations and a `flush` method to immediately invoke them.

     * Provide `options` to indicate whether `func` should be invoked on the

     * leading and/or trailing edge of the `wait` timeout. The `func` is invoked

     * with the last arguments provided to the debounced function. Subsequent

     * calls to the debounced function return the result of the last `func`

     * invocation.

     *

     * **Note:** If `leading` and `trailing` options are `true`, `func` is

     * invoked on the trailing edge of the timeout only if the debounced function

     * is invoked more than once during the `wait` timeout.

     *

     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred

     * until to the next tick, similar to `setTimeout` with a timeout of `0`.

     *

     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)

     * for details over the differences between `_.debounce` and `_.throttle`.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Function

     * @param {Function} func The function to debounce.

     * @param {number} [wait=0] The number of milliseconds to delay.

     * @param {Object} [options={}] The options object.

     * @param {boolean} [options.leading=false]

     *  Specify invoking on the leading edge of the timeout.

     * @param {number} [options.maxWait]

     *  The maximum time `func` is allowed to be delayed before it's invoked.

     * @param {boolean} [options.trailing=true]

     *  Specify invoking on the trailing edge of the timeout.

     * @returns {Function} Returns the new debounced function.

     * @example

     *

     * // Avoid costly calculations while the window size is in flux.

     * jQuery(window).on('resize', _.debounce(calculateLayout, 150));

     *

     * // Invoke `sendMail` when clicked, debouncing subsequent calls.

     * jQuery(element).on('click', _.debounce(sendMail, 300, {

     *   'leading': true,

     *   'trailing': false

     * }));

     *

     * // Ensure `batchLog` is invoked once after 1 second of debounced calls.

     * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });

     * var source = new EventSource('/stream');

     * jQuery(source).on('message', debounced);

     *

     * // Cancel the trailing debounced invocation.

     * jQuery(window).on('popstate', debounced.cancel);

     */

    function debounce(func, wait, options) {

      var lastArgs,

          lastThis,

          maxWait,

          result,

          timerId,

          lastCallTime,

          lastInvokeTime = 0,

          leading = false,

          maxing = false,

          trailing = true;



      if (typeof func != 'function') {

        throw new TypeError(FUNC_ERROR_TEXT);

      }

      wait = toNumber(wait) || 0;

      if (isObject(options)) {

        leading = !!options.leading;

        maxing = 'maxWait' in options;

        maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;

        trailing = 'trailing' in options ? !!options.trailing : trailing;

      }



      function invokeFunc(time) {

        var args = lastArgs,

            thisArg = lastThis;



        lastArgs = lastThis = undefined;

        lastInvokeTime = time;

        result = func.apply(thisArg, args);

        return result;

      }



      function leadingEdge(time) {

        // Reset any `maxWait` timer.

        lastInvokeTime = time;

        // Start the timer for the trailing edge.

        timerId = setTimeout(timerExpired, wait);

        // Invoke the leading edge.

        return leading ? invokeFunc(time) : result;

      }



      function remainingWait(time) {

        var timeSinceLastCall = time - lastCallTime,

            timeSinceLastInvoke = time - lastInvokeTime,

            result = wait - timeSinceLastCall;



        return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;

      }



      function shouldInvoke(time) {

        var timeSinceLastCall = time - lastCallTime,

            timeSinceLastInvoke = time - lastInvokeTime;



        // Either this is the first call, activity has stopped and we're at the

        // trailing edge, the system time has gone backwards and we're treating

        // it as the trailing edge, or we've hit the `maxWait` limit.

        return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||

          (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));

      }



      function timerExpired() {

        var time = now();

        if (shouldInvoke(time)) {

          return trailingEdge(time);

        }

        // Restart the timer.

        timerId = setTimeout(timerExpired, remainingWait(time));

      }



      function trailingEdge(time) {

        timerId = undefined;



        // Only invoke if we have `lastArgs` which means `func` has been

        // debounced at least once.

        if (trailing && lastArgs) {

          return invokeFunc(time);

        }

        lastArgs = lastThis = undefined;

        return result;

      }



      function cancel() {

        if (timerId !== undefined) {

          clearTimeout(timerId);

        }

        lastInvokeTime = 0;

        lastArgs = lastCallTime = lastThis = timerId = undefined;

      }



      function flush() {

        return timerId === undefined ? result : trailingEdge(now());

      }



      function debounced() {

        var time = now(),

            isInvoking = shouldInvoke(time);



        lastArgs = arguments;

        lastThis = this;

        lastCallTime = time;



        if (isInvoking) {

          if (timerId === undefined) {

            return leadingEdge(lastCallTime);

          }

          if (maxing) {

            // Handle invocations in a tight loop.

            timerId = setTimeout(timerExpired, wait);

            return invokeFunc(lastCallTime);

          }

        }

        if (timerId === undefined) {

          timerId = setTimeout(timerExpired, wait);

        }

        return result;

      }

      debounced.cancel = cancel;

      debounced.flush = flush;

      return debounced;

    }



    /**

     * Defers invoking the `func` until the current call stack has cleared. Any

     * additional arguments are provided to `func` when it's invoked.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Function

     * @param {Function} func The function to defer.

     * @param {...*} [args] The arguments to invoke `func` with.

     * @returns {number} Returns the timer id.

     * @example

     *

     * _.defer(function(text) {

     *   console.log(text);

     * }, 'deferred');

     * // => Logs 'deferred' after one millisecond.

     */

    var defer = baseRest(function(func, args) {

      return baseDelay(func, 1, args);

    });



    /**

     * Invokes `func` after `wait` milliseconds. Any additional arguments are

     * provided to `func` when it's invoked.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Function

     * @param {Function} func The function to delay.

     * @param {number} wait The number of milliseconds to delay invocation.

     * @param {...*} [args] The arguments to invoke `func` with.

     * @returns {number} Returns the timer id.

     * @example

     *

     * _.delay(function(text) {

     *   console.log(text);

     * }, 1000, 'later');

     * // => Logs 'later' after one second.

     */

    var delay = baseRest(function(func, wait, args) {

      return baseDelay(func, toNumber(wait) || 0, args);

    });



    /**

     * Creates a function that invokes `func` with arguments reversed.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Function

     * @param {Function} func The function to flip arguments for.

     * @returns {Function} Returns the new flipped function.

     * @example

     *

     * var flipped = _.flip(function() {

     *   return _.toArray(arguments);

     * });

     *

     * flipped('a', 'b', 'c', 'd');

     * // => ['d', 'c', 'b', 'a']

     */

    function flip(func) {

      return createWrap(func, WRAP_FLIP_FLAG);

    }



    /**

     * Creates a function that memoizes the result of `func`. If `resolver` is

     * provided, it determines the cache key for storing the result based on the

     * arguments provided to the memoized function. By default, the first argument

     * provided to the memoized function is used as the map cache key. The `func`

     * is invoked with the `this` binding of the memoized function.

     *

     * **Note:** The cache is exposed as the `cache` property on the memoized

     * function. Its creation may be customized by replacing the `_.memoize.Cache`

     * constructor with one whose instances implement the

     * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)

     * method interface of `clear`, `delete`, `get`, `has`, and `set`.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Function

     * @param {Function} func The function to have its output memoized.

     * @param {Function} [resolver] The function to resolve the cache key.

     * @returns {Function} Returns the new memoized function.

     * @example

     *

     * var object = { 'a': 1, 'b': 2 };

     * var other = { 'c': 3, 'd': 4 };

     *

     * var values = _.memoize(_.values);

     * values(object);

     * // => [1, 2]

     *

     * values(other);

     * // => [3, 4]

     *

     * object.a = 2;

     * values(object);

     * // => [1, 2]

     *

     * // Modify the result cache.

     * values.cache.set(object, ['a', 'b']);

     * values(object);

     * // => ['a', 'b']

     *

     * // Replace `_.memoize.Cache`.

     * _.memoize.Cache = WeakMap;

     */

    function memoize(func, resolver) {

      if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {

        throw new TypeError(FUNC_ERROR_TEXT);

      }

      var memoized = function() {

        var args = arguments,

            key = resolver ? resolver.apply(this, args) : args[0],

            cache = memoized.cache;



        if (cache.has(key)) {

          return cache.get(key);

        }

        var result = func.apply(this, args);

        memoized.cache = cache.set(key, result) || cache;

        return result;

      };

      memoized.cache = new (memoize.Cache || MapCache);

      return memoized;

    }



    // Expose `MapCache`.

    memoize.Cache = MapCache;



    /**

     * Creates a function that negates the result of the predicate `func`. The

     * `func` predicate is invoked with the `this` binding and arguments of the

     * created function.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Function

     * @param {Function} predicate The predicate to negate.

     * @returns {Function} Returns the new negated function.

     * @example

     *

     * function isEven(n) {

     *   return n % 2 == 0;

     * }

     *

     * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));

     * // => [1, 3, 5]

     */

    function negate(predicate) {

      if (typeof predicate != 'function') {

        throw new TypeError(FUNC_ERROR_TEXT);

      }

      return function() {

        var args = arguments;

        switch (args.length) {

          case 0: return !predicate.call(this);

          case 1: return !predicate.call(this, args[0]);

          case 2: return !predicate.call(this, args[0], args[1]);

          case 3: return !predicate.call(this, args[0], args[1], args[2]);

        }

        return !predicate.apply(this, args);

      };

    }



    /**

     * Creates a function that is restricted to invoking `func` once. Repeat calls

     * to the function return the value of the first invocation. The `func` is

     * invoked with the `this` binding and arguments of the created function.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Function

     * @param {Function} func The function to restrict.

     * @returns {Function} Returns the new restricted function.

     * @example

     *

     * var initialize = _.once(createApplication);

     * initialize();

     * initialize();

     * // => `createApplication` is invoked once

     */

    function once(func) {

      return before(2, func);

    }



    /**

     * Creates a function that invokes `func` with its arguments transformed.

     *

     * @static

     * @since 4.0.0

     * @memberOf _

     * @category Function

     * @param {Function} func The function to wrap.

     * @param {...(Function|Function[])} [transforms=[_.identity]]

     *  The argument transforms.

     * @returns {Function} Returns the new function.

     * @example

     *

     * function doubled(n) {

     *   return n * 2;

     * }

     *

     * function square(n) {

     *   return n * n;

     * }

     *

     * var func = _.overArgs(function(x, y) {

     *   return [x, y];

     * }, [square, doubled]);

     *

     * func(9, 3);

     * // => [81, 6]

     *

     * func(10, 5);

     * // => [100, 10]

     */

    var overArgs = castRest(function(func, transforms) {

      transforms = (transforms.length == 1 && isArray(transforms[0]))

        ? arrayMap(transforms[0], baseUnary(getIteratee()))

        : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));



      var funcsLength = transforms.length;

      return baseRest(function(args) {

        var index = -1,

            length = nativeMin(args.length, funcsLength);



        while (++index < length) {

          args[index] = transforms[index].call(this, args[index]);

        }

        return apply(func, this, args);

      });

    });



    /**

     * Creates a function that invokes `func` with `partials` prepended to the

     * arguments it receives. This method is like `_.bind` except it does **not**

     * alter the `this` binding.

     *

     * The `_.partial.placeholder` value, which defaults to `_` in monolithic

     * builds, may be used as a placeholder for partially applied arguments.

     *

     * **Note:** This method doesn't set the "length" property of partially

     * applied functions.

     *

     * @static

     * @memberOf _

     * @since 0.2.0

     * @category Function

     * @param {Function} func The function to partially apply arguments to.

     * @param {...*} [partials] The arguments to be partially applied.

     * @returns {Function} Returns the new partially applied function.

     * @example

     *

     * function greet(greeting, name) {

     *   return greeting + ' ' + name;

     * }

     *

     * var sayHelloTo = _.partial(greet, 'hello');

     * sayHelloTo('fred');

     * // => 'hello fred'

     *

     * // Partially applied with placeholders.

     * var greetFred = _.partial(greet, _, 'fred');

     * greetFred('hi');

     * // => 'hi fred'

     */

    var partial = baseRest(function(func, partials) {

      var holders = replaceHolders(partials, getHolder(partial));

      return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);

    });



    /**

     * This method is like `_.partial` except that partially applied arguments

     * are appended to the arguments it receives.

     *

     * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic

     * builds, may be used as a placeholder for partially applied arguments.

     *

     * **Note:** This method doesn't set the "length" property of partially

     * applied functions.

     *

     * @static

     * @memberOf _

     * @since 1.0.0

     * @category Function

     * @param {Function} func The function to partially apply arguments to.

     * @param {...*} [partials] The arguments to be partially applied.

     * @returns {Function} Returns the new partially applied function.

     * @example

     *

     * function greet(greeting, name) {

     *   return greeting + ' ' + name;

     * }

     *

     * var greetFred = _.partialRight(greet, 'fred');

     * greetFred('hi');

     * // => 'hi fred'

     *

     * // Partially applied with placeholders.

     * var sayHelloTo = _.partialRight(greet, 'hello', _);

     * sayHelloTo('fred');

     * // => 'hello fred'

     */

    var partialRight = baseRest(function(func, partials) {

      var holders = replaceHolders(partials, getHolder(partialRight));

      return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);

    });



    /**

     * Creates a function that invokes `func` with arguments arranged according

     * to the specified `indexes` where the argument value at the first index is

     * provided as the first argument, the argument value at the second index is

     * provided as the second argument, and so on.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Function

     * @param {Function} func The function to rearrange arguments for.

     * @param {...(number|number[])} indexes The arranged argument indexes.

     * @returns {Function} Returns the new function.

     * @example

     *

     * var rearged = _.rearg(function(a, b, c) {

     *   return [a, b, c];

     * }, [2, 0, 1]);

     *

     * rearged('b', 'c', 'a')

     * // => ['a', 'b', 'c']

     */

    var rearg = flatRest(function(func, indexes) {

      return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);

    });



    /**

     * Creates a function that invokes `func` with the `this` binding of the

     * created function and arguments from `start` and beyond provided as

     * an array.

     *

     * **Note:** This method is based on the

     * [rest parameter](https://mdn.io/rest_parameters).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Function

     * @param {Function} func The function to apply a rest parameter to.

     * @param {number} [start=func.length-1] The start position of the rest parameter.

     * @returns {Function} Returns the new function.

     * @example

     *

     * var say = _.rest(function(what, names) {

     *   return what + ' ' + _.initial(names).join(', ') +

     *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);

     * });

     *

     * say('hello', 'fred', 'barney', 'pebbles');

     * // => 'hello fred, barney, & pebbles'

     */

    function rest(func, start) {

      if (typeof func != 'function') {

        throw new TypeError(FUNC_ERROR_TEXT);

      }

      start = start === undefined ? start : toInteger(start);

      return baseRest(func, start);

    }



    /**

     * Creates a function that invokes `func` with the `this` binding of the

     * create function and an array of arguments much like

     * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).

     *

     * **Note:** This method is based on the

     * [spread operator](https://mdn.io/spread_operator).

     *

     * @static

     * @memberOf _

     * @since 3.2.0

     * @category Function

     * @param {Function} func The function to spread arguments over.

     * @param {number} [start=0] The start position of the spread.

     * @returns {Function} Returns the new function.

     * @example

     *

     * var say = _.spread(function(who, what) {

     *   return who + ' says ' + what;

     * });

     *

     * say(['fred', 'hello']);

     * // => 'fred says hello'

     *

     * var numbers = Promise.all([

     *   Promise.resolve(40),

     *   Promise.resolve(36)

     * ]);

     *

     * numbers.then(_.spread(function(x, y) {

     *   return x + y;

     * }));

     * // => a Promise of 76

     */

    function spread(func, start) {

      if (typeof func != 'function') {

        throw new TypeError(FUNC_ERROR_TEXT);

      }

      start = start == null ? 0 : nativeMax(toInteger(start), 0);

      return baseRest(function(args) {

        var array = args[start],

            otherArgs = castSlice(args, 0, start);



        if (array) {

          arrayPush(otherArgs, array);

        }

        return apply(func, this, otherArgs);

      });

    }



    /**

     * Creates a throttled function that only invokes `func` at most once per

     * every `wait` milliseconds. The throttled function comes with a `cancel`

     * method to cancel delayed `func` invocations and a `flush` method to

     * immediately invoke them. Provide `options` to indicate whether `func`

     * should be invoked on the leading and/or trailing edge of the `wait`

     * timeout. The `func` is invoked with the last arguments provided to the

     * throttled function. Subsequent calls to the throttled function return the

     * result of the last `func` invocation.

     *

     * **Note:** If `leading` and `trailing` options are `true`, `func` is

     * invoked on the trailing edge of the timeout only if the throttled function

     * is invoked more than once during the `wait` timeout.

     *

     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred

     * until to the next tick, similar to `setTimeout` with a timeout of `0`.

     *

     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)

     * for details over the differences between `_.throttle` and `_.debounce`.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Function

     * @param {Function} func The function to throttle.

     * @param {number} [wait=0] The number of milliseconds to throttle invocations to.

     * @param {Object} [options={}] The options object.

     * @param {boolean} [options.leading=true]

     *  Specify invoking on the leading edge of the timeout.

     * @param {boolean} [options.trailing=true]

     *  Specify invoking on the trailing edge of the timeout.

     * @returns {Function} Returns the new throttled function.

     * @example

     *

     * // Avoid excessively updating the position while scrolling.

     * jQuery(window).on('scroll', _.throttle(updatePosition, 100));

     *

     * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.

     * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });

     * jQuery(element).on('click', throttled);

     *

     * // Cancel the trailing throttled invocation.

     * jQuery(window).on('popstate', throttled.cancel);

     */

    function throttle(func, wait, options) {

      var leading = true,

          trailing = true;



      if (typeof func != 'function') {

        throw new TypeError(FUNC_ERROR_TEXT);

      }

      if (isObject(options)) {

        leading = 'leading' in options ? !!options.leading : leading;

        trailing = 'trailing' in options ? !!options.trailing : trailing;

      }

      return debounce(func, wait, {

        'leading': leading,

        'maxWait': wait,

        'trailing': trailing

      });

    }



    /**

     * Creates a function that accepts up to one argument, ignoring any

     * additional arguments.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Function

     * @param {Function} func The function to cap arguments for.

     * @returns {Function} Returns the new capped function.

     * @example

     *

     * _.map(['6', '8', '10'], _.unary(parseInt));

     * // => [6, 8, 10]

     */

    function unary(func) {

      return ary(func, 1);

    }



    /**

     * Creates a function that provides `value` to `wrapper` as its first

     * argument. Any additional arguments provided to the function are appended

     * to those provided to the `wrapper`. The wrapper is invoked with the `this`

     * binding of the created function.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Function

     * @param {*} value The value to wrap.

     * @param {Function} [wrapper=identity] The wrapper function.

     * @returns {Function} Returns the new function.

     * @example

     *

     * var p = _.wrap(_.escape, function(func, text) {

     *   return '<p>' + func(text) + '</p>';

     * });

     *

     * p('fred, barney, & pebbles');

     * // => '<p>fred, barney, &amp; pebbles</p>'

     */

    function wrap(value, wrapper) {

      return partial(castFunction(wrapper), value);

    }



    /*------------------------------------------------------------------------*/



    /**

     * Casts `value` as an array if it's not one.

     *

     * @static

     * @memberOf _

     * @since 4.4.0

     * @category Lang

     * @param {*} value The value to inspect.

     * @returns {Array} Returns the cast array.

     * @example

     *

     * _.castArray(1);

     * // => [1]

     *

     * _.castArray({ 'a': 1 });

     * // => [{ 'a': 1 }]

     *

     * _.castArray('abc');

     * // => ['abc']

     *

     * _.castArray(null);

     * // => [null]

     *

     * _.castArray(undefined);

     * // => [undefined]

     *

     * _.castArray();

     * // => []

     *

     * var array = [1, 2, 3];

     * console.log(_.castArray(array) === array);

     * // => true

     */

    function castArray() {

      if (!arguments.length) {

        return [];

      }

      var value = arguments[0];

      return isArray(value) ? value : [value];

    }



    /**

     * Creates a shallow clone of `value`.

     *

     * **Note:** This method is loosely based on the

     * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)

     * and supports cloning arrays, array buffers, booleans, date objects, maps,

     * numbers, `Object` objects, regexes, sets, strings, symbols, and typed

     * arrays. The own enumerable properties of `arguments` objects are cloned

     * as plain objects. An empty object is returned for uncloneable values such

     * as error objects, functions, DOM nodes, and WeakMaps.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Lang

     * @param {*} value The value to clone.

     * @returns {*} Returns the cloned value.

     * @see _.cloneDeep

     * @example

     *

     * var objects = [{ 'a': 1 }, { 'b': 2 }];

     *

     * var shallow = _.clone(objects);

     * console.log(shallow[0] === objects[0]);

     * // => true

     */

    function clone(value) {

      return baseClone(value, CLONE_SYMBOLS_FLAG);

    }



    /**

     * This method is like `_.clone` except that it accepts `customizer` which

     * is invoked to produce the cloned value. If `customizer` returns `undefined`,

     * cloning is handled by the method instead. The `customizer` is invoked with

     * up to four arguments; (value [, index|key, object, stack]).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Lang

     * @param {*} value The value to clone.

     * @param {Function} [customizer] The function to customize cloning.

     * @returns {*} Returns the cloned value.

     * @see _.cloneDeepWith

     * @example

     *

     * function customizer(value) {

     *   if (_.isElement(value)) {

     *     return value.cloneNode(false);

     *   }

     * }

     *

     * var el = _.cloneWith(document.body, customizer);

     *

     * console.log(el === document.body);

     * // => false

     * console.log(el.nodeName);

     * // => 'BODY'

     * console.log(el.childNodes.length);

     * // => 0

     */

    function cloneWith(value, customizer) {

      customizer = typeof customizer == 'function' ? customizer : undefined;

      return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);

    }



    /**

     * This method is like `_.clone` except that it recursively clones `value`.

     *

     * @static

     * @memberOf _

     * @since 1.0.0

     * @category Lang

     * @param {*} value The value to recursively clone.

     * @returns {*} Returns the deep cloned value.

     * @see _.clone

     * @example

     *

     * var objects = [{ 'a': 1 }, { 'b': 2 }];

     *

     * var deep = _.cloneDeep(objects);

     * console.log(deep[0] === objects[0]);

     * // => false

     */

    function cloneDeep(value) {

      return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);

    }



    /**

     * This method is like `_.cloneWith` except that it recursively clones `value`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Lang

     * @param {*} value The value to recursively clone.

     * @param {Function} [customizer] The function to customize cloning.

     * @returns {*} Returns the deep cloned value.

     * @see _.cloneWith

     * @example

     *

     * function customizer(value) {

     *   if (_.isElement(value)) {

     *     return value.cloneNode(true);

     *   }

     * }

     *

     * var el = _.cloneDeepWith(document.body, customizer);

     *

     * console.log(el === document.body);

     * // => false

     * console.log(el.nodeName);

     * // => 'BODY'

     * console.log(el.childNodes.length);

     * // => 20

     */

    function cloneDeepWith(value, customizer) {

      customizer = typeof customizer == 'function' ? customizer : undefined;

      return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);

    }



    /**

     * Checks if `object` conforms to `source` by invoking the predicate

     * properties of `source` with the corresponding property values of `object`.

     *

     * **Note:** This method is equivalent to `_.conforms` when `source` is

     * partially applied.

     *

     * @static

     * @memberOf _

     * @since 4.14.0

     * @category Lang

     * @param {Object} object The object to inspect.

     * @param {Object} source The object of property predicates to conform to.

     * @returns {boolean} Returns `true` if `object` conforms, else `false`.

     * @example

     *

     * var object = { 'a': 1, 'b': 2 };

     *

     * _.conformsTo(object, { 'b': function(n) { return n > 1; } });

     * // => true

     *

     * _.conformsTo(object, { 'b': function(n) { return n > 2; } });

     * // => false

     */

    function conformsTo(object, source) {

      return source == null || baseConformsTo(object, source, keys(source));

    }



    /**

     * Performs a

     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)

     * comparison between two values to determine if they are equivalent.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Lang

     * @param {*} value The value to compare.

     * @param {*} other The other value to compare.

     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.

     * @example

     *

     * var object = { 'a': 1 };

     * var other = { 'a': 1 };

     *

     * _.eq(object, object);

     * // => true

     *

     * _.eq(object, other);

     * // => false

     *

     * _.eq('a', 'a');

     * // => true

     *

     * _.eq('a', Object('a'));

     * // => false

     *

     * _.eq(NaN, NaN);

     * // => true

     */

    function eq(value, other) {

      return value === other || (value !== value && other !== other);

    }



    /**

     * Checks if `value` is greater than `other`.

     *

     * @static

     * @memberOf _

     * @since 3.9.0

     * @category Lang

     * @param {*} value The value to compare.

     * @param {*} other The other value to compare.

     * @returns {boolean} Returns `true` if `value` is greater than `other`,

     *  else `false`.

     * @see _.lt

     * @example

     *

     * _.gt(3, 1);

     * // => true

     *

     * _.gt(3, 3);

     * // => false

     *

     * _.gt(1, 3);

     * // => false

     */

    var gt = createRelationalOperation(baseGt);



    /**

     * Checks if `value` is greater than or equal to `other`.

     *

     * @static

     * @memberOf _

     * @since 3.9.0

     * @category Lang

     * @param {*} value The value to compare.

     * @param {*} other The other value to compare.

     * @returns {boolean} Returns `true` if `value` is greater than or equal to

     *  `other`, else `false`.

     * @see _.lte

     * @example

     *

     * _.gte(3, 1);

     * // => true

     *

     * _.gte(3, 3);

     * // => true

     *

     * _.gte(1, 3);

     * // => false

     */

    var gte = createRelationalOperation(function(value, other) {

      return value >= other;

    });



    /**

     * Checks if `value` is likely an `arguments` object.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is an `arguments` object,

     *  else `false`.

     * @example

     *

     * _.isArguments(function() { return arguments; }());

     * // => true

     *

     * _.isArguments([1, 2, 3]);

     * // => false

     */

    var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {

      return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&

        !propertyIsEnumerable.call(value, 'callee');

    };



    /**

     * Checks if `value` is classified as an `Array` object.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is an array, else `false`.

     * @example

     *

     * _.isArray([1, 2, 3]);

     * // => true

     *

     * _.isArray(document.body.children);

     * // => false

     *

     * _.isArray('abc');

     * // => false

     *

     * _.isArray(_.noop);

     * // => false

     */

    var isArray = Array.isArray;



    /**

     * Checks if `value` is classified as an `ArrayBuffer` object.

     *

     * @static

     * @memberOf _

     * @since 4.3.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.

     * @example

     *

     * _.isArrayBuffer(new ArrayBuffer(2));

     * // => true

     *

     * _.isArrayBuffer(new Array(2));

     * // => false

     */

    var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;



    /**

     * Checks if `value` is array-like. A value is considered array-like if it's

     * not a function and has a `value.length` that's an integer greater than or

     * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is array-like, else `false`.

     * @example

     *

     * _.isArrayLike([1, 2, 3]);

     * // => true

     *

     * _.isArrayLike(document.body.children);

     * // => true

     *

     * _.isArrayLike('abc');

     * // => true

     *

     * _.isArrayLike(_.noop);

     * // => false

     */

    function isArrayLike(value) {

      return value != null && isLength(value.length) && !isFunction(value);

    }



    /**

     * This method is like `_.isArrayLike` except that it also checks if `value`

     * is an object.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is an array-like object,

     *  else `false`.

     * @example

     *

     * _.isArrayLikeObject([1, 2, 3]);

     * // => true

     *

     * _.isArrayLikeObject(document.body.children);

     * // => true

     *

     * _.isArrayLikeObject('abc');

     * // => false

     *

     * _.isArrayLikeObject(_.noop);

     * // => false

     */

    function isArrayLikeObject(value) {

      return isObjectLike(value) && isArrayLike(value);

    }



    /**

     * Checks if `value` is classified as a boolean primitive or object.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.

     * @example

     *

     * _.isBoolean(false);

     * // => true

     *

     * _.isBoolean(null);

     * // => false

     */

    function isBoolean(value) {

      return value === true || value === false ||

        (isObjectLike(value) && baseGetTag(value) == boolTag);

    }



    /**

     * Checks if `value` is a buffer.

     *

     * @static

     * @memberOf _

     * @since 4.3.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.

     * @example

     *

     * _.isBuffer(new Buffer(2));

     * // => true

     *

     * _.isBuffer(new Uint8Array(2));

     * // => false

     */

    var isBuffer = nativeIsBuffer || stubFalse;



    /**

     * Checks if `value` is classified as a `Date` object.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.

     * @example

     *

     * _.isDate(new Date);

     * // => true

     *

     * _.isDate('Mon April 23 2012');

     * // => false

     */

    var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;



    /**

     * Checks if `value` is likely a DOM element.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.

     * @example

     *

     * _.isElement(document.body);

     * // => true

     *

     * _.isElement('<body>');

     * // => false

     */

    function isElement(value) {

      return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);

    }



    /**

     * Checks if `value` is an empty object, collection, map, or set.

     *

     * Objects are considered empty if they have no own enumerable string keyed

     * properties.

     *

     * Array-like values such as `arguments` objects, arrays, buffers, strings, or

     * jQuery-like collections are considered empty if they have a `length` of `0`.

     * Similarly, maps and sets are considered empty if they have a `size` of `0`.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is empty, else `false`.

     * @example

     *

     * _.isEmpty(null);

     * // => true

     *

     * _.isEmpty(true);

     * // => true

     *

     * _.isEmpty(1);

     * // => true

     *

     * _.isEmpty([1, 2, 3]);

     * // => false

     *

     * _.isEmpty({ 'a': 1 });

     * // => false

     */

    function isEmpty(value) {

      if (value == null) {

        return true;

      }

      if (isArrayLike(value) &&

          (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||

            isBuffer(value) || isTypedArray(value) || isArguments(value))) {

        return !value.length;

      }

      var tag = getTag(value);

      if (tag == mapTag || tag == setTag) {

        return !value.size;

      }

      if (isPrototype(value)) {

        return !baseKeys(value).length;

      }

      for (var key in value) {

        if (hasOwnProperty.call(value, key)) {

          return false;

        }

      }

      return true;

    }



    /**

     * Performs a deep comparison between two values to determine if they are

     * equivalent.

     *

     * **Note:** This method supports comparing arrays, array buffers, booleans,

     * date objects, error objects, maps, numbers, `Object` objects, regexes,

     * sets, strings, symbols, and typed arrays. `Object` objects are compared

     * by their own, not inherited, enumerable properties. Functions and DOM

     * nodes are compared by strict equality, i.e. `===`.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Lang

     * @param {*} value The value to compare.

     * @param {*} other The other value to compare.

     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.

     * @example

     *

     * var object = { 'a': 1 };

     * var other = { 'a': 1 };

     *

     * _.isEqual(object, other);

     * // => true

     *

     * object === other;

     * // => false

     */

    function isEqual(value, other) {

      return baseIsEqual(value, other);

    }



    /**

     * This method is like `_.isEqual` except that it accepts `customizer` which

     * is invoked to compare values. If `customizer` returns `undefined`, comparisons

     * are handled by the method instead. The `customizer` is invoked with up to

     * six arguments: (objValue, othValue [, index|key, object, other, stack]).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Lang

     * @param {*} value The value to compare.

     * @param {*} other The other value to compare.

     * @param {Function} [customizer] The function to customize comparisons.

     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.

     * @example

     *

     * function isGreeting(value) {

     *   return /^h(?:i|ello)$/.test(value);

     * }

     *

     * function customizer(objValue, othValue) {

     *   if (isGreeting(objValue) && isGreeting(othValue)) {

     *     return true;

     *   }

     * }

     *

     * var array = ['hello', 'goodbye'];

     * var other = ['hi', 'goodbye'];

     *

     * _.isEqualWith(array, other, customizer);

     * // => true

     */

    function isEqualWith(value, other, customizer) {

      customizer = typeof customizer == 'function' ? customizer : undefined;

      var result = customizer ? customizer(value, other) : undefined;

      return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;

    }



    /**

     * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,

     * `SyntaxError`, `TypeError`, or `URIError` object.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is an error object, else `false`.

     * @example

     *

     * _.isError(new Error);

     * // => true

     *

     * _.isError(Error);

     * // => false

     */

    function isError(value) {

      if (!isObjectLike(value)) {

        return false;

      }

      var tag = baseGetTag(value);

      return tag == errorTag || tag == domExcTag ||

        (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));

    }



    /**

     * Checks if `value` is a finite primitive number.

     *

     * **Note:** This method is based on

     * [`Number.isFinite`](https://mdn.io/Number/isFinite).

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.

     * @example

     *

     * _.isFinite(3);

     * // => true

     *

     * _.isFinite(Number.MIN_VALUE);

     * // => true

     *

     * _.isFinite(Infinity);

     * // => false

     *

     * _.isFinite('3');

     * // => false

     */

    function isFinite(value) {

      return typeof value == 'number' && nativeIsFinite(value);

    }



    /**

     * Checks if `value` is classified as a `Function` object.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a function, else `false`.

     * @example

     *

     * _.isFunction(_);

     * // => true

     *

     * _.isFunction(/abc/);

     * // => false

     */

    function isFunction(value) {

      if (!isObject(value)) {

        return false;

      }

      // The use of `Object#toString` avoids issues with the `typeof` operator

      // in Safari 9 which returns 'object' for typed arrays and other constructors.

      var tag = baseGetTag(value);

      return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;

    }



    /**

     * Checks if `value` is an integer.

     *

     * **Note:** This method is based on

     * [`Number.isInteger`](https://mdn.io/Number/isInteger).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is an integer, else `false`.

     * @example

     *

     * _.isInteger(3);

     * // => true

     *

     * _.isInteger(Number.MIN_VALUE);

     * // => false

     *

     * _.isInteger(Infinity);

     * // => false

     *

     * _.isInteger('3');

     * // => false

     */

    function isInteger(value) {

      return typeof value == 'number' && value == toInteger(value);

    }



    /**

     * Checks if `value` is a valid array-like length.

     *

     * **Note:** This method is loosely based on

     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.

     * @example

     *

     * _.isLength(3);

     * // => true

     *

     * _.isLength(Number.MIN_VALUE);

     * // => false

     *

     * _.isLength(Infinity);

     * // => false

     *

     * _.isLength('3');

     * // => false

     */

    function isLength(value) {

      return typeof value == 'number' &&

        value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;

    }



    /**

     * Checks if `value` is the

     * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)

     * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is an object, else `false`.

     * @example

     *

     * _.isObject({});

     * // => true

     *

     * _.isObject([1, 2, 3]);

     * // => true

     *

     * _.isObject(_.noop);

     * // => true

     *

     * _.isObject(null);

     * // => false

     */

    function isObject(value) {

      var type = typeof value;

      return value != null && (type == 'object' || type == 'function');

    }



    /**

     * Checks if `value` is object-like. A value is object-like if it's not `null`

     * and has a `typeof` result of "object".

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is object-like, else `false`.

     * @example

     *

     * _.isObjectLike({});

     * // => true

     *

     * _.isObjectLike([1, 2, 3]);

     * // => true

     *

     * _.isObjectLike(_.noop);

     * // => false

     *

     * _.isObjectLike(null);

     * // => false

     */

    function isObjectLike(value) {

      return value != null && typeof value == 'object';

    }



    /**

     * Checks if `value` is classified as a `Map` object.

     *

     * @static

     * @memberOf _

     * @since 4.3.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a map, else `false`.

     * @example

     *

     * _.isMap(new Map);

     * // => true

     *

     * _.isMap(new WeakMap);

     * // => false

     */

    var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;



    /**

     * Performs a partial deep comparison between `object` and `source` to

     * determine if `object` contains equivalent property values.

     *

     * **Note:** This method is equivalent to `_.matches` when `source` is

     * partially applied.

     *

     * Partial comparisons will match empty array and empty object `source`

     * values against any array or object value, respectively. See `_.isEqual`

     * for a list of supported value comparisons.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Lang

     * @param {Object} object The object to inspect.

     * @param {Object} source The object of property values to match.

     * @returns {boolean} Returns `true` if `object` is a match, else `false`.

     * @example

     *

     * var object = { 'a': 1, 'b': 2 };

     *

     * _.isMatch(object, { 'b': 2 });

     * // => true

     *

     * _.isMatch(object, { 'b': 1 });

     * // => false

     */

    function isMatch(object, source) {

      return object === source || baseIsMatch(object, source, getMatchData(source));

    }



    /**

     * This method is like `_.isMatch` except that it accepts `customizer` which

     * is invoked to compare values. If `customizer` returns `undefined`, comparisons

     * are handled by the method instead. The `customizer` is invoked with five

     * arguments: (objValue, srcValue, index|key, object, source).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Lang

     * @param {Object} object The object to inspect.

     * @param {Object} source The object of property values to match.

     * @param {Function} [customizer] The function to customize comparisons.

     * @returns {boolean} Returns `true` if `object` is a match, else `false`.

     * @example

     *

     * function isGreeting(value) {

     *   return /^h(?:i|ello)$/.test(value);

     * }

     *

     * function customizer(objValue, srcValue) {

     *   if (isGreeting(objValue) && isGreeting(srcValue)) {

     *     return true;

     *   }

     * }

     *

     * var object = { 'greeting': 'hello' };

     * var source = { 'greeting': 'hi' };

     *

     * _.isMatchWith(object, source, customizer);

     * // => true

     */

    function isMatchWith(object, source, customizer) {

      customizer = typeof customizer == 'function' ? customizer : undefined;

      return baseIsMatch(object, source, getMatchData(source), customizer);

    }



    /**

     * Checks if `value` is `NaN`.

     *

     * **Note:** This method is based on

     * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as

     * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for

     * `undefined` and other non-number values.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.

     * @example

     *

     * _.isNaN(NaN);

     * // => true

     *

     * _.isNaN(new Number(NaN));

     * // => true

     *

     * isNaN(undefined);

     * // => true

     *

     * _.isNaN(undefined);

     * // => false

     */

    function isNaN(value) {

      // An `NaN` primitive is the only value that is not equal to itself.

      // Perform the `toStringTag` check first to avoid errors with some

      // ActiveX objects in IE.

      return isNumber(value) && value != +value;

    }



    /**

     * Checks if `value` is a pristine native function.

     *

     * **Note:** This method can't reliably detect native functions in the presence

     * of the core-js package because core-js circumvents this kind of detection.

     * Despite multiple requests, the core-js maintainer has made it clear: any

     * attempt to fix the detection will be obstructed. As a result, we're left

     * with little choice but to throw an error. Unfortunately, this also affects

     * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),

     * which rely on core-js.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a native function,

     *  else `false`.

     * @example

     *

     * _.isNative(Array.prototype.push);

     * // => true

     *

     * _.isNative(_);

     * // => false

     */

    function isNative(value) {

      if (isMaskable(value)) {

        throw new Error(CORE_ERROR_TEXT);

      }

      return baseIsNative(value);

    }



    /**

     * Checks if `value` is `null`.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is `null`, else `false`.

     * @example

     *

     * _.isNull(null);

     * // => true

     *

     * _.isNull(void 0);

     * // => false

     */

    function isNull(value) {

      return value === null;

    }



    /**

     * Checks if `value` is `null` or `undefined`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is nullish, else `false`.

     * @example

     *

     * _.isNil(null);

     * // => true

     *

     * _.isNil(void 0);

     * // => true

     *

     * _.isNil(NaN);

     * // => false

     */

    function isNil(value) {

      return value == null;

    }



    /**

     * Checks if `value` is classified as a `Number` primitive or object.

     *

     * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are

     * classified as numbers, use the `_.isFinite` method.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a number, else `false`.

     * @example

     *

     * _.isNumber(3);

     * // => true

     *

     * _.isNumber(Number.MIN_VALUE);

     * // => true

     *

     * _.isNumber(Infinity);

     * // => true

     *

     * _.isNumber('3');

     * // => false

     */

    function isNumber(value) {

      return typeof value == 'number' ||

        (isObjectLike(value) && baseGetTag(value) == numberTag);

    }



    /**

     * Checks if `value` is a plain object, that is, an object created by the

     * `Object` constructor or one with a `[[Prototype]]` of `null`.

     *

     * @static

     * @memberOf _

     * @since 0.8.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.

     * @example

     *

     * function Foo() {

     *   this.a = 1;

     * }

     *

     * _.isPlainObject(new Foo);

     * // => false

     *

     * _.isPlainObject([1, 2, 3]);

     * // => false

     *

     * _.isPlainObject({ 'x': 0, 'y': 0 });

     * // => true

     *

     * _.isPlainObject(Object.create(null));

     * // => true

     */

    function isPlainObject(value) {

      if (!isObjectLike(value) || baseGetTag(value) != objectTag) {

        return false;

      }

      var proto = getPrototype(value);

      if (proto === null) {

        return true;

      }

      var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;

      return typeof Ctor == 'function' && Ctor instanceof Ctor &&

        funcToString.call(Ctor) == objectCtorString;

    }



    /**

     * Checks if `value` is classified as a `RegExp` object.

     *

     * @static

     * @memberOf _

     * @since 0.1.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.

     * @example

     *

     * _.isRegExp(/abc/);

     * // => true

     *

     * _.isRegExp('/abc/');

     * // => false

     */

    var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;



    /**

     * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754

     * double precision number which isn't the result of a rounded unsafe integer.

     *

     * **Note:** This method is based on

     * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.

     * @example

     *

     * _.isSafeInteger(3);

     * // => true

     *

     * _.isSafeInteger(Number.MIN_VALUE);

     * // => false

     *

     * _.isSafeInteger(Infinity);

     * // => false

     *

     * _.isSafeInteger('3');

     * // => false

     */

    function isSafeInteger(value) {

      return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;

    }



    /**

     * Checks if `value` is classified as a `Set` object.

     *

     * @static

     * @memberOf _

     * @since 4.3.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a set, else `false`.

     * @example

     *

     * _.isSet(new Set);

     * // => true

     *

     * _.isSet(new WeakSet);

     * // => false

     */

    var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;



    /**

     * Checks if `value` is classified as a `String` primitive or object.

     *

     * @static

     * @since 0.1.0

     * @memberOf _

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a string, else `false`.

     * @example

     *

     * _.isString('abc');

     * // => true

     *

     * _.isString(1);

     * // => false

     */

    function isString(value) {

      return typeof value == 'string' ||

        (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);

    }



    /**

     * Checks if `value` is classified as a `Symbol` primitive or object.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.

     * @example

     *

     * _.isSymbol(Symbol.iterator);

     * // => true

     *

     * _.isSymbol('abc');

     * // => false

     */

    function isSymbol(value) {

      return typeof value == 'symbol' ||

        (isObjectLike(value) && baseGetTag(value) == symbolTag);

    }



    /**

     * Checks if `value` is classified as a typed array.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.

     * @example

     *

     * _.isTypedArray(new Uint8Array);

     * // => true

     *

     * _.isTypedArray([]);

     * // => false

     */

    var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;



    /**

     * Checks if `value` is `undefined`.

     *

     * @static

     * @since 0.1.0

     * @memberOf _

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.

     * @example

     *

     * _.isUndefined(void 0);

     * // => true

     *

     * _.isUndefined(null);

     * // => false

     */

    function isUndefined(value) {

      return value === undefined;

    }



    /**

     * Checks if `value` is classified as a `WeakMap` object.

     *

     * @static

     * @memberOf _

     * @since 4.3.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.

     * @example

     *

     * _.isWeakMap(new WeakMap);

     * // => true

     *

     * _.isWeakMap(new Map);

     * // => false

     */

    function isWeakMap(value) {

      return isObjectLike(value) && getTag(value) == weakMapTag;

    }



    /**

     * Checks if `value` is classified as a `WeakSet` object.

     *

     * @static

     * @memberOf _

     * @since 4.3.0

     * @category Lang

     * @param {*} value The value to check.

     * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.

     * @example

     *

     * _.isWeakSet(new WeakSet);

     * // => true

     *

     * _.isWeakSet(new Set);

     * // => false

     */

    function isWeakSet(value) {

      return isObjectLike(value) && baseGetTag(value) == weakSetTag;

    }



    /**

     * Checks if `value` is less than `other`.

     *

     * @static

     * @memberOf _

     * @since 3.9.0

     * @category Lang

     * @param {*} value The value to compare.

     * @param {*} other The other value to compare.

     * @returns {boolean} Returns `true` if `value` is less than `other`,

     *  else `false`.

     * @see _.gt

     * @example

     *

     * _.lt(1, 3);

     * // => true

     *

     * _.lt(3, 3);

     * // => false

     *

     * _.lt(3, 1);

     * // => false

     */

    var lt = createRelationalOperation(baseLt);



    /**

     * Checks if `value` is less than or equal to `other`.

     *

     * @static

     * @memberOf _

     * @since 3.9.0

     * @category Lang

     * @param {*} value The value to compare.

     * @param {*} other The other value to compare.

     * @returns {boolean} Returns `true` if `value` is less than or equal to

     *  `other`, else `false`.

     * @see _.gte

     * @example

     *

     * _.lte(1, 3);

     * // => true

     *

     * _.lte(3, 3);

     * // => true

     *

     * _.lte(3, 1);

     * // => false

     */

    var lte = createRelationalOperation(function(value, other) {

      return value <= other;

    });



    /**

     * Converts `value` to an array.

     *

     * @static

     * @since 0.1.0

     * @memberOf _

     * @category Lang

     * @param {*} value The value to convert.

     * @returns {Array} Returns the converted array.

     * @example

     *

     * _.toArray({ 'a': 1, 'b': 2 });

     * // => [1, 2]

     *

     * _.toArray('abc');

     * // => ['a', 'b', 'c']

     *

     * _.toArray(1);

     * // => []

     *

     * _.toArray(null);

     * // => []

     */

    function toArray(value) {

      if (!value) {

        return [];

      }

      if (isArrayLike(value)) {

        return isString(value) ? stringToArray(value) : copyArray(value);

      }

      if (symIterator && value[symIterator]) {

        return iteratorToArray(value[symIterator]());

      }

      var tag = getTag(value),

          func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);



      return func(value);

    }



    /**

     * Converts `value` to a finite number.

     *

     * @static

     * @memberOf _

     * @since 4.12.0

     * @category Lang

     * @param {*} value The value to convert.

     * @returns {number} Returns the converted number.

     * @example

     *

     * _.toFinite(3.2);

     * // => 3.2

     *

     * _.toFinite(Number.MIN_VALUE);

     * // => 5e-324

     *

     * _.toFinite(Infinity);

     * // => 1.7976931348623157e+308

     *

     * _.toFinite('3.2');

     * // => 3.2

     */

    function toFinite(value) {

      if (!value) {

        return value === 0 ? value : 0;

      }

      value = toNumber(value);

      if (value === INFINITY || value === -INFINITY) {

        var sign = (value < 0 ? -1 : 1);

        return sign * MAX_INTEGER;

      }

      return value === value ? value : 0;

    }



    /**

     * Converts `value` to an integer.

     *

     * **Note:** This method is loosely based on

     * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Lang

     * @param {*} value The value to convert.

     * @returns {number} Returns the converted integer.

     * @example

     *

     * _.toInteger(3.2);

     * // => 3

     *

     * _.toInteger(Number.MIN_VALUE);

     * // => 0

     *

     * _.toInteger(Infinity);

     * // => 1.7976931348623157e+308

     *

     * _.toInteger('3.2');

     * // => 3

     */

    function toInteger(value) {

      var result = toFinite(value),

          remainder = result % 1;



      return result === result ? (remainder ? result - remainder : result) : 0;

    }



    /**

     * Converts `value` to an integer suitable for use as the length of an

     * array-like object.

     *

     * **Note:** This method is based on

     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Lang

     * @param {*} value The value to convert.

     * @returns {number} Returns the converted integer.

     * @example

     *

     * _.toLength(3.2);

     * // => 3

     *

     * _.toLength(Number.MIN_VALUE);

     * // => 0

     *

     * _.toLength(Infinity);

     * // => 4294967295

     *

     * _.toLength('3.2');

     * // => 3

     */

    function toLength(value) {

      return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;

    }



    /**

     * Converts `value` to a number.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Lang

     * @param {*} value The value to process.

     * @returns {number} Returns the number.

     * @example

     *

     * _.toNumber(3.2);

     * // => 3.2

     *

     * _.toNumber(Number.MIN_VALUE);

     * // => 5e-324

     *

     * _.toNumber(Infinity);

     * // => Infinity

     *

     * _.toNumber('3.2');

     * // => 3.2

     */

    function toNumber(value) {

      if (typeof value == 'number') {

        return value;

      }

      if (isSymbol(value)) {

        return NAN;

      }

      if (isObject(value)) {

        var other = typeof value.valueOf == 'function' ? value.valueOf() : value;

        value = isObject(other) ? (other + '') : other;

      }

      if (typeof value != 'string') {

        return value === 0 ? value : +value;

      }

      value = value.replace(reTrim, '');

      var isBinary = reIsBinary.test(value);

      return (isBinary || reIsOctal.test(value))

        ? freeParseInt(value.slice(2), isBinary ? 2 : 8)

        : (reIsBadHex.test(value) ? NAN : +value);

    }



    /**

     * Converts `value` to a plain object flattening inherited enumerable string

     * keyed properties of `value` to own properties of the plain object.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Lang

     * @param {*} value The value to convert.

     * @returns {Object} Returns the converted plain object.

     * @example

     *

     * function Foo() {

     *   this.b = 2;

     * }

     *

     * Foo.prototype.c = 3;

     *

     * _.assign({ 'a': 1 }, new Foo);

     * // => { 'a': 1, 'b': 2 }

     *

     * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));

     * // => { 'a': 1, 'b': 2, 'c': 3 }

     */

    function toPlainObject(value) {

      return copyObject(value, keysIn(value));

    }



    /**

     * Converts `value` to a safe integer. A safe integer can be compared and

     * represented correctly.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Lang

     * @param {*} value The value to convert.

     * @returns {number} Returns the converted integer.

     * @example

     *

     * _.toSafeInteger(3.2);

     * // => 3

     *

     * _.toSafeInteger(Number.MIN_VALUE);

     * // => 0

     *

     * _.toSafeInteger(Infinity);

     * // => 9007199254740991

     *

     * _.toSafeInteger('3.2');

     * // => 3

     */

    function toSafeInteger(value) {

      return value

        ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)

        : (value === 0 ? value : 0);

    }



    /**

     * Converts `value` to a string. An empty string is returned for `null`

     * and `undefined` values. The sign of `-0` is preserved.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Lang

     * @param {*} value The value to convert.

     * @returns {string} Returns the converted string.

     * @example

     *

     * _.toString(null);

     * // => ''

     *

     * _.toString(-0);

     * // => '-0'

     *

     * _.toString([1, 2, 3]);

     * // => '1,2,3'

     */

    function toString(value) {

      return value == null ? '' : baseToString(value);

    }



    /*------------------------------------------------------------------------*/



    /**

     * Assigns own enumerable string keyed properties of source objects to the

     * destination object. Source objects are applied from left to right.

     * Subsequent sources overwrite property assignments of previous sources.

     *

     * **Note:** This method mutates `object` and is loosely based on

     * [`Object.assign`](https://mdn.io/Object/assign).

     *

     * @static

     * @memberOf _

     * @since 0.10.0

     * @category Object

     * @param {Object} object The destination object.

     * @param {...Object} [sources] The source objects.

     * @returns {Object} Returns `object`.

     * @see _.assignIn

     * @example

     *

     * function Foo() {

     *   this.a = 1;

     * }

     *

     * function Bar() {

     *   this.c = 3;

     * }

     *

     * Foo.prototype.b = 2;

     * Bar.prototype.d = 4;

     *

     * _.assign({ 'a': 0 }, new Foo, new Bar);

     * // => { 'a': 1, 'c': 3 }

     */

    var assign = createAssigner(function(object, source) {

      if (isPrototype(source) || isArrayLike(source)) {

        copyObject(source, keys(source), object);

        return;

      }

      for (var key in source) {

        if (hasOwnProperty.call(source, key)) {

          assignValue(object, key, source[key]);

        }

      }

    });



    /**

     * This method is like `_.assign` except that it iterates over own and

     * inherited source properties.

     *

     * **Note:** This method mutates `object`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @alias extend

     * @category Object

     * @param {Object} object The destination object.

     * @param {...Object} [sources] The source objects.

     * @returns {Object} Returns `object`.

     * @see _.assign

     * @example

     *

     * function Foo() {

     *   this.a = 1;

     * }

     *

     * function Bar() {

     *   this.c = 3;

     * }

     *

     * Foo.prototype.b = 2;

     * Bar.prototype.d = 4;

     *

     * _.assignIn({ 'a': 0 }, new Foo, new Bar);

     * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }

     */

    var assignIn = createAssigner(function(object, source) {

      copyObject(source, keysIn(source), object);

    });



    /**

     * This method is like `_.assignIn` except that it accepts `customizer`

     * which is invoked to produce the assigned values. If `customizer` returns

     * `undefined`, assignment is handled by the method instead. The `customizer`

     * is invoked with five arguments: (objValue, srcValue, key, object, source).

     *

     * **Note:** This method mutates `object`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @alias extendWith

     * @category Object

     * @param {Object} object The destination object.

     * @param {...Object} sources The source objects.

     * @param {Function} [customizer] The function to customize assigned values.

     * @returns {Object} Returns `object`.

     * @see _.assignWith

     * @example

     *

     * function customizer(objValue, srcValue) {

     *   return _.isUndefined(objValue) ? srcValue : objValue;

     * }

     *

     * var defaults = _.partialRight(_.assignInWith, customizer);

     *

     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });

     * // => { 'a': 1, 'b': 2 }

     */

    var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {

      copyObject(source, keysIn(source), object, customizer);

    });



    /**

     * This method is like `_.assign` except that it accepts `customizer`

     * which is invoked to produce the assigned values. If `customizer` returns

     * `undefined`, assignment is handled by the method instead. The `customizer`

     * is invoked with five arguments: (objValue, srcValue, key, object, source).

     *

     * **Note:** This method mutates `object`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Object

     * @param {Object} object The destination object.

     * @param {...Object} sources The source objects.

     * @param {Function} [customizer] The function to customize assigned values.

     * @returns {Object} Returns `object`.

     * @see _.assignInWith

     * @example

     *

     * function customizer(objValue, srcValue) {

     *   return _.isUndefined(objValue) ? srcValue : objValue;

     * }

     *

     * var defaults = _.partialRight(_.assignWith, customizer);

     *

     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });

     * // => { 'a': 1, 'b': 2 }

     */

    var assignWith = createAssigner(function(object, source, srcIndex, customizer) {

      copyObject(source, keys(source), object, customizer);

    });



    /**

     * Creates an array of values corresponding to `paths` of `object`.

     *

     * @static

     * @memberOf _

     * @since 1.0.0

     * @category Object

     * @param {Object} object The object to iterate over.

     * @param {...(string|string[])} [paths] The property paths to pick.

     * @returns {Array} Returns the picked values.

     * @example

     *

     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };

     *

     * _.at(object, ['a[0].b.c', 'a[1]']);

     * // => [3, 4]

     */

    var at = flatRest(baseAt);



    /**

     * Creates an object that inherits from the `prototype` object. If a

     * `properties` object is given, its own enumerable string keyed properties

     * are assigned to the created object.

     *

     * @static

     * @memberOf _

     * @since 2.3.0

     * @category Object

     * @param {Object} prototype The object to inherit from.

     * @param {Object} [properties] The properties to assign to the object.

     * @returns {Object} Returns the new object.

     * @example

     *

     * function Shape() {

     *   this.x = 0;

     *   this.y = 0;

     * }

     *

     * function Circle() {

     *   Shape.call(this);

     * }

     *

     * Circle.prototype = _.create(Shape.prototype, {

     *   'constructor': Circle

     * });

     *

     * var circle = new Circle;

     * circle instanceof Circle;

     * // => true

     *

     * circle instanceof Shape;

     * // => true

     */

    function create(prototype, properties) {

      var result = baseCreate(prototype);

      return properties == null ? result : baseAssign(result, properties);

    }



    /**

     * Assigns own and inherited enumerable string keyed properties of source

     * objects to the destination object for all destination properties that

     * resolve to `undefined`. Source objects are applied from left to right.

     * Once a property is set, additional values of the same property are ignored.

     *

     * **Note:** This method mutates `object`.

     *

     * @static

     * @since 0.1.0

     * @memberOf _

     * @category Object

     * @param {Object} object The destination object.

     * @param {...Object} [sources] The source objects.

     * @returns {Object} Returns `object`.

     * @see _.defaultsDeep

     * @example

     *

     * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });

     * // => { 'a': 1, 'b': 2 }

     */

    var defaults = baseRest(function(args) {

      args.push(undefined, customDefaultsAssignIn);

      return apply(assignInWith, undefined, args);

    });



    /**

     * This method is like `_.defaults` except that it recursively assigns

     * default properties.

     *

     * **Note:** This method mutates `object`.

     *

     * @static

     * @memberOf _

     * @since 3.10.0

     * @category Object

     * @param {Object} object The destination object.

     * @param {...Object} [sources] The source objects.

     * @returns {Object} Returns `object`.

     * @see _.defaults

     * @example

     *

     * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });

     * // => { 'a': { 'b': 2, 'c': 3 } }

     */

    var defaultsDeep = baseRest(function(args) {

      args.push(undefined, customDefaultsMerge);

      return apply(mergeWith, undefined, args);

    });



    /**

     * This method is like `_.find` except that it returns the key of the first

     * element `predicate` returns truthy for instead of the element itself.

     *

     * @static

     * @memberOf _

     * @since 1.1.0

     * @category Object

     * @param {Object} object The object to inspect.

     * @param {Function} [predicate=_.identity] The function invoked per iteration.

     * @returns {string|undefined} Returns the key of the matched element,

     *  else `undefined`.

     * @example

     *

     * var users = {

     *   'barney':  { 'age': 36, 'active': true },

     *   'fred':    { 'age': 40, 'active': false },

     *   'pebbles': { 'age': 1,  'active': true }

     * };

     *

     * _.findKey(users, function(o) { return o.age < 40; });

     * // => 'barney' (iteration order is not guaranteed)

     *

     * // The `_.matches` iteratee shorthand.

     * _.findKey(users, { 'age': 1, 'active': true });

     * // => 'pebbles'

     *

     * // The `_.matchesProperty` iteratee shorthand.

     * _.findKey(users, ['active', false]);

     * // => 'fred'

     *

     * // The `_.property` iteratee shorthand.

     * _.findKey(users, 'active');

     * // => 'barney'

     */

    function findKey(object, predicate) {

      return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);

    }



    /**

     * This method is like `_.findKey` except that it iterates over elements of

     * a collection in the opposite order.

     *

     * @static

     * @memberOf _

     * @since 2.0.0

     * @category Object

     * @param {Object} object The object to inspect.

     * @param {Function} [predicate=_.identity] The function invoked per iteration.

     * @returns {string|undefined} Returns the key of the matched element,

     *  else `undefined`.

     * @example

     *

     * var users = {

     *   'barney':  { 'age': 36, 'active': true },

     *   'fred':    { 'age': 40, 'active': false },

     *   'pebbles': { 'age': 1,  'active': true }

     * };

     *

     * _.findLastKey(users, function(o) { return o.age < 40; });

     * // => returns 'pebbles' assuming `_.findKey` returns 'barney'

     *

     * // The `_.matches` iteratee shorthand.

     * _.findLastKey(users, { 'age': 36, 'active': true });

     * // => 'barney'

     *

     * // The `_.matchesProperty` iteratee shorthand.

     * _.findLastKey(users, ['active', false]);

     * // => 'fred'

     *

     * // The `_.property` iteratee shorthand.

     * _.findLastKey(users, 'active');

     * // => 'pebbles'

     */

    function findLastKey(object, predicate) {

      return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);

    }



    /**

     * Iterates over own and inherited enumerable string keyed properties of an

     * object and invokes `iteratee` for each property. The iteratee is invoked

     * with three arguments: (value, key, object). Iteratee functions may exit

     * iteration early by explicitly returning `false`.

     *

     * @static

     * @memberOf _

     * @since 0.3.0

     * @category Object

     * @param {Object} object The object to iterate over.

     * @param {Function} [iteratee=_.identity] The function invoked per iteration.

     * @returns {Object} Returns `object`.

     * @see _.forInRight

     * @example

     *

     * function Foo() {

     *   this.a = 1;

     *   this.b = 2;

     * }

     *

     * Foo.prototype.c = 3;

     *

     * _.forIn(new Foo, function(value, key) {

     *   console.log(key);

     * });

     * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).

     */

    function forIn(object, iteratee) {

      return object == null

        ? object

        : baseFor(object, getIteratee(iteratee, 3), keysIn);

    }



    /**

     * This method is like `_.forIn` except that it iterates over properties of

     * `object` in the opposite order.

     *

     * @static

     * @memberOf _

     * @since 2.0.0

     * @category Object

     * @param {Object} object The object to iterate over.

     * @param {Function} [iteratee=_.identity] The function invoked per iteration.

     * @returns {Object} Returns `object`.

     * @see _.forIn

     * @example

     *

     * function Foo() {

     *   this.a = 1;

     *   this.b = 2;

     * }

     *

     * Foo.prototype.c = 3;

     *

     * _.forInRight(new Foo, function(value, key) {

     *   console.log(key);

     * });

     * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.

     */

    function forInRight(object, iteratee) {

      return object == null

        ? object

        : baseForRight(object, getIteratee(iteratee, 3), keysIn);

    }



    /**

     * Iterates over own enumerable string keyed properties of an object and

     * invokes `iteratee` for each property. The iteratee is invoked with three

     * arguments: (value, key, object). Iteratee functions may exit iteration

     * early by explicitly returning `false`.

     *

     * @static

     * @memberOf _

     * @since 0.3.0

     * @category Object

     * @param {Object} object The object to iterate over.

     * @param {Function} [iteratee=_.identity] The function invoked per iteration.

     * @returns {Object} Returns `object`.

     * @see _.forOwnRight

     * @example

     *

     * function Foo() {

     *   this.a = 1;

     *   this.b = 2;

     * }

     *

     * Foo.prototype.c = 3;

     *

     * _.forOwn(new Foo, function(value, key) {

     *   console.log(key);

     * });

     * // => Logs 'a' then 'b' (iteration order is not guaranteed).

     */

    function forOwn(object, iteratee) {

      return object && baseForOwn(object, getIteratee(iteratee, 3));

    }



    /**

     * This method is like `_.forOwn` except that it iterates over properties of

     * `object` in the opposite order.

     *

     * @static

     * @memberOf _

     * @since 2.0.0

     * @category Object

     * @param {Object} object The object to iterate over.

     * @param {Function} [iteratee=_.identity] The function invoked per iteration.

     * @returns {Object} Returns `object`.

     * @see _.forOwn

     * @example

     *

     * function Foo() {

     *   this.a = 1;

     *   this.b = 2;

     * }

     *

     * Foo.prototype.c = 3;

     *

     * _.forOwnRight(new Foo, function(value, key) {

     *   console.log(key);

     * });

     * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.

     */

    function forOwnRight(object, iteratee) {

      return object && baseForOwnRight(object, getIteratee(iteratee, 3));

    }



    /**

     * Creates an array of function property names from own enumerable properties

     * of `object`.

     *

     * @static

     * @since 0.1.0

     * @memberOf _

     * @category Object

     * @param {Object} object The object to inspect.

     * @returns {Array} Returns the function names.

     * @see _.functionsIn

     * @example

     *

     * function Foo() {

     *   this.a = _.constant('a');

     *   this.b = _.constant('b');

     * }

     *

     * Foo.prototype.c = _.constant('c');

     *

     * _.functions(new Foo);

     * // => ['a', 'b']

     */

    function functions(object) {

      return object == null ? [] : baseFunctions(object, keys(object));

    }



    /**

     * Creates an array of function property names from own and inherited

     * enumerable properties of `object`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Object

     * @param {Object} object The object to inspect.

     * @returns {Array} Returns the function names.

     * @see _.functions

     * @example

     *

     * function Foo() {

     *   this.a = _.constant('a');

     *   this.b = _.constant('b');

     * }

     *

     * Foo.prototype.c = _.constant('c');

     *

     * _.functionsIn(new Foo);

     * // => ['a', 'b', 'c']

     */

    function functionsIn(object) {

      return object == null ? [] : baseFunctions(object, keysIn(object));

    }



    /**

     * Gets the value at `path` of `object`. If the resolved value is

     * `undefined`, the `defaultValue` is returned in its place.

     *

     * @static

     * @memberOf _

     * @since 3.7.0

     * @category Object

     * @param {Object} object The object to query.

     * @param {Array|string} path The path of the property to get.

     * @param {*} [defaultValue] The value returned for `undefined` resolved values.

     * @returns {*} Returns the resolved value.

     * @example

     *

     * var object = { 'a': [{ 'b': { 'c': 3 } }] };

     *

     * _.get(object, 'a[0].b.c');

     * // => 3

     *

     * _.get(object, ['a', '0', 'b', 'c']);

     * // => 3

     *

     * _.get(object, 'a.b.c', 'default');

     * // => 'default'

     */

    function get(object, path, defaultValue) {

      var result = object == null ? undefined : baseGet(object, path);

      return result === undefined ? defaultValue : result;

    }



    /**

     * Checks if `path` is a direct property of `object`.

     *

     * @static

     * @since 0.1.0

     * @memberOf _

     * @category Object

     * @param {Object} object The object to query.

     * @param {Array|string} path The path to check.

     * @returns {boolean} Returns `true` if `path` exists, else `false`.

     * @example

     *

     * var object = { 'a': { 'b': 2 } };

     * var other = _.create({ 'a': _.create({ 'b': 2 }) });

     *

     * _.has(object, 'a');

     * // => true

     *

     * _.has(object, 'a.b');

     * // => true

     *

     * _.has(object, ['a', 'b']);

     * // => true

     *

     * _.has(other, 'a');

     * // => false

     */

    function has(object, path) {

      return object != null && hasPath(object, path, baseHas);

    }



    /**

     * Checks if `path` is a direct or inherited property of `object`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Object

     * @param {Object} object The object to query.

     * @param {Array|string} path The path to check.

     * @returns {boolean} Returns `true` if `path` exists, else `false`.

     * @example

     *

     * var object = _.create({ 'a': _.create({ 'b': 2 }) });

     *

     * _.hasIn(object, 'a');

     * // => true

     *

     * _.hasIn(object, 'a.b');

     * // => true

     *

     * _.hasIn(object, ['a', 'b']);

     * // => true

     *

     * _.hasIn(object, 'b');

     * // => false

     */

    function hasIn(object, path) {

      return object != null && hasPath(object, path, baseHasIn);

    }



    /**

     * Creates an object composed of the inverted keys and values of `object`.

     * If `object` contains duplicate values, subsequent values overwrite

     * property assignments of previous values.

     *

     * @static

     * @memberOf _

     * @since 0.7.0

     * @category Object

     * @param {Object} object The object to invert.

     * @returns {Object} Returns the new inverted object.

     * @example

     *

     * var object = { 'a': 1, 'b': 2, 'c': 1 };

     *

     * _.invert(object);

     * // => { '1': 'c', '2': 'b' }

     */

    var invert = createInverter(function(result, value, key) {

      result[value] = key;

    }, constant(identity));



    /**

     * This method is like `_.invert` except that the inverted object is generated

     * from the results of running each element of `object` thru `iteratee`. The

     * corresponding inverted value of each inverted key is an array of keys

     * responsible for generating the inverted value. The iteratee is invoked

     * with one argument: (value).

     *

     * @static

     * @memberOf _

     * @since 4.1.0

     * @category Object

     * @param {Object} object The object to invert.

     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.

     * @returns {Object} Returns the new inverted object.

     * @example

     *

     * var object = { 'a': 1, 'b': 2, 'c': 1 };

     *

     * _.invertBy(object);

     * // => { '1': ['a', 'c'], '2': ['b'] }

     *

     * _.invertBy(object, function(value) {

     *   return 'group' + value;

     * });

     * // => { 'group1': ['a', 'c'], 'group2': ['b'] }

     */

    var invertBy = createInverter(function(result, value, key) {

      if (hasOwnProperty.call(result, value)) {

        result[value].push(key);

      } else {

        result[value] = [key];

      }

    }, getIteratee);



    /**

     * Invokes the method at `path` of `object`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Object

     * @param {Object} object The object to query.

     * @param {Array|string} path The path of the method to invoke.

     * @param {...*} [args] The arguments to invoke the method with.

     * @returns {*} Returns the result of the invoked method.

     * @example

     *

     * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };

     *

     * _.invoke(object, 'a[0].b.c.slice', 1, 3);

     * // => [2, 3]

     */

    var invoke = baseRest(baseInvoke);



    /**

     * Creates an array of the own enumerable property names of `object`.

     *

     * **Note:** Non-object values are coerced to objects. See the

     * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)

     * for more details.

     *

     * @static

     * @since 0.1.0

     * @memberOf _

     * @category Object

     * @param {Object} object The object to query.

     * @returns {Array} Returns the array of property names.

     * @example

     *

     * function Foo() {

     *   this.a = 1;

     *   this.b = 2;

     * }

     *

     * Foo.prototype.c = 3;

     *

     * _.keys(new Foo);

     * // => ['a', 'b'] (iteration order is not guaranteed)

     *

     * _.keys('hi');

     * // => ['0', '1']

     */

    function keys(object) {

      return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);

    }



    /**

     * Creates an array of the own and inherited enumerable property names of `object`.

     *

     * **Note:** Non-object values are coerced to objects.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Object

     * @param {Object} object The object to query.

     * @returns {Array} Returns the array of property names.

     * @example

     *

     * function Foo() {

     *   this.a = 1;

     *   this.b = 2;

     * }

     *

     * Foo.prototype.c = 3;

     *

     * _.keysIn(new Foo);

     * // => ['a', 'b', 'c'] (iteration order is not guaranteed)

     */

    function keysIn(object) {

      return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);

    }



    /**

     * The opposite of `_.mapValues`; this method creates an object with the

     * same values as `object` and keys generated by running each own enumerable

     * string keyed property of `object` thru `iteratee`. The iteratee is invoked

     * with three arguments: (value, key, object).

     *

     * @static

     * @memberOf _

     * @since 3.8.0

     * @category Object

     * @param {Object} object The object to iterate over.

     * @param {Function} [iteratee=_.identity] The function invoked per iteration.

     * @returns {Object} Returns the new mapped object.

     * @see _.mapValues

     * @example

     *

     * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {

     *   return key + value;

     * });

     * // => { 'a1': 1, 'b2': 2 }

     */

    function mapKeys(object, iteratee) {

      var result = {};

      iteratee = getIteratee(iteratee, 3);



      baseForOwn(object, function(value, key, object) {

        baseAssignValue(result, iteratee(value, key, object), value);

      });

      return result;

    }



    /**

     * Creates an object with the same keys as `object` and values generated

     * by running each own enumerable string keyed property of `object` thru

     * `iteratee`. The iteratee is invoked with three arguments:

     * (value, key, object).

     *

     * @static

     * @memberOf _

     * @since 2.4.0

     * @category Object

     * @param {Object} object The object to iterate over.

     * @param {Function} [iteratee=_.identity] The function invoked per iteration.

     * @returns {Object} Returns the new mapped object.

     * @see _.mapKeys

     * @example

     *

     * var users = {

     *   'fred':    { 'user': 'fred',    'age': 40 },

     *   'pebbles': { 'user': 'pebbles', 'age': 1 }

     * };

     *

     * _.mapValues(users, function(o) { return o.age; });

     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)

     *

     * // The `_.property` iteratee shorthand.

     * _.mapValues(users, 'age');

     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)

     */

    function mapValues(object, iteratee) {

      var result = {};

      iteratee = getIteratee(iteratee, 3);



      baseForOwn(object, function(value, key, object) {

        baseAssignValue(result, key, iteratee(value, key, object));

      });

      return result;

    }



    /**

     * This method is like `_.assign` except that it recursively merges own and

     * inherited enumerable string keyed properties of source objects into the

     * destination object. Source properties that resolve to `undefined` are

     * skipped if a destination value exists. Array and plain object properties

     * are merged recursively. Other objects and value types are overridden by

     * assignment. Source objects are applied from left to right. Subsequent

     * sources overwrite property assignments of previous sources.

     *

     * **Note:** This method mutates `object`.

     *

     * @static

     * @memberOf _

     * @since 0.5.0

     * @category Object

     * @param {Object} object The destination object.

     * @param {...Object} [sources] The source objects.

     * @returns {Object} Returns `object`.

     * @example

     *

     * var object = {

     *   'a': [{ 'b': 2 }, { 'd': 4 }]

     * };

     *

     * var other = {

     *   'a': [{ 'c': 3 }, { 'e': 5 }]

     * };

     *

     * _.merge(object, other);

     * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }

     */

    var merge = createAssigner(function(object, source, srcIndex) {

      baseMerge(object, source, srcIndex);

    });



    /**

     * This method is like `_.merge` except that it accepts `customizer` which

     * is invoked to produce the merged values of the destination and source

     * properties. If `customizer` returns `undefined`, merging is handled by the

     * method instead. The `customizer` is invoked with six arguments:

     * (objValue, srcValue, key, object, source, stack).

     *

     * **Note:** This method mutates `object`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Object

     * @param {Object} object The destination object.

     * @param {...Object} sources The source objects.

     * @param {Function} customizer The function to customize assigned values.

     * @returns {Object} Returns `object`.

     * @example

     *

     * function customizer(objValue, srcValue) {

     *   if (_.isArray(objValue)) {

     *     return objValue.concat(srcValue);

     *   }

     * }

     *

     * var object = { 'a': [1], 'b': [2] };

     * var other = { 'a': [3], 'b': [4] };

     *

     * _.mergeWith(object, other, customizer);

     * // => { 'a': [1, 3], 'b': [2, 4] }

     */

    var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {

      baseMerge(object, source, srcIndex, customizer);

    });



    /**

     * The opposite of `_.pick`; this method creates an object composed of the

     * own and inherited enumerable property paths of `object` that are not omitted.

     *

     * **Note:** This method is considerably slower than `_.pick`.

     *

     * @static

     * @since 0.1.0

     * @memberOf _

     * @category Object

     * @param {Object} object The source object.

     * @param {...(string|string[])} [paths] The property paths to omit.

     * @returns {Object} Returns the new object.

     * @example

     *

     * var object = { 'a': 1, 'b': '2', 'c': 3 };

     *

     * _.omit(object, ['a', 'c']);

     * // => { 'b': '2' }

     */

    var omit = flatRest(function(object, paths) {

      var result = {};

      if (object == null) {

        return result;

      }

      var isDeep = false;

      paths = arrayMap(paths, function(path) {

        path = castPath(path, object);

        isDeep || (isDeep = path.length > 1);

        return path;

      });

      copyObject(object, getAllKeysIn(object), result);

      if (isDeep) {

        result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);

      }

      var length = paths.length;

      while (length--) {

        baseUnset(result, paths[length]);

      }

      return result;

    });



    /**

     * The opposite of `_.pickBy`; this method creates an object composed of

     * the own and inherited enumerable string keyed properties of `object` that

     * `predicate` doesn't return truthy for. The predicate is invoked with two

     * arguments: (value, key).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Object

     * @param {Object} object The source object.

     * @param {Function} [predicate=_.identity] The function invoked per property.

     * @returns {Object} Returns the new object.

     * @example

     *

     * var object = { 'a': 1, 'b': '2', 'c': 3 };

     *

     * _.omitBy(object, _.isNumber);

     * // => { 'b': '2' }

     */

    function omitBy(object, predicate) {

      return pickBy(object, negate(getIteratee(predicate)));

    }



    /**

     * Creates an object composed of the picked `object` properties.

     *

     * @static

     * @since 0.1.0

     * @memberOf _

     * @category Object

     * @param {Object} object The source object.

     * @param {...(string|string[])} [paths] The property paths to pick.

     * @returns {Object} Returns the new object.

     * @example

     *

     * var object = { 'a': 1, 'b': '2', 'c': 3 };

     *

     * _.pick(object, ['a', 'c']);

     * // => { 'a': 1, 'c': 3 }

     */

    var pick = flatRest(function(object, paths) {

      return object == null ? {} : basePick(object, paths);

    });



    /**

     * Creates an object composed of the `object` properties `predicate` returns

     * truthy for. The predicate is invoked with two arguments: (value, key).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Object

     * @param {Object} object The source object.

     * @param {Function} [predicate=_.identity] The function invoked per property.

     * @returns {Object} Returns the new object.

     * @example

     *

     * var object = { 'a': 1, 'b': '2', 'c': 3 };

     *

     * _.pickBy(object, _.isNumber);

     * // => { 'a': 1, 'c': 3 }

     */

    function pickBy(object, predicate) {

      if (object == null) {

        return {};

      }

      var props = arrayMap(getAllKeysIn(object), function(prop) {

        return [prop];

      });

      predicate = getIteratee(predicate);

      return basePickBy(object, props, function(value, path) {

        return predicate(value, path[0]);

      });

    }



    /**

     * This method is like `_.get` except that if the resolved value is a

     * function it's invoked with the `this` binding of its parent object and

     * its result is returned.

     *

     * @static

     * @since 0.1.0

     * @memberOf _

     * @category Object

     * @param {Object} object The object to query.

     * @param {Array|string} path The path of the property to resolve.

     * @param {*} [defaultValue] The value returned for `undefined` resolved values.

     * @returns {*} Returns the resolved value.

     * @example

     *

     * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };

     *

     * _.result(object, 'a[0].b.c1');

     * // => 3

     *

     * _.result(object, 'a[0].b.c2');

     * // => 4

     *

     * _.result(object, 'a[0].b.c3', 'default');

     * // => 'default'

     *

     * _.result(object, 'a[0].b.c3', _.constant('default'));

     * // => 'default'

     */

    function result(object, path, defaultValue) {

      path = castPath(path, object);



      var index = -1,

          length = path.length;



      // Ensure the loop is entered when path is empty.

      if (!length) {

        length = 1;

        object = undefined;

      }

      while (++index < length) {

        var value = object == null ? undefined : object[toKey(path[index])];

        if (value === undefined) {

          index = length;

          value = defaultValue;

        }

        object = isFunction(value) ? value.call(object) : value;

      }

      return object;

    }



    /**

     * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,

     * it's created. Arrays are created for missing index properties while objects

     * are created for all other missing properties. Use `_.setWith` to customize

     * `path` creation.

     *

     * **Note:** This method mutates `object`.

     *

     * @static

     * @memberOf _

     * @since 3.7.0

     * @category Object

     * @param {Object} object The object to modify.

     * @param {Array|string} path The path of the property to set.

     * @param {*} value The value to set.

     * @returns {Object} Returns `object`.

     * @example

     *

     * var object = { 'a': [{ 'b': { 'c': 3 } }] };

     *

     * _.set(object, 'a[0].b.c', 4);

     * console.log(object.a[0].b.c);

     * // => 4

     *

     * _.set(object, ['x', '0', 'y', 'z'], 5);

     * console.log(object.x[0].y.z);

     * // => 5

     */

    function set(object, path, value) {

      return object == null ? object : baseSet(object, path, value);

    }



    /**

     * This method is like `_.set` except that it accepts `customizer` which is

     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`

     * path creation is handled by the method instead. The `customizer` is invoked

     * with three arguments: (nsValue, key, nsObject).

     *

     * **Note:** This method mutates `object`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Object

     * @param {Object} object The object to modify.

     * @param {Array|string} path The path of the property to set.

     * @param {*} value The value to set.

     * @param {Function} [customizer] The function to customize assigned values.

     * @returns {Object} Returns `object`.

     * @example

     *

     * var object = {};

     *

     * _.setWith(object, '[0][1]', 'a', Object);

     * // => { '0': { '1': 'a' } }

     */

    function setWith(object, path, value, customizer) {

      customizer = typeof customizer == 'function' ? customizer : undefined;

      return object == null ? object : baseSet(object, path, value, customizer);

    }



    /**

     * Creates an array of own enumerable string keyed-value pairs for `object`

     * which can be consumed by `_.fromPairs`. If `object` is a map or set, its

     * entries are returned.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @alias entries

     * @category Object

     * @param {Object} object The object to query.

     * @returns {Array} Returns the key-value pairs.

     * @example

     *

     * function Foo() {

     *   this.a = 1;

     *   this.b = 2;

     * }

     *

     * Foo.prototype.c = 3;

     *

     * _.toPairs(new Foo);

     * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)

     */

    var toPairs = createToPairs(keys);



    /**

     * Creates an array of own and inherited enumerable string keyed-value pairs

     * for `object` which can be consumed by `_.fromPairs`. If `object` is a map

     * or set, its entries are returned.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @alias entriesIn

     * @category Object

     * @param {Object} object The object to query.

     * @returns {Array} Returns the key-value pairs.

     * @example

     *

     * function Foo() {

     *   this.a = 1;

     *   this.b = 2;

     * }

     *

     * Foo.prototype.c = 3;

     *

     * _.toPairsIn(new Foo);

     * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)

     */

    var toPairsIn = createToPairs(keysIn);



    /**

     * An alternative to `_.reduce`; this method transforms `object` to a new

     * `accumulator` object which is the result of running each of its own

     * enumerable string keyed properties thru `iteratee`, with each invocation

     * potentially mutating the `accumulator` object. If `accumulator` is not

     * provided, a new object with the same `[[Prototype]]` will be used. The

     * iteratee is invoked with four arguments: (accumulator, value, key, object).

     * Iteratee functions may exit iteration early by explicitly returning `false`.

     *

     * @static

     * @memberOf _

     * @since 1.3.0

     * @category Object

     * @param {Object} object The object to iterate over.

     * @param {Function} [iteratee=_.identity] The function invoked per iteration.

     * @param {*} [accumulator] The custom accumulator value.

     * @returns {*} Returns the accumulated value.

     * @example

     *

     * _.transform([2, 3, 4], function(result, n) {

     *   result.push(n *= n);

     *   return n % 2 == 0;

     * }, []);

     * // => [4, 9]

     *

     * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {

     *   (result[value] || (result[value] = [])).push(key);

     * }, {});

     * // => { '1': ['a', 'c'], '2': ['b'] }

     */

    function transform(object, iteratee, accumulator) {

      var isArr = isArray(object),

          isArrLike = isArr || isBuffer(object) || isTypedArray(object);



      iteratee = getIteratee(iteratee, 4);

      if (accumulator == null) {

        var Ctor = object && object.constructor;

        if (isArrLike) {

          accumulator = isArr ? new Ctor : [];

        }

        else if (isObject(object)) {

          accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};

        }

        else {

          accumulator = {};

        }

      }

      (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {

        return iteratee(accumulator, value, index, object);

      });

      return accumulator;

    }



    /**

     * Removes the property at `path` of `object`.

     *

     * **Note:** This method mutates `object`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Object

     * @param {Object} object The object to modify.

     * @param {Array|string} path The path of the property to unset.

     * @returns {boolean} Returns `true` if the property is deleted, else `false`.

     * @example

     *

     * var object = { 'a': [{ 'b': { 'c': 7 } }] };

     * _.unset(object, 'a[0].b.c');

     * // => true

     *

     * console.log(object);

     * // => { 'a': [{ 'b': {} }] };

     *

     * _.unset(object, ['a', '0', 'b', 'c']);

     * // => true

     *

     * console.log(object);

     * // => { 'a': [{ 'b': {} }] };

     */

    function unset(object, path) {

      return object == null ? true : baseUnset(object, path);

    }



    /**

     * This method is like `_.set` except that accepts `updater` to produce the

     * value to set. Use `_.updateWith` to customize `path` creation. The `updater`

     * is invoked with one argument: (value).

     *

     * **Note:** This method mutates `object`.

     *

     * @static

     * @memberOf _

     * @since 4.6.0

     * @category Object

     * @param {Object} object The object to modify.

     * @param {Array|string} path The path of the property to set.

     * @param {Function} updater The function to produce the updated value.

     * @returns {Object} Returns `object`.

     * @example

     *

     * var object = { 'a': [{ 'b': { 'c': 3 } }] };

     *

     * _.update(object, 'a[0].b.c', function(n) { return n * n; });

     * console.log(object.a[0].b.c);

     * // => 9

     *

     * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });

     * console.log(object.x[0].y.z);

     * // => 0

     */

    function update(object, path, updater) {

      return object == null ? object : baseUpdate(object, path, castFunction(updater));

    }



    /**

     * This method is like `_.update` except that it accepts `customizer` which is

     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`

     * path creation is handled by the method instead. The `customizer` is invoked

     * with three arguments: (nsValue, key, nsObject).

     *

     * **Note:** This method mutates `object`.

     *

     * @static

     * @memberOf _

     * @since 4.6.0

     * @category Object

     * @param {Object} object The object to modify.

     * @param {Array|string} path The path of the property to set.

     * @param {Function} updater The function to produce the updated value.

     * @param {Function} [customizer] The function to customize assigned values.

     * @returns {Object} Returns `object`.

     * @example

     *

     * var object = {};

     *

     * _.updateWith(object, '[0][1]', _.constant('a'), Object);

     * // => { '0': { '1': 'a' } }

     */

    function updateWith(object, path, updater, customizer) {

      customizer = typeof customizer == 'function' ? customizer : undefined;

      return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);

    }



    /**

     * Creates an array of the own enumerable string keyed property values of `object`.

     *

     * **Note:** Non-object values are coerced to objects.

     *

     * @static

     * @since 0.1.0

     * @memberOf _

     * @category Object

     * @param {Object} object The object to query.

     * @returns {Array} Returns the array of property values.

     * @example

     *

     * function Foo() {

     *   this.a = 1;

     *   this.b = 2;

     * }

     *

     * Foo.prototype.c = 3;

     *

     * _.values(new Foo);

     * // => [1, 2] (iteration order is not guaranteed)

     *

     * _.values('hi');

     * // => ['h', 'i']

     */

    function values(object) {

      return object == null ? [] : baseValues(object, keys(object));

    }



    /**

     * Creates an array of the own and inherited enumerable string keyed property

     * values of `object`.

     *

     * **Note:** Non-object values are coerced to objects.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Object

     * @param {Object} object The object to query.

     * @returns {Array} Returns the array of property values.

     * @example

     *

     * function Foo() {

     *   this.a = 1;

     *   this.b = 2;

     * }

     *

     * Foo.prototype.c = 3;

     *

     * _.valuesIn(new Foo);

     * // => [1, 2, 3] (iteration order is not guaranteed)

     */

    function valuesIn(object) {

      return object == null ? [] : baseValues(object, keysIn(object));

    }



    /*------------------------------------------------------------------------*/



    /**

     * Clamps `number` within the inclusive `lower` and `upper` bounds.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Number

     * @param {number} number The number to clamp.

     * @param {number} [lower] The lower bound.

     * @param {number} upper The upper bound.

     * @returns {number} Returns the clamped number.

     * @example

     *

     * _.clamp(-10, -5, 5);

     * // => -5

     *

     * _.clamp(10, -5, 5);

     * // => 5

     */

    function clamp(number, lower, upper) {

      if (upper === undefined) {

        upper = lower;

        lower = undefined;

      }

      if (upper !== undefined) {

        upper = toNumber(upper);

        upper = upper === upper ? upper : 0;

      }

      if (lower !== undefined) {

        lower = toNumber(lower);

        lower = lower === lower ? lower : 0;

      }

      return baseClamp(toNumber(number), lower, upper);

    }



    /**

     * Checks if `n` is between `start` and up to, but not including, `end`. If

     * `end` is not specified, it's set to `start` with `start` then set to `0`.

     * If `start` is greater than `end` the params are swapped to support

     * negative ranges.

     *

     * @static

     * @memberOf _

     * @since 3.3.0

     * @category Number

     * @param {number} number The number to check.

     * @param {number} [start=0] The start of the range.

     * @param {number} end The end of the range.

     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.

     * @see _.range, _.rangeRight

     * @example

     *

     * _.inRange(3, 2, 4);

     * // => true

     *

     * _.inRange(4, 8);

     * // => true

     *

     * _.inRange(4, 2);

     * // => false

     *

     * _.inRange(2, 2);

     * // => false

     *

     * _.inRange(1.2, 2);

     * // => true

     *

     * _.inRange(5.2, 4);

     * // => false

     *

     * _.inRange(-3, -2, -6);

     * // => true

     */

    function inRange(number, start, end) {

      start = toFinite(start);

      if (end === undefined) {

        end = start;

        start = 0;

      } else {

        end = toFinite(end);

      }

      number = toNumber(number);

      return baseInRange(number, start, end);

    }



    /**

     * Produces a random number between the inclusive `lower` and `upper` bounds.

     * If only one argument is provided a number between `0` and the given number

     * is returned. If `floating` is `true`, or either `lower` or `upper` are

     * floats, a floating-point number is returned instead of an integer.

     *

     * **Note:** JavaScript follows the IEEE-754 standard for resolving

     * floating-point values which can produce unexpected results.

     *

     * @static

     * @memberOf _

     * @since 0.7.0

     * @category Number

     * @param {number} [lower=0] The lower bound.

     * @param {number} [upper=1] The upper bound.

     * @param {boolean} [floating] Specify returning a floating-point number.

     * @returns {number} Returns the random number.

     * @example

     *

     * _.random(0, 5);

     * // => an integer between 0 and 5

     *

     * _.random(5);

     * // => also an integer between 0 and 5

     *

     * _.random(5, true);

     * // => a floating-point number between 0 and 5

     *

     * _.random(1.2, 5.2);

     * // => a floating-point number between 1.2 and 5.2

     */

    function random(lower, upper, floating) {

      if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {

        upper = floating = undefined;

      }

      if (floating === undefined) {

        if (typeof upper == 'boolean') {

          floating = upper;

          upper = undefined;

        }

        else if (typeof lower == 'boolean') {

          floating = lower;

          lower = undefined;

        }

      }

      if (lower === undefined && upper === undefined) {

        lower = 0;

        upper = 1;

      }

      else {

        lower = toFinite(lower);

        if (upper === undefined) {

          upper = lower;

          lower = 0;

        } else {

          upper = toFinite(upper);

        }

      }

      if (lower > upper) {

        var temp = lower;

        lower = upper;

        upper = temp;

      }

      if (floating || lower % 1 || upper % 1) {

        var rand = nativeRandom();

        return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);

      }

      return baseRandom(lower, upper);

    }



    /*------------------------------------------------------------------------*/



    /**

     * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category String

     * @param {string} [string=''] The string to convert.

     * @returns {string} Returns the camel cased string.

     * @example

     *

     * _.camelCase('Foo Bar');

     * // => 'fooBar'

     *

     * _.camelCase('--foo-bar--');

     * // => 'fooBar'

     *

     * _.camelCase('__FOO_BAR__');

     * // => 'fooBar'

     */

    var camelCase = createCompounder(function(result, word, index) {

      word = word.toLowerCase();

      return result + (index ? capitalize(word) : word);

    });



    /**

     * Converts the first character of `string` to upper case and the remaining

     * to lower case.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category String

     * @param {string} [string=''] The string to capitalize.

     * @returns {string} Returns the capitalized string.

     * @example

     *

     * _.capitalize('FRED');

     * // => 'Fred'

     */

    function capitalize(string) {

      return upperFirst(toString(string).toLowerCase());

    }



    /**

     * Deburrs `string` by converting

     * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)

     * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)

     * letters to basic Latin letters and removing

     * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category String

     * @param {string} [string=''] The string to deburr.

     * @returns {string} Returns the deburred string.

     * @example

     *

     * _.deburr('déjà vu');

     * // => 'deja vu'

     */

    function deburr(string) {

      string = toString(string);

      return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');

    }



    /**

     * Checks if `string` ends with the given target string.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category String

     * @param {string} [string=''] The string to inspect.

     * @param {string} [target] The string to search for.

     * @param {number} [position=string.length] The position to search up to.

     * @returns {boolean} Returns `true` if `string` ends with `target`,

     *  else `false`.

     * @example

     *

     * _.endsWith('abc', 'c');

     * // => true

     *

     * _.endsWith('abc', 'b');

     * // => false

     *

     * _.endsWith('abc', 'b', 2);

     * // => true

     */

    function endsWith(string, target, position) {

      string = toString(string);

      target = baseToString(target);



      var length = string.length;

      position = position === undefined

        ? length

        : baseClamp(toInteger(position), 0, length);



      var end = position;

      position -= target.length;

      return position >= 0 && string.slice(position, end) == target;

    }



    /**

     * Converts the characters "&", "<", ">", '"', and "'" in `string` to their

     * corresponding HTML entities.

     *

     * **Note:** No other characters are escaped. To escape additional

     * characters use a third-party library like [_he_](https://mths.be/he).

     *

     * Though the ">" character is escaped for symmetry, characters like

     * ">" and "/" don't need escaping in HTML and have no special meaning

     * unless they're part of a tag or unquoted attribute value. See

     * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)

     * (under "semi-related fun fact") for more details.

     *

     * When working with HTML you should always

     * [quote attribute values](http://wonko.com/post/html-escaping) to reduce

     * XSS vectors.

     *

     * @static

     * @since 0.1.0

     * @memberOf _

     * @category String

     * @param {string} [string=''] The string to escape.

     * @returns {string} Returns the escaped string.

     * @example

     *

     * _.escape('fred, barney, & pebbles');

     * // => 'fred, barney, &amp; pebbles'

     */

    function escape(string) {

      string = toString(string);

      return (string && reHasUnescapedHtml.test(string))

        ? string.replace(reUnescapedHtml, escapeHtmlChar)

        : string;

    }



    /**

     * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",

     * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category String

     * @param {string} [string=''] The string to escape.

     * @returns {string} Returns the escaped string.

     * @example

     *

     * _.escapeRegExp('[lodash](https://lodash.com/)');

     * // => '\[lodash\]\(https://lodash\.com/\)'

     */

    function escapeRegExp(string) {

      string = toString(string);

      return (string && reHasRegExpChar.test(string))

        ? string.replace(reRegExpChar, '\\$&')

        : string;

    }



    /**

     * Converts `string` to

     * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category String

     * @param {string} [string=''] The string to convert.

     * @returns {string} Returns the kebab cased string.

     * @example

     *

     * _.kebabCase('Foo Bar');

     * // => 'foo-bar'

     *

     * _.kebabCase('fooBar');

     * // => 'foo-bar'

     *

     * _.kebabCase('__FOO_BAR__');

     * // => 'foo-bar'

     */

    var kebabCase = createCompounder(function(result, word, index) {

      return result + (index ? '-' : '') + word.toLowerCase();

    });



    /**

     * Converts `string`, as space separated words, to lower case.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category String

     * @param {string} [string=''] The string to convert.

     * @returns {string} Returns the lower cased string.

     * @example

     *

     * _.lowerCase('--Foo-Bar--');

     * // => 'foo bar'

     *

     * _.lowerCase('fooBar');

     * // => 'foo bar'

     *

     * _.lowerCase('__FOO_BAR__');

     * // => 'foo bar'

     */

    var lowerCase = createCompounder(function(result, word, index) {

      return result + (index ? ' ' : '') + word.toLowerCase();

    });



    /**

     * Converts the first character of `string` to lower case.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category String

     * @param {string} [string=''] The string to convert.

     * @returns {string} Returns the converted string.

     * @example

     *

     * _.lowerFirst('Fred');

     * // => 'fred'

     *

     * _.lowerFirst('FRED');

     * // => 'fRED'

     */

    var lowerFirst = createCaseFirst('toLowerCase');



    /**

     * Pads `string` on the left and right sides if it's shorter than `length`.

     * Padding characters are truncated if they can't be evenly divided by `length`.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category String

     * @param {string} [string=''] The string to pad.

     * @param {number} [length=0] The padding length.

     * @param {string} [chars=' '] The string used as padding.

     * @returns {string} Returns the padded string.

     * @example

     *

     * _.pad('abc', 8);

     * // => '  abc   '

     *

     * _.pad('abc', 8, '_-');

     * // => '_-abc_-_'

     *

     * _.pad('abc', 3);

     * // => 'abc'

     */

    function pad(string, length, chars) {

      string = toString(string);

      length = toInteger(length);



      var strLength = length ? stringSize(string) : 0;

      if (!length || strLength >= length) {

        return string;

      }

      var mid = (length - strLength) / 2;

      return (

        createPadding(nativeFloor(mid), chars) +

        string +

        createPadding(nativeCeil(mid), chars)

      );

    }



    /**

     * Pads `string` on the right side if it's shorter than `length`. Padding

     * characters are truncated if they exceed `length`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category String

     * @param {string} [string=''] The string to pad.

     * @param {number} [length=0] The padding length.

     * @param {string} [chars=' '] The string used as padding.

     * @returns {string} Returns the padded string.

     * @example

     *

     * _.padEnd('abc', 6);

     * // => 'abc   '

     *

     * _.padEnd('abc', 6, '_-');

     * // => 'abc_-_'

     *

     * _.padEnd('abc', 3);

     * // => 'abc'

     */

    function padEnd(string, length, chars) {

      string = toString(string);

      length = toInteger(length);



      var strLength = length ? stringSize(string) : 0;

      return (length && strLength < length)

        ? (string + createPadding(length - strLength, chars))

        : string;

    }



    /**

     * Pads `string` on the left side if it's shorter than `length`. Padding

     * characters are truncated if they exceed `length`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category String

     * @param {string} [string=''] The string to pad.

     * @param {number} [length=0] The padding length.

     * @param {string} [chars=' '] The string used as padding.

     * @returns {string} Returns the padded string.

     * @example

     *

     * _.padStart('abc', 6);

     * // => '   abc'

     *

     * _.padStart('abc', 6, '_-');

     * // => '_-_abc'

     *

     * _.padStart('abc', 3);

     * // => 'abc'

     */

    function padStart(string, length, chars) {

      string = toString(string);

      length = toInteger(length);



      var strLength = length ? stringSize(string) : 0;

      return (length && strLength < length)

        ? (createPadding(length - strLength, chars) + string)

        : string;

    }



    /**

     * Converts `string` to an integer of the specified radix. If `radix` is

     * `undefined` or `0`, a `radix` of `10` is used unless `value` is a

     * hexadecimal, in which case a `radix` of `16` is used.

     *

     * **Note:** This method aligns with the

     * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.

     *

     * @static

     * @memberOf _

     * @since 1.1.0

     * @category String

     * @param {string} string The string to convert.

     * @param {number} [radix=10] The radix to interpret `value` by.

     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.

     * @returns {number} Returns the converted integer.

     * @example

     *

     * _.parseInt('08');

     * // => 8

     *

     * _.map(['6', '08', '10'], _.parseInt);

     * // => [6, 8, 10]

     */

    function parseInt(string, radix, guard) {

      if (guard || radix == null) {

        radix = 0;

      } else if (radix) {

        radix = +radix;

      }

      return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);

    }



    /**

     * Repeats the given string `n` times.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category String

     * @param {string} [string=''] The string to repeat.

     * @param {number} [n=1] The number of times to repeat the string.

     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.

     * @returns {string} Returns the repeated string.

     * @example

     *

     * _.repeat('*', 3);

     * // => '***'

     *

     * _.repeat('abc', 2);

     * // => 'abcabc'

     *

     * _.repeat('abc', 0);

     * // => ''

     */

    function repeat(string, n, guard) {

      if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {

        n = 1;

      } else {

        n = toInteger(n);

      }

      return baseRepeat(toString(string), n);

    }



    /**

     * Replaces matches for `pattern` in `string` with `replacement`.

     *

     * **Note:** This method is based on

     * [`String#replace`](https://mdn.io/String/replace).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category String

     * @param {string} [string=''] The string to modify.

     * @param {RegExp|string} pattern The pattern to replace.

     * @param {Function|string} replacement The match replacement.

     * @returns {string} Returns the modified string.

     * @example

     *

     * _.replace('Hi Fred', 'Fred', 'Barney');

     * // => 'Hi Barney'

     */

    function replace() {

      var args = arguments,

          string = toString(args[0]);



      return args.length < 3 ? string : string.replace(args[1], args[2]);

    }



    /**

     * Converts `string` to

     * [snake case](https://en.wikipedia.org/wiki/Snake_case).

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category String

     * @param {string} [string=''] The string to convert.

     * @returns {string} Returns the snake cased string.

     * @example

     *

     * _.snakeCase('Foo Bar');

     * // => 'foo_bar'

     *

     * _.snakeCase('fooBar');

     * // => 'foo_bar'

     *

     * _.snakeCase('--FOO-BAR--');

     * // => 'foo_bar'

     */

    var snakeCase = createCompounder(function(result, word, index) {

      return result + (index ? '_' : '') + word.toLowerCase();

    });



    /**

     * Splits `string` by `separator`.

     *

     * **Note:** This method is based on

     * [`String#split`](https://mdn.io/String/split).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category String

     * @param {string} [string=''] The string to split.

     * @param {RegExp|string} separator The separator pattern to split by.

     * @param {number} [limit] The length to truncate results to.

     * @returns {Array} Returns the string segments.

     * @example

     *

     * _.split('a-b-c', '-', 2);

     * // => ['a', 'b']

     */

    function split(string, separator, limit) {

      if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {

        separator = limit = undefined;

      }

      limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;

      if (!limit) {

        return [];

      }

      string = toString(string);

      if (string && (

            typeof separator == 'string' ||

            (separator != null && !isRegExp(separator))

          )) {

        separator = baseToString(separator);

        if (!separator && hasUnicode(string)) {

          return castSlice(stringToArray(string), 0, limit);

        }

      }

      return string.split(separator, limit);

    }



    /**

     * Converts `string` to

     * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).

     *

     * @static

     * @memberOf _

     * @since 3.1.0

     * @category String

     * @param {string} [string=''] The string to convert.

     * @returns {string} Returns the start cased string.

     * @example

     *

     * _.startCase('--foo-bar--');

     * // => 'Foo Bar'

     *

     * _.startCase('fooBar');

     * // => 'Foo Bar'

     *

     * _.startCase('__FOO_BAR__');

     * // => 'FOO BAR'

     */

    var startCase = createCompounder(function(result, word, index) {

      return result + (index ? ' ' : '') + upperFirst(word);

    });



    /**

     * Checks if `string` starts with the given target string.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category String

     * @param {string} [string=''] The string to inspect.

     * @param {string} [target] The string to search for.

     * @param {number} [position=0] The position to search from.

     * @returns {boolean} Returns `true` if `string` starts with `target`,

     *  else `false`.

     * @example

     *

     * _.startsWith('abc', 'a');

     * // => true

     *

     * _.startsWith('abc', 'b');

     * // => false

     *

     * _.startsWith('abc', 'b', 1);

     * // => true

     */

    function startsWith(string, target, position) {

      string = toString(string);

      position = position == null

        ? 0

        : baseClamp(toInteger(position), 0, string.length);



      target = baseToString(target);

      return string.slice(position, position + target.length) == target;

    }



    /**

     * Creates a compiled template function that can interpolate data properties

     * in "interpolate" delimiters, HTML-escape interpolated data properties in

     * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data

     * properties may be accessed as free variables in the template. If a setting

     * object is given, it takes precedence over `_.templateSettings` values.

     *

     * **Note:** In the development build `_.template` utilizes

     * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)

     * for easier debugging.

     *

     * For more information on precompiling templates see

     * [lodash's custom builds documentation](https://lodash.com/custom-builds).

     *

     * For more information on Chrome extension sandboxes see

     * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).

     *

     * @static

     * @since 0.1.0

     * @memberOf _

     * @category String

     * @param {string} [string=''] The template string.

     * @param {Object} [options={}] The options object.

     * @param {RegExp} [options.escape=_.templateSettings.escape]

     *  The HTML "escape" delimiter.

     * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]

     *  The "evaluate" delimiter.

     * @param {Object} [options.imports=_.templateSettings.imports]

     *  An object to import into the template as free variables.

     * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]

     *  The "interpolate" delimiter.

     * @param {string} [options.sourceURL='lodash.templateSources[n]']

     *  The sourceURL of the compiled template.

     * @param {string} [options.variable='obj']

     *  The data object variable name.

     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.

     * @returns {Function} Returns the compiled template function.

     * @example

     *

     * // Use the "interpolate" delimiter to create a compiled template.

     * var compiled = _.template('hello <%= user %>!');

     * compiled({ 'user': 'fred' });

     * // => 'hello fred!'

     *

     * // Use the HTML "escape" delimiter to escape data property values.

     * var compiled = _.template('<b><%- value %></b>');

     * compiled({ 'value': '<script>' });

     * // => '<b>&lt;script&gt;</b>'

     *

     * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.

     * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');

     * compiled({ 'users': ['fred', 'barney'] });

     * // => '<li>fred</li><li>barney</li>'

     *

     * // Use the internal `print` function in "evaluate" delimiters.

     * var compiled = _.template('<% print("hello " + user); %>!');

     * compiled({ 'user': 'barney' });

     * // => 'hello barney!'

     *

     * // Use the ES template literal delimiter as an "interpolate" delimiter.

     * // Disable support by replacing the "interpolate" delimiter.

     * var compiled = _.template('hello ${ user }!');

     * compiled({ 'user': 'pebbles' });

     * // => 'hello pebbles!'

     *

     * // Use backslashes to treat delimiters as plain text.

     * var compiled = _.template('<%= "\\<%- value %\\>" %>');

     * compiled({ 'value': 'ignored' });

     * // => '<%- value %>'

     *

     * // Use the `imports` option to import `jQuery` as `jq`.

     * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';

     * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });

     * compiled({ 'users': ['fred', 'barney'] });

     * // => '<li>fred</li><li>barney</li>'

     *

     * // Use the `sourceURL` option to specify a custom sourceURL for the template.

     * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });

     * compiled(data);

     * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.

     *

     * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.

     * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });

     * compiled.source;

     * // => function(data) {

     * //   var __t, __p = '';

     * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';

     * //   return __p;

     * // }

     *

     * // Use custom template delimiters.

     * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;

     * var compiled = _.template('hello {{ user }}!');

     * compiled({ 'user': 'mustache' });

     * // => 'hello mustache!'

     *

     * // Use the `source` property to inline compiled templates for meaningful

     * // line numbers in error messages and stack traces.

     * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\

     *   var JST = {\

     *     "main": ' + _.template(mainText).source + '\

     *   };\

     * ');

     */

    function template(string, options, guard) {

      // Based on John Resig's `tmpl` implementation

      // (http://ejohn.org/blog/javascript-micro-templating/)

      // and Laura Doktorova's doT.js (https://github.com/olado/doT).

      var settings = lodash.templateSettings;



      if (guard && isIterateeCall(string, options, guard)) {

        options = undefined;

      }

      string = toString(string);

      options = assignInWith({}, options, settings, customDefaultsAssignIn);



      var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn),

          importsKeys = keys(imports),

          importsValues = baseValues(imports, importsKeys);



      var isEscaping,

          isEvaluating,

          index = 0,

          interpolate = options.interpolate || reNoMatch,

          source = "__p += '";



      // Compile the regexp to match each delimiter.

      var reDelimiters = RegExp(

        (options.escape || reNoMatch).source + '|' +

        interpolate.source + '|' +

        (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +

        (options.evaluate || reNoMatch).source + '|$'

      , 'g');



      // Use a sourceURL for easier debugging.

      var sourceURL = '//# sourceURL=' +

        ('sourceURL' in options

          ? options.sourceURL

          : ('lodash.templateSources[' + (++templateCounter) + ']')

        ) + '\n';



      string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {

        interpolateValue || (interpolateValue = esTemplateValue);



        // Escape characters that can't be included in string literals.

        source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);



        // Replace delimiters with snippets.

        if (escapeValue) {

          isEscaping = true;

          source += "' +\n__e(" + escapeValue + ") +\n'";

        }

        if (evaluateValue) {

          isEvaluating = true;

          source += "';\n" + evaluateValue + ";\n__p += '";

        }

        if (interpolateValue) {

          source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";

        }

        index = offset + match.length;



        // The JS engine embedded in Adobe products needs `match` returned in

        // order to produce the correct `offset` value.

        return match;

      });



      source += "';\n";



      // If `variable` is not specified wrap a with-statement around the generated

      // code to add the data object to the top of the scope chain.

      var variable = options.variable;

      if (!variable) {

        source = 'with (obj) {\n' + source + '\n}\n';

      }

      // Cleanup code by stripping empty strings.

      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)

        .replace(reEmptyStringMiddle, '$1')

        .replace(reEmptyStringTrailing, '$1;');



      // Frame code as the function body.

      source = 'function(' + (variable || 'obj') + ') {\n' +

        (variable

          ? ''

          : 'obj || (obj = {});\n'

        ) +

        "var __t, __p = ''" +

        (isEscaping

           ? ', __e = _.escape'

           : ''

        ) +

        (isEvaluating

          ? ', __j = Array.prototype.join;\n' +

            "function print() { __p += __j.call(arguments, '') }\n"

          : ';\n'

        ) +

        source +

        'return __p\n}';



      var result = attempt(function() {

        return Function(importsKeys, sourceURL + 'return ' + source)

          .apply(undefined, importsValues);

      });



      // Provide the compiled function's source by its `toString` method or

      // the `source` property as a convenience for inlining compiled templates.

      result.source = source;

      if (isError(result)) {

        throw result;

      }

      return result;

    }



    /**

     * Converts `string`, as a whole, to lower case just like

     * [String#toLowerCase](https://mdn.io/toLowerCase).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category String

     * @param {string} [string=''] The string to convert.

     * @returns {string} Returns the lower cased string.

     * @example

     *

     * _.toLower('--Foo-Bar--');

     * // => '--foo-bar--'

     *

     * _.toLower('fooBar');

     * // => 'foobar'

     *

     * _.toLower('__FOO_BAR__');

     * // => '__foo_bar__'

     */

    function toLower(value) {

      return toString(value).toLowerCase();

    }



    /**

     * Converts `string`, as a whole, to upper case just like

     * [String#toUpperCase](https://mdn.io/toUpperCase).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category String

     * @param {string} [string=''] The string to convert.

     * @returns {string} Returns the upper cased string.

     * @example

     *

     * _.toUpper('--foo-bar--');

     * // => '--FOO-BAR--'

     *

     * _.toUpper('fooBar');

     * // => 'FOOBAR'

     *

     * _.toUpper('__foo_bar__');

     * // => '__FOO_BAR__'

     */

    function toUpper(value) {

      return toString(value).toUpperCase();

    }



    /**

     * Removes leading and trailing whitespace or specified characters from `string`.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category String

     * @param {string} [string=''] The string to trim.

     * @param {string} [chars=whitespace] The characters to trim.

     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.

     * @returns {string} Returns the trimmed string.

     * @example

     *

     * _.trim('  abc  ');

     * // => 'abc'

     *

     * _.trim('-_-abc-_-', '_-');

     * // => 'abc'

     *

     * _.map(['  foo  ', '  bar  '], _.trim);

     * // => ['foo', 'bar']

     */

    function trim(string, chars, guard) {

      string = toString(string);

      if (string && (guard || chars === undefined)) {

        return string.replace(reTrim, '');

      }

      if (!string || !(chars = baseToString(chars))) {

        return string;

      }

      var strSymbols = stringToArray(string),

          chrSymbols = stringToArray(chars),

          start = charsStartIndex(strSymbols, chrSymbols),

          end = charsEndIndex(strSymbols, chrSymbols) + 1;



      return castSlice(strSymbols, start, end).join('');

    }



    /**

     * Removes trailing whitespace or specified characters from `string`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category String

     * @param {string} [string=''] The string to trim.

     * @param {string} [chars=whitespace] The characters to trim.

     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.

     * @returns {string} Returns the trimmed string.

     * @example

     *

     * _.trimEnd('  abc  ');

     * // => '  abc'

     *

     * _.trimEnd('-_-abc-_-', '_-');

     * // => '-_-abc'

     */

    function trimEnd(string, chars, guard) {

      string = toString(string);

      if (string && (guard || chars === undefined)) {

        return string.replace(reTrimEnd, '');

      }

      if (!string || !(chars = baseToString(chars))) {

        return string;

      }

      var strSymbols = stringToArray(string),

          end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;



      return castSlice(strSymbols, 0, end).join('');

    }



    /**

     * Removes leading whitespace or specified characters from `string`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category String

     * @param {string} [string=''] The string to trim.

     * @param {string} [chars=whitespace] The characters to trim.

     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.

     * @returns {string} Returns the trimmed string.

     * @example

     *

     * _.trimStart('  abc  ');

     * // => 'abc  '

     *

     * _.trimStart('-_-abc-_-', '_-');

     * // => 'abc-_-'

     */

    function trimStart(string, chars, guard) {

      string = toString(string);

      if (string && (guard || chars === undefined)) {

        return string.replace(reTrimStart, '');

      }

      if (!string || !(chars = baseToString(chars))) {

        return string;

      }

      var strSymbols = stringToArray(string),

          start = charsStartIndex(strSymbols, stringToArray(chars));



      return castSlice(strSymbols, start).join('');

    }



    /**

     * Truncates `string` if it's longer than the given maximum string length.

     * The last characters of the truncated string are replaced with the omission

     * string which defaults to "...".

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category String

     * @param {string} [string=''] The string to truncate.

     * @param {Object} [options={}] The options object.

     * @param {number} [options.length=30] The maximum string length.

     * @param {string} [options.omission='...'] The string to indicate text is omitted.

     * @param {RegExp|string} [options.separator] The separator pattern to truncate to.

     * @returns {string} Returns the truncated string.

     * @example

     *

     * _.truncate('hi-diddly-ho there, neighborino');

     * // => 'hi-diddly-ho there, neighbo...'

     *

     * _.truncate('hi-diddly-ho there, neighborino', {

     *   'length': 24,

     *   'separator': ' '

     * });

     * // => 'hi-diddly-ho there,...'

     *

     * _.truncate('hi-diddly-ho there, neighborino', {

     *   'length': 24,

     *   'separator': /,? +/

     * });

     * // => 'hi-diddly-ho there...'

     *

     * _.truncate('hi-diddly-ho there, neighborino', {

     *   'omission': ' [...]'

     * });

     * // => 'hi-diddly-ho there, neig [...]'

     */

    function truncate(string, options) {

      var length = DEFAULT_TRUNC_LENGTH,

          omission = DEFAULT_TRUNC_OMISSION;



      if (isObject(options)) {

        var separator = 'separator' in options ? options.separator : separator;

        length = 'length' in options ? toInteger(options.length) : length;

        omission = 'omission' in options ? baseToString(options.omission) : omission;

      }

      string = toString(string);



      var strLength = string.length;

      if (hasUnicode(string)) {

        var strSymbols = stringToArray(string);

        strLength = strSymbols.length;

      }

      if (length >= strLength) {

        return string;

      }

      var end = length - stringSize(omission);

      if (end < 1) {

        return omission;

      }

      var result = strSymbols

        ? castSlice(strSymbols, 0, end).join('')

        : string.slice(0, end);



      if (separator === undefined) {

        return result + omission;

      }

      if (strSymbols) {

        end += (result.length - end);

      }

      if (isRegExp(separator)) {

        if (string.slice(end).search(separator)) {

          var match,

              substring = result;



          if (!separator.global) {

            separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');

          }

          separator.lastIndex = 0;

          while ((match = separator.exec(substring))) {

            var newEnd = match.index;

          }

          result = result.slice(0, newEnd === undefined ? end : newEnd);

        }

      } else if (string.indexOf(baseToString(separator), end) != end) {

        var index = result.lastIndexOf(separator);

        if (index > -1) {

          result = result.slice(0, index);

        }

      }

      return result + omission;

    }



    /**

     * The inverse of `_.escape`; this method converts the HTML entities

     * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to

     * their corresponding characters.

     *

     * **Note:** No other HTML entities are unescaped. To unescape additional

     * HTML entities use a third-party library like [_he_](https://mths.be/he).

     *

     * @static

     * @memberOf _

     * @since 0.6.0

     * @category String

     * @param {string} [string=''] The string to unescape.

     * @returns {string} Returns the unescaped string.

     * @example

     *

     * _.unescape('fred, barney, &amp; pebbles');

     * // => 'fred, barney, & pebbles'

     */

    function unescape(string) {

      string = toString(string);

      return (string && reHasEscapedHtml.test(string))

        ? string.replace(reEscapedHtml, unescapeHtmlChar)

        : string;

    }



    /**

     * Converts `string`, as space separated words, to upper case.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category String

     * @param {string} [string=''] The string to convert.

     * @returns {string} Returns the upper cased string.

     * @example

     *

     * _.upperCase('--foo-bar');

     * // => 'FOO BAR'

     *

     * _.upperCase('fooBar');

     * // => 'FOO BAR'

     *

     * _.upperCase('__foo_bar__');

     * // => 'FOO BAR'

     */

    var upperCase = createCompounder(function(result, word, index) {

      return result + (index ? ' ' : '') + word.toUpperCase();

    });



    /**

     * Converts the first character of `string` to upper case.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category String

     * @param {string} [string=''] The string to convert.

     * @returns {string} Returns the converted string.

     * @example

     *

     * _.upperFirst('fred');

     * // => 'Fred'

     *

     * _.upperFirst('FRED');

     * // => 'FRED'

     */

    var upperFirst = createCaseFirst('toUpperCase');



    /**

     * Splits `string` into an array of its words.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category String

     * @param {string} [string=''] The string to inspect.

     * @param {RegExp|string} [pattern] The pattern to match words.

     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.

     * @returns {Array} Returns the words of `string`.

     * @example

     *

     * _.words('fred, barney, & pebbles');

     * // => ['fred', 'barney', 'pebbles']

     *

     * _.words('fred, barney, & pebbles', /[^, ]+/g);

     * // => ['fred', 'barney', '&', 'pebbles']

     */

    function words(string, pattern, guard) {

      string = toString(string);

      pattern = guard ? undefined : pattern;



      if (pattern === undefined) {

        return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);

      }

      return string.match(pattern) || [];

    }



    /*------------------------------------------------------------------------*/



    /**

     * Attempts to invoke `func`, returning either the result or the caught error

     * object. Any additional arguments are provided to `func` when it's invoked.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Util

     * @param {Function} func The function to attempt.

     * @param {...*} [args] The arguments to invoke `func` with.

     * @returns {*} Returns the `func` result or error object.

     * @example

     *

     * // Avoid throwing errors for invalid selectors.

     * var elements = _.attempt(function(selector) {

     *   return document.querySelectorAll(selector);

     * }, '>_>');

     *

     * if (_.isError(elements)) {

     *   elements = [];

     * }

     */

    var attempt = baseRest(function(func, args) {

      try {

        return apply(func, undefined, args);

      } catch (e) {

        return isError(e) ? e : new Error(e);

      }

    });



    /**

     * Binds methods of an object to the object itself, overwriting the existing

     * method.

     *

     * **Note:** This method doesn't set the "length" property of bound functions.

     *

     * @static

     * @since 0.1.0

     * @memberOf _

     * @category Util

     * @param {Object} object The object to bind and assign the bound methods to.

     * @param {...(string|string[])} methodNames The object method names to bind.

     * @returns {Object} Returns `object`.

     * @example

     *

     * var view = {

     *   'label': 'docs',

     *   'click': function() {

     *     console.log('clicked ' + this.label);

     *   }

     * };

     *

     * _.bindAll(view, ['click']);

     * jQuery(element).on('click', view.click);

     * // => Logs 'clicked docs' when clicked.

     */

    var bindAll = flatRest(function(object, methodNames) {

      arrayEach(methodNames, function(key) {

        key = toKey(key);

        baseAssignValue(object, key, bind(object[key], object));

      });

      return object;

    });



    /**

     * Creates a function that iterates over `pairs` and invokes the corresponding

     * function of the first predicate to return truthy. The predicate-function

     * pairs are invoked with the `this` binding and arguments of the created

     * function.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Util

     * @param {Array} pairs The predicate-function pairs.

     * @returns {Function} Returns the new composite function.

     * @example

     *

     * var func = _.cond([

     *   [_.matches({ 'a': 1 }),           _.constant('matches A')],

     *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],

     *   [_.stubTrue,                      _.constant('no match')]

     * ]);

     *

     * func({ 'a': 1, 'b': 2 });

     * // => 'matches A'

     *

     * func({ 'a': 0, 'b': 1 });

     * // => 'matches B'

     *

     * func({ 'a': '1', 'b': '2' });

     * // => 'no match'

     */

    function cond(pairs) {

      var length = pairs == null ? 0 : pairs.length,

          toIteratee = getIteratee();



      pairs = !length ? [] : arrayMap(pairs, function(pair) {

        if (typeof pair[1] != 'function') {

          throw new TypeError(FUNC_ERROR_TEXT);

        }

        return [toIteratee(pair[0]), pair[1]];

      });



      return baseRest(function(args) {

        var index = -1;

        while (++index < length) {

          var pair = pairs[index];

          if (apply(pair[0], this, args)) {

            return apply(pair[1], this, args);

          }

        }

      });

    }



    /**

     * Creates a function that invokes the predicate properties of `source` with

     * the corresponding property values of a given object, returning `true` if

     * all predicates return truthy, else `false`.

     *

     * **Note:** The created function is equivalent to `_.conformsTo` with

     * `source` partially applied.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Util

     * @param {Object} source The object of property predicates to conform to.

     * @returns {Function} Returns the new spec function.

     * @example

     *

     * var objects = [

     *   { 'a': 2, 'b': 1 },

     *   { 'a': 1, 'b': 2 }

     * ];

     *

     * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));

     * // => [{ 'a': 1, 'b': 2 }]

     */

    function conforms(source) {

      return baseConforms(baseClone(source, CLONE_DEEP_FLAG));

    }



    /**

     * Creates a function that returns `value`.

     *

     * @static

     * @memberOf _

     * @since 2.4.0

     * @category Util

     * @param {*} value The value to return from the new function.

     * @returns {Function} Returns the new constant function.

     * @example

     *

     * var objects = _.times(2, _.constant({ 'a': 1 }));

     *

     * console.log(objects);

     * // => [{ 'a': 1 }, { 'a': 1 }]

     *

     * console.log(objects[0] === objects[1]);

     * // => true

     */

    function constant(value) {

      return function() {

        return value;

      };

    }



    /**

     * Checks `value` to determine whether a default value should be returned in

     * its place. The `defaultValue` is returned if `value` is `NaN`, `null`,

     * or `undefined`.

     *

     * @static

     * @memberOf _

     * @since 4.14.0

     * @category Util

     * @param {*} value The value to check.

     * @param {*} defaultValue The default value.

     * @returns {*} Returns the resolved value.

     * @example

     *

     * _.defaultTo(1, 10);

     * // => 1

     *

     * _.defaultTo(undefined, 10);

     * // => 10

     */

    function defaultTo(value, defaultValue) {

      return (value == null || value !== value) ? defaultValue : value;

    }



    /**

     * Creates a function that returns the result of invoking the given functions

     * with the `this` binding of the created function, where each successive

     * invocation is supplied the return value of the previous.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Util

     * @param {...(Function|Function[])} [funcs] The functions to invoke.

     * @returns {Function} Returns the new composite function.

     * @see _.flowRight

     * @example

     *

     * function square(n) {

     *   return n * n;

     * }

     *

     * var addSquare = _.flow([_.add, square]);

     * addSquare(1, 2);

     * // => 9

     */

    var flow = createFlow();



    /**

     * This method is like `_.flow` except that it creates a function that

     * invokes the given functions from right to left.

     *

     * @static

     * @since 3.0.0

     * @memberOf _

     * @category Util

     * @param {...(Function|Function[])} [funcs] The functions to invoke.

     * @returns {Function} Returns the new composite function.

     * @see _.flow

     * @example

     *

     * function square(n) {

     *   return n * n;

     * }

     *

     * var addSquare = _.flowRight([square, _.add]);

     * addSquare(1, 2);

     * // => 9

     */

    var flowRight = createFlow(true);



    /**

     * This method returns the first argument it receives.

     *

     * @static

     * @since 0.1.0

     * @memberOf _

     * @category Util

     * @param {*} value Any value.

     * @returns {*} Returns `value`.

     * @example

     *

     * var object = { 'a': 1 };

     *

     * console.log(_.identity(object) === object);

     * // => true

     */

    function identity(value) {

      return value;

    }



    /**

     * Creates a function that invokes `func` with the arguments of the created

     * function. If `func` is a property name, the created function returns the

     * property value for a given element. If `func` is an array or object, the

     * created function returns `true` for elements that contain the equivalent

     * source properties, otherwise it returns `false`.

     *

     * @static

     * @since 4.0.0

     * @memberOf _

     * @category Util

     * @param {*} [func=_.identity] The value to convert to a callback.

     * @returns {Function} Returns the callback.

     * @example

     *

     * var users = [

     *   { 'user': 'barney', 'age': 36, 'active': true },

     *   { 'user': 'fred',   'age': 40, 'active': false }

     * ];

     *

     * // The `_.matches` iteratee shorthand.

     * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));

     * // => [{ 'user': 'barney', 'age': 36, 'active': true }]

     *

     * // The `_.matchesProperty` iteratee shorthand.

     * _.filter(users, _.iteratee(['user', 'fred']));

     * // => [{ 'user': 'fred', 'age': 40 }]

     *

     * // The `_.property` iteratee shorthand.

     * _.map(users, _.iteratee('user'));

     * // => ['barney', 'fred']

     *

     * // Create custom iteratee shorthands.

     * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {

     *   return !_.isRegExp(func) ? iteratee(func) : function(string) {

     *     return func.test(string);

     *   };

     * });

     *

     * _.filter(['abc', 'def'], /ef/);

     * // => ['def']

     */

    function iteratee(func) {

      return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));

    }



    /**

     * Creates a function that performs a partial deep comparison between a given

     * object and `source`, returning `true` if the given object has equivalent

     * property values, else `false`.

     *

     * **Note:** The created function is equivalent to `_.isMatch` with `source`

     * partially applied.

     *

     * Partial comparisons will match empty array and empty object `source`

     * values against any array or object value, respectively. See `_.isEqual`

     * for a list of supported value comparisons.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Util

     * @param {Object} source The object of property values to match.

     * @returns {Function} Returns the new spec function.

     * @example

     *

     * var objects = [

     *   { 'a': 1, 'b': 2, 'c': 3 },

     *   { 'a': 4, 'b': 5, 'c': 6 }

     * ];

     *

     * _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));

     * // => [{ 'a': 4, 'b': 5, 'c': 6 }]

     */

    function matches(source) {

      return baseMatches(baseClone(source, CLONE_DEEP_FLAG));

    }



    /**

     * Creates a function that performs a partial deep comparison between the

     * value at `path` of a given object to `srcValue`, returning `true` if the

     * object value is equivalent, else `false`.

     *

     * **Note:** Partial comparisons will match empty array and empty object

     * `srcValue` values against any array or object value, respectively. See

     * `_.isEqual` for a list of supported value comparisons.

     *

     * @static

     * @memberOf _

     * @since 3.2.0

     * @category Util

     * @param {Array|string} path The path of the property to get.

     * @param {*} srcValue The value to match.

     * @returns {Function} Returns the new spec function.

     * @example

     *

     * var objects = [

     *   { 'a': 1, 'b': 2, 'c': 3 },

     *   { 'a': 4, 'b': 5, 'c': 6 }

     * ];

     *

     * _.find(objects, _.matchesProperty('a', 4));

     * // => { 'a': 4, 'b': 5, 'c': 6 }

     */

    function matchesProperty(path, srcValue) {

      return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));

    }



    /**

     * Creates a function that invokes the method at `path` of a given object.

     * Any additional arguments are provided to the invoked method.

     *

     * @static

     * @memberOf _

     * @since 3.7.0

     * @category Util

     * @param {Array|string} path The path of the method to invoke.

     * @param {...*} [args] The arguments to invoke the method with.

     * @returns {Function} Returns the new invoker function.

     * @example

     *

     * var objects = [

     *   { 'a': { 'b': _.constant(2) } },

     *   { 'a': { 'b': _.constant(1) } }

     * ];

     *

     * _.map(objects, _.method('a.b'));

     * // => [2, 1]

     *

     * _.map(objects, _.method(['a', 'b']));

     * // => [2, 1]

     */

    var method = baseRest(function(path, args) {

      return function(object) {

        return baseInvoke(object, path, args);

      };

    });



    /**

     * The opposite of `_.method`; this method creates a function that invokes

     * the method at a given path of `object`. Any additional arguments are

     * provided to the invoked method.

     *

     * @static

     * @memberOf _

     * @since 3.7.0

     * @category Util

     * @param {Object} object The object to query.

     * @param {...*} [args] The arguments to invoke the method with.

     * @returns {Function} Returns the new invoker function.

     * @example

     *

     * var array = _.times(3, _.constant),

     *     object = { 'a': array, 'b': array, 'c': array };

     *

     * _.map(['a[2]', 'c[0]'], _.methodOf(object));

     * // => [2, 0]

     *

     * _.map([['a', '2'], ['c', '0']], _.methodOf(object));

     * // => [2, 0]

     */

    var methodOf = baseRest(function(object, args) {

      return function(path) {

        return baseInvoke(object, path, args);

      };

    });



    /**

     * Adds all own enumerable string keyed function properties of a source

     * object to the destination object. If `object` is a function, then methods

     * are added to its prototype as well.

     *

     * **Note:** Use `_.runInContext` to create a pristine `lodash` function to

     * avoid conflicts caused by modifying the original.

     *

     * @static

     * @since 0.1.0

     * @memberOf _

     * @category Util

     * @param {Function|Object} [object=lodash] The destination object.

     * @param {Object} source The object of functions to add.

     * @param {Object} [options={}] The options object.

     * @param {boolean} [options.chain=true] Specify whether mixins are chainable.

     * @returns {Function|Object} Returns `object`.

     * @example

     *

     * function vowels(string) {

     *   return _.filter(string, function(v) {

     *     return /[aeiou]/i.test(v);

     *   });

     * }

     *

     * _.mixin({ 'vowels': vowels });

     * _.vowels('fred');

     * // => ['e']

     *

     * _('fred').vowels().value();

     * // => ['e']

     *

     * _.mixin({ 'vowels': vowels }, { 'chain': false });

     * _('fred').vowels();

     * // => ['e']

     */

    function mixin(object, source, options) {

      var props = keys(source),

          methodNames = baseFunctions(source, props);



      if (options == null &&

          !(isObject(source) && (methodNames.length || !props.length))) {

        options = source;

        source = object;

        object = this;

        methodNames = baseFunctions(source, keys(source));

      }

      var chain = !(isObject(options) && 'chain' in options) || !!options.chain,

          isFunc = isFunction(object);



      arrayEach(methodNames, function(methodName) {

        var func = source[methodName];

        object[methodName] = func;

        if (isFunc) {

          object.prototype[methodName] = function() {

            var chainAll = this.__chain__;

            if (chain || chainAll) {

              var result = object(this.__wrapped__),

                  actions = result.__actions__ = copyArray(this.__actions__);



              actions.push({ 'func': func, 'args': arguments, 'thisArg': object });

              result.__chain__ = chainAll;

              return result;

            }

            return func.apply(object, arrayPush([this.value()], arguments));

          };

        }

      });



      return object;

    }



    /**

     * Reverts the `_` variable to its previous value and returns a reference to

     * the `lodash` function.

     *

     * @static

     * @since 0.1.0

     * @memberOf _

     * @category Util

     * @returns {Function} Returns the `lodash` function.

     * @example

     *

     * var lodash = _.noConflict();

     */

    function noConflict() {

      if (root._ === this) {

        root._ = oldDash;

      }

      return this;

    }



    /**

     * This method returns `undefined`.

     *

     * @static

     * @memberOf _

     * @since 2.3.0

     * @category Util

     * @example

     *

     * _.times(2, _.noop);

     * // => [undefined, undefined]

     */

    function noop() {

      // No operation performed.

    }



    /**

     * Creates a function that gets the argument at index `n`. If `n` is negative,

     * the nth argument from the end is returned.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Util

     * @param {number} [n=0] The index of the argument to return.

     * @returns {Function} Returns the new pass-thru function.

     * @example

     *

     * var func = _.nthArg(1);

     * func('a', 'b', 'c', 'd');

     * // => 'b'

     *

     * var func = _.nthArg(-2);

     * func('a', 'b', 'c', 'd');

     * // => 'c'

     */

    function nthArg(n) {

      n = toInteger(n);

      return baseRest(function(args) {

        return baseNth(args, n);

      });

    }



    /**

     * Creates a function that invokes `iteratees` with the arguments it receives

     * and returns their results.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Util

     * @param {...(Function|Function[])} [iteratees=[_.identity]]

     *  The iteratees to invoke.

     * @returns {Function} Returns the new function.

     * @example

     *

     * var func = _.over([Math.max, Math.min]);

     *

     * func(1, 2, 3, 4);

     * // => [4, 1]

     */

    var over = createOver(arrayMap);



    /**

     * Creates a function that checks if **all** of the `predicates` return

     * truthy when invoked with the arguments it receives.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Util

     * @param {...(Function|Function[])} [predicates=[_.identity]]

     *  The predicates to check.

     * @returns {Function} Returns the new function.

     * @example

     *

     * var func = _.overEvery([Boolean, isFinite]);

     *

     * func('1');

     * // => true

     *

     * func(null);

     * // => false

     *

     * func(NaN);

     * // => false

     */

    var overEvery = createOver(arrayEvery);



    /**

     * Creates a function that checks if **any** of the `predicates` return

     * truthy when invoked with the arguments it receives.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Util

     * @param {...(Function|Function[])} [predicates=[_.identity]]

     *  The predicates to check.

     * @returns {Function} Returns the new function.

     * @example

     *

     * var func = _.overSome([Boolean, isFinite]);

     *

     * func('1');

     * // => true

     *

     * func(null);

     * // => true

     *

     * func(NaN);

     * // => false

     */

    var overSome = createOver(arraySome);



    /**

     * Creates a function that returns the value at `path` of a given object.

     *

     * @static

     * @memberOf _

     * @since 2.4.0

     * @category Util

     * @param {Array|string} path The path of the property to get.

     * @returns {Function} Returns the new accessor function.

     * @example

     *

     * var objects = [

     *   { 'a': { 'b': 2 } },

     *   { 'a': { 'b': 1 } }

     * ];

     *

     * _.map(objects, _.property('a.b'));

     * // => [2, 1]

     *

     * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');

     * // => [1, 2]

     */

    function property(path) {

      return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);

    }



    /**

     * The opposite of `_.property`; this method creates a function that returns

     * the value at a given path of `object`.

     *

     * @static

     * @memberOf _

     * @since 3.0.0

     * @category Util

     * @param {Object} object The object to query.

     * @returns {Function} Returns the new accessor function.

     * @example

     *

     * var array = [0, 1, 2],

     *     object = { 'a': array, 'b': array, 'c': array };

     *

     * _.map(['a[2]', 'c[0]'], _.propertyOf(object));

     * // => [2, 0]

     *

     * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));

     * // => [2, 0]

     */

    function propertyOf(object) {

      return function(path) {

        return object == null ? undefined : baseGet(object, path);

      };

    }



    /**

     * Creates an array of numbers (positive and/or negative) progressing from

     * `start` up to, but not including, `end`. A step of `-1` is used if a negative

     * `start` is specified without an `end` or `step`. If `end` is not specified,

     * it's set to `start` with `start` then set to `0`.

     *

     * **Note:** JavaScript follows the IEEE-754 standard for resolving

     * floating-point values which can produce unexpected results.

     *

     * @static

     * @since 0.1.0

     * @memberOf _

     * @category Util

     * @param {number} [start=0] The start of the range.

     * @param {number} end The end of the range.

     * @param {number} [step=1] The value to increment or decrement by.

     * @returns {Array} Returns the range of numbers.

     * @see _.inRange, _.rangeRight

     * @example

     *

     * _.range(4);

     * // => [0, 1, 2, 3]

     *

     * _.range(-4);

     * // => [0, -1, -2, -3]

     *

     * _.range(1, 5);

     * // => [1, 2, 3, 4]

     *

     * _.range(0, 20, 5);

     * // => [0, 5, 10, 15]

     *

     * _.range(0, -4, -1);

     * // => [0, -1, -2, -3]

     *

     * _.range(1, 4, 0);

     * // => [1, 1, 1]

     *

     * _.range(0);

     * // => []

     */

    var range = createRange();



    /**

     * This method is like `_.range` except that it populates values in

     * descending order.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Util

     * @param {number} [start=0] The start of the range.

     * @param {number} end The end of the range.

     * @param {number} [step=1] The value to increment or decrement by.

     * @returns {Array} Returns the range of numbers.

     * @see _.inRange, _.range

     * @example

     *

     * _.rangeRight(4);

     * // => [3, 2, 1, 0]

     *

     * _.rangeRight(-4);

     * // => [-3, -2, -1, 0]

     *

     * _.rangeRight(1, 5);

     * // => [4, 3, 2, 1]

     *

     * _.rangeRight(0, 20, 5);

     * // => [15, 10, 5, 0]

     *

     * _.rangeRight(0, -4, -1);

     * // => [-3, -2, -1, 0]

     *

     * _.rangeRight(1, 4, 0);

     * // => [1, 1, 1]

     *

     * _.rangeRight(0);

     * // => []

     */

    var rangeRight = createRange(true);



    /**

     * This method returns a new empty array.

     *

     * @static

     * @memberOf _

     * @since 4.13.0

     * @category Util

     * @returns {Array} Returns the new empty array.

     * @example

     *

     * var arrays = _.times(2, _.stubArray);

     *

     * console.log(arrays);

     * // => [[], []]

     *

     * console.log(arrays[0] === arrays[1]);

     * // => false

     */

    function stubArray() {

      return [];

    }



    /**

     * This method returns `false`.

     *

     * @static

     * @memberOf _

     * @since 4.13.0

     * @category Util

     * @returns {boolean} Returns `false`.

     * @example

     *

     * _.times(2, _.stubFalse);

     * // => [false, false]

     */

    function stubFalse() {

      return false;

    }



    /**

     * This method returns a new empty object.

     *

     * @static

     * @memberOf _

     * @since 4.13.0

     * @category Util

     * @returns {Object} Returns the new empty object.

     * @example

     *

     * var objects = _.times(2, _.stubObject);

     *

     * console.log(objects);

     * // => [{}, {}]

     *

     * console.log(objects[0] === objects[1]);

     * // => false

     */

    function stubObject() {

      return {};

    }



    /**

     * This method returns an empty string.

     *

     * @static

     * @memberOf _

     * @since 4.13.0

     * @category Util

     * @returns {string} Returns the empty string.

     * @example

     *

     * _.times(2, _.stubString);

     * // => ['', '']

     */

    function stubString() {

      return '';

    }



    /**

     * This method returns `true`.

     *

     * @static

     * @memberOf _

     * @since 4.13.0

     * @category Util

     * @returns {boolean} Returns `true`.

     * @example

     *

     * _.times(2, _.stubTrue);

     * // => [true, true]

     */

    function stubTrue() {

      return true;

    }



    /**

     * Invokes the iteratee `n` times, returning an array of the results of

     * each invocation. The iteratee is invoked with one argument; (index).

     *

     * @static

     * @since 0.1.0

     * @memberOf _

     * @category Util

     * @param {number} n The number of times to invoke `iteratee`.

     * @param {Function} [iteratee=_.identity] The function invoked per iteration.

     * @returns {Array} Returns the array of results.

     * @example

     *

     * _.times(3, String);

     * // => ['0', '1', '2']

     *

     *  _.times(4, _.constant(0));

     * // => [0, 0, 0, 0]

     */

    function times(n, iteratee) {

      n = toInteger(n);

      if (n < 1 || n > MAX_SAFE_INTEGER) {

        return [];

      }

      var index = MAX_ARRAY_LENGTH,

          length = nativeMin(n, MAX_ARRAY_LENGTH);



      iteratee = getIteratee(iteratee);

      n -= MAX_ARRAY_LENGTH;



      var result = baseTimes(length, iteratee);

      while (++index < n) {

        iteratee(index);

      }

      return result;

    }



    /**

     * Converts `value` to a property path array.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Util

     * @param {*} value The value to convert.

     * @returns {Array} Returns the new property path array.

     * @example

     *

     * _.toPath('a.b.c');

     * // => ['a', 'b', 'c']

     *

     * _.toPath('a[0].b.c');

     * // => ['a', '0', 'b', 'c']

     */

    function toPath(value) {

      if (isArray(value)) {

        return arrayMap(value, toKey);

      }

      return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));

    }



    /**

     * Generates a unique ID. If `prefix` is given, the ID is appended to it.

     *

     * @static

     * @since 0.1.0

     * @memberOf _

     * @category Util

     * @param {string} [prefix=''] The value to prefix the ID with.

     * @returns {string} Returns the unique ID.

     * @example

     *

     * _.uniqueId('contact_');

     * // => 'contact_104'

     *

     * _.uniqueId();

     * // => '105'

     */

    function uniqueId(prefix) {

      var id = ++idCounter;

      return toString(prefix) + id;

    }



    /*------------------------------------------------------------------------*/



    /**

     * Adds two numbers.

     *

     * @static

     * @memberOf _

     * @since 3.4.0

     * @category Math

     * @param {number} augend The first number in an addition.

     * @param {number} addend The second number in an addition.

     * @returns {number} Returns the total.

     * @example

     *

     * _.add(6, 4);

     * // => 10

     */

    var add = createMathOperation(function(augend, addend) {

      return augend + addend;

    }, 0);



    /**

     * Computes `number` rounded up to `precision`.

     *

     * @static

     * @memberOf _

     * @since 3.10.0

     * @category Math

     * @param {number} number The number to round up.

     * @param {number} [precision=0] The precision to round up to.

     * @returns {number} Returns the rounded up number.

     * @example

     *

     * _.ceil(4.006);

     * // => 5

     *

     * _.ceil(6.004, 2);

     * // => 6.01

     *

     * _.ceil(6040, -2);

     * // => 6100

     */

    var ceil = createRound('ceil');



    /**

     * Divide two numbers.

     *

     * @static

     * @memberOf _

     * @since 4.7.0

     * @category Math

     * @param {number} dividend The first number in a division.

     * @param {number} divisor The second number in a division.

     * @returns {number} Returns the quotient.

     * @example

     *

     * _.divide(6, 4);

     * // => 1.5

     */

    var divide = createMathOperation(function(dividend, divisor) {

      return dividend / divisor;

    }, 1);



    /**

     * Computes `number` rounded down to `precision`.

     *

     * @static

     * @memberOf _

     * @since 3.10.0

     * @category Math

     * @param {number} number The number to round down.

     * @param {number} [precision=0] The precision to round down to.

     * @returns {number} Returns the rounded down number.

     * @example

     *

     * _.floor(4.006);

     * // => 4

     *

     * _.floor(0.046, 2);

     * // => 0.04

     *

     * _.floor(4060, -2);

     * // => 4000

     */

    var floor = createRound('floor');



    /**

     * Computes the maximum value of `array`. If `array` is empty or falsey,

     * `undefined` is returned.

     *

     * @static

     * @since 0.1.0

     * @memberOf _

     * @category Math

     * @param {Array} array The array to iterate over.

     * @returns {*} Returns the maximum value.

     * @example

     *

     * _.max([4, 2, 8, 6]);

     * // => 8

     *

     * _.max([]);

     * // => undefined

     */

    function max(array) {

      return (array && array.length)

        ? baseExtremum(array, identity, baseGt)

        : undefined;

    }



    /**

     * This method is like `_.max` except that it accepts `iteratee` which is

     * invoked for each element in `array` to generate the criterion by which

     * the value is ranked. The iteratee is invoked with one argument: (value).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Math

     * @param {Array} array The array to iterate over.

     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.

     * @returns {*} Returns the maximum value.

     * @example

     *

     * var objects = [{ 'n': 1 }, { 'n': 2 }];

     *

     * _.maxBy(objects, function(o) { return o.n; });

     * // => { 'n': 2 }

     *

     * // The `_.property` iteratee shorthand.

     * _.maxBy(objects, 'n');

     * // => { 'n': 2 }

     */

    function maxBy(array, iteratee) {

      return (array && array.length)

        ? baseExtremum(array, getIteratee(iteratee, 2), baseGt)

        : undefined;

    }



    /**

     * Computes the mean of the values in `array`.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Math

     * @param {Array} array The array to iterate over.

     * @returns {number} Returns the mean.

     * @example

     *

     * _.mean([4, 2, 8, 6]);

     * // => 5

     */

    function mean(array) {

      return baseMean(array, identity);

    }



    /**

     * This method is like `_.mean` except that it accepts `iteratee` which is

     * invoked for each element in `array` to generate the value to be averaged.

     * The iteratee is invoked with one argument: (value).

     *

     * @static

     * @memberOf _

     * @since 4.7.0

     * @category Math

     * @param {Array} array The array to iterate over.

     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.

     * @returns {number} Returns the mean.

     * @example

     *

     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];

     *

     * _.meanBy(objects, function(o) { return o.n; });

     * // => 5

     *

     * // The `_.property` iteratee shorthand.

     * _.meanBy(objects, 'n');

     * // => 5

     */

    function meanBy(array, iteratee) {

      return baseMean(array, getIteratee(iteratee, 2));

    }



    /**

     * Computes the minimum value of `array`. If `array` is empty or falsey,

     * `undefined` is returned.

     *

     * @static

     * @since 0.1.0

     * @memberOf _

     * @category Math

     * @param {Array} array The array to iterate over.

     * @returns {*} Returns the minimum value.

     * @example

     *

     * _.min([4, 2, 8, 6]);

     * // => 2

     *

     * _.min([]);

     * // => undefined

     */

    function min(array) {

      return (array && array.length)

        ? baseExtremum(array, identity, baseLt)

        : undefined;

    }



    /**

     * This method is like `_.min` except that it accepts `iteratee` which is

     * invoked for each element in `array` to generate the criterion by which

     * the value is ranked. The iteratee is invoked with one argument: (value).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Math

     * @param {Array} array The array to iterate over.

     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.

     * @returns {*} Returns the minimum value.

     * @example

     *

     * var objects = [{ 'n': 1 }, { 'n': 2 }];

     *

     * _.minBy(objects, function(o) { return o.n; });

     * // => { 'n': 1 }

     *

     * // The `_.property` iteratee shorthand.

     * _.minBy(objects, 'n');

     * // => { 'n': 1 }

     */

    function minBy(array, iteratee) {

      return (array && array.length)

        ? baseExtremum(array, getIteratee(iteratee, 2), baseLt)

        : undefined;

    }



    /**

     * Multiply two numbers.

     *

     * @static

     * @memberOf _

     * @since 4.7.0

     * @category Math

     * @param {number} multiplier The first number in a multiplication.

     * @param {number} multiplicand The second number in a multiplication.

     * @returns {number} Returns the product.

     * @example

     *

     * _.multiply(6, 4);

     * // => 24

     */

    var multiply = createMathOperation(function(multiplier, multiplicand) {

      return multiplier * multiplicand;

    }, 1);



    /**

     * Computes `number` rounded to `precision`.

     *

     * @static

     * @memberOf _

     * @since 3.10.0

     * @category Math

     * @param {number} number The number to round.

     * @param {number} [precision=0] The precision to round to.

     * @returns {number} Returns the rounded number.

     * @example

     *

     * _.round(4.006);

     * // => 4

     *

     * _.round(4.006, 2);

     * // => 4.01

     *

     * _.round(4060, -2);

     * // => 4100

     */

    var round = createRound('round');



    /**

     * Subtract two numbers.

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Math

     * @param {number} minuend The first number in a subtraction.

     * @param {number} subtrahend The second number in a subtraction.

     * @returns {number} Returns the difference.

     * @example

     *

     * _.subtract(6, 4);

     * // => 2

     */

    var subtract = createMathOperation(function(minuend, subtrahend) {

      return minuend - subtrahend;

    }, 0);



    /**

     * Computes the sum of the values in `array`.

     *

     * @static

     * @memberOf _

     * @since 3.4.0

     * @category Math

     * @param {Array} array The array to iterate over.

     * @returns {number} Returns the sum.

     * @example

     *

     * _.sum([4, 2, 8, 6]);

     * // => 20

     */

    function sum(array) {

      return (array && array.length)

        ? baseSum(array, identity)

        : 0;

    }



    /**

     * This method is like `_.sum` except that it accepts `iteratee` which is

     * invoked for each element in `array` to generate the value to be summed.

     * The iteratee is invoked with one argument: (value).

     *

     * @static

     * @memberOf _

     * @since 4.0.0

     * @category Math

     * @param {Array} array The array to iterate over.

     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.

     * @returns {number} Returns the sum.

     * @example

     *

     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];

     *

     * _.sumBy(objects, function(o) { return o.n; });

     * // => 20

     *

     * // The `_.property` iteratee shorthand.

     * _.sumBy(objects, 'n');

     * // => 20

     */

    function sumBy(array, iteratee) {

      return (array && array.length)

        ? baseSum(array, getIteratee(iteratee, 2))

        : 0;

    }



    /*------------------------------------------------------------------------*/



    // Add methods that return wrapped values in chain sequences.

    lodash.after = after;

    lodash.ary = ary;

    lodash.assign = assign;

    lodash.assignIn = assignIn;

    lodash.assignInWith = assignInWith;

    lodash.assignWith = assignWith;

    lodash.at = at;

    lodash.before = before;

    lodash.bind = bind;

    lodash.bindAll = bindAll;

    lodash.bindKey = bindKey;

    lodash.castArray = castArray;

    lodash.chain = chain;

    lodash.chunk = chunk;

    lodash.compact = compact;

    lodash.concat = concat;

    lodash.cond = cond;

    lodash.conforms = conforms;

    lodash.constant = constant;

    lodash.countBy = countBy;

    lodash.create = create;

    lodash.curry = curry;

    lodash.curryRight = curryRight;

    lodash.debounce = debounce;

    lodash.defaults = defaults;

    lodash.defaultsDeep = defaultsDeep;

    lodash.defer = defer;

    lodash.delay = delay;

    lodash.difference = difference;

    lodash.differenceBy = differenceBy;

    lodash.differenceWith = differenceWith;

    lodash.drop = drop;

    lodash.dropRight = dropRight;

    lodash.dropRightWhile = dropRightWhile;

    lodash.dropWhile = dropWhile;

    lodash.fill = fill;

    lodash.filter = filter;

    lodash.flatMap = flatMap;

    lodash.flatMapDeep = flatMapDeep;

    lodash.flatMapDepth = flatMapDepth;

    lodash.flatten = flatten;

    lodash.flattenDeep = flattenDeep;

    lodash.flattenDepth = flattenDepth;

    lodash.flip = flip;

    lodash.flow = flow;

    lodash.flowRight = flowRight;

    lodash.fromPairs = fromPairs;

    lodash.functions = functions;

    lodash.functionsIn = functionsIn;

    lodash.groupBy = groupBy;

    lodash.initial = initial;

    lodash.intersection = intersection;

    lodash.intersectionBy = intersectionBy;

    lodash.intersectionWith = intersectionWith;

    lodash.invert = invert;

    lodash.invertBy = invertBy;

    lodash.invokeMap = invokeMap;

    lodash.iteratee = iteratee;

    lodash.keyBy = keyBy;

    lodash.keys = keys;

    lodash.keysIn = keysIn;

    lodash.map = map;

    lodash.mapKeys = mapKeys;

    lodash.mapValues = mapValues;

    lodash.matches = matches;

    lodash.matchesProperty = matchesProperty;

    lodash.memoize = memoize;

    lodash.merge = merge;

    lodash.mergeWith = mergeWith;

    lodash.method = method;

    lodash.methodOf = methodOf;

    lodash.mixin = mixin;

    lodash.negate = negate;

    lodash.nthArg = nthArg;

    lodash.omit = omit;

    lodash.omitBy = omitBy;

    lodash.once = once;

    lodash.orderBy = orderBy;

    lodash.over = over;

    lodash.overArgs = overArgs;

    lodash.overEvery = overEvery;

    lodash.overSome = overSome;

    lodash.partial = partial;

    lodash.partialRight = partialRight;

    lodash.partition = partition;

    lodash.pick = pick;

    lodash.pickBy = pickBy;

    lodash.property = property;

    lodash.propertyOf = propertyOf;

    lodash.pull = pull;

    lodash.pullAll = pullAll;

    lodash.pullAllBy = pullAllBy;

    lodash.pullAllWith = pullAllWith;

    lodash.pullAt = pullAt;

    lodash.range = range;

    lodash.rangeRight = rangeRight;

    lodash.rearg = rearg;

    lodash.reject = reject;

    lodash.remove = remove;

    lodash.rest = rest;

    lodash.reverse = reverse;

    lodash.sampleSize = sampleSize;

    lodash.set = set;

    lodash.setWith = setWith;

    lodash.shuffle = shuffle;

    lodash.slice = slice;

    lodash.sortBy = sortBy;

    lodash.sortedUniq = sortedUniq;

    lodash.sortedUniqBy = sortedUniqBy;

    lodash.split = split;

    lodash.spread = spread;

    lodash.tail = tail;

    lodash.take = take;

    lodash.takeRight = takeRight;

    lodash.takeRightWhile = takeRightWhile;

    lodash.takeWhile = takeWhile;

    lodash.tap = tap;

    lodash.throttle = throttle;

    lodash.thru = thru;

    lodash.toArray = toArray;

    lodash.toPairs = toPairs;

    lodash.toPairsIn = toPairsIn;

    lodash.toPath = toPath;

    lodash.toPlainObject = toPlainObject;

    lodash.transform = transform;

    lodash.unary = unary;

    lodash.union = union;

    lodash.unionBy = unionBy;

    lodash.unionWith = unionWith;

    lodash.uniq = uniq;

    lodash.uniqBy = uniqBy;

    lodash.uniqWith = uniqWith;

    lodash.unset = unset;

    lodash.unzip = unzip;

    lodash.unzipWith = unzipWith;

    lodash.update = update;

    lodash.updateWith = updateWith;

    lodash.values = values;

    lodash.valuesIn = valuesIn;

    lodash.without = without;

    lodash.words = words;

    lodash.wrap = wrap;

    lodash.xor = xor;

    lodash.xorBy = xorBy;

    lodash.xorWith = xorWith;

    lodash.zip = zip;

    lodash.zipObject = zipObject;

    lodash.zipObjectDeep = zipObjectDeep;

    lodash.zipWith = zipWith;



    // Add aliases.

    lodash.entries = toPairs;

    lodash.entriesIn = toPairsIn;

    lodash.extend = assignIn;

    lodash.extendWith = assignInWith;



    // Add methods to `lodash.prototype`.

    mixin(lodash, lodash);



    /*------------------------------------------------------------------------*/



    // Add methods that return unwrapped values in chain sequences.

    lodash.add = add;

    lodash.attempt = attempt;

    lodash.camelCase = camelCase;

    lodash.capitalize = capitalize;

    lodash.ceil = ceil;

    lodash.clamp = clamp;

    lodash.clone = clone;

    lodash.cloneDeep = cloneDeep;

    lodash.cloneDeepWith = cloneDeepWith;

    lodash.cloneWith = cloneWith;

    lodash.conformsTo = conformsTo;

    lodash.deburr = deburr;

    lodash.defaultTo = defaultTo;

    lodash.divide = divide;

    lodash.endsWith = endsWith;

    lodash.eq = eq;

    lodash.escape = escape;

    lodash.escapeRegExp = escapeRegExp;

    lodash.every = every;

    lodash.find = find;

    lodash.findIndex = findIndex;

    lodash.findKey = findKey;

    lodash.findLast = findLast;

    lodash.findLastIndex = findLastIndex;

    lodash.findLastKey = findLastKey;

    lodash.floor = floor;

    lodash.forEach = forEach;

    lodash.forEachRight = forEachRight;

    lodash.forIn = forIn;

    lodash.forInRight = forInRight;

    lodash.forOwn = forOwn;

    lodash.forOwnRight = forOwnRight;

    lodash.get = get;

    lodash.gt = gt;

    lodash.gte = gte;

    lodash.has = has;

    lodash.hasIn = hasIn;

    lodash.head = head;

    lodash.identity = identity;

    lodash.includes = includes;

    lodash.indexOf = indexOf;

    lodash.inRange = inRange;

    lodash.invoke = invoke;

    lodash.isArguments = isArguments;

    lodash.isArray = isArray;

    lodash.isArrayBuffer = isArrayBuffer;

    lodash.isArrayLike = isArrayLike;

    lodash.isArrayLikeObject = isArrayLikeObject;

    lodash.isBoolean = isBoolean;

    lodash.isBuffer = isBuffer;

    lodash.isDate = isDate;

    lodash.isElement = isElement;

    lodash.isEmpty = isEmpty;

    lodash.isEqual = isEqual;

    lodash.isEqualWith = isEqualWith;

    lodash.isError = isError;

    lodash.isFinite = isFinite;

    lodash.isFunction = isFunction;

    lodash.isInteger = isInteger;

    lodash.isLength = isLength;

    lodash.isMap = isMap;

    lodash.isMatch = isMatch;

    lodash.isMatchWith = isMatchWith;

    lodash.isNaN = isNaN;

    lodash.isNative = isNative;

    lodash.isNil = isNil;

    lodash.isNull = isNull;

    lodash.isNumber = isNumber;

    lodash.isObject = isObject;

    lodash.isObjectLike = isObjectLike;

    lodash.isPlainObject = isPlainObject;

    lodash.isRegExp = isRegExp;

    lodash.isSafeInteger = isSafeInteger;

    lodash.isSet = isSet;

    lodash.isString = isString;

    lodash.isSymbol = isSymbol;

    lodash.isTypedArray = isTypedArray;

    lodash.isUndefined = isUndefined;

    lodash.isWeakMap = isWeakMap;

    lodash.isWeakSet = isWeakSet;

    lodash.join = join;

    lodash.kebabCase = kebabCase;

    lodash.last = last;

    lodash.lastIndexOf = lastIndexOf;

    lodash.lowerCase = lowerCase;

    lodash.lowerFirst = lowerFirst;

    lodash.lt = lt;

    lodash.lte = lte;

    lodash.max = max;

    lodash.maxBy = maxBy;

    lodash.mean = mean;

    lodash.meanBy = meanBy;

    lodash.min = min;

    lodash.minBy = minBy;

    lodash.stubArray = stubArray;

    lodash.stubFalse = stubFalse;

    lodash.stubObject = stubObject;

    lodash.stubString = stubString;

    lodash.stubTrue = stubTrue;

    lodash.multiply = multiply;

    lodash.nth = nth;

    lodash.noConflict = noConflict;

    lodash.noop = noop;

    lodash.now = now;

    lodash.pad = pad;

    lodash.padEnd = padEnd;

    lodash.padStart = padStart;

    lodash.parseInt = parseInt;

    lodash.random = random;

    lodash.reduce = reduce;

    lodash.reduceRight = reduceRight;

    lodash.repeat = repeat;

    lodash.replace = replace;

    lodash.result = result;

    lodash.round = round;

    lodash.runInContext = runInContext;

    lodash.sample = sample;

    lodash.size = size;

    lodash.snakeCase = snakeCase;

    lodash.some = some;

    lodash.sortedIndex = sortedIndex;

    lodash.sortedIndexBy = sortedIndexBy;

    lodash.sortedIndexOf = sortedIndexOf;

    lodash.sortedLastIndex = sortedLastIndex;

    lodash.sortedLastIndexBy = sortedLastIndexBy;

    lodash.sortedLastIndexOf = sortedLastIndexOf;

    lodash.startCase = startCase;

    lodash.startsWith = startsWith;

    lodash.subtract = subtract;

    lodash.sum = sum;

    lodash.sumBy = sumBy;

    lodash.template = template;

    lodash.times = times;

    lodash.toFinite = toFinite;

    lodash.toInteger = toInteger;

    lodash.toLength = toLength;

    lodash.toLower = toLower;

    lodash.toNumber = toNumber;

    lodash.toSafeInteger = toSafeInteger;

    lodash.toString = toString;

    lodash.toUpper = toUpper;

    lodash.trim = trim;

    lodash.trimEnd = trimEnd;

    lodash.trimStart = trimStart;

    lodash.truncate = truncate;

    lodash.unescape = unescape;

    lodash.uniqueId = uniqueId;

    lodash.upperCase = upperCase;

    lodash.upperFirst = upperFirst;



    // Add aliases.

    lodash.each = forEach;

    lodash.eachRight = forEachRight;

    lodash.first = head;



    mixin(lodash, (function() {

      var source = {};

      baseForOwn(lodash, function(func, methodName) {

        if (!hasOwnProperty.call(lodash.prototype, methodName)) {

          source[methodName] = func;

        }

      });

      return source;

    }()), { 'chain': false });



    /*------------------------------------------------------------------------*/



    /**

     * The semantic version number.

     *

     * @static

     * @memberOf _

     * @type {string}

     */

    lodash.VERSION = VERSION;



    // Assign default placeholders.

    arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {

      lodash[methodName].placeholder = lodash;

    });



    // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.

    arrayEach(['drop', 'take'], function(methodName, index) {

      LazyWrapper.prototype[methodName] = function(n) {

        n = n === undefined ? 1 : nativeMax(toInteger(n), 0);



        var result = (this.__filtered__ && !index)

          ? new LazyWrapper(this)

          : this.clone();



        if (result.__filtered__) {

          result.__takeCount__ = nativeMin(n, result.__takeCount__);

        } else {

          result.__views__.push({

            'size': nativeMin(n, MAX_ARRAY_LENGTH),

            'type': methodName + (result.__dir__ < 0 ? 'Right' : '')

          });

        }

        return result;

      };



      LazyWrapper.prototype[methodName + 'Right'] = function(n) {

        return this.reverse()[methodName](n).reverse();

      };

    });



    // Add `LazyWrapper` methods that accept an `iteratee` value.

    arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {

      var type = index + 1,

          isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;



      LazyWrapper.prototype[methodName] = function(iteratee) {

        var result = this.clone();

        result.__iteratees__.push({

          'iteratee': getIteratee(iteratee, 3),

          'type': type

        });

        result.__filtered__ = result.__filtered__ || isFilter;

        return result;

      };

    });



    // Add `LazyWrapper` methods for `_.head` and `_.last`.

    arrayEach(['head', 'last'], function(methodName, index) {

      var takeName = 'take' + (index ? 'Right' : '');



      LazyWrapper.prototype[methodName] = function() {

        return this[takeName](1).value()[0];

      };

    });



    // Add `LazyWrapper` methods for `_.initial` and `_.tail`.

    arrayEach(['initial', 'tail'], function(methodName, index) {

      var dropName = 'drop' + (index ? '' : 'Right');



      LazyWrapper.prototype[methodName] = function() {

        return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);

      };

    });



    LazyWrapper.prototype.compact = function() {

      return this.filter(identity);

    };



    LazyWrapper.prototype.find = function(predicate) {

      return this.filter(predicate).head();

    };



    LazyWrapper.prototype.findLast = function(predicate) {

      return this.reverse().find(predicate);

    };



    LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {

      if (typeof path == 'function') {

        return new LazyWrapper(this);

      }

      return this.map(function(value) {

        return baseInvoke(value, path, args);

      });

    });



    LazyWrapper.prototype.reject = function(predicate) {

      return this.filter(negate(getIteratee(predicate)));

    };



    LazyWrapper.prototype.slice = function(start, end) {

      start = toInteger(start);



      var result = this;

      if (result.__filtered__ && (start > 0 || end < 0)) {

        return new LazyWrapper(result);

      }

      if (start < 0) {

        result = result.takeRight(-start);

      } else if (start) {

        result = result.drop(start);

      }

      if (end !== undefined) {

        end = toInteger(end);

        result = end < 0 ? result.dropRight(-end) : result.take(end - start);

      }

      return result;

    };



    LazyWrapper.prototype.takeRightWhile = function(predicate) {

      return this.reverse().takeWhile(predicate).reverse();

    };



    LazyWrapper.prototype.toArray = function() {

      return this.take(MAX_ARRAY_LENGTH);

    };



    // Add `LazyWrapper` methods to `lodash.prototype`.

    baseForOwn(LazyWrapper.prototype, function(func, methodName) {

      var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),

          isTaker = /^(?:head|last)$/.test(methodName),

          lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],

          retUnwrapped = isTaker || /^find/.test(methodName);



      if (!lodashFunc) {

        return;

      }

      lodash.prototype[methodName] = function() {

        var value = this.__wrapped__,

            args = isTaker ? [1] : arguments,

            isLazy = value instanceof LazyWrapper,

            iteratee = args[0],

            useLazy = isLazy || isArray(value);



        var interceptor = function(value) {

          var result = lodashFunc.apply(lodash, arrayPush([value], args));

          return (isTaker && chainAll) ? result[0] : result;

        };



        if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {

          // Avoid lazy use if the iteratee has a "length" value other than `1`.

          isLazy = useLazy = false;

        }

        var chainAll = this.__chain__,

            isHybrid = !!this.__actions__.length,

            isUnwrapped = retUnwrapped && !chainAll,

            onlyLazy = isLazy && !isHybrid;



        if (!retUnwrapped && useLazy) {

          value = onlyLazy ? value : new LazyWrapper(this);

          var result = func.apply(value, args);

          result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });

          return new LodashWrapper(result, chainAll);

        }

        if (isUnwrapped && onlyLazy) {

          return func.apply(this, args);

        }

        result = this.thru(interceptor);

        return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;

      };

    });



    // Add `Array` methods to `lodash.prototype`.

    arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {

      var func = arrayProto[methodName],

          chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',

          retUnwrapped = /^(?:pop|shift)$/.test(methodName);



      lodash.prototype[methodName] = function() {

        var args = arguments;

        if (retUnwrapped && !this.__chain__) {

          var value = this.value();

          return func.apply(isArray(value) ? value : [], args);

        }

        return this[chainName](function(value) {

          return func.apply(isArray(value) ? value : [], args);

        });

      };

    });



    // Map minified method names to their real names.

    baseForOwn(LazyWrapper.prototype, function(func, methodName) {

      var lodashFunc = lodash[methodName];

      if (lodashFunc) {

        var key = (lodashFunc.name + ''),

            names = realNames[key] || (realNames[key] = []);



        names.push({ 'name': methodName, 'func': lodashFunc });

      }

    });



    realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{

      'name': 'wrapper',

      'func': undefined

    }];



    // Add methods to `LazyWrapper`.

    LazyWrapper.prototype.clone = lazyClone;

    LazyWrapper.prototype.reverse = lazyReverse;

    LazyWrapper.prototype.value = lazyValue;



    // Add chain sequence methods to the `lodash` wrapper.

    lodash.prototype.at = wrapperAt;

    lodash.prototype.chain = wrapperChain;

    lodash.prototype.commit = wrapperCommit;

    lodash.prototype.next = wrapperNext;

    lodash.prototype.plant = wrapperPlant;

    lodash.prototype.reverse = wrapperReverse;

    lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;



    // Add lazy aliases.

    lodash.prototype.first = lodash.prototype.head;



    if (symIterator) {

      lodash.prototype[symIterator] = wrapperToIterator;

    }

    return lodash;

  });



  /*--------------------------------------------------------------------------*/



  // Export lodash.

  var _ = runInContext();



  // Some AMD build optimizers, like r.js, check for condition patterns like:

  if (true) {

    // Expose Lodash on the global object to prevent errors when Lodash is

    // loaded by a script tag in the presence of an AMD loader.

    // See http://requirejs.org/docs/errors.html#mismatch for more details.

    // Use `_.noConflict` to remove Lodash from the global object.

    root._ = _;



    // Define as an anonymous module so, through path mapping, it can be

    // referenced as the "underscore" module.

    !(__WEBPACK_AMD_DEFINE_RESULT__ = (function() {

      return _;

    }).call(exports, __webpack_require__, exports, module),

				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));

  }

  // Check for `exports` after `define` in case a build optimizer adds it.

  else if (freeModule) {

    // Export for Node.js.

    (freeModule.exports = _)._ = _;

    // Export for CommonJS support.

    freeExports._ = _;

  }

  else {

    // Export to the global object.

    root._ = _;

  }

}.call(this));



/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1), __webpack_require__(15)(module)))



/***/ }),

/* 15 */

/***/ (function(module, exports) {



module.exports = function(module) {

	if(!module.webpackPolyfill) {

		module.deprecate = function() {};

		module.paths = [];

		// module.parent = undefined by default

		if(!module.children) module.children = [];

		Object.defineProperty(module, "loaded", {

			enumerable: true,

			get: function() {

				return module.l;

			}

		});

		Object.defineProperty(module, "id", {

			enumerable: true,

			get: function() {

				return module.i;

			}

		});

		module.webpackPolyfill = 1;

	}

	return module;

};





/***/ }),

/* 16 */

/***/ (function(module, exports, __webpack_require__) {



/*!

  * Bootstrap v4.1.0 (https://getbootstrap.com/)

  * Copyright 2011-2018 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)

  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

  */

(function (global, factory) {

   true ? factory(exports, __webpack_require__(3), __webpack_require__(4)) :

  typeof define === 'function' && define.amd ? define(['exports', 'jquery', 'popper.js'], factory) :

  (factory((global.bootstrap = {}),global.jQuery,global.Popper));

}(this, (function (exports,$,Popper) { 'use strict';



  $ = $ && $.hasOwnProperty('default') ? $['default'] : $;

  Popper = Popper && Popper.hasOwnProperty('default') ? Popper['default'] : Popper;



  function _defineProperties(target, props) {

    for (var i = 0; i < props.length; i++) {

      var descriptor = props[i];

      descriptor.enumerable = descriptor.enumerable || false;

      descriptor.configurable = true;

      if ("value" in descriptor) descriptor.writable = true;

      Object.defineProperty(target, descriptor.key, descriptor);

    }

  }



  function _createClass(Constructor, protoProps, staticProps) {

    if (protoProps) _defineProperties(Constructor.prototype, protoProps);

    if (staticProps) _defineProperties(Constructor, staticProps);

    return Constructor;

  }



  function _defineProperty(obj, key, value) {

    if (key in obj) {

      Object.defineProperty(obj, key, {

        value: value,

        enumerable: true,

        configurable: true,

        writable: true

      });

    } else {

      obj[key] = value;

    }



    return obj;

  }



  function _objectSpread(target) {

    for (var i = 1; i < arguments.length; i++) {

      var source = arguments[i] != null ? arguments[i] : {};

      var ownKeys = Object.keys(source);



      if (typeof Object.getOwnPropertySymbols === 'function') {

        ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {

          return Object.getOwnPropertyDescriptor(source, sym).enumerable;

        }));

      }



      ownKeys.forEach(function (key) {

        _defineProperty(target, key, source[key]);

      });

    }



    return target;

  }



  function _inheritsLoose(subClass, superClass) {

    subClass.prototype = Object.create(superClass.prototype);

    subClass.prototype.constructor = subClass;

    subClass.__proto__ = superClass;

  }



  /**

   * --------------------------------------------------------------------------

   * Bootstrap (v4.1.0): util.js

   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

   * --------------------------------------------------------------------------

   */



  var Util = function ($$$1) {

    /**

     * ------------------------------------------------------------------------

     * Private TransitionEnd Helpers

     * ------------------------------------------------------------------------

     */

    var TRANSITION_END = 'transitionend';

    var MAX_UID = 1000000;

    var MILLISECONDS_MULTIPLIER = 1000; // Shoutout AngusCroll (https://goo.gl/pxwQGp)



    function toType(obj) {

      return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();

    }



    function getSpecialTransitionEndEvent() {

      return {

        bindType: TRANSITION_END,

        delegateType: TRANSITION_END,

        handle: function handle(event) {

          if ($$$1(event.target).is(this)) {

            return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params

          }



          return undefined; // eslint-disable-line no-undefined

        }

      };

    }



    function transitionEndEmulator(duration) {

      var _this = this;



      var called = false;

      $$$1(this).one(Util.TRANSITION_END, function () {

        called = true;

      });

      setTimeout(function () {

        if (!called) {

          Util.triggerTransitionEnd(_this);

        }

      }, duration);

      return this;

    }



    function setTransitionEndSupport() {

      $$$1.fn.emulateTransitionEnd = transitionEndEmulator;

      $$$1.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent();

    }

    /**

     * --------------------------------------------------------------------------

     * Public Util Api

     * --------------------------------------------------------------------------

     */





    var Util = {

      TRANSITION_END: 'bsTransitionEnd',

      getUID: function getUID(prefix) {

        do {

          // eslint-disable-next-line no-bitwise

          prefix += ~~(Math.random() * MAX_UID); // "~~" acts like a faster Math.floor() here

        } while (document.getElementById(prefix));



        return prefix;

      },

      getSelectorFromElement: function getSelectorFromElement(element) {

        var selector = element.getAttribute('data-target');



        if (!selector || selector === '#') {

          selector = element.getAttribute('href') || '';

        }



        try {

          var $selector = $$$1(document).find(selector);

          return $selector.length > 0 ? selector : null;

        } catch (err) {

          return null;

        }

      },

      getTransitionDurationFromElement: function getTransitionDurationFromElement(element) {

        if (!element) {

          return 0;

        } // Get transition-duration of the element





        var transitionDuration = $$$1(element).css('transition-duration');

        var floatTransitionDuration = parseFloat(transitionDuration); // Return 0 if element or transition duration is not found



        if (!floatTransitionDuration) {

          return 0;

        } // If multiple durations are defined, take the first





        transitionDuration = transitionDuration.split(',')[0];

        return parseFloat(transitionDuration) * MILLISECONDS_MULTIPLIER;

      },

      reflow: function reflow(element) {

        return element.offsetHeight;

      },

      triggerTransitionEnd: function triggerTransitionEnd(element) {

        $$$1(element).trigger(TRANSITION_END);

      },

      // TODO: Remove in v5

      supportsTransitionEnd: function supportsTransitionEnd() {

        return Boolean(TRANSITION_END);

      },

      isElement: function isElement(obj) {

        return (obj[0] || obj).nodeType;

      },

      typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) {

        for (var property in configTypes) {

          if (Object.prototype.hasOwnProperty.call(configTypes, property)) {

            var expectedTypes = configTypes[property];

            var value = config[property];

            var valueType = value && Util.isElement(value) ? 'element' : toType(value);



            if (!new RegExp(expectedTypes).test(valueType)) {

              throw new Error(componentName.toUpperCase() + ": " + ("Option \"" + property + "\" provided type \"" + valueType + "\" ") + ("but expected type \"" + expectedTypes + "\"."));

            }

          }

        }

      }

    };

    setTransitionEndSupport();

    return Util;

  }($);



  /**

   * --------------------------------------------------------------------------

   * Bootstrap (v4.1.0): alert.js

   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

   * --------------------------------------------------------------------------

   */



  var Alert = function ($$$1) {

    /**

     * ------------------------------------------------------------------------

     * Constants

     * ------------------------------------------------------------------------

     */

    var NAME = 'alert';

    var VERSION = '4.1.0';

    var DATA_KEY = 'bs.alert';

    var EVENT_KEY = "." + DATA_KEY;

    var DATA_API_KEY = '.data-api';

    var JQUERY_NO_CONFLICT = $$$1.fn[NAME];

    var Selector = {

      DISMISS: '[data-dismiss="alert"]'

    };

    var Event = {

      CLOSE: "close" + EVENT_KEY,

      CLOSED: "closed" + EVENT_KEY,

      CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY

    };

    var ClassName = {

      ALERT: 'alert',

      FADE: 'fade',

      SHOW: 'show'

      /**

       * ------------------------------------------------------------------------

       * Class Definition

       * ------------------------------------------------------------------------

       */



    };



    var Alert =

    /*#__PURE__*/

    function () {

      function Alert(element) {

        this._element = element;

      } // Getters





      var _proto = Alert.prototype;



      // Public

      _proto.close = function close(element) {

        element = element || this._element;



        var rootElement = this._getRootElement(element);



        var customEvent = this._triggerCloseEvent(rootElement);



        if (customEvent.isDefaultPrevented()) {

          return;

        }



        this._removeElement(rootElement);

      };



      _proto.dispose = function dispose() {

        $$$1.removeData(this._element, DATA_KEY);

        this._element = null;

      }; // Private





      _proto._getRootElement = function _getRootElement(element) {

        var selector = Util.getSelectorFromElement(element);

        var parent = false;



        if (selector) {

          parent = $$$1(selector)[0];

        }



        if (!parent) {

          parent = $$$1(element).closest("." + ClassName.ALERT)[0];

        }



        return parent;

      };



      _proto._triggerCloseEvent = function _triggerCloseEvent(element) {

        var closeEvent = $$$1.Event(Event.CLOSE);

        $$$1(element).trigger(closeEvent);

        return closeEvent;

      };



      _proto._removeElement = function _removeElement(element) {

        var _this = this;



        $$$1(element).removeClass(ClassName.SHOW);



        if (!$$$1(element).hasClass(ClassName.FADE)) {

          this._destroyElement(element);



          return;

        }



        var transitionDuration = Util.getTransitionDurationFromElement(element);

        $$$1(element).one(Util.TRANSITION_END, function (event) {

          return _this._destroyElement(element, event);

        }).emulateTransitionEnd(transitionDuration);

      };



      _proto._destroyElement = function _destroyElement(element) {

        $$$1(element).detach().trigger(Event.CLOSED).remove();

      }; // Static





      Alert._jQueryInterface = function _jQueryInterface(config) {

        return this.each(function () {

          var $element = $$$1(this);

          var data = $element.data(DATA_KEY);



          if (!data) {

            data = new Alert(this);

            $element.data(DATA_KEY, data);

          }



          if (config === 'close') {

            data[config](this);

          }

        });

      };



      Alert._handleDismiss = function _handleDismiss(alertInstance) {

        return function (event) {

          if (event) {

            event.preventDefault();

          }



          alertInstance.close(this);

        };

      };



      _createClass(Alert, null, [{

        key: "VERSION",

        get: function get() {

          return VERSION;

        }

      }]);



      return Alert;

    }();

    /**

     * ------------------------------------------------------------------------

     * Data Api implementation

     * ------------------------------------------------------------------------

     */





    $$$1(document).on(Event.CLICK_DATA_API, Selector.DISMISS, Alert._handleDismiss(new Alert()));

    /**

     * ------------------------------------------------------------------------

     * jQuery

     * ------------------------------------------------------------------------

     */



    $$$1.fn[NAME] = Alert._jQueryInterface;

    $$$1.fn[NAME].Constructor = Alert;



    $$$1.fn[NAME].noConflict = function () {

      $$$1.fn[NAME] = JQUERY_NO_CONFLICT;

      return Alert._jQueryInterface;

    };



    return Alert;

  }($);



  /**

   * --------------------------------------------------------------------------

   * Bootstrap (v4.1.0): button.js

   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

   * --------------------------------------------------------------------------

   */



  var Button = function ($$$1) {

    /**

     * ------------------------------------------------------------------------

     * Constants

     * ------------------------------------------------------------------------

     */

    var NAME = 'button';

    var VERSION = '4.1.0';

    var DATA_KEY = 'bs.button';

    var EVENT_KEY = "." + DATA_KEY;

    var DATA_API_KEY = '.data-api';

    var JQUERY_NO_CONFLICT = $$$1.fn[NAME];

    var ClassName = {

      ACTIVE: 'active',

      BUTTON: 'btn',

      FOCUS: 'focus'

    };

    var Selector = {

      DATA_TOGGLE_CARROT: '[data-toggle^="button"]',

      DATA_TOGGLE: '[data-toggle="buttons"]',

      INPUT: 'input',

      ACTIVE: '.active',

      BUTTON: '.btn'

    };

    var Event = {

      CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY,

      FOCUS_BLUR_DATA_API: "focus" + EVENT_KEY + DATA_API_KEY + " " + ("blur" + EVENT_KEY + DATA_API_KEY)

      /**

       * ------------------------------------------------------------------------

       * Class Definition

       * ------------------------------------------------------------------------

       */



    };



    var Button =

    /*#__PURE__*/

    function () {

      function Button(element) {

        this._element = element;

      } // Getters





      var _proto = Button.prototype;



      // Public

      _proto.toggle = function toggle() {

        var triggerChangeEvent = true;

        var addAriaPressed = true;

        var rootElement = $$$1(this._element).closest(Selector.DATA_TOGGLE)[0];



        if (rootElement) {

          var input = $$$1(this._element).find(Selector.INPUT)[0];



          if (input) {

            if (input.type === 'radio') {

              if (input.checked && $$$1(this._element).hasClass(ClassName.ACTIVE)) {

                triggerChangeEvent = false;

              } else {

                var activeElement = $$$1(rootElement).find(Selector.ACTIVE)[0];



                if (activeElement) {

                  $$$1(activeElement).removeClass(ClassName.ACTIVE);

                }

              }

            }



            if (triggerChangeEvent) {

              if (input.hasAttribute('disabled') || rootElement.hasAttribute('disabled') || input.classList.contains('disabled') || rootElement.classList.contains('disabled')) {

                return;

              }



              input.checked = !$$$1(this._element).hasClass(ClassName.ACTIVE);

              $$$1(input).trigger('change');

            }



            input.focus();

            addAriaPressed = false;

          }

        }



        if (addAriaPressed) {

          this._element.setAttribute('aria-pressed', !$$$1(this._element).hasClass(ClassName.ACTIVE));

        }



        if (triggerChangeEvent) {

          $$$1(this._element).toggleClass(ClassName.ACTIVE);

        }

      };



      _proto.dispose = function dispose() {

        $$$1.removeData(this._element, DATA_KEY);

        this._element = null;

      }; // Static





      Button._jQueryInterface = function _jQueryInterface(config) {

        return this.each(function () {

          var data = $$$1(this).data(DATA_KEY);



          if (!data) {

            data = new Button(this);

            $$$1(this).data(DATA_KEY, data);

          }



          if (config === 'toggle') {

            data[config]();

          }

        });

      };



      _createClass(Button, null, [{

        key: "VERSION",

        get: function get() {

          return VERSION;

        }

      }]);



      return Button;

    }();

    /**

     * ------------------------------------------------------------------------

     * Data Api implementation

     * ------------------------------------------------------------------------

     */





    $$$1(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, function (event) {

      event.preventDefault();

      var button = event.target;



      if (!$$$1(button).hasClass(ClassName.BUTTON)) {

        button = $$$1(button).closest(Selector.BUTTON);

      }



      Button._jQueryInterface.call($$$1(button), 'toggle');

    }).on(Event.FOCUS_BLUR_DATA_API, Selector.DATA_TOGGLE_CARROT, function (event) {

      var button = $$$1(event.target).closest(Selector.BUTTON)[0];

      $$$1(button).toggleClass(ClassName.FOCUS, /^focus(in)?$/.test(event.type));

    });

    /**

     * ------------------------------------------------------------------------

     * jQuery

     * ------------------------------------------------------------------------

     */



    $$$1.fn[NAME] = Button._jQueryInterface;

    $$$1.fn[NAME].Constructor = Button;



    $$$1.fn[NAME].noConflict = function () {

      $$$1.fn[NAME] = JQUERY_NO_CONFLICT;

      return Button._jQueryInterface;

    };



    return Button;

  }($);



  /**

   * --------------------------------------------------------------------------

   * Bootstrap (v4.1.0): carousel.js

   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

   * --------------------------------------------------------------------------

   */



  var Carousel = function ($$$1) {

    /**

     * ------------------------------------------------------------------------

     * Constants

     * ------------------------------------------------------------------------

     */

    var NAME = 'carousel';

    var VERSION = '4.1.0';

    var DATA_KEY = 'bs.carousel';

    var EVENT_KEY = "." + DATA_KEY;

    var DATA_API_KEY = '.data-api';

    var JQUERY_NO_CONFLICT = $$$1.fn[NAME];

    var ARROW_LEFT_KEYCODE = 37; // KeyboardEvent.which value for left arrow key



    var ARROW_RIGHT_KEYCODE = 39; // KeyboardEvent.which value for right arrow key



    var TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch



    var Default = {

      interval: 5000,

      keyboard: true,

      slide: false,

      pause: 'hover',

      wrap: true

    };

    var DefaultType = {

      interval: '(number|boolean)',

      keyboard: 'boolean',

      slide: '(boolean|string)',

      pause: '(string|boolean)',

      wrap: 'boolean'

    };

    var Direction = {

      NEXT: 'next',

      PREV: 'prev',

      LEFT: 'left',

      RIGHT: 'right'

    };

    var Event = {

      SLIDE: "slide" + EVENT_KEY,

      SLID: "slid" + EVENT_KEY,

      KEYDOWN: "keydown" + EVENT_KEY,

      MOUSEENTER: "mouseenter" + EVENT_KEY,

      MOUSELEAVE: "mouseleave" + EVENT_KEY,

      TOUCHEND: "touchend" + EVENT_KEY,

      LOAD_DATA_API: "load" + EVENT_KEY + DATA_API_KEY,

      CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY

    };

    var ClassName = {

      CAROUSEL: 'carousel',

      ACTIVE: 'active',

      SLIDE: 'slide',

      RIGHT: 'carousel-item-right',

      LEFT: 'carousel-item-left',

      NEXT: 'carousel-item-next',

      PREV: 'carousel-item-prev',

      ITEM: 'carousel-item'

    };

    var Selector = {

      ACTIVE: '.active',

      ACTIVE_ITEM: '.active.carousel-item',

      ITEM: '.carousel-item',

      NEXT_PREV: '.carousel-item-next, .carousel-item-prev',

      INDICATORS: '.carousel-indicators',

      DATA_SLIDE: '[data-slide], [data-slide-to]',

      DATA_RIDE: '[data-ride="carousel"]'

      /**

       * ------------------------------------------------------------------------

       * Class Definition

       * ------------------------------------------------------------------------

       */



    };



    var Carousel =

    /*#__PURE__*/

    function () {

      function Carousel(element, config) {

        this._items = null;

        this._interval = null;

        this._activeElement = null;

        this._isPaused = false;

        this._isSliding = false;

        this.touchTimeout = null;

        this._config = this._getConfig(config);

        this._element = $$$1(element)[0];

        this._indicatorsElement = $$$1(this._element).find(Selector.INDICATORS)[0];



        this._addEventListeners();

      } // Getters





      var _proto = Carousel.prototype;



      // Public

      _proto.next = function next() {

        if (!this._isSliding) {

          this._slide(Direction.NEXT);

        }

      };



      _proto.nextWhenVisible = function nextWhenVisible() {

        // Don't call next when the page isn't visible

        // or the carousel or its parent isn't visible

        if (!document.hidden && $$$1(this._element).is(':visible') && $$$1(this._element).css('visibility') !== 'hidden') {

          this.next();

        }

      };



      _proto.prev = function prev() {

        if (!this._isSliding) {

          this._slide(Direction.PREV);

        }

      };



      _proto.pause = function pause(event) {

        if (!event) {

          this._isPaused = true;

        }



        if ($$$1(this._element).find(Selector.NEXT_PREV)[0]) {

          Util.triggerTransitionEnd(this._element);

          this.cycle(true);

        }



        clearInterval(this._interval);

        this._interval = null;

      };



      _proto.cycle = function cycle(event) {

        if (!event) {

          this._isPaused = false;

        }



        if (this._interval) {

          clearInterval(this._interval);

          this._interval = null;

        }



        if (this._config.interval && !this._isPaused) {

          this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval);

        }

      };



      _proto.to = function to(index) {

        var _this = this;



        this._activeElement = $$$1(this._element).find(Selector.ACTIVE_ITEM)[0];



        var activeIndex = this._getItemIndex(this._activeElement);



        if (index > this._items.length - 1 || index < 0) {

          return;

        }



        if (this._isSliding) {

          $$$1(this._element).one(Event.SLID, function () {

            return _this.to(index);

          });

          return;

        }



        if (activeIndex === index) {

          this.pause();

          this.cycle();

          return;

        }



        var direction = index > activeIndex ? Direction.NEXT : Direction.PREV;



        this._slide(direction, this._items[index]);

      };



      _proto.dispose = function dispose() {

        $$$1(this._element).off(EVENT_KEY);

        $$$1.removeData(this._element, DATA_KEY);

        this._items = null;

        this._config = null;

        this._element = null;

        this._interval = null;

        this._isPaused = null;

        this._isSliding = null;

        this._activeElement = null;

        this._indicatorsElement = null;

      }; // Private





      _proto._getConfig = function _getConfig(config) {

        config = _objectSpread({}, Default, config);

        Util.typeCheckConfig(NAME, config, DefaultType);

        return config;

      };



      _proto._addEventListeners = function _addEventListeners() {

        var _this2 = this;



        if (this._config.keyboard) {

          $$$1(this._element).on(Event.KEYDOWN, function (event) {

            return _this2._keydown(event);

          });

        }



        if (this._config.pause === 'hover') {

          $$$1(this._element).on(Event.MOUSEENTER, function (event) {

            return _this2.pause(event);

          }).on(Event.MOUSELEAVE, function (event) {

            return _this2.cycle(event);

          });



          if ('ontouchstart' in document.documentElement) {

            // If it's a touch-enabled device, mouseenter/leave are fired as

            // part of the mouse compatibility events on first tap - the carousel

            // would stop cycling until user tapped out of it;

            // here, we listen for touchend, explicitly pause the carousel

            // (as if it's the second time we tap on it, mouseenter compat event

            // is NOT fired) and after a timeout (to allow for mouse compatibility

            // events to fire) we explicitly restart cycling

            $$$1(this._element).on(Event.TOUCHEND, function () {

              _this2.pause();



              if (_this2.touchTimeout) {

                clearTimeout(_this2.touchTimeout);

              }



              _this2.touchTimeout = setTimeout(function (event) {

                return _this2.cycle(event);

              }, TOUCHEVENT_COMPAT_WAIT + _this2._config.interval);

            });

          }

        }

      };



      _proto._keydown = function _keydown(event) {

        if (/input|textarea/i.test(event.target.tagName)) {

          return;

        }



        switch (event.which) {

          case ARROW_LEFT_KEYCODE:

            event.preventDefault();

            this.prev();

            break;



          case ARROW_RIGHT_KEYCODE:

            event.preventDefault();

            this.next();

            break;



          default:

        }

      };



      _proto._getItemIndex = function _getItemIndex(element) {

        this._items = $$$1.makeArray($$$1(element).parent().find(Selector.ITEM));

        return this._items.indexOf(element);

      };



      _proto._getItemByDirection = function _getItemByDirection(direction, activeElement) {

        var isNextDirection = direction === Direction.NEXT;

        var isPrevDirection = direction === Direction.PREV;



        var activeIndex = this._getItemIndex(activeElement);



        var lastItemIndex = this._items.length - 1;

        var isGoingToWrap = isPrevDirection && activeIndex === 0 || isNextDirection && activeIndex === lastItemIndex;



        if (isGoingToWrap && !this._config.wrap) {

          return activeElement;

        }



        var delta = direction === Direction.PREV ? -1 : 1;

        var itemIndex = (activeIndex + delta) % this._items.length;

        return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex];

      };



      _proto._triggerSlideEvent = function _triggerSlideEvent(relatedTarget, eventDirectionName) {

        var targetIndex = this._getItemIndex(relatedTarget);



        var fromIndex = this._getItemIndex($$$1(this._element).find(Selector.ACTIVE_ITEM)[0]);



        var slideEvent = $$$1.Event(Event.SLIDE, {

          relatedTarget: relatedTarget,

          direction: eventDirectionName,

          from: fromIndex,

          to: targetIndex

        });

        $$$1(this._element).trigger(slideEvent);

        return slideEvent;

      };



      _proto._setActiveIndicatorElement = function _setActiveIndicatorElement(element) {

        if (this._indicatorsElement) {

          $$$1(this._indicatorsElement).find(Selector.ACTIVE).removeClass(ClassName.ACTIVE);



          var nextIndicator = this._indicatorsElement.children[this._getItemIndex(element)];



          if (nextIndicator) {

            $$$1(nextIndicator).addClass(ClassName.ACTIVE);

          }

        }

      };



      _proto._slide = function _slide(direction, element) {

        var _this3 = this;



        var activeElement = $$$1(this._element).find(Selector.ACTIVE_ITEM)[0];



        var activeElementIndex = this._getItemIndex(activeElement);



        var nextElement = element || activeElement && this._getItemByDirection(direction, activeElement);



        var nextElementIndex = this._getItemIndex(nextElement);



        var isCycling = Boolean(this._interval);

        var directionalClassName;

        var orderClassName;

        var eventDirectionName;



        if (direction === Direction.NEXT) {

          directionalClassName = ClassName.LEFT;

          orderClassName = ClassName.NEXT;

          eventDirectionName = Direction.LEFT;

        } else {

          directionalClassName = ClassName.RIGHT;

          orderClassName = ClassName.PREV;

          eventDirectionName = Direction.RIGHT;

        }



        if (nextElement && $$$1(nextElement).hasClass(ClassName.ACTIVE)) {

          this._isSliding = false;

          return;

        }



        var slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName);



        if (slideEvent.isDefaultPrevented()) {

          return;

        }



        if (!activeElement || !nextElement) {

          // Some weirdness is happening, so we bail

          return;

        }



        this._isSliding = true;



        if (isCycling) {

          this.pause();

        }



        this._setActiveIndicatorElement(nextElement);



        var slidEvent = $$$1.Event(Event.SLID, {

          relatedTarget: nextElement,

          direction: eventDirectionName,

          from: activeElementIndex,

          to: nextElementIndex

        });



        if ($$$1(this._element).hasClass(ClassName.SLIDE)) {

          $$$1(nextElement).addClass(orderClassName);

          Util.reflow(nextElement);

          $$$1(activeElement).addClass(directionalClassName);

          $$$1(nextElement).addClass(directionalClassName);

          var transitionDuration = Util.getTransitionDurationFromElement(activeElement);

          $$$1(activeElement).one(Util.TRANSITION_END, function () {

            $$$1(nextElement).removeClass(directionalClassName + " " + orderClassName).addClass(ClassName.ACTIVE);

            $$$1(activeElement).removeClass(ClassName.ACTIVE + " " + orderClassName + " " + directionalClassName);

            _this3._isSliding = false;

            setTimeout(function () {

              return $$$1(_this3._element).trigger(slidEvent);

            }, 0);

          }).emulateTransitionEnd(transitionDuration);

        } else {

          $$$1(activeElement).removeClass(ClassName.ACTIVE);

          $$$1(nextElement).addClass(ClassName.ACTIVE);

          this._isSliding = false;

          $$$1(this._element).trigger(slidEvent);

        }



        if (isCycling) {

          this.cycle();

        }

      }; // Static





      Carousel._jQueryInterface = function _jQueryInterface(config) {

        return this.each(function () {

          var data = $$$1(this).data(DATA_KEY);



          var _config = _objectSpread({}, Default, $$$1(this).data());



          if (typeof config === 'object') {

            _config = _objectSpread({}, _config, config);

          }



          var action = typeof config === 'string' ? config : _config.slide;



          if (!data) {

            data = new Carousel(this, _config);

            $$$1(this).data(DATA_KEY, data);

          }



          if (typeof config === 'number') {

            data.to(config);

          } else if (typeof action === 'string') {

            if (typeof data[action] === 'undefined') {

              throw new TypeError("No method named \"" + action + "\"");

            }



            data[action]();

          } else if (_config.interval) {

            data.pause();

            data.cycle();

          }

        });

      };



      Carousel._dataApiClickHandler = function _dataApiClickHandler(event) {

        var selector = Util.getSelectorFromElement(this);



        if (!selector) {

          return;

        }



        var target = $$$1(selector)[0];



        if (!target || !$$$1(target).hasClass(ClassName.CAROUSEL)) {

          return;

        }



        var config = _objectSpread({}, $$$1(target).data(), $$$1(this).data());



        var slideIndex = this.getAttribute('data-slide-to');



        if (slideIndex) {

          config.interval = false;

        }



        Carousel._jQueryInterface.call($$$1(target), config);



        if (slideIndex) {

          $$$1(target).data(DATA_KEY).to(slideIndex);

        }



        event.preventDefault();

      };



      _createClass(Carousel, null, [{

        key: "VERSION",

        get: function get() {

          return VERSION;

        }

      }, {

        key: "Default",

        get: function get() {

          return Default;

        }

      }]);



      return Carousel;

    }();

    /**

     * ------------------------------------------------------------------------

     * Data Api implementation

     * ------------------------------------------------------------------------

     */





    $$$1(document).on(Event.CLICK_DATA_API, Selector.DATA_SLIDE, Carousel._dataApiClickHandler);

    $$$1(window).on(Event.LOAD_DATA_API, function () {

      $$$1(Selector.DATA_RIDE).each(function () {

        var $carousel = $$$1(this);



        Carousel._jQueryInterface.call($carousel, $carousel.data());

      });

    });

    /**

     * ------------------------------------------------------------------------

     * jQuery

     * ------------------------------------------------------------------------

     */



    $$$1.fn[NAME] = Carousel._jQueryInterface;

    $$$1.fn[NAME].Constructor = Carousel;



    $$$1.fn[NAME].noConflict = function () {

      $$$1.fn[NAME] = JQUERY_NO_CONFLICT;

      return Carousel._jQueryInterface;

    };



    return Carousel;

  }($);



  /**

   * --------------------------------------------------------------------------

   * Bootstrap (v4.1.0): collapse.js

   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

   * --------------------------------------------------------------------------

   */



  var Collapse = function ($$$1) {

    /**

     * ------------------------------------------------------------------------

     * Constants

     * ------------------------------------------------------------------------

     */

    var NAME = 'collapse';

    var VERSION = '4.1.0';

    var DATA_KEY = 'bs.collapse';

    var EVENT_KEY = "." + DATA_KEY;

    var DATA_API_KEY = '.data-api';

    var JQUERY_NO_CONFLICT = $$$1.fn[NAME];

    var Default = {

      toggle: true,

      parent: ''

    };

    var DefaultType = {

      toggle: 'boolean',

      parent: '(string|element)'

    };

    var Event = {

      SHOW: "show" + EVENT_KEY,

      SHOWN: "shown" + EVENT_KEY,

      HIDE: "hide" + EVENT_KEY,

      HIDDEN: "hidden" + EVENT_KEY,

      CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY

    };

    var ClassName = {

      SHOW: 'show',

      COLLAPSE: 'collapse',

      COLLAPSING: 'collapsing',

      COLLAPSED: 'collapsed'

    };

    var Dimension = {

      WIDTH: 'width',

      HEIGHT: 'height'

    };

    var Selector = {

      ACTIVES: '.show, .collapsing',

      DATA_TOGGLE: '[data-toggle="collapse"]'

      /**

       * ------------------------------------------------------------------------

       * Class Definition

       * ------------------------------------------------------------------------

       */



    };



    var Collapse =

    /*#__PURE__*/

    function () {

      function Collapse(element, config) {

        this._isTransitioning = false;

        this._element = element;

        this._config = this._getConfig(config);

        this._triggerArray = $$$1.makeArray($$$1("[data-toggle=\"collapse\"][href=\"#" + element.id + "\"]," + ("[data-toggle=\"collapse\"][data-target=\"#" + element.id + "\"]")));

        var tabToggles = $$$1(Selector.DATA_TOGGLE);



        for (var i = 0; i < tabToggles.length; i++) {

          var elem = tabToggles[i];

          var selector = Util.getSelectorFromElement(elem);



          if (selector !== null && $$$1(selector).filter(element).length > 0) {

            this._selector = selector;



            this._triggerArray.push(elem);

          }

        }



        this._parent = this._config.parent ? this._getParent() : null;



        if (!this._config.parent) {

          this._addAriaAndCollapsedClass(this._element, this._triggerArray);

        }



        if (this._config.toggle) {

          this.toggle();

        }

      } // Getters





      var _proto = Collapse.prototype;



      // Public

      _proto.toggle = function toggle() {

        if ($$$1(this._element).hasClass(ClassName.SHOW)) {

          this.hide();

        } else {

          this.show();

        }

      };



      _proto.show = function show() {

        var _this = this;



        if (this._isTransitioning || $$$1(this._element).hasClass(ClassName.SHOW)) {

          return;

        }



        var actives;

        var activesData;



        if (this._parent) {

          actives = $$$1.makeArray($$$1(this._parent).find(Selector.ACTIVES).filter("[data-parent=\"" + this._config.parent + "\"]"));



          if (actives.length === 0) {

            actives = null;

          }

        }



        if (actives) {

          activesData = $$$1(actives).not(this._selector).data(DATA_KEY);



          if (activesData && activesData._isTransitioning) {

            return;

          }

        }



        var startEvent = $$$1.Event(Event.SHOW);

        $$$1(this._element).trigger(startEvent);



        if (startEvent.isDefaultPrevented()) {

          return;

        }



        if (actives) {

          Collapse._jQueryInterface.call($$$1(actives).not(this._selector), 'hide');



          if (!activesData) {

            $$$1(actives).data(DATA_KEY, null);

          }

        }



        var dimension = this._getDimension();



        $$$1(this._element).removeClass(ClassName.COLLAPSE).addClass(ClassName.COLLAPSING);

        this._element.style[dimension] = 0;



        if (this._triggerArray.length > 0) {

          $$$1(this._triggerArray).removeClass(ClassName.COLLAPSED).attr('aria-expanded', true);

        }



        this.setTransitioning(true);



        var complete = function complete() {

          $$$1(_this._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).addClass(ClassName.SHOW);

          _this._element.style[dimension] = '';



          _this.setTransitioning(false);



          $$$1(_this._element).trigger(Event.SHOWN);

        };



        var capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);

        var scrollSize = "scroll" + capitalizedDimension;

        var transitionDuration = Util.getTransitionDurationFromElement(this._element);

        $$$1(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);

        this._element.style[dimension] = this._element[scrollSize] + "px";

      };



      _proto.hide = function hide() {

        var _this2 = this;



        if (this._isTransitioning || !$$$1(this._element).hasClass(ClassName.SHOW)) {

          return;

        }



        var startEvent = $$$1.Event(Event.HIDE);

        $$$1(this._element).trigger(startEvent);



        if (startEvent.isDefaultPrevented()) {

          return;

        }



        var dimension = this._getDimension();



        this._element.style[dimension] = this._element.getBoundingClientRect()[dimension] + "px";

        Util.reflow(this._element);

        $$$1(this._element).addClass(ClassName.COLLAPSING).removeClass(ClassName.COLLAPSE).removeClass(ClassName.SHOW);



        if (this._triggerArray.length > 0) {

          for (var i = 0; i < this._triggerArray.length; i++) {

            var trigger = this._triggerArray[i];

            var selector = Util.getSelectorFromElement(trigger);



            if (selector !== null) {

              var $elem = $$$1(selector);



              if (!$elem.hasClass(ClassName.SHOW)) {

                $$$1(trigger).addClass(ClassName.COLLAPSED).attr('aria-expanded', false);

              }

            }

          }

        }



        this.setTransitioning(true);



        var complete = function complete() {

          _this2.setTransitioning(false);



          $$$1(_this2._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).trigger(Event.HIDDEN);

        };



        this._element.style[dimension] = '';

        var transitionDuration = Util.getTransitionDurationFromElement(this._element);

        $$$1(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);

      };



      _proto.setTransitioning = function setTransitioning(isTransitioning) {

        this._isTransitioning = isTransitioning;

      };



      _proto.dispose = function dispose() {

        $$$1.removeData(this._element, DATA_KEY);

        this._config = null;

        this._parent = null;

        this._element = null;

        this._triggerArray = null;

        this._isTransitioning = null;

      }; // Private





      _proto._getConfig = function _getConfig(config) {

        config = _objectSpread({}, Default, config);

        config.toggle = Boolean(config.toggle); // Coerce string values



        Util.typeCheckConfig(NAME, config, DefaultType);

        return config;

      };



      _proto._getDimension = function _getDimension() {

        var hasWidth = $$$1(this._element).hasClass(Dimension.WIDTH);

        return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT;

      };



      _proto._getParent = function _getParent() {

        var _this3 = this;



        var parent = null;



        if (Util.isElement(this._config.parent)) {

          parent = this._config.parent; // It's a jQuery object



          if (typeof this._config.parent.jquery !== 'undefined') {

            parent = this._config.parent[0];

          }

        } else {

          parent = $$$1(this._config.parent)[0];

        }



        var selector = "[data-toggle=\"collapse\"][data-parent=\"" + this._config.parent + "\"]";

        $$$1(parent).find(selector).each(function (i, element) {

          _this3._addAriaAndCollapsedClass(Collapse._getTargetFromElement(element), [element]);

        });

        return parent;

      };



      _proto._addAriaAndCollapsedClass = function _addAriaAndCollapsedClass(element, triggerArray) {

        if (element) {

          var isOpen = $$$1(element).hasClass(ClassName.SHOW);



          if (triggerArray.length > 0) {

            $$$1(triggerArray).toggleClass(ClassName.COLLAPSED, !isOpen).attr('aria-expanded', isOpen);

          }

        }

      }; // Static





      Collapse._getTargetFromElement = function _getTargetFromElement(element) {

        var selector = Util.getSelectorFromElement(element);

        return selector ? $$$1(selector)[0] : null;

      };



      Collapse._jQueryInterface = function _jQueryInterface(config) {

        return this.each(function () {

          var $this = $$$1(this);

          var data = $this.data(DATA_KEY);



          var _config = _objectSpread({}, Default, $this.data(), typeof config === 'object' && config);



          if (!data && _config.toggle && /show|hide/.test(config)) {

            _config.toggle = false;

          }



          if (!data) {

            data = new Collapse(this, _config);

            $this.data(DATA_KEY, data);

          }



          if (typeof config === 'string') {

            if (typeof data[config] === 'undefined') {

              throw new TypeError("No method named \"" + config + "\"");

            }



            data[config]();

          }

        });

      };



      _createClass(Collapse, null, [{

        key: "VERSION",

        get: function get() {

          return VERSION;

        }

      }, {

        key: "Default",

        get: function get() {

          return Default;

        }

      }]);



      return Collapse;

    }();

    /**

     * ------------------------------------------------------------------------

     * Data Api implementation

     * ------------------------------------------------------------------------

     */





    $$$1(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {

      // preventDefault only for <a> elements (which change the URL) not inside the collapsible element

      if (event.currentTarget.tagName === 'A') {

        event.preventDefault();

      }



      var $trigger = $$$1(this);

      var selector = Util.getSelectorFromElement(this);

      $$$1(selector).each(function () {

        var $target = $$$1(this);

        var data = $target.data(DATA_KEY);

        var config = data ? 'toggle' : $trigger.data();



        Collapse._jQueryInterface.call($target, config);

      });

    });

    /**

     * ------------------------------------------------------------------------

     * jQuery

     * ------------------------------------------------------------------------

     */



    $$$1.fn[NAME] = Collapse._jQueryInterface;

    $$$1.fn[NAME].Constructor = Collapse;



    $$$1.fn[NAME].noConflict = function () {

      $$$1.fn[NAME] = JQUERY_NO_CONFLICT;

      return Collapse._jQueryInterface;

    };



    return Collapse;

  }($);



  /**

   * --------------------------------------------------------------------------

   * Bootstrap (v4.1.0): dropdown.js

   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

   * --------------------------------------------------------------------------

   */



  var Dropdown = function ($$$1) {

    /**

     * ------------------------------------------------------------------------

     * Constants

     * ------------------------------------------------------------------------

     */

    var NAME = 'dropdown';

    var VERSION = '4.1.0';

    var DATA_KEY = 'bs.dropdown';

    var EVENT_KEY = "." + DATA_KEY;

    var DATA_API_KEY = '.data-api';

    var JQUERY_NO_CONFLICT = $$$1.fn[NAME];

    var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key



    var SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key



    var TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key



    var ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key



    var ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key



    var RIGHT_MOUSE_BUTTON_WHICH = 3; // MouseEvent.which value for the right button (assuming a right-handed mouse)



    var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEYCODE + "|" + ARROW_DOWN_KEYCODE + "|" + ESCAPE_KEYCODE);

    var Event = {

      HIDE: "hide" + EVENT_KEY,

      HIDDEN: "hidden" + EVENT_KEY,

      SHOW: "show" + EVENT_KEY,

      SHOWN: "shown" + EVENT_KEY,

      CLICK: "click" + EVENT_KEY,

      CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY,

      KEYDOWN_DATA_API: "keydown" + EVENT_KEY + DATA_API_KEY,

      KEYUP_DATA_API: "keyup" + EVENT_KEY + DATA_API_KEY

    };

    var ClassName = {

      DISABLED: 'disabled',

      SHOW: 'show',

      DROPUP: 'dropup',

      DROPRIGHT: 'dropright',

      DROPLEFT: 'dropleft',

      MENURIGHT: 'dropdown-menu-right',

      MENULEFT: 'dropdown-menu-left',

      POSITION_STATIC: 'position-static'

    };

    var Selector = {

      DATA_TOGGLE: '[data-toggle="dropdown"]',

      FORM_CHILD: '.dropdown form',

      MENU: '.dropdown-menu',

      NAVBAR_NAV: '.navbar-nav',

      VISIBLE_ITEMS: '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'

    };

    var AttachmentMap = {

      TOP: 'top-start',

      TOPEND: 'top-end',

      BOTTOM: 'bottom-start',

      BOTTOMEND: 'bottom-end',

      RIGHT: 'right-start',

      RIGHTEND: 'right-end',

      LEFT: 'left-start',

      LEFTEND: 'left-end'

    };

    var Default = {

      offset: 0,

      flip: true,

      boundary: 'scrollParent',

      reference: 'toggle',

      display: 'dynamic'

    };

    var DefaultType = {

      offset: '(number|string|function)',

      flip: 'boolean',

      boundary: '(string|element)',

      reference: '(string|element)',

      display: 'string'

      /**

       * ------------------------------------------------------------------------

       * Class Definition

       * ------------------------------------------------------------------------

       */



    };



    var Dropdown =

    /*#__PURE__*/

    function () {

      function Dropdown(element, config) {

        this._element = element;

        this._popper = null;

        this._config = this._getConfig(config);

        this._menu = this._getMenuElement();

        this._inNavbar = this._detectNavbar();



        this._addEventListeners();

      } // Getters





      var _proto = Dropdown.prototype;



      // Public

      _proto.toggle = function toggle() {

        if (this._element.disabled || $$$1(this._element).hasClass(ClassName.DISABLED)) {

          return;

        }



        var parent = Dropdown._getParentFromElement(this._element);



        var isActive = $$$1(this._menu).hasClass(ClassName.SHOW);



        Dropdown._clearMenus();



        if (isActive) {

          return;

        }



        var relatedTarget = {

          relatedTarget: this._element

        };

        var showEvent = $$$1.Event(Event.SHOW, relatedTarget);

        $$$1(parent).trigger(showEvent);



        if (showEvent.isDefaultPrevented()) {

          return;

        } // Disable totally Popper.js for Dropdown in Navbar





        if (!this._inNavbar) {

          /**

           * Check for Popper dependency

           * Popper - https://popper.js.org

           */

          if (typeof Popper === 'undefined') {

            throw new TypeError('Bootstrap dropdown require Popper.js (https://popper.js.org)');

          }



          var referenceElement = this._element;



          if (this._config.reference === 'parent') {

            referenceElement = parent;

          } else if (Util.isElement(this._config.reference)) {

            referenceElement = this._config.reference; // Check if it's jQuery element



            if (typeof this._config.reference.jquery !== 'undefined') {

              referenceElement = this._config.reference[0];

            }

          } // If boundary is not `scrollParent`, then set position to `static`

          // to allow the menu to "escape" the scroll parent's boundaries

          // https://github.com/twbs/bootstrap/issues/24251





          if (this._config.boundary !== 'scrollParent') {

            $$$1(parent).addClass(ClassName.POSITION_STATIC);

          }



          this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig());

        } // If this is a touch-enabled device we add extra

        // empty mouseover listeners to the body's immediate children;

        // only needed because of broken event delegation on iOS

        // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html





        if ('ontouchstart' in document.documentElement && $$$1(parent).closest(Selector.NAVBAR_NAV).length === 0) {

          $$$1(document.body).children().on('mouseover', null, $$$1.noop);

        }



        this._element.focus();



        this._element.setAttribute('aria-expanded', true);



        $$$1(this._menu).toggleClass(ClassName.SHOW);

        $$$1(parent).toggleClass(ClassName.SHOW).trigger($$$1.Event(Event.SHOWN, relatedTarget));

      };



      _proto.dispose = function dispose() {

        $$$1.removeData(this._element, DATA_KEY);

        $$$1(this._element).off(EVENT_KEY);

        this._element = null;

        this._menu = null;



        if (this._popper !== null) {

          this._popper.destroy();



          this._popper = null;

        }

      };



      _proto.update = function update() {

        this._inNavbar = this._detectNavbar();



        if (this._popper !== null) {

          this._popper.scheduleUpdate();

        }

      }; // Private





      _proto._addEventListeners = function _addEventListeners() {

        var _this = this;



        $$$1(this._element).on(Event.CLICK, function (event) {

          event.preventDefault();

          event.stopPropagation();



          _this.toggle();

        });

      };



      _proto._getConfig = function _getConfig(config) {

        config = _objectSpread({}, this.constructor.Default, $$$1(this._element).data(), config);

        Util.typeCheckConfig(NAME, config, this.constructor.DefaultType);

        return config;

      };



      _proto._getMenuElement = function _getMenuElement() {

        if (!this._menu) {

          var parent = Dropdown._getParentFromElement(this._element);



          this._menu = $$$1(parent).find(Selector.MENU)[0];

        }



        return this._menu;

      };



      _proto._getPlacement = function _getPlacement() {

        var $parentDropdown = $$$1(this._element).parent();

        var placement = AttachmentMap.BOTTOM; // Handle dropup



        if ($parentDropdown.hasClass(ClassName.DROPUP)) {

          placement = AttachmentMap.TOP;



          if ($$$1(this._menu).hasClass(ClassName.MENURIGHT)) {

            placement = AttachmentMap.TOPEND;

          }

        } else if ($parentDropdown.hasClass(ClassName.DROPRIGHT)) {

          placement = AttachmentMap.RIGHT;

        } else if ($parentDropdown.hasClass(ClassName.DROPLEFT)) {

          placement = AttachmentMap.LEFT;

        } else if ($$$1(this._menu).hasClass(ClassName.MENURIGHT)) {

          placement = AttachmentMap.BOTTOMEND;

        }



        return placement;

      };



      _proto._detectNavbar = function _detectNavbar() {

        return $$$1(this._element).closest('.navbar').length > 0;

      };



      _proto._getPopperConfig = function _getPopperConfig() {

        var _this2 = this;



        var offsetConf = {};



        if (typeof this._config.offset === 'function') {

          offsetConf.fn = function (data) {

            data.offsets = _objectSpread({}, data.offsets, _this2._config.offset(data.offsets) || {});

            return data;

          };

        } else {

          offsetConf.offset = this._config.offset;

        }



        var popperConfig = {

          placement: this._getPlacement(),

          modifiers: {

            offset: offsetConf,

            flip: {

              enabled: this._config.flip

            },

            preventOverflow: {

              boundariesElement: this._config.boundary

            }

          } // Disable Popper.js if we have a static display



        };



        if (this._config.display === 'static') {

          popperConfig.modifiers.applyStyle = {

            enabled: false

          };

        }



        return popperConfig;

      }; // Static





      Dropdown._jQueryInterface = function _jQueryInterface(config) {

        return this.each(function () {

          var data = $$$1(this).data(DATA_KEY);



          var _config = typeof config === 'object' ? config : null;



          if (!data) {

            data = new Dropdown(this, _config);

            $$$1(this).data(DATA_KEY, data);

          }



          if (typeof config === 'string') {

            if (typeof data[config] === 'undefined') {

              throw new TypeError("No method named \"" + config + "\"");

            }



            data[config]();

          }

        });

      };



      Dropdown._clearMenus = function _clearMenus(event) {

        if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== TAB_KEYCODE)) {

          return;

        }



        var toggles = $$$1.makeArray($$$1(Selector.DATA_TOGGLE));



        for (var i = 0; i < toggles.length; i++) {

          var parent = Dropdown._getParentFromElement(toggles[i]);



          var context = $$$1(toggles[i]).data(DATA_KEY);

          var relatedTarget = {

            relatedTarget: toggles[i]

          };



          if (!context) {

            continue;

          }



          var dropdownMenu = context._menu;



          if (!$$$1(parent).hasClass(ClassName.SHOW)) {

            continue;

          }



          if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) && $$$1.contains(parent, event.target)) {

            continue;

          }



          var hideEvent = $$$1.Event(Event.HIDE, relatedTarget);

          $$$1(parent).trigger(hideEvent);



          if (hideEvent.isDefaultPrevented()) {

            continue;

          } // If this is a touch-enabled device we remove the extra

          // empty mouseover listeners we added for iOS support





          if ('ontouchstart' in document.documentElement) {

            $$$1(document.body).children().off('mouseover', null, $$$1.noop);

          }



          toggles[i].setAttribute('aria-expanded', 'false');

          $$$1(dropdownMenu).removeClass(ClassName.SHOW);

          $$$1(parent).removeClass(ClassName.SHOW).trigger($$$1.Event(Event.HIDDEN, relatedTarget));

        }

      };



      Dropdown._getParentFromElement = function _getParentFromElement(element) {

        var parent;

        var selector = Util.getSelectorFromElement(element);



        if (selector) {

          parent = $$$1(selector)[0];

        }



        return parent || element.parentNode;

      }; // eslint-disable-next-line complexity





      Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) {

        // If not input/textarea:

        //  - And not a key in REGEXP_KEYDOWN => not a dropdown command

        // If input/textarea:

        //  - If space key => not a dropdown command

        //  - If key is other than escape

        //    - If key is not up or down => not a dropdown command

        //    - If trigger inside the menu => not a dropdown command

        if (/input|textarea/i.test(event.target.tagName) ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE && (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE || $$$1(event.target).closest(Selector.MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {

          return;

        }



        event.preventDefault();

        event.stopPropagation();



        if (this.disabled || $$$1(this).hasClass(ClassName.DISABLED)) {

          return;

        }



        var parent = Dropdown._getParentFromElement(this);



        var isActive = $$$1(parent).hasClass(ClassName.SHOW);



        if (!isActive && (event.which !== ESCAPE_KEYCODE || event.which !== SPACE_KEYCODE) || isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {

          if (event.which === ESCAPE_KEYCODE) {

            var toggle = $$$1(parent).find(Selector.DATA_TOGGLE)[0];

            $$$1(toggle).trigger('focus');

          }



          $$$1(this).trigger('click');

          return;

        }



        var items = $$$1(parent).find(Selector.VISIBLE_ITEMS).get();



        if (items.length === 0) {

          return;

        }



        var index = items.indexOf(event.target);



        if (event.which === ARROW_UP_KEYCODE && index > 0) {

          // Up

          index--;

        }



        if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) {

          // Down

          index++;

        }



        if (index < 0) {

          index = 0;

        }



        items[index].focus();

      };



      _createClass(Dropdown, null, [{

        key: "VERSION",

        get: function get() {

          return VERSION;

        }

      }, {

        key: "Default",

        get: function get() {

          return Default;

        }

      }, {

        key: "DefaultType",

        get: function get() {

          return DefaultType;

        }

      }]);



      return Dropdown;

    }();

    /**

     * ------------------------------------------------------------------------

     * Data Api implementation

     * ------------------------------------------------------------------------

     */





    $$$1(document).on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, Selector.MENU, Dropdown._dataApiKeydownHandler).on(Event.CLICK_DATA_API + " " + Event.KEYUP_DATA_API, Dropdown._clearMenus).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {

      event.preventDefault();

      event.stopPropagation();



      Dropdown._jQueryInterface.call($$$1(this), 'toggle');

    }).on(Event.CLICK_DATA_API, Selector.FORM_CHILD, function (e) {

      e.stopPropagation();

    });

    /**

     * ------------------------------------------------------------------------

     * jQuery

     * ------------------------------------------------------------------------

     */



    $$$1.fn[NAME] = Dropdown._jQueryInterface;

    $$$1.fn[NAME].Constructor = Dropdown;



    $$$1.fn[NAME].noConflict = function () {

      $$$1.fn[NAME] = JQUERY_NO_CONFLICT;

      return Dropdown._jQueryInterface;

    };



    return Dropdown;

  }($, Popper);



  /**

   * --------------------------------------------------------------------------

   * Bootstrap (v4.1.0): modal.js

   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

   * --------------------------------------------------------------------------

   */



  var Modal = function ($$$1) {

    /**

     * ------------------------------------------------------------------------

     * Constants

     * ------------------------------------------------------------------------

     */

    var NAME = 'modal';

    var VERSION = '4.1.0';

    var DATA_KEY = 'bs.modal';

    var EVENT_KEY = "." + DATA_KEY;

    var DATA_API_KEY = '.data-api';

    var JQUERY_NO_CONFLICT = $$$1.fn[NAME];

    var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key



    var Default = {

      backdrop: true,

      keyboard: true,

      focus: true,

      show: true

    };

    var DefaultType = {

      backdrop: '(boolean|string)',

      keyboard: 'boolean',

      focus: 'boolean',

      show: 'boolean'

    };

    var Event = {

      HIDE: "hide" + EVENT_KEY,

      HIDDEN: "hidden" + EVENT_KEY,

      SHOW: "show" + EVENT_KEY,

      SHOWN: "shown" + EVENT_KEY,

      FOCUSIN: "focusin" + EVENT_KEY,

      RESIZE: "resize" + EVENT_KEY,

      CLICK_DISMISS: "click.dismiss" + EVENT_KEY,

      KEYDOWN_DISMISS: "keydown.dismiss" + EVENT_KEY,

      MOUSEUP_DISMISS: "mouseup.dismiss" + EVENT_KEY,

      MOUSEDOWN_DISMISS: "mousedown.dismiss" + EVENT_KEY,

      CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY

    };

    var ClassName = {

      SCROLLBAR_MEASURER: 'modal-scrollbar-measure',

      BACKDROP: 'modal-backdrop',

      OPEN: 'modal-open',

      FADE: 'fade',

      SHOW: 'show'

    };

    var Selector = {

      DIALOG: '.modal-dialog',

      DATA_TOGGLE: '[data-toggle="modal"]',

      DATA_DISMISS: '[data-dismiss="modal"]',

      FIXED_CONTENT: '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top',

      STICKY_CONTENT: '.sticky-top',

      NAVBAR_TOGGLER: '.navbar-toggler'

      /**

       * ------------------------------------------------------------------------

       * Class Definition

       * ------------------------------------------------------------------------

       */



    };



    var Modal =

    /*#__PURE__*/

    function () {

      function Modal(element, config) {

        this._config = this._getConfig(config);

        this._element = element;

        this._dialog = $$$1(element).find(Selector.DIALOG)[0];

        this._backdrop = null;

        this._isShown = false;

        this._isBodyOverflowing = false;

        this._ignoreBackdropClick = false;

        this._scrollbarWidth = 0;

      } // Getters





      var _proto = Modal.prototype;



      // Public

      _proto.toggle = function toggle(relatedTarget) {

        return this._isShown ? this.hide() : this.show(relatedTarget);

      };



      _proto.show = function show(relatedTarget) {

        var _this = this;



        if (this._isTransitioning || this._isShown) {

          return;

        }



        if ($$$1(this._element).hasClass(ClassName.FADE)) {

          this._isTransitioning = true;

        }



        var showEvent = $$$1.Event(Event.SHOW, {

          relatedTarget: relatedTarget

        });

        $$$1(this._element).trigger(showEvent);



        if (this._isShown || showEvent.isDefaultPrevented()) {

          return;

        }



        this._isShown = true;



        this._checkScrollbar();



        this._setScrollbar();



        this._adjustDialog();



        $$$1(document.body).addClass(ClassName.OPEN);



        this._setEscapeEvent();



        this._setResizeEvent();



        $$$1(this._element).on(Event.CLICK_DISMISS, Selector.DATA_DISMISS, function (event) {

          return _this.hide(event);

        });

        $$$1(this._dialog).on(Event.MOUSEDOWN_DISMISS, function () {

          $$$1(_this._element).one(Event.MOUSEUP_DISMISS, function (event) {

            if ($$$1(event.target).is(_this._element)) {

              _this._ignoreBackdropClick = true;

            }

          });

        });



        this._showBackdrop(function () {

          return _this._showElement(relatedTarget);

        });

      };



      _proto.hide = function hide(event) {

        var _this2 = this;



        if (event) {

          event.preventDefault();

        }



        if (this._isTransitioning || !this._isShown) {

          return;

        }



        var hideEvent = $$$1.Event(Event.HIDE);

        $$$1(this._element).trigger(hideEvent);



        if (!this._isShown || hideEvent.isDefaultPrevented()) {

          return;

        }



        this._isShown = false;

        var transition = $$$1(this._element).hasClass(ClassName.FADE);



        if (transition) {

          this._isTransitioning = true;

        }



        this._setEscapeEvent();



        this._setResizeEvent();



        $$$1(document).off(Event.FOCUSIN);

        $$$1(this._element).removeClass(ClassName.SHOW);

        $$$1(this._element).off(Event.CLICK_DISMISS);

        $$$1(this._dialog).off(Event.MOUSEDOWN_DISMISS);



        if (transition) {

          var transitionDuration = Util.getTransitionDurationFromElement(this._element);

          $$$1(this._element).one(Util.TRANSITION_END, function (event) {

            return _this2._hideModal(event);

          }).emulateTransitionEnd(transitionDuration);

        } else {

          this._hideModal();

        }

      };



      _proto.dispose = function dispose() {

        $$$1.removeData(this._element, DATA_KEY);

        $$$1(window, document, this._element, this._backdrop).off(EVENT_KEY);

        this._config = null;

        this._element = null;

        this._dialog = null;

        this._backdrop = null;

        this._isShown = null;

        this._isBodyOverflowing = null;

        this._ignoreBackdropClick = null;

        this._scrollbarWidth = null;

      };



      _proto.handleUpdate = function handleUpdate() {

        this._adjustDialog();

      }; // Private





      _proto._getConfig = function _getConfig(config) {

        config = _objectSpread({}, Default, config);

        Util.typeCheckConfig(NAME, config, DefaultType);

        return config;

      };



      _proto._showElement = function _showElement(relatedTarget) {

        var _this3 = this;



        var transition = $$$1(this._element).hasClass(ClassName.FADE);



        if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {

          // Don't move modal's DOM position

          document.body.appendChild(this._element);

        }



        this._element.style.display = 'block';



        this._element.removeAttribute('aria-hidden');



        this._element.scrollTop = 0;



        if (transition) {

          Util.reflow(this._element);

        }



        $$$1(this._element).addClass(ClassName.SHOW);



        if (this._config.focus) {

          this._enforceFocus();

        }



        var shownEvent = $$$1.Event(Event.SHOWN, {

          relatedTarget: relatedTarget

        });



        var transitionComplete = function transitionComplete() {

          if (_this3._config.focus) {

            _this3._element.focus();

          }



          _this3._isTransitioning = false;

          $$$1(_this3._element).trigger(shownEvent);

        };



        if (transition) {

          var transitionDuration = Util.getTransitionDurationFromElement(this._element);

          $$$1(this._dialog).one(Util.TRANSITION_END, transitionComplete).emulateTransitionEnd(transitionDuration);

        } else {

          transitionComplete();

        }

      };



      _proto._enforceFocus = function _enforceFocus() {

        var _this4 = this;



        $$$1(document).off(Event.FOCUSIN) // Guard against infinite focus loop

        .on(Event.FOCUSIN, function (event) {

          if (document !== event.target && _this4._element !== event.target && $$$1(_this4._element).has(event.target).length === 0) {

            _this4._element.focus();

          }

        });

      };



      _proto._setEscapeEvent = function _setEscapeEvent() {

        var _this5 = this;



        if (this._isShown && this._config.keyboard) {

          $$$1(this._element).on(Event.KEYDOWN_DISMISS, function (event) {

            if (event.which === ESCAPE_KEYCODE) {

              event.preventDefault();



              _this5.hide();

            }

          });

        } else if (!this._isShown) {

          $$$1(this._element).off(Event.KEYDOWN_DISMISS);

        }

      };



      _proto._setResizeEvent = function _setResizeEvent() {

        var _this6 = this;



        if (this._isShown) {

          $$$1(window).on(Event.RESIZE, function (event) {

            return _this6.handleUpdate(event);

          });

        } else {

          $$$1(window).off(Event.RESIZE);

        }

      };



      _proto._hideModal = function _hideModal() {

        var _this7 = this;



        this._element.style.display = 'none';



        this._element.setAttribute('aria-hidden', true);



        this._isTransitioning = false;



        this._showBackdrop(function () {

          $$$1(document.body).removeClass(ClassName.OPEN);



          _this7._resetAdjustments();



          _this7._resetScrollbar();



          $$$1(_this7._element).trigger(Event.HIDDEN);

        });

      };



      _proto._removeBackdrop = function _removeBackdrop() {

        if (this._backdrop) {

          $$$1(this._backdrop).remove();

          this._backdrop = null;

        }

      };



      _proto._showBackdrop = function _showBackdrop(callback) {

        var _this8 = this;



        var animate = $$$1(this._element).hasClass(ClassName.FADE) ? ClassName.FADE : '';



        if (this._isShown && this._config.backdrop) {

          this._backdrop = document.createElement('div');

          this._backdrop.className = ClassName.BACKDROP;



          if (animate) {

            $$$1(this._backdrop).addClass(animate);

          }



          $$$1(this._backdrop).appendTo(document.body);

          $$$1(this._element).on(Event.CLICK_DISMISS, function (event) {

            if (_this8._ignoreBackdropClick) {

              _this8._ignoreBackdropClick = false;

              return;

            }



            if (event.target !== event.currentTarget) {

              return;

            }



            if (_this8._config.backdrop === 'static') {

              _this8._element.focus();

            } else {

              _this8.hide();

            }

          });



          if (animate) {

            Util.reflow(this._backdrop);

          }



          $$$1(this._backdrop).addClass(ClassName.SHOW);



          if (!callback) {

            return;

          }



          if (!animate) {

            callback();

            return;

          }



          var backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop);

          $$$1(this._backdrop).one(Util.TRANSITION_END, callback).emulateTransitionEnd(backdropTransitionDuration);

        } else if (!this._isShown && this._backdrop) {

          $$$1(this._backdrop).removeClass(ClassName.SHOW);



          var callbackRemove = function callbackRemove() {

            _this8._removeBackdrop();



            if (callback) {

              callback();

            }

          };



          if ($$$1(this._element).hasClass(ClassName.FADE)) {

            var _backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop);



            $$$1(this._backdrop).one(Util.TRANSITION_END, callbackRemove).emulateTransitionEnd(_backdropTransitionDuration);

          } else {

            callbackRemove();

          }

        } else if (callback) {

          callback();

        }

      }; // ----------------------------------------------------------------------

      // the following methods are used to handle overflowing modals

      // todo (fat): these should probably be refactored out of modal.js

      // ----------------------------------------------------------------------





      _proto._adjustDialog = function _adjustDialog() {

        var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;



        if (!this._isBodyOverflowing && isModalOverflowing) {

          this._element.style.paddingLeft = this._scrollbarWidth + "px";

        }



        if (this._isBodyOverflowing && !isModalOverflowing) {

          this._element.style.paddingRight = this._scrollbarWidth + "px";

        }

      };



      _proto._resetAdjustments = function _resetAdjustments() {

        this._element.style.paddingLeft = '';

        this._element.style.paddingRight = '';

      };



      _proto._checkScrollbar = function _checkScrollbar() {

        var rect = document.body.getBoundingClientRect();

        this._isBodyOverflowing = rect.left + rect.right < window.innerWidth;

        this._scrollbarWidth = this._getScrollbarWidth();

      };



      _proto._setScrollbar = function _setScrollbar() {

        var _this9 = this;



        if (this._isBodyOverflowing) {

          // Note: DOMNode.style.paddingRight returns the actual value or '' if not set

          //   while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set

          // Adjust fixed content padding

          $$$1(Selector.FIXED_CONTENT).each(function (index, element) {

            var actualPadding = $$$1(element)[0].style.paddingRight;

            var calculatedPadding = $$$1(element).css('padding-right');

            $$$1(element).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + _this9._scrollbarWidth + "px");

          }); // Adjust sticky content margin



          $$$1(Selector.STICKY_CONTENT).each(function (index, element) {

            var actualMargin = $$$1(element)[0].style.marginRight;

            var calculatedMargin = $$$1(element).css('margin-right');

            $$$1(element).data('margin-right', actualMargin).css('margin-right', parseFloat(calculatedMargin) - _this9._scrollbarWidth + "px");

          }); // Adjust navbar-toggler margin



          $$$1(Selector.NAVBAR_TOGGLER).each(function (index, element) {

            var actualMargin = $$$1(element)[0].style.marginRight;

            var calculatedMargin = $$$1(element).css('margin-right');

            $$$1(element).data('margin-right', actualMargin).css('margin-right', parseFloat(calculatedMargin) + _this9._scrollbarWidth + "px");

          }); // Adjust body padding



          var actualPadding = document.body.style.paddingRight;

          var calculatedPadding = $$$1(document.body).css('padding-right');

          $$$1(document.body).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + this._scrollbarWidth + "px");

        }

      };



      _proto._resetScrollbar = function _resetScrollbar() {

        // Restore fixed content padding

        $$$1(Selector.FIXED_CONTENT).each(function (index, element) {

          var padding = $$$1(element).data('padding-right');



          if (typeof padding !== 'undefined') {

            $$$1(element).css('padding-right', padding).removeData('padding-right');

          }

        }); // Restore sticky content and navbar-toggler margin



        $$$1(Selector.STICKY_CONTENT + ", " + Selector.NAVBAR_TOGGLER).each(function (index, element) {

          var margin = $$$1(element).data('margin-right');



          if (typeof margin !== 'undefined') {

            $$$1(element).css('margin-right', margin).removeData('margin-right');

          }

        }); // Restore body padding



        var padding = $$$1(document.body).data('padding-right');



        if (typeof padding !== 'undefined') {

          $$$1(document.body).css('padding-right', padding).removeData('padding-right');

        }

      };



      _proto._getScrollbarWidth = function _getScrollbarWidth() {

        // thx d.walsh

        var scrollDiv = document.createElement('div');

        scrollDiv.className = ClassName.SCROLLBAR_MEASURER;

        document.body.appendChild(scrollDiv);

        var scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;

        document.body.removeChild(scrollDiv);

        return scrollbarWidth;

      }; // Static





      Modal._jQueryInterface = function _jQueryInterface(config, relatedTarget) {

        return this.each(function () {

          var data = $$$1(this).data(DATA_KEY);



          var _config = _objectSpread({}, Modal.Default, $$$1(this).data(), typeof config === 'object' && config);



          if (!data) {

            data = new Modal(this, _config);

            $$$1(this).data(DATA_KEY, data);

          }



          if (typeof config === 'string') {

            if (typeof data[config] === 'undefined') {

              throw new TypeError("No method named \"" + config + "\"");

            }



            data[config](relatedTarget);

          } else if (_config.show) {

            data.show(relatedTarget);

          }

        });

      };



      _createClass(Modal, null, [{

        key: "VERSION",

        get: function get() {

          return VERSION;

        }

      }, {

        key: "Default",

        get: function get() {

          return Default;

        }

      }]);



      return Modal;

    }();

    /**

     * ------------------------------------------------------------------------

     * Data Api implementation

     * ------------------------------------------------------------------------

     */





    $$$1(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {

      var _this10 = this;



      var target;

      var selector = Util.getSelectorFromElement(this);



      if (selector) {

        target = $$$1(selector)[0];

      }



      var config = $$$1(target).data(DATA_KEY) ? 'toggle' : _objectSpread({}, $$$1(target).data(), $$$1(this).data());



      if (this.tagName === 'A' || this.tagName === 'AREA') {

        event.preventDefault();

      }



      var $target = $$$1(target).one(Event.SHOW, function (showEvent) {

        if (showEvent.isDefaultPrevented()) {

          // Only register focus restorer if modal will actually get shown

          return;

        }



        $target.one(Event.HIDDEN, function () {

          if ($$$1(_this10).is(':visible')) {

            _this10.focus();

          }

        });

      });



      Modal._jQueryInterface.call($$$1(target), config, this);

    });

    /**

     * ------------------------------------------------------------------------

     * jQuery

     * ------------------------------------------------------------------------

     */



    $$$1.fn[NAME] = Modal._jQueryInterface;

    $$$1.fn[NAME].Constructor = Modal;



    $$$1.fn[NAME].noConflict = function () {

      $$$1.fn[NAME] = JQUERY_NO_CONFLICT;

      return Modal._jQueryInterface;

    };



    return Modal;

  }($);



  /**

   * --------------------------------------------------------------------------

   * Bootstrap (v4.1.0): tooltip.js

   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

   * --------------------------------------------------------------------------

   */



  var Tooltip = function ($$$1) {

    /**

     * ------------------------------------------------------------------------

     * Constants

     * ------------------------------------------------------------------------

     */

    var NAME = 'tooltip';

    var VERSION = '4.1.0';

    var DATA_KEY = 'bs.tooltip';

    var EVENT_KEY = "." + DATA_KEY;

    var JQUERY_NO_CONFLICT = $$$1.fn[NAME];

    var CLASS_PREFIX = 'bs-tooltip';

    var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g');

    var DefaultType = {

      animation: 'boolean',

      template: 'string',

      title: '(string|element|function)',

      trigger: 'string',

      delay: '(number|object)',

      html: 'boolean',

      selector: '(string|boolean)',

      placement: '(string|function)',

      offset: '(number|string)',

      container: '(string|element|boolean)',

      fallbackPlacement: '(string|array)',

      boundary: '(string|element)'

    };

    var AttachmentMap = {

      AUTO: 'auto',

      TOP: 'top',

      RIGHT: 'right',

      BOTTOM: 'bottom',

      LEFT: 'left'

    };

    var Default = {

      animation: true,

      template: '<div class="tooltip" role="tooltip">' + '<div class="arrow"></div>' + '<div class="tooltip-inner"></div></div>',

      trigger: 'hover focus',

      title: '',

      delay: 0,

      html: false,

      selector: false,

      placement: 'top',

      offset: 0,

      container: false,

      fallbackPlacement: 'flip',

      boundary: 'scrollParent'

    };

    var HoverState = {

      SHOW: 'show',

      OUT: 'out'

    };

    var Event = {

      HIDE: "hide" + EVENT_KEY,

      HIDDEN: "hidden" + EVENT_KEY,

      SHOW: "show" + EVENT_KEY,

      SHOWN: "shown" + EVENT_KEY,

      INSERTED: "inserted" + EVENT_KEY,

      CLICK: "click" + EVENT_KEY,

      FOCUSIN: "focusin" + EVENT_KEY,

      FOCUSOUT: "focusout" + EVENT_KEY,

      MOUSEENTER: "mouseenter" + EVENT_KEY,

      MOUSELEAVE: "mouseleave" + EVENT_KEY

    };

    var ClassName = {

      FADE: 'fade',

      SHOW: 'show'

    };

    var Selector = {

      TOOLTIP: '.tooltip',

      TOOLTIP_INNER: '.tooltip-inner',

      ARROW: '.arrow'

    };

    var Trigger = {

      HOVER: 'hover',

      FOCUS: 'focus',

      CLICK: 'click',

      MANUAL: 'manual'

      /**

       * ------------------------------------------------------------------------

       * Class Definition

       * ------------------------------------------------------------------------

       */



    };



    var Tooltip =

    /*#__PURE__*/

    function () {

      function Tooltip(element, config) {

        /**

         * Check for Popper dependency

         * Popper - https://popper.js.org

         */

        if (typeof Popper === 'undefined') {

          throw new TypeError('Bootstrap tooltips require Popper.js (https://popper.js.org)');

        } // private





        this._isEnabled = true;

        this._timeout = 0;

        this._hoverState = '';

        this._activeTrigger = {};

        this._popper = null; // Protected



        this.element = element;

        this.config = this._getConfig(config);

        this.tip = null;



        this._setListeners();

      } // Getters





      var _proto = Tooltip.prototype;



      // Public

      _proto.enable = function enable() {

        this._isEnabled = true;

      };



      _proto.disable = function disable() {

        this._isEnabled = false;

      };



      _proto.toggleEnabled = function toggleEnabled() {

        this._isEnabled = !this._isEnabled;

      };



      _proto.toggle = function toggle(event) {

        if (!this._isEnabled) {

          return;

        }



        if (event) {

          var dataKey = this.constructor.DATA_KEY;

          var context = $$$1(event.currentTarget).data(dataKey);



          if (!context) {

            context = new this.constructor(event.currentTarget, this._getDelegateConfig());

            $$$1(event.currentTarget).data(dataKey, context);

          }



          context._activeTrigger.click = !context._activeTrigger.click;



          if (context._isWithActiveTrigger()) {

            context._enter(null, context);

          } else {

            context._leave(null, context);

          }

        } else {

          if ($$$1(this.getTipElement()).hasClass(ClassName.SHOW)) {

            this._leave(null, this);



            return;

          }



          this._enter(null, this);

        }

      };



      _proto.dispose = function dispose() {

        clearTimeout(this._timeout);

        $$$1.removeData(this.element, this.constructor.DATA_KEY);

        $$$1(this.element).off(this.constructor.EVENT_KEY);

        $$$1(this.element).closest('.modal').off('hide.bs.modal');



        if (this.tip) {

          $$$1(this.tip).remove();

        }



        this._isEnabled = null;

        this._timeout = null;

        this._hoverState = null;

        this._activeTrigger = null;



        if (this._popper !== null) {

          this._popper.destroy();

        }



        this._popper = null;

        this.element = null;

        this.config = null;

        this.tip = null;

      };



      _proto.show = function show() {

        var _this = this;



        if ($$$1(this.element).css('display') === 'none') {

          throw new Error('Please use show on visible elements');

        }



        var showEvent = $$$1.Event(this.constructor.Event.SHOW);



        if (this.isWithContent() && this._isEnabled) {

          $$$1(this.element).trigger(showEvent);

          var isInTheDom = $$$1.contains(this.element.ownerDocument.documentElement, this.element);



          if (showEvent.isDefaultPrevented() || !isInTheDom) {

            return;

          }



          var tip = this.getTipElement();

          var tipId = Util.getUID(this.constructor.NAME);

          tip.setAttribute('id', tipId);

          this.element.setAttribute('aria-describedby', tipId);

          this.setContent();



          if (this.config.animation) {

            $$$1(tip).addClass(ClassName.FADE);

          }



          var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement;



          var attachment = this._getAttachment(placement);



          this.addAttachmentClass(attachment);

          var container = this.config.container === false ? document.body : $$$1(this.config.container);

          $$$1(tip).data(this.constructor.DATA_KEY, this);



          if (!$$$1.contains(this.element.ownerDocument.documentElement, this.tip)) {

            $$$1(tip).appendTo(container);

          }



          $$$1(this.element).trigger(this.constructor.Event.INSERTED);

          this._popper = new Popper(this.element, tip, {

            placement: attachment,

            modifiers: {

              offset: {

                offset: this.config.offset

              },

              flip: {

                behavior: this.config.fallbackPlacement

              },

              arrow: {

                element: Selector.ARROW

              },

              preventOverflow: {

                boundariesElement: this.config.boundary

              }

            },

            onCreate: function onCreate(data) {

              if (data.originalPlacement !== data.placement) {

                _this._handlePopperPlacementChange(data);

              }

            },

            onUpdate: function onUpdate(data) {

              _this._handlePopperPlacementChange(data);

            }

          });

          $$$1(tip).addClass(ClassName.SHOW); // If this is a touch-enabled device we add extra

          // empty mouseover listeners to the body's immediate children;

          // only needed because of broken event delegation on iOS

          // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html



          if ('ontouchstart' in document.documentElement) {

            $$$1(document.body).children().on('mouseover', null, $$$1.noop);

          }



          var complete = function complete() {

            if (_this.config.animation) {

              _this._fixTransition();

            }



            var prevHoverState = _this._hoverState;

            _this._hoverState = null;

            $$$1(_this.element).trigger(_this.constructor.Event.SHOWN);



            if (prevHoverState === HoverState.OUT) {

              _this._leave(null, _this);

            }

          };



          if ($$$1(this.tip).hasClass(ClassName.FADE)) {

            var transitionDuration = Util.getTransitionDurationFromElement(this.tip);

            $$$1(this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);

          } else {

            complete();

          }

        }

      };



      _proto.hide = function hide(callback) {

        var _this2 = this;



        var tip = this.getTipElement();

        var hideEvent = $$$1.Event(this.constructor.Event.HIDE);



        var complete = function complete() {

          if (_this2._hoverState !== HoverState.SHOW && tip.parentNode) {

            tip.parentNode.removeChild(tip);

          }



          _this2._cleanTipClass();



          _this2.element.removeAttribute('aria-describedby');



          $$$1(_this2.element).trigger(_this2.constructor.Event.HIDDEN);



          if (_this2._popper !== null) {

            _this2._popper.destroy();

          }



          if (callback) {

            callback();

          }

        };



        $$$1(this.element).trigger(hideEvent);



        if (hideEvent.isDefaultPrevented()) {

          return;

        }



        $$$1(tip).removeClass(ClassName.SHOW); // If this is a touch-enabled device we remove the extra

        // empty mouseover listeners we added for iOS support



        if ('ontouchstart' in document.documentElement) {

          $$$1(document.body).children().off('mouseover', null, $$$1.noop);

        }



        this._activeTrigger[Trigger.CLICK] = false;

        this._activeTrigger[Trigger.FOCUS] = false;

        this._activeTrigger[Trigger.HOVER] = false;



        if ($$$1(this.tip).hasClass(ClassName.FADE)) {

          var transitionDuration = Util.getTransitionDurationFromElement(tip);

          $$$1(tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);

        } else {

          complete();

        }



        this._hoverState = '';

      };



      _proto.update = function update() {

        if (this._popper !== null) {

          this._popper.scheduleUpdate();

        }

      }; // Protected





      _proto.isWithContent = function isWithContent() {

        return Boolean(this.getTitle());

      };



      _proto.addAttachmentClass = function addAttachmentClass(attachment) {

        $$$1(this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment);

      };



      _proto.getTipElement = function getTipElement() {

        this.tip = this.tip || $$$1(this.config.template)[0];

        return this.tip;

      };



      _proto.setContent = function setContent() {

        var $tip = $$$1(this.getTipElement());

        this.setElementContent($tip.find(Selector.TOOLTIP_INNER), this.getTitle());

        $tip.removeClass(ClassName.FADE + " " + ClassName.SHOW);

      };



      _proto.setElementContent = function setElementContent($element, content) {

        var html = this.config.html;



        if (typeof content === 'object' && (content.nodeType || content.jquery)) {

          // Content is a DOM node or a jQuery

          if (html) {

            if (!$$$1(content).parent().is($element)) {

              $element.empty().append(content);

            }

          } else {

            $element.text($$$1(content).text());

          }

        } else {

          $element[html ? 'html' : 'text'](content);

        }

      };



      _proto.getTitle = function getTitle() {

        var title = this.element.getAttribute('data-original-title');



        if (!title) {

          title = typeof this.config.title === 'function' ? this.config.title.call(this.element) : this.config.title;

        }



        return title;

      }; // Private





      _proto._getAttachment = function _getAttachment(placement) {

        return AttachmentMap[placement.toUpperCase()];

      };



      _proto._setListeners = function _setListeners() {

        var _this3 = this;



        var triggers = this.config.trigger.split(' ');

        triggers.forEach(function (trigger) {

          if (trigger === 'click') {

            $$$1(_this3.element).on(_this3.constructor.Event.CLICK, _this3.config.selector, function (event) {

              return _this3.toggle(event);

            });

          } else if (trigger !== Trigger.MANUAL) {

            var eventIn = trigger === Trigger.HOVER ? _this3.constructor.Event.MOUSEENTER : _this3.constructor.Event.FOCUSIN;

            var eventOut = trigger === Trigger.HOVER ? _this3.constructor.Event.MOUSELEAVE : _this3.constructor.Event.FOCUSOUT;

            $$$1(_this3.element).on(eventIn, _this3.config.selector, function (event) {

              return _this3._enter(event);

            }).on(eventOut, _this3.config.selector, function (event) {

              return _this3._leave(event);

            });

          }



          $$$1(_this3.element).closest('.modal').on('hide.bs.modal', function () {

            return _this3.hide();

          });

        });



        if (this.config.selector) {

          this.config = _objectSpread({}, this.config, {

            trigger: 'manual',

            selector: ''

          });

        } else {

          this._fixTitle();

        }

      };



      _proto._fixTitle = function _fixTitle() {

        var titleType = typeof this.element.getAttribute('data-original-title');



        if (this.element.getAttribute('title') || titleType !== 'string') {

          this.element.setAttribute('data-original-title', this.element.getAttribute('title') || '');

          this.element.setAttribute('title', '');

        }

      };



      _proto._enter = function _enter(event, context) {

        var dataKey = this.constructor.DATA_KEY;

        context = context || $$$1(event.currentTarget).data(dataKey);



        if (!context) {

          context = new this.constructor(event.currentTarget, this._getDelegateConfig());

          $$$1(event.currentTarget).data(dataKey, context);

        }



        if (event) {

          context._activeTrigger[event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER] = true;

        }



        if ($$$1(context.getTipElement()).hasClass(ClassName.SHOW) || context._hoverState === HoverState.SHOW) {

          context._hoverState = HoverState.SHOW;

          return;

        }



        clearTimeout(context._timeout);

        context._hoverState = HoverState.SHOW;



        if (!context.config.delay || !context.config.delay.show) {

          context.show();

          return;

        }



        context._timeout = setTimeout(function () {

          if (context._hoverState === HoverState.SHOW) {

            context.show();

          }

        }, context.config.delay.show);

      };



      _proto._leave = function _leave(event, context) {

        var dataKey = this.constructor.DATA_KEY;

        context = context || $$$1(event.currentTarget).data(dataKey);



        if (!context) {

          context = new this.constructor(event.currentTarget, this._getDelegateConfig());

          $$$1(event.currentTarget).data(dataKey, context);

        }



        if (event) {

          context._activeTrigger[event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER] = false;

        }



        if (context._isWithActiveTrigger()) {

          return;

        }



        clearTimeout(context._timeout);

        context._hoverState = HoverState.OUT;



        if (!context.config.delay || !context.config.delay.hide) {

          context.hide();

          return;

        }



        context._timeout = setTimeout(function () {

          if (context._hoverState === HoverState.OUT) {

            context.hide();

          }

        }, context.config.delay.hide);

      };



      _proto._isWithActiveTrigger = function _isWithActiveTrigger() {

        for (var trigger in this._activeTrigger) {

          if (this._activeTrigger[trigger]) {

            return true;

          }

        }



        return false;

      };



      _proto._getConfig = function _getConfig(config) {

        config = _objectSpread({}, this.constructor.Default, $$$1(this.element).data(), config);



        if (typeof config.delay === 'number') {

          config.delay = {

            show: config.delay,

            hide: config.delay

          };

        }



        if (typeof config.title === 'number') {

          config.title = config.title.toString();

        }



        if (typeof config.content === 'number') {

          config.content = config.content.toString();

        }



        Util.typeCheckConfig(NAME, config, this.constructor.DefaultType);

        return config;

      };



      _proto._getDelegateConfig = function _getDelegateConfig() {

        var config = {};



        if (this.config) {

          for (var key in this.config) {

            if (this.constructor.Default[key] !== this.config[key]) {

              config[key] = this.config[key];

            }

          }

        }



        return config;

      };



      _proto._cleanTipClass = function _cleanTipClass() {

        var $tip = $$$1(this.getTipElement());

        var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX);



        if (tabClass !== null && tabClass.length > 0) {

          $tip.removeClass(tabClass.join(''));

        }

      };



      _proto._handlePopperPlacementChange = function _handlePopperPlacementChange(data) {

        this._cleanTipClass();



        this.addAttachmentClass(this._getAttachment(data.placement));

      };



      _proto._fixTransition = function _fixTransition() {

        var tip = this.getTipElement();

        var initConfigAnimation = this.config.animation;



        if (tip.getAttribute('x-placement') !== null) {

          return;

        }



        $$$1(tip).removeClass(ClassName.FADE);

        this.config.animation = false;

        this.hide();

        this.show();

        this.config.animation = initConfigAnimation;

      }; // Static





      Tooltip._jQueryInterface = function _jQueryInterface(config) {

        return this.each(function () {

          var data = $$$1(this).data(DATA_KEY);



          var _config = typeof config === 'object' && config;



          if (!data && /dispose|hide/.test(config)) {

            return;

          }



          if (!data) {

            data = new Tooltip(this, _config);

            $$$1(this).data(DATA_KEY, data);

          }



          if (typeof config === 'string') {

            if (typeof data[config] === 'undefined') {

              throw new TypeError("No method named \"" + config + "\"");

            }



            data[config]();

          }

        });

      };



      _createClass(Tooltip, null, [{

        key: "VERSION",

        get: function get() {

          return VERSION;

        }

      }, {

        key: "Default",

        get: function get() {

          return Default;

        }

      }, {

        key: "NAME",

        get: function get() {

          return NAME;

        }

      }, {

        key: "DATA_KEY",

        get: function get() {

          return DATA_KEY;

        }

      }, {

        key: "Event",

        get: function get() {

          return Event;

        }

      }, {

        key: "EVENT_KEY",

        get: function get() {

          return EVENT_KEY;

        }

      }, {

        key: "DefaultType",

        get: function get() {

          return DefaultType;

        }

      }]);



      return Tooltip;

    }();

    /**

     * ------------------------------------------------------------------------

     * jQuery

     * ------------------------------------------------------------------------

     */





    $$$1.fn[NAME] = Tooltip._jQueryInterface;

    $$$1.fn[NAME].Constructor = Tooltip;



    $$$1.fn[NAME].noConflict = function () {

      $$$1.fn[NAME] = JQUERY_NO_CONFLICT;

      return Tooltip._jQueryInterface;

    };



    return Tooltip;

  }($, Popper);



  /**

   * --------------------------------------------------------------------------

   * Bootstrap (v4.1.0): popover.js

   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

   * --------------------------------------------------------------------------

   */



  var Popover = function ($$$1) {

    /**

     * ------------------------------------------------------------------------

     * Constants

     * ------------------------------------------------------------------------

     */

    var NAME = 'popover';

    var VERSION = '4.1.0';

    var DATA_KEY = 'bs.popover';

    var EVENT_KEY = "." + DATA_KEY;

    var JQUERY_NO_CONFLICT = $$$1.fn[NAME];

    var CLASS_PREFIX = 'bs-popover';

    var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g');



    var Default = _objectSpread({}, Tooltip.Default, {

      placement: 'right',

      trigger: 'click',

      content: '',

      template: '<div class="popover" role="tooltip">' + '<div class="arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div></div>'

    });



    var DefaultType = _objectSpread({}, Tooltip.DefaultType, {

      content: '(string|element|function)'

    });



    var ClassName = {

      FADE: 'fade',

      SHOW: 'show'

    };

    var Selector = {

      TITLE: '.popover-header',

      CONTENT: '.popover-body'

    };

    var Event = {

      HIDE: "hide" + EVENT_KEY,

      HIDDEN: "hidden" + EVENT_KEY,

      SHOW: "show" + EVENT_KEY,

      SHOWN: "shown" + EVENT_KEY,

      INSERTED: "inserted" + EVENT_KEY,

      CLICK: "click" + EVENT_KEY,

      FOCUSIN: "focusin" + EVENT_KEY,

      FOCUSOUT: "focusout" + EVENT_KEY,

      MOUSEENTER: "mouseenter" + EVENT_KEY,

      MOUSELEAVE: "mouseleave" + EVENT_KEY

      /**

       * ------------------------------------------------------------------------

       * Class Definition

       * ------------------------------------------------------------------------

       */



    };



    var Popover =

    /*#__PURE__*/

    function (_Tooltip) {

      _inheritsLoose(Popover, _Tooltip);



      function Popover() {

        return _Tooltip.apply(this, arguments) || this;

      }



      var _proto = Popover.prototype;



      // Overrides

      _proto.isWithContent = function isWithContent() {

        return this.getTitle() || this._getContent();

      };



      _proto.addAttachmentClass = function addAttachmentClass(attachment) {

        $$$1(this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment);

      };



      _proto.getTipElement = function getTipElement() {

        this.tip = this.tip || $$$1(this.config.template)[0];

        return this.tip;

      };



      _proto.setContent = function setContent() {

        var $tip = $$$1(this.getTipElement()); // We use append for html objects to maintain js events



        this.setElementContent($tip.find(Selector.TITLE), this.getTitle());



        var content = this._getContent();



        if (typeof content === 'function') {

          content = content.call(this.element);

        }



        this.setElementContent($tip.find(Selector.CONTENT), content);

        $tip.removeClass(ClassName.FADE + " " + ClassName.SHOW);

      }; // Private





      _proto._getContent = function _getContent() {

        return this.element.getAttribute('data-content') || this.config.content;

      };



      _proto._cleanTipClass = function _cleanTipClass() {

        var $tip = $$$1(this.getTipElement());

        var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX);



        if (tabClass !== null && tabClass.length > 0) {

          $tip.removeClass(tabClass.join(''));

        }

      }; // Static





      Popover._jQueryInterface = function _jQueryInterface(config) {

        return this.each(function () {

          var data = $$$1(this).data(DATA_KEY);



          var _config = typeof config === 'object' ? config : null;



          if (!data && /destroy|hide/.test(config)) {

            return;

          }



          if (!data) {

            data = new Popover(this, _config);

            $$$1(this).data(DATA_KEY, data);

          }



          if (typeof config === 'string') {

            if (typeof data[config] === 'undefined') {

              throw new TypeError("No method named \"" + config + "\"");

            }



            data[config]();

          }

        });

      };



      _createClass(Popover, null, [{

        key: "VERSION",

        // Getters

        get: function get() {

          return VERSION;

        }

      }, {

        key: "Default",

        get: function get() {

          return Default;

        }

      }, {

        key: "NAME",

        get: function get() {

          return NAME;

        }

      }, {

        key: "DATA_KEY",

        get: function get() {

          return DATA_KEY;

        }

      }, {

        key: "Event",

        get: function get() {

          return Event;

        }

      }, {

        key: "EVENT_KEY",

        get: function get() {

          return EVENT_KEY;

        }

      }, {

        key: "DefaultType",

        get: function get() {

          return DefaultType;

        }

      }]);



      return Popover;

    }(Tooltip);

    /**

     * ------------------------------------------------------------------------

     * jQuery

     * ------------------------------------------------------------------------

     */





    $$$1.fn[NAME] = Popover._jQueryInterface;

    $$$1.fn[NAME].Constructor = Popover;



    $$$1.fn[NAME].noConflict = function () {

      $$$1.fn[NAME] = JQUERY_NO_CONFLICT;

      return Popover._jQueryInterface;

    };



    return Popover;

  }($);



  /**

   * --------------------------------------------------------------------------

   * Bootstrap (v4.1.0): scrollspy.js

   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

   * --------------------------------------------------------------------------

   */



  var ScrollSpy = function ($$$1) {

    /**

     * ------------------------------------------------------------------------

     * Constants

     * ------------------------------------------------------------------------

     */

    var NAME = 'scrollspy';

    var VERSION = '4.1.0';

    var DATA_KEY = 'bs.scrollspy';

    var EVENT_KEY = "." + DATA_KEY;

    var DATA_API_KEY = '.data-api';

    var JQUERY_NO_CONFLICT = $$$1.fn[NAME];

    var Default = {

      offset: 10,

      method: 'auto',

      target: ''

    };

    var DefaultType = {

      offset: 'number',

      method: 'string',

      target: '(string|element)'

    };

    var Event = {

      ACTIVATE: "activate" + EVENT_KEY,

      SCROLL: "scroll" + EVENT_KEY,

      LOAD_DATA_API: "load" + EVENT_KEY + DATA_API_KEY

    };

    var ClassName = {

      DROPDOWN_ITEM: 'dropdown-item',

      DROPDOWN_MENU: 'dropdown-menu',

      ACTIVE: 'active'

    };

    var Selector = {

      DATA_SPY: '[data-spy="scroll"]',

      ACTIVE: '.active',

      NAV_LIST_GROUP: '.nav, .list-group',

      NAV_LINKS: '.nav-link',

      NAV_ITEMS: '.nav-item',

      LIST_ITEMS: '.list-group-item',

      DROPDOWN: '.dropdown',

      DROPDOWN_ITEMS: '.dropdown-item',

      DROPDOWN_TOGGLE: '.dropdown-toggle'

    };

    var OffsetMethod = {

      OFFSET: 'offset',

      POSITION: 'position'

      /**

       * ------------------------------------------------------------------------

       * Class Definition

       * ------------------------------------------------------------------------

       */



    };



    var ScrollSpy =

    /*#__PURE__*/

    function () {

      function ScrollSpy(element, config) {

        var _this = this;



        this._element = element;

        this._scrollElement = element.tagName === 'BODY' ? window : element;

        this._config = this._getConfig(config);

        this._selector = this._config.target + " " + Selector.NAV_LINKS + "," + (this._config.target + " " + Selector.LIST_ITEMS + ",") + (this._config.target + " " + Selector.DROPDOWN_ITEMS);

        this._offsets = [];

        this._targets = [];

        this._activeTarget = null;

        this._scrollHeight = 0;

        $$$1(this._scrollElement).on(Event.SCROLL, function (event) {

          return _this._process(event);

        });

        this.refresh();



        this._process();

      } // Getters





      var _proto = ScrollSpy.prototype;



      // Public

      _proto.refresh = function refresh() {

        var _this2 = this;



        var autoMethod = this._scrollElement === this._scrollElement.window ? OffsetMethod.OFFSET : OffsetMethod.POSITION;

        var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;

        var offsetBase = offsetMethod === OffsetMethod.POSITION ? this._getScrollTop() : 0;

        this._offsets = [];

        this._targets = [];

        this._scrollHeight = this._getScrollHeight();

        var targets = $$$1.makeArray($$$1(this._selector));

        targets.map(function (element) {

          var target;

          var targetSelector = Util.getSelectorFromElement(element);



          if (targetSelector) {

            target = $$$1(targetSelector)[0];

          }



          if (target) {

            var targetBCR = target.getBoundingClientRect();



            if (targetBCR.width || targetBCR.height) {

              // TODO (fat): remove sketch reliance on jQuery position/offset

              return [$$$1(target)[offsetMethod]().top + offsetBase, targetSelector];

            }

          }



          return null;

        }).filter(function (item) {

          return item;

        }).sort(function (a, b) {

          return a[0] - b[0];

        }).forEach(function (item) {

          _this2._offsets.push(item[0]);



          _this2._targets.push(item[1]);

        });

      };



      _proto.dispose = function dispose() {

        $$$1.removeData(this._element, DATA_KEY);

        $$$1(this._scrollElement).off(EVENT_KEY);

        this._element = null;

        this._scrollElement = null;

        this._config = null;

        this._selector = null;

        this._offsets = null;

        this._targets = null;

        this._activeTarget = null;

        this._scrollHeight = null;

      }; // Private





      _proto._getConfig = function _getConfig(config) {

        config = _objectSpread({}, Default, config);



        if (typeof config.target !== 'string') {

          var id = $$$1(config.target).attr('id');



          if (!id) {

            id = Util.getUID(NAME);

            $$$1(config.target).attr('id', id);

          }



          config.target = "#" + id;

        }



        Util.typeCheckConfig(NAME, config, DefaultType);

        return config;

      };



      _proto._getScrollTop = function _getScrollTop() {

        return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop;

      };



      _proto._getScrollHeight = function _getScrollHeight() {

        return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);

      };



      _proto._getOffsetHeight = function _getOffsetHeight() {

        return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height;

      };



      _proto._process = function _process() {

        var scrollTop = this._getScrollTop() + this._config.offset;



        var scrollHeight = this._getScrollHeight();



        var maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight();



        if (this._scrollHeight !== scrollHeight) {

          this.refresh();

        }



        if (scrollTop >= maxScroll) {

          var target = this._targets[this._targets.length - 1];



          if (this._activeTarget !== target) {

            this._activate(target);

          }



          return;

        }



        if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {

          this._activeTarget = null;



          this._clear();



          return;

        }



        for (var i = this._offsets.length; i--;) {

          var isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]);



          if (isActiveTarget) {

            this._activate(this._targets[i]);

          }

        }

      };



      _proto._activate = function _activate(target) {

        this._activeTarget = target;



        this._clear();



        var queries = this._selector.split(','); // eslint-disable-next-line arrow-body-style





        queries = queries.map(function (selector) {

          return selector + "[data-target=\"" + target + "\"]," + (selector + "[href=\"" + target + "\"]");

        });

        var $link = $$$1(queries.join(','));



        if ($link.hasClass(ClassName.DROPDOWN_ITEM)) {

          $link.closest(Selector.DROPDOWN).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE);

          $link.addClass(ClassName.ACTIVE);

        } else {

          // Set triggered link as active

          $link.addClass(ClassName.ACTIVE); // Set triggered links parents as active

          // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor



          $link.parents(Selector.NAV_LIST_GROUP).prev(Selector.NAV_LINKS + ", " + Selector.LIST_ITEMS).addClass(ClassName.ACTIVE); // Handle special case when .nav-link is inside .nav-item



          $link.parents(Selector.NAV_LIST_GROUP).prev(Selector.NAV_ITEMS).children(Selector.NAV_LINKS).addClass(ClassName.ACTIVE);

        }



        $$$1(this._scrollElement).trigger(Event.ACTIVATE, {

          relatedTarget: target

        });

      };



      _proto._clear = function _clear() {

        $$$1(this._selector).filter(Selector.ACTIVE).removeClass(ClassName.ACTIVE);

      }; // Static





      ScrollSpy._jQueryInterface = function _jQueryInterface(config) {

        return this.each(function () {

          var data = $$$1(this).data(DATA_KEY);



          var _config = typeof config === 'object' && config;



          if (!data) {

            data = new ScrollSpy(this, _config);

            $$$1(this).data(DATA_KEY, data);

          }



          if (typeof config === 'string') {

            if (typeof data[config] === 'undefined') {

              throw new TypeError("No method named \"" + config + "\"");

            }



            data[config]();

          }

        });

      };



      _createClass(ScrollSpy, null, [{

        key: "VERSION",

        get: function get() {

          return VERSION;

        }

      }, {

        key: "Default",

        get: function get() {

          return Default;

        }

      }]);



      return ScrollSpy;

    }();

    /**

     * ------------------------------------------------------------------------

     * Data Api implementation

     * ------------------------------------------------------------------------

     */





    $$$1(window).on(Event.LOAD_DATA_API, function () {

      var scrollSpys = $$$1.makeArray($$$1(Selector.DATA_SPY));



      for (var i = scrollSpys.length; i--;) {

        var $spy = $$$1(scrollSpys[i]);



        ScrollSpy._jQueryInterface.call($spy, $spy.data());

      }

    });

    /**

     * ------------------------------------------------------------------------

     * jQuery

     * ------------------------------------------------------------------------

     */



    $$$1.fn[NAME] = ScrollSpy._jQueryInterface;

    $$$1.fn[NAME].Constructor = ScrollSpy;



    $$$1.fn[NAME].noConflict = function () {

      $$$1.fn[NAME] = JQUERY_NO_CONFLICT;

      return ScrollSpy._jQueryInterface;

    };



    return ScrollSpy;

  }($);



  /**

   * --------------------------------------------------------------------------

   * Bootstrap (v4.1.0): tab.js

   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

   * --------------------------------------------------------------------------

   */



  var Tab = function ($$$1) {

    /**

     * ------------------------------------------------------------------------

     * Constants

     * ------------------------------------------------------------------------

     */

    var NAME = 'tab';

    var VERSION = '4.1.0';

    var DATA_KEY = 'bs.tab';

    var EVENT_KEY = "." + DATA_KEY;

    var DATA_API_KEY = '.data-api';

    var JQUERY_NO_CONFLICT = $$$1.fn[NAME];

    var Event = {

      HIDE: "hide" + EVENT_KEY,

      HIDDEN: "hidden" + EVENT_KEY,

      SHOW: "show" + EVENT_KEY,

      SHOWN: "shown" + EVENT_KEY,

      CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY

    };

    var ClassName = {

      DROPDOWN_MENU: 'dropdown-menu',

      ACTIVE: 'active',

      DISABLED: 'disabled',

      FADE: 'fade',

      SHOW: 'show'

    };

    var Selector = {

      DROPDOWN: '.dropdown',

      NAV_LIST_GROUP: '.nav, .list-group',

      ACTIVE: '.active',

      ACTIVE_UL: '> li > .active',

      DATA_TOGGLE: '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',

      DROPDOWN_TOGGLE: '.dropdown-toggle',

      DROPDOWN_ACTIVE_CHILD: '> .dropdown-menu .active'

      /**

       * ------------------------------------------------------------------------

       * Class Definition

       * ------------------------------------------------------------------------

       */



    };



    var Tab =

    /*#__PURE__*/

    function () {

      function Tab(element) {

        this._element = element;

      } // Getters





      var _proto = Tab.prototype;



      // Public

      _proto.show = function show() {

        var _this = this;



        if (this._element.parentNode && this._element.parentNode.nodeType === Node.ELEMENT_NODE && $$$1(this._element).hasClass(ClassName.ACTIVE) || $$$1(this._element).hasClass(ClassName.DISABLED)) {

          return;

        }



        var target;

        var previous;

        var listElement = $$$1(this._element).closest(Selector.NAV_LIST_GROUP)[0];

        var selector = Util.getSelectorFromElement(this._element);



        if (listElement) {

          var itemSelector = listElement.nodeName === 'UL' ? Selector.ACTIVE_UL : Selector.ACTIVE;

          previous = $$$1.makeArray($$$1(listElement).find(itemSelector));

          previous = previous[previous.length - 1];

        }



        var hideEvent = $$$1.Event(Event.HIDE, {

          relatedTarget: this._element

        });

        var showEvent = $$$1.Event(Event.SHOW, {

          relatedTarget: previous

        });



        if (previous) {

          $$$1(previous).trigger(hideEvent);

        }



        $$$1(this._element).trigger(showEvent);



        if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) {

          return;

        }



        if (selector) {

          target = $$$1(selector)[0];

        }



        this._activate(this._element, listElement);



        var complete = function complete() {

          var hiddenEvent = $$$1.Event(Event.HIDDEN, {

            relatedTarget: _this._element

          });

          var shownEvent = $$$1.Event(Event.SHOWN, {

            relatedTarget: previous

          });

          $$$1(previous).trigger(hiddenEvent);

          $$$1(_this._element).trigger(shownEvent);

        };



        if (target) {

          this._activate(target, target.parentNode, complete);

        } else {

          complete();

        }

      };



      _proto.dispose = function dispose() {

        $$$1.removeData(this._element, DATA_KEY);

        this._element = null;

      }; // Private





      _proto._activate = function _activate(element, container, callback) {

        var _this2 = this;



        var activeElements;



        if (container.nodeName === 'UL') {

          activeElements = $$$1(container).find(Selector.ACTIVE_UL);

        } else {

          activeElements = $$$1(container).children(Selector.ACTIVE);

        }



        var active = activeElements[0];

        var isTransitioning = callback && active && $$$1(active).hasClass(ClassName.FADE);



        var complete = function complete() {

          return _this2._transitionComplete(element, active, callback);

        };



        if (active && isTransitioning) {

          var transitionDuration = Util.getTransitionDurationFromElement(active);

          $$$1(active).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);

        } else {

          complete();

        }

      };



      _proto._transitionComplete = function _transitionComplete(element, active, callback) {

        if (active) {

          $$$1(active).removeClass(ClassName.SHOW + " " + ClassName.ACTIVE);

          var dropdownChild = $$$1(active.parentNode).find(Selector.DROPDOWN_ACTIVE_CHILD)[0];



          if (dropdownChild) {

            $$$1(dropdownChild).removeClass(ClassName.ACTIVE);

          }



          if (active.getAttribute('role') === 'tab') {

            active.setAttribute('aria-selected', false);

          }

        }



        $$$1(element).addClass(ClassName.ACTIVE);



        if (element.getAttribute('role') === 'tab') {

          element.setAttribute('aria-selected', true);

        }



        Util.reflow(element);

        $$$1(element).addClass(ClassName.SHOW);



        if (element.parentNode && $$$1(element.parentNode).hasClass(ClassName.DROPDOWN_MENU)) {

          var dropdownElement = $$$1(element).closest(Selector.DROPDOWN)[0];



          if (dropdownElement) {

            $$$1(dropdownElement).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE);

          }



          element.setAttribute('aria-expanded', true);

        }



        if (callback) {

          callback();

        }

      }; // Static





      Tab._jQueryInterface = function _jQueryInterface(config) {

        return this.each(function () {

          var $this = $$$1(this);

          var data = $this.data(DATA_KEY);



          if (!data) {

            data = new Tab(this);

            $this.data(DATA_KEY, data);

          }



          if (typeof config === 'string') {

            if (typeof data[config] === 'undefined') {

              throw new TypeError("No method named \"" + config + "\"");

            }



            data[config]();

          }

        });

      };



      _createClass(Tab, null, [{

        key: "VERSION",

        get: function get() {

          return VERSION;

        }

      }]);



      return Tab;

    }();

    /**

     * ------------------------------------------------------------------------

     * Data Api implementation

     * ------------------------------------------------------------------------

     */





    $$$1(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {

      event.preventDefault();



      Tab._jQueryInterface.call($$$1(this), 'show');

    });

    /**

     * ------------------------------------------------------------------------

     * jQuery

     * ------------------------------------------------------------------------

     */



    $$$1.fn[NAME] = Tab._jQueryInterface;

    $$$1.fn[NAME].Constructor = Tab;



    $$$1.fn[NAME].noConflict = function () {

      $$$1.fn[NAME] = JQUERY_NO_CONFLICT;

      return Tab._jQueryInterface;

    };



    return Tab;

  }($);



  /**

   * --------------------------------------------------------------------------

   * Bootstrap (v4.0.0): index.js

   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

   * --------------------------------------------------------------------------

   */



  (function ($$$1) {

    if (typeof $$$1 === 'undefined') {

      throw new TypeError('Bootstrap\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\'s JavaScript.');

    }



    var version = $$$1.fn.jquery.split(' ')[0].split('.');

    var minMajor = 1;

    var ltMajor = 2;

    var minMinor = 9;

    var minPatch = 1;

    var maxMajor = 4;



    if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) {

      throw new Error('Bootstrap\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0');

    }

  })($);



  exports.Util = Util;

  exports.Alert = Alert;

  exports.Button = Button;

  exports.Carousel = Carousel;

  exports.Collapse = Collapse;

  exports.Dropdown = Dropdown;

  exports.Modal = Modal;

  exports.Popover = Popover;

  exports.Scrollspy = ScrollSpy;

  exports.Tab = Tab;

  exports.Tooltip = Tooltip;



  Object.defineProperty(exports, '__esModule', { value: true });



})));

//# sourceMappingURL=bootstrap.js.map





/***/ }),

/* 17 */

/***/ (function(module, exports, __webpack_require__) {



module.exports = __webpack_require__(18);



/***/ }),

/* 18 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";





var utils = __webpack_require__(0);

var bind = __webpack_require__(5);

var Axios = __webpack_require__(20);

var defaults = __webpack_require__(2);



/**

 * Create an instance of Axios

 *

 * @param {Object} defaultConfig The default config for the instance

 * @return {Axios} A new instance of Axios

 */

function createInstance(defaultConfig) {

  var context = new Axios(defaultConfig);

  var instance = bind(Axios.prototype.request, context);



  // Copy axios.prototype to instance

  utils.extend(instance, Axios.prototype, context);



  // Copy context to instance

  utils.extend(instance, context);



  return instance;

}



// Create the default instance to be exported

var axios = createInstance(defaults);



// Expose Axios class to allow class inheritance

axios.Axios = Axios;



// Factory for creating new instances

axios.create = function create(instanceConfig) {

  return createInstance(utils.merge(defaults, instanceConfig));

};



// Expose Cancel & CancelToken

axios.Cancel = __webpack_require__(10);

axios.CancelToken = __webpack_require__(34);

axios.isCancel = __webpack_require__(9);



// Expose all/spread

axios.all = function all(promises) {

  return Promise.all(promises);

};

axios.spread = __webpack_require__(35);



module.exports = axios;



// Allow use of default import syntax in TypeScript

module.exports.default = axios;





/***/ }),

/* 19 */

/***/ (function(module, exports) {



/*!

 * Determine if an object is a Buffer

 *

 * @author   Feross Aboukhadijeh <https://feross.org>

 * @license  MIT

 */



// The _isBuffer check is for Safari 5-7 support, because it's missing

// Object.prototype.constructor. Remove this eventually

module.exports = function (obj) {

  return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)

}



function isBuffer (obj) {

  return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)

}



// For Node v0.10 support. Remove this eventually.

function isSlowBuffer (obj) {

  return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))

}





/***/ }),

/* 20 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";





var defaults = __webpack_require__(2);

var utils = __webpack_require__(0);

var InterceptorManager = __webpack_require__(29);

var dispatchRequest = __webpack_require__(30);

var isAbsoluteURL = __webpack_require__(32);

var combineURLs = __webpack_require__(33);



/**

 * Create a new instance of Axios

 *

 * @param {Object} instanceConfig The default config for the instance

 */

function Axios(instanceConfig) {

  this.defaults = instanceConfig;

  this.interceptors = {

    request: new InterceptorManager(),

    response: new InterceptorManager()

  };

}



/**

 * Dispatch a request

 *

 * @param {Object} config The config specific for this request (merged with this.defaults)

 */

Axios.prototype.request = function request(config) {

  /*eslint no-param-reassign:0*/

  // Allow for axios('example/url'[, config]) a la fetch API

  if (typeof config === 'string') {

    config = utils.merge({

      url: arguments[0]

    }, arguments[1]);

  }



  config = utils.merge(defaults, this.defaults, { method: 'get' }, config);

  config.method = config.method.toLowerCase();



  // Support baseURL config

  if (config.baseURL && !isAbsoluteURL(config.url)) {

    config.url = combineURLs(config.baseURL, config.url);

  }



  // Hook up interceptors middleware

  var chain = [dispatchRequest, undefined];

  var promise = Promise.resolve(config);



  this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {

    chain.unshift(interceptor.fulfilled, interceptor.rejected);

  });



  this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {

    chain.push(interceptor.fulfilled, interceptor.rejected);

  });



  while (chain.length) {

    promise = promise.then(chain.shift(), chain.shift());

  }



  return promise;

};



// Provide aliases for supported request methods

utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {

  /*eslint func-names:0*/

  Axios.prototype[method] = function(url, config) {

    return this.request(utils.merge(config || {}, {

      method: method,

      url: url

    }));

  };

});



utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {

  /*eslint func-names:0*/

  Axios.prototype[method] = function(url, data, config) {

    return this.request(utils.merge(config || {}, {

      method: method,

      url: url,

      data: data

    }));

  };

});



module.exports = Axios;





/***/ }),

/* 21 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";





var utils = __webpack_require__(0);



module.exports = function normalizeHeaderName(headers, normalizedName) {

  utils.forEach(headers, function processHeader(value, name) {

    if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) {

      headers[normalizedName] = value;

      delete headers[name];

    }

  });

};





/***/ }),

/* 22 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";





var createError = __webpack_require__(8);



/**

 * Resolve or reject a Promise based on response status.

 *

 * @param {Function} resolve A function that resolves the promise.

 * @param {Function} reject A function that rejects the promise.

 * @param {object} response The response.

 */

module.exports = function settle(resolve, reject, response) {

  var validateStatus = response.config.validateStatus;

  // Note: status is not exposed by XDomainRequest

  if (!response.status || !validateStatus || validateStatus(response.status)) {

    resolve(response);

  } else {

    reject(createError(

      'Request failed with status code ' + response.status,

      response.config,

      null,

      response.request,

      response

    ));

  }

};





/***/ }),

/* 23 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";





/**

 * Update an Error with the specified config, error code, and response.

 *

 * @param {Error} error The error to update.

 * @param {Object} config The config.

 * @param {string} [code] The error code (for example, 'ECONNABORTED').

 * @param {Object} [request] The request.

 * @param {Object} [response] The response.

 * @returns {Error} The error.

 */

module.exports = function enhanceError(error, config, code, request, response) {

  error.config = config;

  if (code) {

    error.code = code;

  }

  error.request = request;

  error.response = response;

  return error;

};





/***/ }),

/* 24 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";





var utils = __webpack_require__(0);



function encode(val) {

  return encodeURIComponent(val).

    replace(/%40/gi, '@').

    replace(/%3A/gi, ':').

    replace(/%24/g, '$').

    replace(/%2C/gi, ',').

    replace(/%20/g, '+').

    replace(/%5B/gi, '[').

    replace(/%5D/gi, ']');

}



/**

 * Build a URL by appending params to the end

 *

 * @param {string} url The base of the url (e.g., http://www.google.com)

 * @param {object} [params] The params to be appended

 * @returns {string} The formatted url

 */

module.exports = function buildURL(url, params, paramsSerializer) {

  /*eslint no-param-reassign:0*/

  if (!params) {

    return url;

  }



  var serializedParams;

  if (paramsSerializer) {

    serializedParams = paramsSerializer(params);

  } else if (utils.isURLSearchParams(params)) {

    serializedParams = params.toString();

  } else {

    var parts = [];



    utils.forEach(params, function serialize(val, key) {

      if (val === null || typeof val === 'undefined') {

        return;

      }



      if (utils.isArray(val)) {

        key = key + '[]';

      }



      if (!utils.isArray(val)) {

        val = [val];

      }



      utils.forEach(val, function parseValue(v) {

        if (utils.isDate(v)) {

          v = v.toISOString();

        } else if (utils.isObject(v)) {

          v = JSON.stringify(v);

        }

        parts.push(encode(key) + '=' + encode(v));

      });

    });



    serializedParams = parts.join('&');

  }



  if (serializedParams) {

    url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;

  }



  return url;

};





/***/ }),

/* 25 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";





var utils = __webpack_require__(0);



/**

 * Parse headers into an object

 *

 * ```

 * Date: Wed, 27 Aug 2014 08:58:49 GMT

 * Content-Type: application/json

 * Connection: keep-alive

 * Transfer-Encoding: chunked

 * ```

 *

 * @param {String} headers Headers needing to be parsed

 * @returns {Object} Headers parsed into an object

 */

module.exports = function parseHeaders(headers) {

  var parsed = {};

  var key;

  var val;

  var i;



  if (!headers) { return parsed; }



  utils.forEach(headers.split('\n'), function parser(line) {

    i = line.indexOf(':');

    key = utils.trim(line.substr(0, i)).toLowerCase();

    val = utils.trim(line.substr(i + 1));



    if (key) {

      parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;

    }

  });



  return parsed;

};





/***/ }),

/* 26 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";





var utils = __webpack_require__(0);



module.exports = (

  utils.isStandardBrowserEnv() ?



  // Standard browser envs have full support of the APIs needed to test

  // whether the request URL is of the same origin as current location.

  (function standardBrowserEnv() {

    var msie = /(msie|trident)/i.test(navigator.userAgent);

    var urlParsingNode = document.createElement('a');

    var originURL;



    /**

    * Parse a URL to discover it's components

    *

    * @param {String} url The URL to be parsed

    * @returns {Object}

    */

    function resolveURL(url) {

      var href = url;



      if (msie) {

        // IE needs attribute set twice to normalize properties

        urlParsingNode.setAttribute('href', href);

        href = urlParsingNode.href;

      }



      urlParsingNode.setAttribute('href', href);



      // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils

      return {

        href: urlParsingNode.href,

        protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',

        host: urlParsingNode.host,

        search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '',

        hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',

        hostname: urlParsingNode.hostname,

        port: urlParsingNode.port,

        pathname: (urlParsingNode.pathname.charAt(0) === '/') ?

                  urlParsingNode.pathname :

                  '/' + urlParsingNode.pathname

      };

    }



    originURL = resolveURL(window.location.href);



    /**

    * Determine if a URL shares the same origin as the current location

    *

    * @param {String} requestURL The URL to test

    * @returns {boolean} True if URL shares the same origin, otherwise false

    */

    return function isURLSameOrigin(requestURL) {

      var parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL;

      return (parsed.protocol === originURL.protocol &&

            parsed.host === originURL.host);

    };

  })() :



  // Non standard browser envs (web workers, react-native) lack needed support.

  (function nonStandardBrowserEnv() {

    return function isURLSameOrigin() {

      return true;

    };

  })()

);





/***/ }),

/* 27 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";





// btoa polyfill for IE<10 courtesy https://github.com/davidchambers/Base64.js



var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';



function E() {

  this.message = 'String contains an invalid character';

}

E.prototype = new Error;

E.prototype.code = 5;

E.prototype.name = 'InvalidCharacterError';



function btoa(input) {

  var str = String(input);

  var output = '';

  for (

    // initialize result and counter

    var block, charCode, idx = 0, map = chars;

    // if the next str index does not exist:

    //   change the mapping table to "="

    //   check if d has no fractional digits

    str.charAt(idx | 0) || (map = '=', idx % 1);

    // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8

    output += map.charAt(63 & block >> 8 - idx % 1 * 8)

  ) {

    charCode = str.charCodeAt(idx += 3 / 4);

    if (charCode > 0xFF) {

      throw new E();

    }

    block = block << 8 | charCode;

  }

  return output;

}



module.exports = btoa;





/***/ }),

/* 28 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";





var utils = __webpack_require__(0);



module.exports = (

  utils.isStandardBrowserEnv() ?



  // Standard browser envs support document.cookie

  (function standardBrowserEnv() {

    return {

      write: function write(name, value, expires, path, domain, secure) {

        var cookie = [];

        cookie.push(name + '=' + encodeURIComponent(value));



        if (utils.isNumber(expires)) {

          cookie.push('expires=' + new Date(expires).toGMTString());

        }



        if (utils.isString(path)) {

          cookie.push('path=' + path);

        }



        if (utils.isString(domain)) {

          cookie.push('domain=' + domain);

        }



        if (secure === true) {

          cookie.push('secure');

        }



        document.cookie = cookie.join('; ');

      },



      read: function read(name) {

        var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)'));

        return (match ? decodeURIComponent(match[3]) : null);

      },



      remove: function remove(name) {

        this.write(name, '', Date.now() - 86400000);

      }

    };

  })() :



  // Non standard browser env (web workers, react-native) lack needed support.

  (function nonStandardBrowserEnv() {

    return {

      write: function write() {},

      read: function read() { return null; },

      remove: function remove() {}

    };

  })()

);





/***/ }),

/* 29 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";





var utils = __webpack_require__(0);



function InterceptorManager() {

  this.handlers = [];

}



/**

 * Add a new interceptor to the stack

 *

 * @param {Function} fulfilled The function to handle `then` for a `Promise`

 * @param {Function} rejected The function to handle `reject` for a `Promise`

 *

 * @return {Number} An ID used to remove interceptor later

 */

InterceptorManager.prototype.use = function use(fulfilled, rejected) {

  this.handlers.push({

    fulfilled: fulfilled,

    rejected: rejected

  });

  return this.handlers.length - 1;

};



/**

 * Remove an interceptor from the stack

 *

 * @param {Number} id The ID that was returned by `use`

 */

InterceptorManager.prototype.eject = function eject(id) {

  if (this.handlers[id]) {

    this.handlers[id] = null;

  }

};



/**

 * Iterate over all the registered interceptors

 *

 * This method is particularly useful for skipping over any

 * interceptors that may have become `null` calling `eject`.

 *

 * @param {Function} fn The function to call for each interceptor

 */

InterceptorManager.prototype.forEach = function forEach(fn) {

  utils.forEach(this.handlers, function forEachHandler(h) {

    if (h !== null) {

      fn(h);

    }

  });

};



module.exports = InterceptorManager;





/***/ }),

/* 30 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";





var utils = __webpack_require__(0);

var transformData = __webpack_require__(31);

var isCancel = __webpack_require__(9);

var defaults = __webpack_require__(2);



/**

 * Throws a `Cancel` if cancellation has been requested.

 */

function throwIfCancellationRequested(config) {

  if (config.cancelToken) {

    config.cancelToken.throwIfRequested();

  }

}



/**

 * Dispatch a request to the server using the configured adapter.

 *

 * @param {object} config The config that is to be used for the request

 * @returns {Promise} The Promise to be fulfilled

 */

module.exports = function dispatchRequest(config) {

  throwIfCancellationRequested(config);



  // Ensure headers exist

  config.headers = config.headers || {};



  // Transform request data

  config.data = transformData(

    config.data,

    config.headers,

    config.transformRequest

  );



  // Flatten headers

  config.headers = utils.merge(

    config.headers.common || {},

    config.headers[config.method] || {},

    config.headers || {}

  );



  utils.forEach(

    ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],

    function cleanHeaderConfig(method) {

      delete config.headers[method];

    }

  );



  var adapter = config.adapter || defaults.adapter;



  return adapter(config).then(function onAdapterResolution(response) {

    throwIfCancellationRequested(config);



    // Transform response data

    response.data = transformData(

      response.data,

      response.headers,

      config.transformResponse

    );



    return response;

  }, function onAdapterRejection(reason) {

    if (!isCancel(reason)) {

      throwIfCancellationRequested(config);



      // Transform response data

      if (reason && reason.response) {

        reason.response.data = transformData(

          reason.response.data,

          reason.response.headers,

          config.transformResponse

        );

      }

    }



    return Promise.reject(reason);

  });

};





/***/ }),

/* 31 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";





var utils = __webpack_require__(0);



/**

 * Transform the data for a request or a response

 *

 * @param {Object|String} data The data to be transformed

 * @param {Array} headers The headers for the request or response

 * @param {Array|Function} fns A single function or Array of functions

 * @returns {*} The resulting transformed data

 */

module.exports = function transformData(data, headers, fns) {

  /*eslint no-param-reassign:0*/

  utils.forEach(fns, function transform(fn) {

    data = fn(data, headers);

  });



  return data;

};





/***/ }),

/* 32 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";





/**

 * Determines whether the specified URL is absolute

 *

 * @param {string} url The URL to test

 * @returns {boolean} True if the specified URL is absolute, otherwise false

 */

module.exports = function isAbsoluteURL(url) {

  // A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).

  // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed

  // by any combination of letters, digits, plus, period, or hyphen.

  return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url);

};





/***/ }),

/* 33 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";





/**

 * Creates a new URL by combining the specified URLs

 *

 * @param {string} baseURL The base URL

 * @param {string} relativeURL The relative URL

 * @returns {string} The combined URL

 */

module.exports = function combineURLs(baseURL, relativeURL) {

  return relativeURL

    ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '')

    : baseURL;

};





/***/ }),

/* 34 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";





var Cancel = __webpack_require__(10);



/**

 * A `CancelToken` is an object that can be used to request cancellation of an operation.

 *

 * @class

 * @param {Function} executor The executor function.

 */

function CancelToken(executor) {

  if (typeof executor !== 'function') {

    throw new TypeError('executor must be a function.');

  }



  var resolvePromise;

  this.promise = new Promise(function promiseExecutor(resolve) {

    resolvePromise = resolve;

  });



  var token = this;

  executor(function cancel(message) {

    if (token.reason) {

      // Cancellation has already been requested

      return;

    }



    token.reason = new Cancel(message);

    resolvePromise(token.reason);

  });

}



/**

 * Throws a `Cancel` if cancellation has been requested.

 */

CancelToken.prototype.throwIfRequested = function throwIfRequested() {

  if (this.reason) {

    throw this.reason;

  }

};



/**

 * Returns an object that contains a new `CancelToken` and a function that, when called,

 * cancels the `CancelToken`.

 */

CancelToken.source = function source() {

  var cancel;

  var token = new CancelToken(function executor(c) {

    cancel = c;

  });

  return {

    token: token,

    cancel: cancel

  };

};



module.exports = CancelToken;





/***/ }),

/* 35 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";





/**

 * Syntactic sugar for invoking a function and expanding an array for arguments.

 *

 * Common use case would be to use `Function.prototype.apply`.

 *

 *  ```js

 *  function f(x, y, z) {}

 *  var args = [1, 2, 3];

 *  f.apply(null, args);

 *  ```

 *

 * With `spread` this example can be re-written.

 *

 *  ```js

 *  spread(function(x, y, z) {})([1, 2, 3]);

 *  ```

 *

 * @param {Function} callback

 * @returns {Function}

 */

module.exports = function spread(callback) {

  return function wrap(arr) {

    return callback.apply(null, arr);

  };

};





/***/ }),

/* 36 */

/***/ (function(module, exports, __webpack_require__) {



"use strict";

/* WEBPACK VAR INJECTION */(function(global, setImmediate) {/*!

 * Vue.js v2.5.13

 * (c) 2014-2017 Evan You

 * Released under the MIT License.

 */





/*  */



var emptyObject = Object.freeze({});



// these helpers produces better vm code in JS engines due to their

// explicitness and function inlining

function isUndef (v) {

  return v === undefined || v === null

}



function isDef (v) {

  return v !== undefined && v !== null

}



function isTrue (v) {

  return v === true

}



function isFalse (v) {

  return v === false

}



/**

 * Check if value is primitive

 */

function isPrimitive (value) {

  return (

    typeof value === 'string' ||

    typeof value === 'number' ||

    // $flow-disable-line

    typeof value === 'symbol' ||

    typeof value === 'boolean'

  )

}



/**

 * Quick object check - this is primarily used to tell

 * Objects from primitive values when we know the value

 * is a JSON-compliant type.

 */

function isObject (obj) {

  return obj !== null && typeof obj === 'object'

}



/**

 * Get the raw type string of a value e.g. [object Object]

 */

var _toString = Object.prototype.toString;



function toRawType (value) {

  return _toString.call(value).slice(8, -1)

}



/**

 * Strict object type check. Only returns true

 * for plain JavaScript objects.

 */

function isPlainObject (obj) {

  return _toString.call(obj) === '[object Object]'

}



function isRegExp (v) {

  return _toString.call(v) === '[object RegExp]'

}



/**

 * Check if val is a valid array index.

 */

function isValidArrayIndex (val) {

  var n = parseFloat(String(val));

  return n >= 0 && Math.floor(n) === n && isFinite(val)

}



/**

 * Convert a value to a string that is actually rendered.

 */

function toString (val) {

  return val == null

    ? ''

    : typeof val === 'object'

      ? JSON.stringify(val, null, 2)

      : String(val)

}



/**

 * Convert a input value to a number for persistence.

 * If the conversion fails, return original string.

 */

function toNumber (val) {

  var n = parseFloat(val);

  return isNaN(n) ? val : n

}



/**

 * Make a map and return a function for checking if a key

 * is in that map.

 */

function makeMap (

  str,

  expectsLowerCase

) {

  var map = Object.create(null);

  var list = str.split(',');

  for (var i = 0; i < list.length; i++) {

    map[list[i]] = true;

  }

  return expectsLowerCase

    ? function (val) { return map[val.toLowerCase()]; }

    : function (val) { return map[val]; }

}



/**

 * Check if a tag is a built-in tag.

 */

var isBuiltInTag = makeMap('slot,component', true);



/**

 * Check if a attribute is a reserved attribute.

 */

var isReservedAttribute = makeMap('key,ref,slot,slot-scope,is');



/**

 * Remove an item from an array

 */

function remove (arr, item) {

  if (arr.length) {

    var index = arr.indexOf(item);

    if (index > -1) {

      return arr.splice(index, 1)

    }

  }

}



/**

 * Check whether the object has the property.

 */

var hasOwnProperty = Object.prototype.hasOwnProperty;

function hasOwn (obj, key) {

  return hasOwnProperty.call(obj, key)

}



/**

 * Create a cached version of a pure function.

 */

function cached (fn) {

  var cache = Object.create(null);

  return (function cachedFn (str) {

    var hit = cache[str];

    return hit || (cache[str] = fn(str))

  })

}



/**

 * Camelize a hyphen-delimited string.

 */

var camelizeRE = /-(\w)/g;

var camelize = cached(function (str) {

  return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ''; })

});



/**

 * Capitalize a string.

 */

var capitalize = cached(function (str) {

  return str.charAt(0).toUpperCase() + str.slice(1)

});



/**

 * Hyphenate a camelCase string.

 */

var hyphenateRE = /\B([A-Z])/g;

var hyphenate = cached(function (str) {

  return str.replace(hyphenateRE, '-$1').toLowerCase()

});



/**

 * Simple bind, faster than native

 */

function bind (fn, ctx) {

  function boundFn (a) {

    var l = arguments.length;

    return l

      ? l > 1

        ? fn.apply(ctx, arguments)

        : fn.call(ctx, a)

      : fn.call(ctx)

  }

  // record original fn length

  boundFn._length = fn.length;

  return boundFn

}



/**

 * Convert an Array-like object to a real Array.

 */

function toArray (list, start) {

  start = start || 0;

  var i = list.length - start;

  var ret = new Array(i);

  while (i--) {

    ret[i] = list[i + start];

  }

  return ret

}



/**

 * Mix properties into target object.

 */

function extend (to, _from) {

  for (var key in _from) {

    to[key] = _from[key];

  }

  return to

}



/**

 * Merge an Array of Objects into a single Object.

 */

function toObject (arr) {

  var res = {};

  for (var i = 0; i < arr.length; i++) {

    if (arr[i]) {

      extend(res, arr[i]);

    }

  }

  return res

}



/**

 * Perform no operation.

 * Stubbing args to make Flow happy without leaving useless transpiled code

 * with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/)

 */

function noop (a, b, c) {}



/**

 * Always return false.

 */

var no = function (a, b, c) { return false; };



/**

 * Return same value

 */

var identity = function (_) { return _; };



/**

 * Generate a static keys string from compiler modules.

 */

function genStaticKeys (modules) {

  return modules.reduce(function (keys, m) {

    return keys.concat(m.staticKeys || [])

  }, []).join(',')

}



/**

 * Check if two values are loosely equal - that is,

 * if they are plain objects, do they have the same shape?

 */

function looseEqual (a, b) {

  if (a === b) { return true }

  var isObjectA = isObject(a);

  var isObjectB = isObject(b);

  if (isObjectA && isObjectB) {

    try {

      var isArrayA = Array.isArray(a);

      var isArrayB = Array.isArray(b);

      if (isArrayA && isArrayB) {

        return a.length === b.length && a.every(function (e, i) {

          return looseEqual(e, b[i])

        })

      } else if (!isArrayA && !isArrayB) {

        var keysA = Object.keys(a);

        var keysB = Object.keys(b);

        return keysA.length === keysB.length && keysA.every(function (key) {

          return looseEqual(a[key], b[key])

        })

      } else {

        /* istanbul ignore next */

        return false

      }

    } catch (e) {

      /* istanbul ignore next */

      return false

    }

  } else if (!isObjectA && !isObjectB) {

    return String(a) === String(b)

  } else {

    return false

  }

}



function looseIndexOf (arr, val) {

  for (var i = 0; i < arr.length; i++) {

    if (looseEqual(arr[i], val)) { return i }

  }

  return -1

}



/**

 * Ensure a function is called only once.

 */

function once (fn) {

  var called = false;

  return function () {

    if (!called) {

      called = true;

      fn.apply(this, arguments);

    }

  }

}



var SSR_ATTR = 'data-server-rendered';



var ASSET_TYPES = [

  'component',

  'directive',

  'filter'

];



var LIFECYCLE_HOOKS = [

  'beforeCreate',

  'created',

  'beforeMount',

  'mounted',

  'beforeUpdate',

  'updated',

  'beforeDestroy',

  'destroyed',

  'activated',

  'deactivated',

  'errorCaptured'

];



/*  */



var config = ({

  /**

   * Option merge strategies (used in core/util/options)

   */

  // $flow-disable-line

  optionMergeStrategies: Object.create(null),



  /**

   * Whether to suppress warnings.

   */

  silent: false,



  /**

   * Show production mode tip message on boot?

   */

  productionTip: "development" !== 'production',



  /**

   * Whether to enable devtools

   */

  devtools: "development" !== 'production',



  /**

   * Whether to record perf

   */

  performance: false,



  /**

   * Error handler for watcher errors

   */

  errorHandler: null,



  /**

   * Warn handler for watcher warns

   */

  warnHandler: null,



  /**

   * Ignore certain custom elements

   */

  ignoredElements: [],



  /**

   * Custom user key aliases for v-on

   */

  // $flow-disable-line

  keyCodes: Object.create(null),



  /**

   * Check if a tag is reserved so that it cannot be registered as a

   * component. This is platform-dependent and may be overwritten.

   */

  isReservedTag: no,



  /**

   * Check if an attribute is reserved so that it cannot be used as a component

   * prop. This is platform-dependent and may be overwritten.

   */

  isReservedAttr: no,



  /**

   * Check if a tag is an unknown element.

   * Platform-dependent.

   */

  isUnknownElement: no,



  /**

   * Get the namespace of an element

   */

  getTagNamespace: noop,



  /**

   * Parse the real tag name for the specific platform.

   */

  parsePlatformTagName: identity,



  /**

   * Check if an attribute must be bound using property, e.g. value

   * Platform-dependent.

   */

  mustUseProp: no,



  /**

   * Exposed for legacy reasons

   */

  _lifecycleHooks: LIFECYCLE_HOOKS

});



/*  */



/**

 * Check if a string starts with $ or _

 */

function isReserved (str) {

  var c = (str + '').charCodeAt(0);

  return c === 0x24 || c === 0x5F

}



/**

 * Define a property.

 */

function def (obj, key, val, enumerable) {

  Object.defineProperty(obj, key, {

    value: val,

    enumerable: !!enumerable,

    writable: true,

    configurable: true

  });

}



/**

 * Parse simple path.

 */

var bailRE = /[^\w.$]/;

function parsePath (path) {

  if (bailRE.test(path)) {

    return

  }

  var segments = path.split('.');

  return function (obj) {

    for (var i = 0; i < segments.length; i++) {

      if (!obj) { return }

      obj = obj[segments[i]];

    }

    return obj

  }

}



/*  */





// can we use __proto__?

var hasProto = '__proto__' in {};



// Browser environment sniffing

var inBrowser = typeof window !== 'undefined';

var inWeex = typeof WXEnvironment !== 'undefined' && !!WXEnvironment.platform;

var weexPlatform = inWeex && WXEnvironment.platform.toLowerCase();

var UA = inBrowser && window.navigator.userAgent.toLowerCase();

var isIE = UA && /msie|trident/.test(UA);

var isIE9 = UA && UA.indexOf('msie 9.0') > 0;

var isEdge = UA && UA.indexOf('edge/') > 0;

var isAndroid = (UA && UA.indexOf('android') > 0) || (weexPlatform === 'android');

var isIOS = (UA && /iphone|ipad|ipod|ios/.test(UA)) || (weexPlatform === 'ios');

var isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge;



// Firefox has a "watch" function on Object.prototype...

var nativeWatch = ({}).watch;



var supportsPassive = false;

if (inBrowser) {

  try {

    var opts = {};

    Object.defineProperty(opts, 'passive', ({

      get: function get () {

        /* istanbul ignore next */

        supportsPassive = true;

      }

    })); // https://github.com/facebook/flow/issues/285

    window.addEventListener('test-passive', null, opts);

  } catch (e) {}

}



// this needs to be lazy-evaled because vue may be required before

// vue-server-renderer can set VUE_ENV

var _isServer;

var isServerRendering = function () {

  if (_isServer === undefined) {

    /* istanbul ignore if */

    if (!inBrowser && typeof global !== 'undefined') {

      // detect presence of vue-server-renderer and avoid

      // Webpack shimming the process

      _isServer = global['process'].env.VUE_ENV === 'server';

    } else {

      _isServer = false;

    }

  }

  return _isServer

};



// detect devtools

var devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__;



/* istanbul ignore next */

function isNative (Ctor) {

  return typeof Ctor === 'function' && /native code/.test(Ctor.toString())

}



var hasSymbol =

  typeof Symbol !== 'undefined' && isNative(Symbol) &&

  typeof Reflect !== 'undefined' && isNative(Reflect.ownKeys);



var _Set;

/* istanbul ignore if */ // $flow-disable-line

if (typeof Set !== 'undefined' && isNative(Set)) {

  // use native Set when available.

  _Set = Set;

} else {

  // a non-standard Set polyfill that only works with primitive keys.

  _Set = (function () {

    function Set () {

      this.set = Object.create(null);

    }

    Set.prototype.has = function has (key) {

      return this.set[key] === true

    };

    Set.prototype.add = function add (key) {

      this.set[key] = true;

    };

    Set.prototype.clear = function clear () {

      this.set = Object.create(null);

    };



    return Set;

  }());

}



/*  */



var warn = noop;

var tip = noop;

var generateComponentTrace = (noop); // work around flow check

var formatComponentName = (noop);



if (true) {

  var hasConsole = typeof console !== 'undefined';

  var classifyRE = /(?:^|[-_])(\w)/g;

  var classify = function (str) { return str

    .replace(classifyRE, function (c) { return c.toUpperCase(); })

    .replace(/[-_]/g, ''); };



  warn = function (msg, vm) {

    var trace = vm ? generateComponentTrace(vm) : '';



    if (config.warnHandler) {

      config.warnHandler.call(null, msg, vm, trace);

    } else if (hasConsole && (!config.silent)) {

      console.error(("[Vue warn]: " + msg + trace));

    }

  };



  tip = function (msg, vm) {

    if (hasConsole && (!config.silent)) {

      console.warn("[Vue tip]: " + msg + (

        vm ? generateComponentTrace(vm) : ''

      ));

    }

  };



  formatComponentName = function (vm, includeFile) {

    if (vm.$root === vm) {

      return '<Root>'

    }

    var options = typeof vm === 'function' && vm.cid != null

      ? vm.options

      : vm._isVue

        ? vm.$options || vm.constructor.options

        : vm || {};

    var name = options.name || options._componentTag;

    var file = options.__file;

    if (!name && file) {

      var match = file.match(/([^/\\]+)\.vue$/);

      name = match && match[1];

    }



    return (

      (name ? ("<" + (classify(name)) + ">") : "<Anonymous>") +

      (file && includeFile !== false ? (" at " + file) : '')

    )

  };



  var repeat = function (str, n) {

    var res = '';

    while (n) {

      if (n % 2 === 1) { res += str; }

      if (n > 1) { str += str; }

      n >>= 1;

    }

    return res

  };



  generateComponentTrace = function (vm) {

    if (vm._isVue && vm.$parent) {

      var tree = [];

      var currentRecursiveSequence = 0;

      while (vm) {

        if (tree.length > 0) {

          var last = tree[tree.length - 1];

          if (last.constructor === vm.constructor) {

            currentRecursiveSequence++;

            vm = vm.$parent;

            continue

          } else if (currentRecursiveSequence > 0) {

            tree[tree.length - 1] = [last, currentRecursiveSequence];

            currentRecursiveSequence = 0;

          }

        }

        tree.push(vm);

        vm = vm.$parent;

      }

      return '\n\nfound in\n\n' + tree

        .map(function (vm, i) { return ("" + (i === 0 ? '---> ' : repeat(' ', 5 + i * 2)) + (Array.isArray(vm)

            ? ((formatComponentName(vm[0])) + "... (" + (vm[1]) + " recursive calls)")

            : formatComponentName(vm))); })

        .join('\n')

    } else {

      return ("\n\n(found in " + (formatComponentName(vm)) + ")")

    }

  };

}



/*  */





var uid = 0;



/**

 * A dep is an observable that can have multiple

 * directives subscribing to it.

 */

var Dep = function Dep () {

  this.id = uid++;

  this.subs = [];

};



Dep.prototype.addSub = function addSub (sub) {

  this.subs.push(sub);

};



Dep.prototype.removeSub = function removeSub (sub) {

  remove(this.subs, sub);

};



Dep.prototype.depend = function depend () {

  if (Dep.target) {

    Dep.target.addDep(this);

  }

};



Dep.prototype.notify = function notify () {

  // stabilize the subscriber list first

  var subs = this.subs.slice();

  for (var i = 0, l = subs.length; i < l; i++) {

    subs[i].update();

  }

};



// the current target watcher being evaluated.

// this is globally unique because there could be only one

// watcher being evaluated at any time.

Dep.target = null;

var targetStack = [];



function pushTarget (_target) {

  if (Dep.target) { targetStack.push(Dep.target); }

  Dep.target = _target;

}



function popTarget () {

  Dep.target = targetStack.pop();

}



/*  */



var VNode = function VNode (

  tag,

  data,

  children,

  text,

  elm,

  context,

  componentOptions,

  asyncFactory

) {

  this.tag = tag;

  this.data = data;

  this.children = children;

  this.text = text;

  this.elm = elm;

  this.ns = undefined;

  this.context = context;

  this.fnContext = undefined;

  this.fnOptions = undefined;

  this.fnScopeId = undefined;

  this.key = data && data.key;

  this.componentOptions = componentOptions;

  this.componentInstance = undefined;

  this.parent = undefined;

  this.raw = false;

  this.isStatic = false;

  this.isRootInsert = true;

  this.isComment = false;

  this.isCloned = false;

  this.isOnce = false;

  this.asyncFactory = asyncFactory;

  this.asyncMeta = undefined;

  this.isAsyncPlaceholder = false;

};



var prototypeAccessors = { child: { configurable: true } };



// DEPRECATED: alias for componentInstance for backwards compat.

/* istanbul ignore next */

prototypeAccessors.child.get = function () {

  return this.componentInstance

};



Object.defineProperties( VNode.prototype, prototypeAccessors );



var createEmptyVNode = function (text) {

  if ( text === void 0 ) text = '';



  var node = new VNode();

  node.text = text;

  node.isComment = true;

  return node

};



function createTextVNode (val) {

  return new VNode(undefined, undefined, undefined, String(val))

}



// optimized shallow clone

// used for static nodes and slot nodes because they may be reused across

// multiple renders, cloning them avoids errors when DOM manipulations rely

// on their elm reference.

function cloneVNode (vnode, deep) {

  var componentOptions = vnode.componentOptions;

  var cloned = new VNode(

    vnode.tag,

    vnode.data,

    vnode.children,

    vnode.text,

    vnode.elm,

    vnode.context,

    componentOptions,

    vnode.asyncFactory

  );

  cloned.ns = vnode.ns;

  cloned.isStatic = vnode.isStatic;

  cloned.key = vnode.key;

  cloned.isComment = vnode.isComment;

  cloned.fnContext = vnode.fnContext;

  cloned.fnOptions = vnode.fnOptions;

  cloned.fnScopeId = vnode.fnScopeId;

  cloned.isCloned = true;

  if (deep) {

    if (vnode.children) {

      cloned.children = cloneVNodes(vnode.children, true);

    }

    if (componentOptions && componentOptions.children) {

      componentOptions.children = cloneVNodes(componentOptions.children, true);

    }

  }

  return cloned

}



function cloneVNodes (vnodes, deep) {

  var len = vnodes.length;

  var res = new Array(len);

  for (var i = 0; i < len; i++) {

    res[i] = cloneVNode(vnodes[i], deep);

  }

  return res

}



/*

 * not type checking this file because flow doesn't play well with

 * dynamically accessing methods on Array prototype

 */



var arrayProto = Array.prototype;

var arrayMethods = Object.create(arrayProto);[

  'push',

  'pop',

  'shift',

  'unshift',

  'splice',

  'sort',

  'reverse'

].forEach(function (method) {

  // cache original method

  var original = arrayProto[method];

  def(arrayMethods, method, function mutator () {

    var args = [], len = arguments.length;

    while ( len-- ) args[ len ] = arguments[ len ];



    var result = original.apply(this, args);

    var ob = this.__ob__;

    var inserted;

    switch (method) {

      case 'push':

      case 'unshift':

        inserted = args;

        break

      case 'splice':

        inserted = args.slice(2);

        break

    }

    if (inserted) { ob.observeArray(inserted); }

    // notify change

    ob.dep.notify();

    return result

  });

});



/*  */



var arrayKeys = Object.getOwnPropertyNames(arrayMethods);



/**

 * By default, when a reactive property is set, the new value is

 * also converted to become reactive. However when passing down props,

 * we don't want to force conversion because the value may be a nested value

 * under a frozen data structure. Converting it would defeat the optimization.

 */

var observerState = {

  shouldConvert: true

};



/**

 * Observer class that are attached to each observed

 * object. Once attached, the observer converts target

 * object's property keys into getter/setters that

 * collect dependencies and dispatches updates.

 */

var Observer = function Observer (value) {

  this.value = value;

  this.dep = new Dep();

  this.vmCount = 0;

  def(value, '__ob__', this);

  if (Array.isArray(value)) {

    var augment = hasProto

      ? protoAugment

      : copyAugment;

    augment(value, arrayMethods, arrayKeys);

    this.observeArray(value);

  } else {

    this.walk(value);

  }

};



/**

 * Walk through each property and convert them into

 * getter/setters. This method should only be called when

 * value type is Object.

 */

Observer.prototype.walk = function walk (obj) {

  var keys = Object.keys(obj);

  for (var i = 0; i < keys.length; i++) {

    defineReactive(obj, keys[i], obj[keys[i]]);

  }

};



/**

 * Observe a list of Array items.

 */

Observer.prototype.observeArray = function observeArray (items) {

  for (var i = 0, l = items.length; i < l; i++) {

    observe(items[i]);

  }

};



// helpers



/**

 * Augment an target Object or Array by intercepting

 * the prototype chain using __proto__

 */

function protoAugment (target, src, keys) {

  /* eslint-disable no-proto */

  target.__proto__ = src;

  /* eslint-enable no-proto */

}



/**

 * Augment an target Object or Array by defining

 * hidden properties.

 */

/* istanbul ignore next */

function copyAugment (target, src, keys) {

  for (var i = 0, l = keys.length; i < l; i++) {

    var key = keys[i];

    def(target, key, src[key]);

  }

}



/**

 * Attempt to create an observer instance for a value,

 * returns the new observer if successfully observed,

 * or the existing observer if the value already has one.

 */

function observe (value, asRootData) {

  if (!isObject(value) || value instanceof VNode) {

    return

  }

  var ob;

  if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {

    ob = value.__ob__;

  } else if (

    observerState.shouldConvert &&

    !isServerRendering() &&

    (Array.isArray(value) || isPlainObject(value)) &&

    Object.isExtensible(value) &&

    !value._isVue

  ) {

    ob = new Observer(value);

  }

  if (asRootData && ob) {

    ob.vmCount++;

  }

  return ob

}



/**

 * Define a reactive property on an Object.

 */

function defineReactive (

  obj,

  key,

  val,

  customSetter,

  shallow

) {

  var dep = new Dep();



  var property = Object.getOwnPropertyDescriptor(obj, key);

  if (property && property.configurable === false) {

    return

  }



  // cater for pre-defined getter/setters

  var getter = property && property.get;

  var setter = property && property.set;



  var childOb = !shallow && observe(val);

  Object.defineProperty(obj, key, {

    enumerable: true,

    configurable: true,

    get: function reactiveGetter () {

      var value = getter ? getter.call(obj) : val;

      if (Dep.target) {

        dep.depend();

        if (childOb) {

          childOb.dep.depend();

          if (Array.isArray(value)) {

            dependArray(value);

          }

        }

      }

      return value

    },

    set: function reactiveSetter (newVal) {

      var value = getter ? getter.call(obj) : val;

      /* eslint-disable no-self-compare */

      if (newVal === value || (newVal !== newVal && value !== value)) {

        return

      }

      /* eslint-enable no-self-compare */

      if ("development" !== 'production' && customSetter) {

        customSetter();

      }

      if (setter) {

        setter.call(obj, newVal);

      } else {

        val = newVal;

      }

      childOb = !shallow && observe(newVal);

      dep.notify();

    }

  });

}



/**

 * Set a property on an object. Adds the new property and

 * triggers change notification if the property doesn't

 * already exist.

 */

function set (target, key, val) {

  if (Array.isArray(target) && isValidArrayIndex(key)) {

    target.length = Math.max(target.length, key);

    target.splice(key, 1, val);

    return val

  }

  if (key in target && !(key in Object.prototype)) {

    target[key] = val;

    return val

  }

  var ob = (target).__ob__;

  if (target._isVue || (ob && ob.vmCount)) {

    "development" !== 'production' && warn(

      'Avoid adding reactive properties to a Vue instance or its root $data ' +

      'at runtime - declare it upfront in the data option.'

    );

    return val

  }

  if (!ob) {

    target[key] = val;

    return val

  }

  defineReactive(ob.value, key, val);

  ob.dep.notify();

  return val

}



/**

 * Delete a property and trigger change if necessary.

 */

function del (target, key) {

  if (Array.isArray(target) && isValidArrayIndex(key)) {

    target.splice(key, 1);

    return

  }

  var ob = (target).__ob__;

  if (target._isVue || (ob && ob.vmCount)) {

    "development" !== 'production' && warn(

      'Avoid deleting properties on a Vue instance or its root $data ' +

      '- just set it to null.'

    );

    return

  }

  if (!hasOwn(target, key)) {

    return

  }

  delete target[key];

  if (!ob) {

    return

  }

  ob.dep.notify();

}



/**

 * Collect dependencies on array elements when the array is touched, since

 * we cannot intercept array element access like property getters.

 */

function dependArray (value) {

  for (var e = (void 0), i = 0, l = value.length; i < l; i++) {

    e = value[i];

    e && e.__ob__ && e.__ob__.dep.depend();

    if (Array.isArray(e)) {

      dependArray(e);

    }

  }

}



/*  */



/**

 * Option overwriting strategies are functions that handle

 * how to merge a parent option value and a child option

 * value into the final value.

 */

var strats = config.optionMergeStrategies;



/**

 * Options with restrictions

 */

if (true) {

  strats.el = strats.propsData = function (parent, child, vm, key) {

    if (!vm) {

      warn(

        "option \"" + key + "\" can only be used during instance " +

        'creation with the `new` keyword.'

      );

    }

    return defaultStrat(parent, child)

  };

}



/**

 * Helper that recursively merges two data objects together.

 */

function mergeData (to, from) {

  if (!from) { return to }

  var key, toVal, fromVal;

  var keys = Object.keys(from);

  for (var i = 0; i < keys.length; i++) {

    key = keys[i];

    toVal = to[key];

    fromVal = from[key];

    if (!hasOwn(to, key)) {

      set(to, key, fromVal);

    } else if (isPlainObject(toVal) && isPlainObject(fromVal)) {

      mergeData(toVal, fromVal);

    }

  }

  return to

}



/**

 * Data

 */

function mergeDataOrFn (

  parentVal,

  childVal,

  vm

) {

  if (!vm) {

    // in a Vue.extend merge, both should be functions

    if (!childVal) {

      return parentVal

    }

    if (!parentVal) {

      return childVal

    }

    // when parentVal & childVal are both present,

    // we need to return a function that returns the

    // merged result of both functions... no need to

    // check if parentVal is a function here because

    // it has to be a function to pass previous merges.

    return function mergedDataFn () {

      return mergeData(

        typeof childVal === 'function' ? childVal.call(this, this) : childVal,

        typeof parentVal === 'function' ? parentVal.call(this, this) : parentVal

      )

    }

  } else {

    return function mergedInstanceDataFn () {

      // instance merge

      var instanceData = typeof childVal === 'function'

        ? childVal.call(vm, vm)

        : childVal;

      var defaultData = typeof parentVal === 'function'

        ? parentVal.call(vm, vm)

        : parentVal;

      if (instanceData) {

        return mergeData(instanceData, defaultData)

      } else {

        return defaultData

      }

    }

  }

}



strats.data = function (

  parentVal,

  childVal,

  vm

) {

  if (!vm) {

    if (childVal && typeof childVal !== 'function') {

      "development" !== 'production' && warn(

        'The "data" option should be a function ' +

        'that returns a per-instance value in component ' +

        'definitions.',

        vm

      );



      return parentVal

    }

    return mergeDataOrFn(parentVal, childVal)

  }



  return mergeDataOrFn(parentVal, childVal, vm)

};



/**

 * Hooks and props are merged as arrays.

 */

function mergeHook (

  parentVal,

  childVal

) {

  return childVal

    ? parentVal

      ? parentVal.concat(childVal)

      : Array.isArray(childVal)

        ? childVal

        : [childVal]

    : parentVal

}



LIFECYCLE_HOOKS.forEach(function (hook) {

  strats[hook] = mergeHook;

});



/**

 * Assets

 *

 * When a vm is present (instance creation), we need to do

 * a three-way merge between constructor options, instance

 * options and parent options.

 */

function mergeAssets (

  parentVal,

  childVal,

  vm,

  key

) {

  var res = Object.create(parentVal || null);

  if (childVal) {

    "development" !== 'production' && assertObjectType(key, childVal, vm);

    return extend(res, childVal)

  } else {

    return res

  }

}



ASSET_TYPES.forEach(function (type) {

  strats[type + 's'] = mergeAssets;

});



/**

 * Watchers.

 *

 * Watchers hashes should not overwrite one

 * another, so we merge them as arrays.

 */

strats.watch = function (

  parentVal,

  childVal,

  vm,

  key

) {

  // work around Firefox's Object.prototype.watch...

  if (parentVal === nativeWatch) { parentVal = undefined; }

  if (childVal === nativeWatch) { childVal = undefined; }

  /* istanbul ignore if */

  if (!childVal) { return Object.create(parentVal || null) }

  if (true) {

    assertObjectType(key, childVal, vm);

  }

  if (!parentVal) { return childVal }

  var ret = {};

  extend(ret, parentVal);

  for (var key$1 in childVal) {

    var parent = ret[key$1];

    var child = childVal[key$1];

    if (parent && !Array.isArray(parent)) {

      parent = [parent];

    }

    ret[key$1] = parent

      ? parent.concat(child)

      : Array.isArray(child) ? child : [child];

  }

  return ret

};



/**

 * Other object hashes.

 */

strats.props =

strats.methods =

strats.inject =

strats.computed = function (

  parentVal,

  childVal,

  vm,

  key

) {

  if (childVal && "development" !== 'production') {

    assertObjectType(key, childVal, vm);

  }

  if (!parentVal) { return childVal }

  var ret = Object.create(null);

  extend(ret, parentVal);

  if (childVal) { extend(ret, childVal); }

  return ret

};

strats.provide = mergeDataOrFn;



/**

 * Default strategy.

 */

var defaultStrat = function (parentVal, childVal) {

  return childVal === undefined

    ? parentVal

    : childVal

};



/**

 * Validate component names

 */

function checkComponents (options) {

  for (var key in options.components) {

    validateComponentName(key);

  }

}



function validateComponentName (name) {

  if (!/^[a-zA-Z][\w-]*$/.test(name)) {

    warn(

      'Invalid component name: "' + name + '". Component names ' +

      'can only contain alphanumeric characters and the hyphen, ' +

      'and must start with a letter.'

    );

  }

  if (isBuiltInTag(name) || config.isReservedTag(name)) {

    warn(

      'Do not use built-in or reserved HTML elements as component ' +

      'id: ' + name

    );

  }

}



/**

 * Ensure all props option syntax are normalized into the

 * Object-based format.

 */

function normalizeProps (options, vm) {

  var props = options.props;

  if (!props) { return }

  var res = {};

  var i, val, name;

  if (Array.isArray(props)) {

    i = props.length;

    while (i--) {

      val = props[i];

      if (typeof val === 'string') {

        name = camelize(val);

        res[name] = { type: null };

      } else if (true) {

        warn('props must be strings when using array syntax.');

      }

    }

  } else if (isPlainObject(props)) {

    for (var key in props) {

      val = props[key];

      name = camelize(key);

      res[name] = isPlainObject(val)

        ? val

        : { type: val };

    }

  } else if (true) {

    warn(

      "Invalid value for option \"props\": expected an Array or an Object, " +

      "but got " + (toRawType(props)) + ".",

      vm

    );

  }

  options.props = res;

}



/**

 * Normalize all injections into Object-based format

 */

function normalizeInject (options, vm) {

  var inject = options.inject;

  if (!inject) { return }

  var normalized = options.inject = {};

  if (Array.isArray(inject)) {

    for (var i = 0; i < inject.length; i++) {

      normalized[inject[i]] = { from: inject[i] };

    }

  } else if (isPlainObject(inject)) {

    for (var key in inject) {

      var val = inject[key];

      normalized[key] = isPlainObject(val)

        ? extend({ from: key }, val)

        : { from: val };

    }

  } else if (true) {

    warn(

      "Invalid value for option \"inject\": expected an Array or an Object, " +

      "but got " + (toRawType(inject)) + ".",

      vm

    );

  }

}



/**

 * Normalize raw function directives into object format.

 */

function normalizeDirectives (options) {

  var dirs = options.directives;

  if (dirs) {

    for (var key in dirs) {

      var def = dirs[key];

      if (typeof def === 'function') {

        dirs[key] = { bind: def, update: def };

      }

    }

  }

}



function assertObjectType (name, value, vm) {

  if (!isPlainObject(value)) {

    warn(

      "Invalid value for option \"" + name + "\": expected an Object, " +

      "but got " + (toRawType(value)) + ".",

      vm

    );

  }

}



/**

 * Merge two option objects into a new one.

 * Core utility used in both instantiation and inheritance.

 */

function mergeOptions (

  parent,

  child,

  vm

) {

  if (true) {

    checkComponents(child);

  }



  if (typeof child === 'function') {

    child = child.options;

  }



  normalizeProps(child, vm);

  normalizeInject(child, vm);

  normalizeDirectives(child);

  var extendsFrom = child.extends;

  if (extendsFrom) {

    parent = mergeOptions(parent, extendsFrom, vm);

  }

  if (child.mixins) {

    for (var i = 0, l = child.mixins.length; i < l; i++) {

      parent = mergeOptions(parent, child.mixins[i], vm);

    }

  }

  var options = {};

  var key;

  for (key in parent) {

    mergeField(key);

  }

  for (key in child) {

    if (!hasOwn(parent, key)) {

      mergeField(key);

    }

  }

  function mergeField (key) {

    var strat = strats[key] || defaultStrat;

    options[key] = strat(parent[key], child[key], vm, key);

  }

  return options

}



/**

 * Resolve an asset.

 * This function is used because child instances need access

 * to assets defined in its ancestor chain.

 */

function resolveAsset (

  options,

  type,

  id,

  warnMissing

) {

  /* istanbul ignore if */

  if (typeof id !== 'string') {

    return

  }

  var assets = options[type];

  // check local registration variations first

  if (hasOwn(assets, id)) { return assets[id] }

  var camelizedId = camelize(id);

  if (hasOwn(assets, camelizedId)) { return assets[camelizedId] }

  var PascalCaseId = capitalize(camelizedId);

  if (hasOwn(assets, PascalCaseId)) { return assets[PascalCaseId] }

  // fallback to prototype chain

  var res = assets[id] || assets[camelizedId] || assets[PascalCaseId];

  if ("development" !== 'production' && warnMissing && !res) {

    warn(

      'Failed to resolve ' + type.slice(0, -1) + ': ' + id,

      options

    );

  }

  return res

}



/*  */



function validateProp (

  key,

  propOptions,

  propsData,

  vm

) {

  var prop = propOptions[key];

  var absent = !hasOwn(propsData, key);

  var value = propsData[key];

  // handle boolean props

  if (isType(Boolean, prop.type)) {

    if (absent && !hasOwn(prop, 'default')) {

      value = false;

    } else if (!isType(String, prop.type) && (value === '' || value === hyphenate(key))) {

      value = true;

    }

  }

  // check default value

  if (value === undefined) {

    value = getPropDefaultValue(vm, prop, key);

    // since the default value is a fresh copy,

    // make sure to observe it.

    var prevShouldConvert = observerState.shouldConvert;

    observerState.shouldConvert = true;

    observe(value);

    observerState.shouldConvert = prevShouldConvert;

  }

  if (

    true

  ) {

    assertProp(prop, key, value, vm, absent);

  }

  return value

}



/**

 * Get the default value of a prop.

 */

function getPropDefaultValue (vm, prop, key) {

  // no default, return undefined

  if (!hasOwn(prop, 'default')) {

    return undefined

  }

  var def = prop.default;

  // warn against non-factory defaults for Object & Array

  if ("development" !== 'production' && isObject(def)) {

    warn(

      'Invalid default value for prop "' + key + '": ' +

      'Props with type Object/Array must use a factory function ' +

      'to return the default value.',

      vm

    );

  }

  // the raw prop value was also undefined from previous render,

  // return previous default value to avoid unnecessary watcher trigger

  if (vm && vm.$options.propsData &&

    vm.$options.propsData[key] === undefined &&

    vm._props[key] !== undefined

  ) {

    return vm._props[key]

  }

  // call factory function for non-Function types

  // a value is Function if its prototype is function even across different execution context

  return typeof def === 'function' && getType(prop.type) !== 'Function'

    ? def.call(vm)

    : def

}



/**

 * Assert whether a prop is valid.

 */

function assertProp (

  prop,

  name,

  value,

  vm,

  absent

) {

  if (prop.required && absent) {

    warn(

      'Missing required prop: "' + name + '"',

      vm

    );

    return

  }

  if (value == null && !prop.required) {

    return

  }

  var type = prop.type;

  var valid = !type || type === true;

  var expectedTypes = [];

  if (type) {

    if (!Array.isArray(type)) {

      type = [type];

    }

    for (var i = 0; i < type.length && !valid; i++) {

      var assertedType = assertType(value, type[i]);

      expectedTypes.push(assertedType.expectedType || '');

      valid = assertedType.valid;

    }

  }

  if (!valid) {

    warn(

      "Invalid prop: type check failed for prop \"" + name + "\"." +

      " Expected " + (expectedTypes.map(capitalize).join(', ')) +

      ", got " + (toRawType(value)) + ".",

      vm

    );

    return

  }

  var validator = prop.validator;

  if (validator) {

    if (!validator(value)) {

      warn(

        'Invalid prop: custom validator check failed for prop "' + name + '".',

        vm

      );

    }

  }

}



var simpleCheckRE = /^(String|Number|Boolean|Function|Symbol)$/;



function assertType (value, type) {

  var valid;

  var expectedType = getType(type);

  if (simpleCheckRE.test(expectedType)) {

    var t = typeof value;

    valid = t === expectedType.toLowerCase();

    // for primitive wrapper objects

    if (!valid && t === 'object') {

      valid = value instanceof type;

    }

  } else if (expectedType === 'Object') {

    valid = isPlainObject(value);

  } else if (expectedType === 'Array') {

    valid = Array.isArray(value);

  } else {

    valid = value instanceof type;

  }

  return {

    valid: valid,

    expectedType: expectedType

  }

}



/**

 * Use function string name to check built-in types,

 * because a simple equality check will fail when running

 * across different vms / iframes.

 */

function getType (fn) {

  var match = fn && fn.toString().match(/^\s*function (\w+)/);

  return match ? match[1] : ''

}



function isType (type, fn) {

  if (!Array.isArray(fn)) {

    return getType(fn) === getType(type)

  }

  for (var i = 0, len = fn.length; i < len; i++) {

    if (getType(fn[i]) === getType(type)) {

      return true

    }

  }

  /* istanbul ignore next */

  return false

}



/*  */



function handleError (err, vm, info) {

  if (vm) {

    var cur = vm;

    while ((cur = cur.$parent)) {

      var hooks = cur.$options.errorCaptured;

      if (hooks) {

        for (var i = 0; i < hooks.length; i++) {

          try {

            var capture = hooks[i].call(cur, err, vm, info) === false;

            if (capture) { return }

          } catch (e) {

            globalHandleError(e, cur, 'errorCaptured hook');

          }

        }

      }

    }

  }

  globalHandleError(err, vm, info);

}



function globalHandleError (err, vm, info) {

  if (config.errorHandler) {

    try {

      return config.errorHandler.call(null, err, vm, info)

    } catch (e) {

      logError(e, null, 'config.errorHandler');

    }

  }

  logError(err, vm, info);

}



function logError (err, vm, info) {

  if (true) {

    warn(("Error in " + info + ": \"" + (err.toString()) + "\""), vm);

  }

  /* istanbul ignore else */

  if ((inBrowser || inWeex) && typeof console !== 'undefined') {

    console.error(err);

  } else {

    throw err

  }

}



/*  */

/* globals MessageChannel */



var callbacks = [];

var pending = false;



function flushCallbacks () {

  pending = false;

  var copies = callbacks.slice(0);

  callbacks.length = 0;

  for (var i = 0; i < copies.length; i++) {

    copies[i]();

  }

}



// Here we have async deferring wrappers using both micro and macro tasks.

// In < 2.4 we used micro tasks everywhere, but there are some scenarios where

// micro tasks have too high a priority and fires in between supposedly

// sequential events (e.g. #4521, #6690) or even between bubbling of the same

// event (#6566). However, using macro tasks everywhere also has subtle problems

// when state is changed right before repaint (e.g. #6813, out-in transitions).

// Here we use micro task by default, but expose a way to force macro task when

// needed (e.g. in event handlers attached by v-on).

var microTimerFunc;

var macroTimerFunc;

var useMacroTask = false;



// Determine (macro) Task defer implementation.

// Technically setImmediate should be the ideal choice, but it's only available

// in IE. The only polyfill that consistently queues the callback after all DOM

// events triggered in the same loop is by using MessageChannel.

/* istanbul ignore if */

if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {

  macroTimerFunc = function () {

    setImmediate(flushCallbacks);

  };

} else if (typeof MessageChannel !== 'undefined' && (

  isNative(MessageChannel) ||

  // PhantomJS

  MessageChannel.toString() === '[object MessageChannelConstructor]'

)) {

  var channel = new MessageChannel();

  var port = channel.port2;

  channel.port1.onmessage = flushCallbacks;

  macroTimerFunc = function () {

    port.postMessage(1);

  };

} else {

  /* istanbul ignore next */

  macroTimerFunc = function () {

    setTimeout(flushCallbacks, 0);

  };

}



// Determine MicroTask defer implementation.

/* istanbul ignore next, $flow-disable-line */

if (typeof Promise !== 'undefined' && isNative(Promise)) {

  var p = Promise.resolve();

  microTimerFunc = function () {

    p.then(flushCallbacks);

    // in problematic UIWebViews, Promise.then doesn't completely break, but

    // it can get stuck in a weird state where callbacks are pushed into the

    // microtask queue but the queue isn't being flushed, until the browser

    // needs to do some other work, e.g. handle a timer. Therefore we can

    // "force" the microtask queue to be flushed by adding an empty timer.

    if (isIOS) { setTimeout(noop); }

  };

} else {

  // fallback to macro

  microTimerFunc = macroTimerFunc;

}



/**

 * Wrap a function so that if any code inside triggers state change,

 * the changes are queued using a Task instead of a MicroTask.

 */

function withMacroTask (fn) {

  return fn._withTask || (fn._withTask = function () {

    useMacroTask = true;

    var res = fn.apply(null, arguments);

    useMacroTask = false;

    return res

  })

}



function nextTick (cb, ctx) {

  var _resolve;

  callbacks.push(function () {

    if (cb) {

      try {

        cb.call(ctx);

      } catch (e) {

        handleError(e, ctx, 'nextTick');

      }

    } else if (_resolve) {

      _resolve(ctx);

    }

  });

  if (!pending) {

    pending = true;

    if (useMacroTask) {

      macroTimerFunc();

    } else {

      microTimerFunc();

    }

  }

  // $flow-disable-line

  if (!cb && typeof Promise !== 'undefined') {

    return new Promise(function (resolve) {

      _resolve = resolve;

    })

  }

}



/*  */



var mark;

var measure;



if (true) {

  var perf = inBrowser && window.performance;

  /* istanbul ignore if */

  if (

    perf &&

    perf.mark &&

    perf.measure &&

    perf.clearMarks &&

    perf.clearMeasures

  ) {

    mark = function (tag) { return perf.mark(tag); };

    measure = function (name, startTag, endTag) {

      perf.measure(name, startTag, endTag);

      perf.clearMarks(startTag);

      perf.clearMarks(endTag);

      perf.clearMeasures(name);

    };

  }

}



/* not type checking this file because flow doesn't play well with Proxy */



var initProxy;



if (true) {

  var allowedGlobals = makeMap(

    'Infinity,undefined,NaN,isFinite,isNaN,' +

    'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' +

    'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' +

    'require' // for Webpack/Browserify

  );



  var warnNonPresent = function (target, key) {

    warn(

      "Property or method \"" + key + "\" is not defined on the instance but " +

      'referenced during render. Make sure that this property is reactive, ' +

      'either in the data option, or for class-based components, by ' +

      'initializing the property. ' +

      'See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.',

      target

    );

  };



  var hasProxy =

    typeof Proxy !== 'undefined' &&

    Proxy.toString().match(/native code/);



  if (hasProxy) {

    var isBuiltInModifier = makeMap('stop,prevent,self,ctrl,shift,alt,meta,exact');

    config.keyCodes = new Proxy(config.keyCodes, {

      set: function set (target, key, value) {

        if (isBuiltInModifier(key)) {

          warn(("Avoid overwriting built-in modifier in config.keyCodes: ." + key));

          return false

        } else {

          target[key] = value;

          return true

        }

      }

    });

  }



  var hasHandler = {

    has: function has (target, key) {

      var has = key in target;

      var isAllowed = allowedGlobals(key) || key.charAt(0) === '_';

      if (!has && !isAllowed) {

        warnNonPresent(target, key);

      }

      return has || !isAllowed

    }

  };



  var getHandler = {

    get: function get (target, key) {

      if (typeof key === 'string' && !(key in target)) {

        warnNonPresent(target, key);

      }

      return target[key]

    }

  };



  initProxy = function initProxy (vm) {

    if (hasProxy) {

      // determine which proxy handler to use

      var options = vm.$options;

      var handlers = options.render && options.render._withStripped

        ? getHandler

        : hasHandler;

      vm._renderProxy = new Proxy(vm, handlers);

    } else {

      vm._renderProxy = vm;

    }

  };

}



/*  */



var seenObjects = new _Set();



/**

 * Recursively traverse an object to evoke all converted

 * getters, so that every nested property inside the object

 * is collected as a "deep" dependency.

 */

function traverse (val) {

  _traverse(val, seenObjects);

  seenObjects.clear();

}



function _traverse (val, seen) {

  var i, keys;

  var isA = Array.isArray(val);

  if ((!isA && !isObject(val)) || Object.isFrozen(val)) {

    return

  }

  if (val.__ob__) {

    var depId = val.__ob__.dep.id;

    if (seen.has(depId)) {

      return

    }

    seen.add(depId);

  }

  if (isA) {

    i = val.length;

    while (i--) { _traverse(val[i], seen); }

  } else {

    keys = Object.keys(val);

    i = keys.length;

    while (i--) { _traverse(val[keys[i]], seen); }

  }

}



/*  */



var normalizeEvent = cached(function (name) {

  var passive = name.charAt(0) === '&';

  name = passive ? name.slice(1) : name;

  var once$$1 = name.charAt(0) === '~'; // Prefixed last, checked first

  name = once$$1 ? name.slice(1) : name;

  var capture = name.charAt(0) === '!';

  name = capture ? name.slice(1) : name;

  return {

    name: name,

    once: once$$1,

    capture: capture,

    passive: passive

  }

});



function createFnInvoker (fns) {

  function invoker () {

    var arguments$1 = arguments;



    var fns = invoker.fns;

    if (Array.isArray(fns)) {

      var cloned = fns.slice();

      for (var i = 0; i < cloned.length; i++) {

        cloned[i].apply(null, arguments$1);

      }

    } else {

      // return handler return value for single handlers

      return fns.apply(null, arguments)

    }

  }

  invoker.fns = fns;

  return invoker

}



function updateListeners (

  on,

  oldOn,

  add,

  remove$$1,

  vm

) {

  var name, def, cur, old, event;

  for (name in on) {

    def = cur = on[name];

    old = oldOn[name];

    event = normalizeEvent(name);

    /* istanbul ignore if */

    if (isUndef(cur)) {

      "development" !== 'production' && warn(

        "Invalid handler for event \"" + (event.name) + "\": got " + String(cur),

        vm

      );

    } else if (isUndef(old)) {

      if (isUndef(cur.fns)) {

        cur = on[name] = createFnInvoker(cur);

      }

      add(event.name, cur, event.once, event.capture, event.passive, event.params);

    } else if (cur !== old) {

      old.fns = cur;

      on[name] = old;

    }

  }

  for (name in oldOn) {

    if (isUndef(on[name])) {

      event = normalizeEvent(name);

      remove$$1(event.name, oldOn[name], event.capture);

    }

  }

}



/*  */



function mergeVNodeHook (def, hookKey, hook) {

  if (def instanceof VNode) {

    def = def.data.hook || (def.data.hook = {});

  }

  var invoker;

  var oldHook = def[hookKey];



  function wrappedHook () {

    hook.apply(this, arguments);

    // important: remove merged hook to ensure it's called only once

    // and prevent memory leak

    remove(invoker.fns, wrappedHook);

  }



  if (isUndef(oldHook)) {

    // no existing hook

    invoker = createFnInvoker([wrappedHook]);

  } else {

    /* istanbul ignore if */

    if (isDef(oldHook.fns) && isTrue(oldHook.merged)) {

      // already a merged invoker

      invoker = oldHook;

      invoker.fns.push(wrappedHook);

    } else {

      // existing plain hook

      invoker = createFnInvoker([oldHook, wrappedHook]);

    }

  }



  invoker.merged = true;

  def[hookKey] = invoker;

}



/*  */



function extractPropsFromVNodeData (

  data,

  Ctor,

  tag

) {

  // we are only extracting raw values here.

  // validation and default values are handled in the child

  // component itself.

  var propOptions = Ctor.options.props;

  if (isUndef(propOptions)) {

    return

  }

  var res = {};

  var attrs = data.attrs;

  var props = data.props;

  if (isDef(attrs) || isDef(props)) {

    for (var key in propOptions) {

      var altKey = hyphenate(key);

      if (true) {

        var keyInLowerCase = key.toLowerCase();

        if (

          key !== keyInLowerCase &&

          attrs && hasOwn(attrs, keyInLowerCase)

        ) {

          tip(

            "Prop \"" + keyInLowerCase + "\" is passed to component " +

            (formatComponentName(tag || Ctor)) + ", but the declared prop name is" +

            " \"" + key + "\". " +

            "Note that HTML attributes are case-insensitive and camelCased " +

            "props need to use their kebab-case equivalents when using in-DOM " +

            "templates. You should probably use \"" + altKey + "\" instead of \"" + key + "\"."

          );

        }

      }

      checkProp(res, props, key, altKey, true) ||

      checkProp(res, attrs, key, altKey, false);

    }

  }

  return res

}



function checkProp (

  res,

  hash,

  key,

  altKey,

  preserve

) {

  if (isDef(hash)) {

    if (hasOwn(hash, key)) {

      res[key] = hash[key];

      if (!preserve) {

        delete hash[key];

      }

      return true

    } else if (hasOwn(hash, altKey)) {

      res[key] = hash[altKey];

      if (!preserve) {

        delete hash[altKey];

      }

      return true

    }

  }

  return false

}



/*  */



// The template compiler attempts to minimize the need for normalization by

// statically analyzing the template at compile time.

//

// For plain HTML markup, normalization can be completely skipped because the

// generated render function is guaranteed to return Array<VNode>. There are

// two cases where extra normalization is needed:



// 1. When the children contains components - because a functional component

// may return an Array instead of a single root. In this case, just a simple

// normalization is needed - if any child is an Array, we flatten the whole

// thing with Array.prototype.concat. It is guaranteed to be only 1-level deep

// because functional components already normalize their own children.

function simpleNormalizeChildren (children) {

  for (var i = 0; i < children.length; i++) {

    if (Array.isArray(children[i])) {

      return Array.prototype.concat.apply([], children)

    }

  }

  return children

}



// 2. When the children contains constructs that always generated nested Arrays,

// e.g. <template>, <slot>, v-for, or when the children is provided by user

// with hand-written render functions / JSX. In such cases a full normalization

// is needed to cater to all possible types of children values.

function normalizeChildren (children) {

  return isPrimitive(children)

    ? [createTextVNode(children)]

    : Array.isArray(children)

      ? normalizeArrayChildren(children)

      : undefined

}



function isTextNode (node) {

  return isDef(node) && isDef(node.text) && isFalse(node.isComment)

}



function normalizeArrayChildren (children, nestedIndex) {

  var res = [];

  var i, c, lastIndex, last;

  for (i = 0; i < children.length; i++) {

    c = children[i];

    if (isUndef(c) || typeof c === 'boolean') { continue }

    lastIndex = res.length - 1;

    last = res[lastIndex];

    //  nested

    if (Array.isArray(c)) {

      if (c.length > 0) {

        c = normalizeArrayChildren(c, ((nestedIndex || '') + "_" + i));

        // merge adjacent text nodes

        if (isTextNode(c[0]) && isTextNode(last)) {

          res[lastIndex] = createTextVNode(last.text + (c[0]).text);

          c.shift();

        }

        res.push.apply(res, c);

      }

    } else if (isPrimitive(c)) {

      if (isTextNode(last)) {

        // merge adjacent text nodes

        // this is necessary for SSR hydration because text nodes are

        // essentially merged when rendered to HTML strings

        res[lastIndex] = createTextVNode(last.text + c);

      } else if (c !== '') {

        // convert primitive to vnode

        res.push(createTextVNode(c));

      }

    } else {

      if (isTextNode(c) && isTextNode(last)) {

        // merge adjacent text nodes

        res[lastIndex] = createTextVNode(last.text + c.text);

      } else {

        // default key for nested array children (likely generated by v-for)

        if (isTrue(children._isVList) &&

          isDef(c.tag) &&

          isUndef(c.key) &&

          isDef(nestedIndex)) {

          c.key = "__vlist" + nestedIndex + "_" + i + "__";

        }

        res.push(c);

      }

    }

  }

  return res

}



/*  */



function ensureCtor (comp, base) {

  if (

    comp.__esModule ||

    (hasSymbol && comp[Symbol.toStringTag] === 'Module')

  ) {

    comp = comp.default;

  }

  return isObject(comp)

    ? base.extend(comp)

    : comp

}



function createAsyncPlaceholder (

  factory,

  data,

  context,

  children,

  tag

) {

  var node = createEmptyVNode();

  node.asyncFactory = factory;

  node.asyncMeta = { data: data, context: context, children: children, tag: tag };

  return node

}



function resolveAsyncComponent (

  factory,

  baseCtor,

  context

) {

  if (isTrue(factory.error) && isDef(factory.errorComp)) {

    return factory.errorComp

  }



  if (isDef(factory.resolved)) {

    return factory.resolved

  }



  if (isTrue(factory.loading) && isDef(factory.loadingComp)) {

    return factory.loadingComp

  }



  if (isDef(factory.contexts)) {

    // already pending

    factory.contexts.push(context);

  } else {

    var contexts = factory.contexts = [context];

    var sync = true;



    var forceRender = function () {

      for (var i = 0, l = contexts.length; i < l; i++) {

        contexts[i].$forceUpdate();

      }

    };



    var resolve = once(function (res) {

      // cache resolved

      factory.resolved = ensureCtor(res, baseCtor);

      // invoke callbacks only if this is not a synchronous resolve

      // (async resolves are shimmed as synchronous during SSR)

      if (!sync) {

        forceRender();

      }

    });



    var reject = once(function (reason) {

      "development" !== 'production' && warn(

        "Failed to resolve async component: " + (String(factory)) +

        (reason ? ("\nReason: " + reason) : '')

      );

      if (isDef(factory.errorComp)) {

        factory.error = true;

        forceRender();

      }

    });



    var res = factory(resolve, reject);



    if (isObject(res)) {

      if (typeof res.then === 'function') {

        // () => Promise

        if (isUndef(factory.resolved)) {

          res.then(resolve, reject);

        }

      } else if (isDef(res.component) && typeof res.component.then === 'function') {

        res.component.then(resolve, reject);



        if (isDef(res.error)) {

          factory.errorComp = ensureCtor(res.error, baseCtor);

        }



        if (isDef(res.loading)) {

          factory.loadingComp = ensureCtor(res.loading, baseCtor);

          if (res.delay === 0) {

            factory.loading = true;

          } else {

            setTimeout(function () {

              if (isUndef(factory.resolved) && isUndef(factory.error)) {

                factory.loading = true;

                forceRender();

              }

            }, res.delay || 200);

          }

        }



        if (isDef(res.timeout)) {

          setTimeout(function () {

            if (isUndef(factory.resolved)) {

              reject(

                 true

                  ? ("timeout (" + (res.timeout) + "ms)")

                  : null

              );

            }

          }, res.timeout);

        }

      }

    }



    sync = false;

    // return in case resolved synchronously

    return factory.loading

      ? factory.loadingComp

      : factory.resolved

  }

}



/*  */



function isAsyncPlaceholder (node) {

  return node.isComment && node.asyncFactory

}



/*  */



function getFirstComponentChild (children) {

  if (Array.isArray(children)) {

    for (var i = 0; i < children.length; i++) {

      var c = children[i];

      if (isDef(c) && (isDef(c.componentOptions) || isAsyncPlaceholder(c))) {

        return c

      }

    }

  }

}



/*  */



/*  */



function initEvents (vm) {

  vm._events = Object.create(null);

  vm._hasHookEvent = false;

  // init parent attached events

  var listeners = vm.$options._parentListeners;

  if (listeners) {

    updateComponentListeners(vm, listeners);

  }

}



var target;



function add (event, fn, once) {

  if (once) {

    target.$once(event, fn);

  } else {

    target.$on(event, fn);

  }

}



function remove$1 (event, fn) {

  target.$off(event, fn);

}



function updateComponentListeners (

  vm,

  listeners,

  oldListeners

) {

  target = vm;

  updateListeners(listeners, oldListeners || {}, add, remove$1, vm);

  target = undefined;

}



function eventsMixin (Vue) {

  var hookRE = /^hook:/;

  Vue.prototype.$on = function (event, fn) {

    var this$1 = this;



    var vm = this;

    if (Array.isArray(event)) {

      for (var i = 0, l = event.length; i < l; i++) {

        this$1.$on(event[i], fn);

      }

    } else {

      (vm._events[event] || (vm._events[event] = [])).push(fn);

      // optimize hook:event cost by using a boolean flag marked at registration

      // instead of a hash lookup

      if (hookRE.test(event)) {

        vm._hasHookEvent = true;

      }

    }

    return vm

  };



  Vue.prototype.$once = function (event, fn) {

    var vm = this;

    function on () {

      vm.$off(event, on);

      fn.apply(vm, arguments);

    }

    on.fn = fn;

    vm.$on(event, on);

    return vm

  };



  Vue.prototype.$off = function (event, fn) {

    var this$1 = this;



    var vm = this;

    // all

    if (!arguments.length) {

      vm._events = Object.create(null);

      return vm

    }

    // array of events

    if (Array.isArray(event)) {

      for (var i = 0, l = event.length; i < l; i++) {

        this$1.$off(event[i], fn);

      }

      return vm

    }

    // specific event

    var cbs = vm._events[event];

    if (!cbs) {

      return vm

    }

    if (!fn) {

      vm._events[event] = null;

      return vm

    }

    if (fn) {

      // specific handler

      var cb;

      var i$1 = cbs.length;

      while (i$1--) {

        cb = cbs[i$1];

        if (cb === fn || cb.fn === fn) {

          cbs.splice(i$1, 1);

          break

        }

      }

    }

    return vm

  };



  Vue.prototype.$emit = function (event) {

    var vm = this;

    if (true) {

      var lowerCaseEvent = event.toLowerCase();

      if (lowerCaseEvent !== event && vm._events[lowerCaseEvent]) {

        tip(

          "Event \"" + lowerCaseEvent + "\" is emitted in component " +

          (formatComponentName(vm)) + " but the handler is registered for \"" + event + "\". " +

          "Note that HTML attributes are case-insensitive and you cannot use " +

          "v-on to listen to camelCase events when using in-DOM templates. " +

          "You should probably use \"" + (hyphenate(event)) + "\" instead of \"" + event + "\"."

        );

      }

    }

    var cbs = vm._events[event];

    if (cbs) {

      cbs = cbs.length > 1 ? toArray(cbs) : cbs;

      var args = toArray(arguments, 1);

      for (var i = 0, l = cbs.length; i < l; i++) {

        try {

          cbs[i].apply(vm, args);

        } catch (e) {

          handleError(e, vm, ("event handler for \"" + event + "\""));

        }

      }

    }

    return vm

  };

}



/*  */







/**

 * Runtime helper for resolving raw children VNodes into a slot object.

 */

function resolveSlots (

  children,

  context

) {

  var slots = {};

  if (!children) {

    return slots

  }

  for (var i = 0, l = children.length; i < l; i++) {

    var child = children[i];

    var data = child.data;

    // remove slot attribute if the node is resolved as a Vue slot node

    if (data && data.attrs && data.attrs.slot) {

      delete data.attrs.slot;

    }

    // named slots should only be respected if the vnode was rendered in the

    // same context.

    if ((child.context === context || child.fnContext === context) &&

      data && data.slot != null

    ) {

      var name = data.slot;

      var slot = (slots[name] || (slots[name] = []));

      if (child.tag === 'template') {

        slot.push.apply(slot, child.children || []);

      } else {

        slot.push(child);

      }

    } else {

      (slots.default || (slots.default = [])).push(child);

    }

  }

  // ignore slots that contains only whitespace

  for (var name$1 in slots) {

    if (slots[name$1].every(isWhitespace)) {

      delete slots[name$1];

    }

  }

  return slots

}



function isWhitespace (node) {

  return (node.isComment && !node.asyncFactory) || node.text === ' '

}



function resolveScopedSlots (

  fns, // see flow/vnode

  res

) {

  res = res || {};

  for (var i = 0; i < fns.length; i++) {

    if (Array.isArray(fns[i])) {

      resolveScopedSlots(fns[i], res);

    } else {

      res[fns[i].key] = fns[i].fn;

    }

  }

  return res

}



/*  */



var activeInstance = null;

var isUpdatingChildComponent = false;



function initLifecycle (vm) {

  var options = vm.$options;



  // locate first non-abstract parent

  var parent = options.parent;

  if (parent && !options.abstract) {

    while (parent.$options.abstract && parent.$parent) {

      parent = parent.$parent;

    }

    parent.$children.push(vm);

  }



  vm.$parent = parent;

  vm.$root = parent ? parent.$root : vm;



  vm.$children = [];

  vm.$refs = {};



  vm._watcher = null;

  vm._inactive = null;

  vm._directInactive = false;

  vm._isMounted = false;

  vm._isDestroyed = false;

  vm._isBeingDestroyed = false;

}



function lifecycleMixin (Vue) {

  Vue.prototype._update = function (vnode, hydrating) {

    var vm = this;

    if (vm._isMounted) {

      callHook(vm, 'beforeUpdate');

    }

    var prevEl = vm.$el;

    var prevVnode = vm._vnode;

    var prevActiveInstance = activeInstance;

    activeInstance = vm;

    vm._vnode = vnode;

    // Vue.prototype.__patch__ is injected in entry points

    // based on the rendering backend used.

    if (!prevVnode) {

      // initial render

      vm.$el = vm.__patch__(

        vm.$el, vnode, hydrating, false /* removeOnly */,

        vm.$options._parentElm,

        vm.$options._refElm

      );

      // no need for the ref nodes after initial patch

      // this prevents keeping a detached DOM tree in memory (#5851)

      vm.$options._parentElm = vm.$options._refElm = null;

    } else {

      // updates

      vm.$el = vm.__patch__(prevVnode, vnode);

    }

    activeInstance = prevActiveInstance;

    // update __vue__ reference

    if (prevEl) {

      prevEl.__vue__ = null;

    }

    if (vm.$el) {

      vm.$el.__vue__ = vm;

    }

    // if parent is an HOC, update its $el as well

    if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) {

      vm.$parent.$el = vm.$el;

    }

    // updated hook is called by the scheduler to ensure that children are

    // updated in a parent's updated hook.

  };



  Vue.prototype.$forceUpdate = function () {

    var vm = this;

    if (vm._watcher) {

      vm._watcher.update();

    }

  };



  Vue.prototype.$destroy = function () {

    var vm = this;

    if (vm._isBeingDestroyed) {

      return

    }

    callHook(vm, 'beforeDestroy');

    vm._isBeingDestroyed = true;

    // remove self from parent

    var parent = vm.$parent;

    if (parent && !parent._isBeingDestroyed && !vm.$options.abstract) {

      remove(parent.$children, vm);

    }

    // teardown watchers

    if (vm._watcher) {

      vm._watcher.teardown();

    }

    var i = vm._watchers.length;

    while (i--) {

      vm._watchers[i].teardown();

    }

    // remove reference from data ob

    // frozen object may not have observer.

    if (vm._data.__ob__) {

      vm._data.__ob__.vmCount--;

    }

    // call the last hook...

    vm._isDestroyed = true;

    // invoke destroy hooks on current rendered tree

    vm.__patch__(vm._vnode, null);

    // fire destroyed hook

    callHook(vm, 'destroyed');

    // turn off all instance listeners.

    vm.$off();

    // remove __vue__ reference

    if (vm.$el) {

      vm.$el.__vue__ = null;

    }

    // release circular reference (#6759)

    if (vm.$vnode) {

      vm.$vnode.parent = null;

    }

  };

}



function mountComponent (

  vm,

  el,

  hydrating

) {

  vm.$el = el;

  if (!vm.$options.render) {

    vm.$options.render = createEmptyVNode;

    if (true) {

      /* istanbul ignore if */

      if ((vm.$options.template && vm.$options.template.charAt(0) !== '#') ||

        vm.$options.el || el) {

        warn(

          'You are using the runtime-only build of Vue where the template ' +

          'compiler is not available. Either pre-compile the templates into ' +

          'render functions, or use the compiler-included build.',

          vm

        );

      } else {

        warn(

          'Failed to mount component: template or render function not defined.',

          vm

        );

      }

    }

  }

  callHook(vm, 'beforeMount');



  var updateComponent;

  /* istanbul ignore if */

  if ("development" !== 'production' && config.performance && mark) {

    updateComponent = function () {

      var name = vm._name;

      var id = vm._uid;

      var startTag = "vue-perf-start:" + id;

      var endTag = "vue-perf-end:" + id;



      mark(startTag);

      var vnode = vm._render();

      mark(endTag);

      measure(("vue " + name + " render"), startTag, endTag);



      mark(startTag);

      vm._update(vnode, hydrating);

      mark(endTag);

      measure(("vue " + name + " patch"), startTag, endTag);

    };

  } else {

    updateComponent = function () {

      vm._update(vm._render(), hydrating);

    };

  }



  // we set this to vm._watcher inside the watcher's constructor

  // since the watcher's initial patch may call $forceUpdate (e.g. inside child

  // component's mounted hook), which relies on vm._watcher being already defined

  new Watcher(vm, updateComponent, noop, null, true /* isRenderWatcher */);

  hydrating = false;



  // manually mounted instance, call mounted on self

  // mounted is called for render-created child components in its inserted hook

  if (vm.$vnode == null) {

    vm._isMounted = true;

    callHook(vm, 'mounted');

  }

  return vm

}



function updateChildComponent (

  vm,

  propsData,

  listeners,

  parentVnode,

  renderChildren

) {

  if (true) {

    isUpdatingChildComponent = true;

  }



  // determine whether component has slot children

  // we need to do this before overwriting $options._renderChildren

  var hasChildren = !!(

    renderChildren ||               // has new static slots

    vm.$options._renderChildren ||  // has old static slots

    parentVnode.data.scopedSlots || // has new scoped slots

    vm.$scopedSlots !== emptyObject // has old scoped slots

  );



  vm.$options._parentVnode = parentVnode;

  vm.$vnode = parentVnode; // update vm's placeholder node without re-render



  if (vm._vnode) { // update child tree's parent

    vm._vnode.parent = parentVnode;

  }

  vm.$options._renderChildren = renderChildren;



  // update $attrs and $listeners hash

  // these are also reactive so they may trigger child update if the child

  // used them during render

  vm.$attrs = (parentVnode.data && parentVnode.data.attrs) || emptyObject;

  vm.$listeners = listeners || emptyObject;



  // update props

  if (propsData && vm.$options.props) {

    observerState.shouldConvert = false;

    var props = vm._props;

    var propKeys = vm.$options._propKeys || [];

    for (var i = 0; i < propKeys.length; i++) {

      var key = propKeys[i];

      props[key] = validateProp(key, vm.$options.props, propsData, vm);

    }

    observerState.shouldConvert = true;

    // keep a copy of raw propsData

    vm.$options.propsData = propsData;

  }



  // update listeners

  if (listeners) {

    var oldListeners = vm.$options._parentListeners;

    vm.$options._parentListeners = listeners;

    updateComponentListeners(vm, listeners, oldListeners);

  }

  // resolve slots + force update if has children

  if (hasChildren) {

    vm.$slots = resolveSlots(renderChildren, parentVnode.context);

    vm.$forceUpdate();

  }



  if (true) {

    isUpdatingChildComponent = false;

  }

}



function isInInactiveTree (vm) {

  while (vm && (vm = vm.$parent)) {

    if (vm._inactive) { return true }

  }

  return false

}



function activateChildComponent (vm, direct) {

  if (direct) {

    vm._directInactive = false;

    if (isInInactiveTree(vm)) {

      return

    }

  } else if (vm._directInactive) {

    return

  }

  if (vm._inactive || vm._inactive === null) {

    vm._inactive = false;

    for (var i = 0; i < vm.$children.length; i++) {

      activateChildComponent(vm.$children[i]);

    }

    callHook(vm, 'activated');

  }

}



function deactivateChildComponent (vm, direct) {

  if (direct) {

    vm._directInactive = true;

    if (isInInactiveTree(vm)) {

      return

    }

  }

  if (!vm._inactive) {

    vm._inactive = true;

    for (var i = 0; i < vm.$children.length; i++) {

      deactivateChildComponent(vm.$children[i]);

    }

    callHook(vm, 'deactivated');

  }

}



function callHook (vm, hook) {

  var handlers = vm.$options[hook];

  if (handlers) {

    for (var i = 0, j = handlers.length; i < j; i++) {

      try {

        handlers[i].call(vm);

      } catch (e) {

        handleError(e, vm, (hook + " hook"));

      }

    }

  }

  if (vm._hasHookEvent) {

    vm.$emit('hook:' + hook);

  }

}



/*  */





var MAX_UPDATE_COUNT = 100;



var queue = [];

var activatedChildren = [];

var has = {};

var circular = {};

var waiting = false;

var flushing = false;

var index = 0;



/**

 * Reset the scheduler's state.

 */

function resetSchedulerState () {

  index = queue.length = activatedChildren.length = 0;

  has = {};

  if (true) {

    circular = {};

  }

  waiting = flushing = false;

}



/**

 * Flush both queues and run the watchers.

 */

function flushSchedulerQueue () {

  flushing = true;

  var watcher, id;



  // Sort queue before flush.

  // This ensures that:

  // 1. Components are updated from parent to child. (because parent is always

  //    created before the child)

  // 2. A component's user watchers are run before its render watcher (because

  //    user watchers are created before the render watcher)

  // 3. If a component is destroyed during a parent component's watcher run,

  //    its watchers can be skipped.

  queue.sort(function (a, b) { return a.id - b.id; });



  // do not cache length because more watchers might be pushed

  // as we run existing watchers

  for (index = 0; index < queue.length; index++) {

    watcher = queue[index];

    id = watcher.id;

    has[id] = null;

    watcher.run();

    // in dev build, check and stop circular updates.

    if ("development" !== 'production' && has[id] != null) {

      circular[id] = (circular[id] || 0) + 1;

      if (circular[id] > MAX_UPDATE_COUNT) {

        warn(

          'You may have an infinite update loop ' + (

            watcher.user

              ? ("in watcher with expression \"" + (watcher.expression) + "\"")

              : "in a component render function."

          ),

          watcher.vm

        );

        break

      }

    }

  }



  // keep copies of post queues before resetting state

  var activatedQueue = activatedChildren.slice();

  var updatedQueue = queue.slice();



  resetSchedulerState();



  // call component updated and activated hooks

  callActivatedHooks(activatedQueue);

  callUpdatedHooks(updatedQueue);



  // devtool hook

  /* istanbul ignore if */

  if (devtools && config.devtools) {

    devtools.emit('flush');

  }

}



function callUpdatedHooks (queue) {

  var i = queue.length;

  while (i--) {

    var watcher = queue[i];

    var vm = watcher.vm;

    if (vm._watcher === watcher && vm._isMounted) {

      callHook(vm, 'updated');

    }

  }

}



/**

 * Queue a kept-alive component that was activated during patch.

 * The queue will be processed after the entire tree has been patched.

 */

function queueActivatedComponent (vm) {

  // setting _inactive to false here so that a render function can

  // rely on checking whether it's in an inactive tree (e.g. router-view)

  vm._inactive = false;

  activatedChildren.push(vm);

}



function callActivatedHooks (queue) {

  for (var i = 0; i < queue.length; i++) {

    queue[i]._inactive = true;

    activateChildComponent(queue[i], true /* true */);

  }

}



/**

 * Push a watcher into the watcher queue.

 * Jobs with duplicate IDs will be skipped unless it's

 * pushed when the queue is being flushed.

 */

function queueWatcher (watcher) {

  var id = watcher.id;

  if (has[id] == null) {

    has[id] = true;

    if (!flushing) {

      queue.push(watcher);

    } else {

      // if already flushing, splice the watcher based on its id

      // if already past its id, it will be run next immediately.

      var i = queue.length - 1;

      while (i > index && queue[i].id > watcher.id) {

        i--;

      }

      queue.splice(i + 1, 0, watcher);

    }

    // queue the flush

    if (!waiting) {

      waiting = true;

      nextTick(flushSchedulerQueue);

    }

  }

}



/*  */



var uid$2 = 0;



/**

 * A watcher parses an expression, collects dependencies,

 * and fires callback when the expression value changes.

 * This is used for both the $watch() api and directives.

 */

var Watcher = function Watcher (

  vm,

  expOrFn,

  cb,

  options,

  isRenderWatcher

) {

  this.vm = vm;

  if (isRenderWatcher) {

    vm._watcher = this;

  }

  vm._watchers.push(this);

  // options

  if (options) {

    this.deep = !!options.deep;

    this.user = !!options.user;

    this.lazy = !!options.lazy;

    this.sync = !!options.sync;

  } else {

    this.deep = this.user = this.lazy = this.sync = false;

  }

  this.cb = cb;

  this.id = ++uid$2; // uid for batching

  this.active = true;

  this.dirty = this.lazy; // for lazy watchers

  this.deps = [];

  this.newDeps = [];

  this.depIds = new _Set();

  this.newDepIds = new _Set();

  this.expression =  true

    ? expOrFn.toString()

    : '';

  // parse expression for getter

  if (typeof expOrFn === 'function') {

    this.getter = expOrFn;

  } else {

    this.getter = parsePath(expOrFn);

    if (!this.getter) {

      this.getter = function () {};

      "development" !== 'production' && warn(

        "Failed watching path: \"" + expOrFn + "\" " +

        'Watcher only accepts simple dot-delimited paths. ' +

        'For full control, use a function instead.',

        vm

      );

    }

  }

  this.value = this.lazy

    ? undefined

    : this.get();

};



/**

 * Evaluate the getter, and re-collect dependencies.

 */

Watcher.prototype.get = function get () {

  pushTarget(this);

  var value;

  var vm = this.vm;

  try {

    value = this.getter.call(vm, vm);

  } catch (e) {

    if (this.user) {

      handleError(e, vm, ("getter for watcher \"" + (this.expression) + "\""));

    } else {

      throw e

    }

  } finally {

    // "touch" every property so they are all tracked as

    // dependencies for deep watching

    if (this.deep) {

      traverse(value);

    }

    popTarget();

    this.cleanupDeps();

  }

  return value

};



/**

 * Add a dependency to this directive.

 */

Watcher.prototype.addDep = function addDep (dep) {

  var id = dep.id;

  if (!this.newDepIds.has(id)) {

    this.newDepIds.add(id);

    this.newDeps.push(dep);

    if (!this.depIds.has(id)) {

      dep.addSub(this);

    }

  }

};



/**

 * Clean up for dependency collection.

 */

Watcher.prototype.cleanupDeps = function cleanupDeps () {

    var this$1 = this;



  var i = this.deps.length;

  while (i--) {

    var dep = this$1.deps[i];

    if (!this$1.newDepIds.has(dep.id)) {

      dep.removeSub(this$1);

    }

  }

  var tmp = this.depIds;

  this.depIds = this.newDepIds;

  this.newDepIds = tmp;

  this.newDepIds.clear();

  tmp = this.deps;

  this.deps = this.newDeps;

  this.newDeps = tmp;

  this.newDeps.length = 0;

};



/**

 * Subscriber interface.

 * Will be called when a dependency changes.

 */

Watcher.prototype.update = function update () {

  /* istanbul ignore else */

  if (this.lazy) {

    this.dirty = true;

  } else if (this.sync) {

    this.run();

  } else {

    queueWatcher(this);

  }

};



/**

 * Scheduler job interface.

 * Will be called by the scheduler.

 */

Watcher.prototype.run = function run () {

  if (this.active) {

    var value = this.get();

    if (

      value !== this.value ||

      // Deep watchers and watchers on Object/Arrays should fire even

      // when the value is the same, because the value may

      // have mutated.

      isObject(value) ||

      this.deep

    ) {

      // set new value

      var oldValue = this.value;

      this.value = value;

      if (this.user) {

        try {

          this.cb.call(this.vm, value, oldValue);

        } catch (e) {

          handleError(e, this.vm, ("callback for watcher \"" + (this.expression) + "\""));

        }

      } else {

        this.cb.call(this.vm, value, oldValue);

      }

    }

  }

};



/**

 * Evaluate the value of the watcher.

 * This only gets called for lazy watchers.

 */

Watcher.prototype.evaluate = function evaluate () {

  this.value = this.get();

  this.dirty = false;

};



/**

 * Depend on all deps collected by this watcher.

 */

Watcher.prototype.depend = function depend () {

    var this$1 = this;



  var i = this.deps.length;

  while (i--) {

    this$1.deps[i].depend();

  }

};



/**

 * Remove self from all dependencies' subscriber list.

 */

Watcher.prototype.teardown = function teardown () {

    var this$1 = this;



  if (this.active) {

    // remove self from vm's watcher list

    // this is a somewhat expensive operation so we skip it

    // if the vm is being destroyed.

    if (!this.vm._isBeingDestroyed) {

      remove(this.vm._watchers, this);

    }

    var i = this.deps.length;

    while (i--) {

      this$1.deps[i].removeSub(this$1);

    }

    this.active = false;

  }

};



/*  */



var sharedPropertyDefinition = {

  enumerable: true,

  configurable: true,

  get: noop,

  set: noop

};



function proxy (target, sourceKey, key) {

  sharedPropertyDefinition.get = function proxyGetter () {

    return this[sourceKey][key]

  };

  sharedPropertyDefinition.set = function proxySetter (val) {

    this[sourceKey][key] = val;

  };

  Object.defineProperty(target, key, sharedPropertyDefinition);

}



function initState (vm) {

  vm._watchers = [];

  var opts = vm.$options;

  if (opts.props) { initProps(vm, opts.props); }

  if (opts.methods) { initMethods(vm, opts.methods); }

  if (opts.data) {

    initData(vm);

  } else {

    observe(vm._data = {}, true /* asRootData */);

  }

  if (opts.computed) { initComputed(vm, opts.computed); }

  if (opts.watch && opts.watch !== nativeWatch) {

    initWatch(vm, opts.watch);

  }

}



function initProps (vm, propsOptions) {

  var propsData = vm.$options.propsData || {};

  var props = vm._props = {};

  // cache prop keys so that future props updates can iterate using Array

  // instead of dynamic object key enumeration.

  var keys = vm.$options._propKeys = [];

  var isRoot = !vm.$parent;

  // root instance props should be converted

  observerState.shouldConvert = isRoot;

  var loop = function ( key ) {

    keys.push(key);

    var value = validateProp(key, propsOptions, propsData, vm);

    /* istanbul ignore else */

    if (true) {

      var hyphenatedKey = hyphenate(key);

      if (isReservedAttribute(hyphenatedKey) ||

          config.isReservedAttr(hyphenatedKey)) {

        warn(

          ("\"" + hyphenatedKey + "\" is a reserved attribute and cannot be used as component prop."),

          vm

        );

      }

      defineReactive(props, key, value, function () {

        if (vm.$parent && !isUpdatingChildComponent) {

          warn(

            "Avoid mutating a prop directly since the value will be " +

            "overwritten whenever the parent component re-renders. " +

            "Instead, use a data or computed property based on the prop's " +

            "value. Prop being mutated: \"" + key + "\"",

            vm

          );

        }

      });

    } else {

      defineReactive(props, key, value);

    }

    // static props are already proxied on the component's prototype

    // during Vue.extend(). We only need to proxy props defined at

    // instantiation here.

    if (!(key in vm)) {

      proxy(vm, "_props", key);

    }

  };



  for (var key in propsOptions) loop( key );

  observerState.shouldConvert = true;

}



function initData (vm) {

  var data = vm.$options.data;

  data = vm._data = typeof data === 'function'

    ? getData(data, vm)

    : data || {};

  if (!isPlainObject(data)) {

    data = {};

    "development" !== 'production' && warn(

      'data functions should return an object:\n' +

      'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function',

      vm

    );

  }

  // proxy data on instance

  var keys = Object.keys(data);

  var props = vm.$options.props;

  var methods = vm.$options.methods;

  var i = keys.length;

  while (i--) {

    var key = keys[i];

    if (true) {

      if (methods && hasOwn(methods, key)) {

        warn(

          ("Method \"" + key + "\" has already been defined as a data property."),

          vm

        );

      }

    }

    if (props && hasOwn(props, key)) {

      "development" !== 'production' && warn(

        "The data property \"" + key + "\" is already declared as a prop. " +

        "Use prop default value instead.",

        vm

      );

    } else if (!isReserved(key)) {

      proxy(vm, "_data", key);

    }

  }

  // observe data

  observe(data, true /* asRootData */);

}



function getData (data, vm) {

  try {

    return data.call(vm, vm)

  } catch (e) {

    handleError(e, vm, "data()");

    return {}

  }

}



var computedWatcherOptions = { lazy: true };



function initComputed (vm, computed) {

  // $flow-disable-line

  var watchers = vm._computedWatchers = Object.create(null);

  // computed properties are just getters during SSR

  var isSSR = isServerRendering();



  for (var key in computed) {

    var userDef = computed[key];

    var getter = typeof userDef === 'function' ? userDef : userDef.get;

    if ("development" !== 'production' && getter == null) {

      warn(

        ("Getter is missing for computed property \"" + key + "\"."),

        vm

      );

    }



    if (!isSSR) {

      // create internal watcher for the computed property.

      watchers[key] = new Watcher(

        vm,

        getter || noop,

        noop,

        computedWatcherOptions

      );

    }



    // component-defined computed properties are already defined on the

    // component prototype. We only need to define computed properties defined

    // at instantiation here.

    if (!(key in vm)) {

      defineComputed(vm, key, userDef);

    } else if (true) {

      if (key in vm.$data) {

        warn(("The computed property \"" + key + "\" is already defined in data."), vm);

      } else if (vm.$options.props && key in vm.$options.props) {

        warn(("The computed property \"" + key + "\" is already defined as a prop."), vm);

      }

    }

  }

}



function defineComputed (

  target,

  key,

  userDef

) {

  var shouldCache = !isServerRendering();

  if (typeof userDef === 'function') {

    sharedPropertyDefinition.get = shouldCache

      ? createComputedGetter(key)

      : userDef;

    sharedPropertyDefinition.set = noop;

  } else {

    sharedPropertyDefinition.get = userDef.get

      ? shouldCache && userDef.cache !== false

        ? createComputedGetter(key)

        : userDef.get

      : noop;

    sharedPropertyDefinition.set = userDef.set

      ? userDef.set

      : noop;

  }

  if ("development" !== 'production' &&

      sharedPropertyDefinition.set === noop) {

    sharedPropertyDefinition.set = function () {

      warn(

        ("Computed property \"" + key + "\" was assigned to but it has no setter."),

        this

      );

    };

  }

  Object.defineProperty(target, key, sharedPropertyDefinition);

}



function createComputedGetter (key) {

  return function computedGetter () {

    var watcher = this._computedWatchers && this._computedWatchers[key];

    if (watcher) {

      if (watcher.dirty) {

        watcher.evaluate();

      }

      if (Dep.target) {

        watcher.depend();

      }

      return watcher.value

    }

  }

}



function initMethods (vm, methods) {

  var props = vm.$options.props;

  for (var key in methods) {

    if (true) {

      if (methods[key] == null) {

        warn(

          "Method \"" + key + "\" has an undefined value in the component definition. " +

          "Did you reference the function correctly?",

          vm

        );

      }

      if (props && hasOwn(props, key)) {

        warn(

          ("Method \"" + key + "\" has already been defined as a prop."),

          vm

        );

      }

      if ((key in vm) && isReserved(key)) {

        warn(

          "Method \"" + key + "\" conflicts with an existing Vue instance method. " +

          "Avoid defining component methods that start with _ or $."

        );

      }

    }

    vm[key] = methods[key] == null ? noop : bind(methods[key], vm);

  }

}



function initWatch (vm, watch) {

  for (var key in watch) {

    var handler = watch[key];

    if (Array.isArray(handler)) {

      for (var i = 0; i < handler.length; i++) {

        createWatcher(vm, key, handler[i]);

      }

    } else {

      createWatcher(vm, key, handler);

    }

  }

}



function createWatcher (

  vm,

  keyOrFn,

  handler,

  options

) {

  if (isPlainObject(handler)) {

    options = handler;

    handler = handler.handler;

  }

  if (typeof handler === 'string') {

    handler = vm[handler];

  }

  return vm.$watch(keyOrFn, handler, options)

}



function stateMixin (Vue) {

  // flow somehow has problems with directly declared definition object

  // when using Object.defineProperty, so we have to procedurally build up

  // the object here.

  var dataDef = {};

  dataDef.get = function () { return this._data };

  var propsDef = {};

  propsDef.get = function () { return this._props };

  if (true) {

    dataDef.set = function (newData) {

      warn(

        'Avoid replacing instance root $data. ' +

        'Use nested data properties instead.',

        this

      );

    };

    propsDef.set = function () {

      warn("$props is readonly.", this);

    };

  }

  Object.defineProperty(Vue.prototype, '$data', dataDef);

  Object.defineProperty(Vue.prototype, '$props', propsDef);



  Vue.prototype.$set = set;

  Vue.prototype.$delete = del;



  Vue.prototype.$watch = function (

    expOrFn,

    cb,

    options

  ) {

    var vm = this;

    if (isPlainObject(cb)) {

      return createWatcher(vm, expOrFn, cb, options)

    }

    options = options || {};

    options.user = true;

    var watcher = new Watcher(vm, expOrFn, cb, options);

    if (options.immediate) {

      cb.call(vm, watcher.value);

    }

    return function unwatchFn () {

      watcher.teardown();

    }

  };

}



/*  */



function initProvide (vm) {

  var provide = vm.$options.provide;

  if (provide) {

    vm._provided = typeof provide === 'function'

      ? provide.call(vm)

      : provide;

  }

}



function initInjections (vm) {

  var result = resolveInject(vm.$options.inject, vm);

  if (result) {

    observerState.shouldConvert = false;

    Object.keys(result).forEach(function (key) {

      /* istanbul ignore else */

      if (true) {

        defineReactive(vm, key, result[key], function () {

          warn(

            "Avoid mutating an injected value directly since the changes will be " +

            "overwritten whenever the provided component re-renders. " +

            "injection being mutated: \"" + key + "\"",

            vm

          );

        });

      } else {

        defineReactive(vm, key, result[key]);

      }

    });

    observerState.shouldConvert = true;

  }

}



function resolveInject (inject, vm) {

  if (inject) {

    // inject is :any because flow is not smart enough to figure out cached

    var result = Object.create(null);

    var keys = hasSymbol

      ? Reflect.ownKeys(inject).filter(function (key) {

        /* istanbul ignore next */

        return Object.getOwnPropertyDescriptor(inject, key).enumerable

      })

      : Object.keys(inject);



    for (var i = 0; i < keys.length; i++) {

      var key = keys[i];

      var provideKey = inject[key].from;

      var source = vm;

      while (source) {

        if (source._provided && provideKey in source._provided) {

          result[key] = source._provided[provideKey];

          break

        }

        source = source.$parent;

      }

      if (!source) {

        if ('default' in inject[key]) {

          var provideDefault = inject[key].default;

          result[key] = typeof provideDefault === 'function'

            ? provideDefault.call(vm)

            : provideDefault;

        } else if (true) {

          warn(("Injection \"" + key + "\" not found"), vm);

        }

      }

    }

    return result

  }

}



/*  */



/**

 * Runtime helper for rendering v-for lists.

 */

function renderList (

  val,

  render

) {

  var ret, i, l, keys, key;

  if (Array.isArray(val) || typeof val === 'string') {

    ret = new Array(val.length);

    for (i = 0, l = val.length; i < l; i++) {

      ret[i] = render(val[i], i);

    }

  } else if (typeof val === 'number') {

    ret = new Array(val);

    for (i = 0; i < val; i++) {

      ret[i] = render(i + 1, i);

    }

  } else if (isObject(val)) {

    keys = Object.keys(val);

    ret = new Array(keys.length);

    for (i = 0, l = keys.length; i < l; i++) {

      key = keys[i];

      ret[i] = render(val[key], key, i);

    }

  }

  if (isDef(ret)) {

    (ret)._isVList = true;

  }

  return ret

}



/*  */



/**

 * Runtime helper for rendering <slot>

 */

function renderSlot (

  name,

  fallback,

  props,

  bindObject

) {

  var scopedSlotFn = this.$scopedSlots[name];

  var nodes;

  if (scopedSlotFn) { // scoped slot

    props = props || {};

    if (bindObject) {

      if ("development" !== 'production' && !isObject(bindObject)) {

        warn(

          'slot v-bind without argument expects an Object',

          this

        );

      }

      props = extend(extend({}, bindObject), props);

    }

    nodes = scopedSlotFn(props) || fallback;

  } else {

    var slotNodes = this.$slots[name];

    // warn duplicate slot usage

    if (slotNodes) {

      if ("development" !== 'production' && slotNodes._rendered) {

        warn(

          "Duplicate presence of slot \"" + name + "\" found in the same render tree " +

          "- this will likely cause render errors.",

          this

        );

      }

      slotNodes._rendered = true;

    }

    nodes = slotNodes || fallback;

  }



  var target = props && props.slot;

  if (target) {

    return this.$createElement('template', { slot: target }, nodes)

  } else {

    return nodes

  }

}



/*  */



/**

 * Runtime helper for resolving filters

 */

function resolveFilter (id) {

  return resolveAsset(this.$options, 'filters', id, true) || identity

}



/*  */



/**

 * Runtime helper for checking keyCodes from config.

 * exposed as Vue.prototype._k

 * passing in eventKeyName as last argument separately for backwards compat

 */

function checkKeyCodes (

  eventKeyCode,

  key,

  builtInAlias,

  eventKeyName

) {

  var keyCodes = config.keyCodes[key] || builtInAlias;

  if (keyCodes) {

    if (Array.isArray(keyCodes)) {

      return keyCodes.indexOf(eventKeyCode) === -1

    } else {

      return keyCodes !== eventKeyCode

    }

  } else if (eventKeyName) {

    return hyphenate(eventKeyName) !== key

  }

}



/*  */



/**

 * Runtime helper for merging v-bind="object" into a VNode's data.

 */

function bindObjectProps (

  data,

  tag,

  value,

  asProp,

  isSync

) {

  if (value) {

    if (!isObject(value)) {

      "development" !== 'production' && warn(

        'v-bind without argument expects an Object or Array value',

        this

      );

    } else {

      if (Array.isArray(value)) {

        value = toObject(value);

      }

      var hash;

      var loop = function ( key ) {

        if (

          key === 'class' ||

          key === 'style' ||

          isReservedAttribute(key)

        ) {

          hash = data;

        } else {

          var type = data.attrs && data.attrs.type;

          hash = asProp || config.mustUseProp(tag, type, key)

            ? data.domProps || (data.domProps = {})

            : data.attrs || (data.attrs = {});

        }

        if (!(key in hash)) {

          hash[key] = value[key];



          if (isSync) {

            var on = data.on || (data.on = {});

            on[("update:" + key)] = function ($event) {

              value[key] = $event;

            };

          }

        }

      };



      for (var key in value) loop( key );

    }

  }

  return data

}



/*  */



/**

 * Runtime helper for rendering static trees.

 */

function renderStatic (

  index,

  isInFor

) {

  var cached = this._staticTrees || (this._staticTrees = []);

  var tree = cached[index];

  // if has already-rendered static tree and not inside v-for,

  // we can reuse the same tree by doing a shallow clone.

  if (tree && !isInFor) {

    return Array.isArray(tree)

      ? cloneVNodes(tree)

      : cloneVNode(tree)

  }

  // otherwise, render a fresh tree.

  tree = cached[index] = this.$options.staticRenderFns[index].call(

    this._renderProxy,

    null,

    this // for render fns generated for functional component templates

  );

  markStatic(tree, ("__static__" + index), false);

  return tree

}



/**

 * Runtime helper for v-once.

 * Effectively it means marking the node as static with a unique key.

 */

function markOnce (

  tree,

  index,

  key

) {

  markStatic(tree, ("__once__" + index + (key ? ("_" + key) : "")), true);

  return tree

}



function markStatic (

  tree,

  key,

  isOnce

) {

  if (Array.isArray(tree)) {

    for (var i = 0; i < tree.length; i++) {

      if (tree[i] && typeof tree[i] !== 'string') {

        markStaticNode(tree[i], (key + "_" + i), isOnce);

      }

    }

  } else {

    markStaticNode(tree, key, isOnce);

  }

}



function markStaticNode (node, key, isOnce) {

  node.isStatic = true;

  node.key = key;

  node.isOnce = isOnce;

}



/*  */



function bindObjectListeners (data, value) {

  if (value) {

    if (!isPlainObject(value)) {

      "development" !== 'production' && warn(

        'v-on without argument expects an Object value',

        this

      );

    } else {

      var on = data.on = data.on ? extend({}, data.on) : {};

      for (var key in value) {

        var existing = on[key];

        var ours = value[key];

        on[key] = existing ? [].concat(existing, ours) : ours;

      }

    }

  }

  return data

}



/*  */



function installRenderHelpers (target) {

  target._o = markOnce;

  target._n = toNumber;

  target._s = toString;

  target._l = renderList;

  target._t = renderSlot;

  target._q = looseEqual;

  target._i = looseIndexOf;

  target._m = renderStatic;

  target._f = resolveFilter;

  target._k = checkKeyCodes;

  target._b = bindObjectProps;

  target._v = createTextVNode;

  target._e = createEmptyVNode;

  target._u = resolveScopedSlots;

  target._g = bindObjectListeners;

}



/*  */



function FunctionalRenderContext (

  data,

  props,

  children,

  parent,

  Ctor

) {

  var options = Ctor.options;

  this.data = data;

  this.props = props;

  this.children = children;

  this.parent = parent;

  this.listeners = data.on || emptyObject;

  this.injections = resolveInject(options.inject, parent);

  this.slots = function () { return resolveSlots(children, parent); };



  // ensure the createElement function in functional components

  // gets a unique context - this is necessary for correct named slot check

  var contextVm = Object.create(parent);

  var isCompiled = isTrue(options._compiled);

  var needNormalization = !isCompiled;



  // support for compiled functional template

  if (isCompiled) {

    // exposing $options for renderStatic()

    this.$options = options;

    // pre-resolve slots for renderSlot()

    this.$slots = this.slots();

    this.$scopedSlots = data.scopedSlots || emptyObject;

  }



  if (options._scopeId) {

    this._c = function (a, b, c, d) {

      var vnode = createElement(contextVm, a, b, c, d, needNormalization);

      if (vnode) {

        vnode.fnScopeId = options._scopeId;

        vnode.fnContext = parent;

      }

      return vnode

    };

  } else {

    this._c = function (a, b, c, d) { return createElement(contextVm, a, b, c, d, needNormalization); };

  }

}



installRenderHelpers(FunctionalRenderContext.prototype);



function createFunctionalComponent (

  Ctor,

  propsData,

  data,

  contextVm,

  children

) {

  var options = Ctor.options;

  var props = {};

  var propOptions = options.props;

  if (isDef(propOptions)) {

    for (var key in propOptions) {

      props[key] = validateProp(key, propOptions, propsData || emptyObject);

    }

  } else {

    if (isDef(data.attrs)) { mergeProps(props, data.attrs); }

    if (isDef(data.props)) { mergeProps(props, data.props); }

  }



  var renderContext = new FunctionalRenderContext(

    data,

    props,

    children,

    contextVm,

    Ctor

  );



  var vnode = options.render.call(null, renderContext._c, renderContext);



  if (vnode instanceof VNode) {

    vnode.fnContext = contextVm;

    vnode.fnOptions = options;

    if (data.slot) {

      (vnode.data || (vnode.data = {})).slot = data.slot;

    }

  }



  return vnode

}



function mergeProps (to, from) {

  for (var key in from) {

    to[camelize(key)] = from[key];

  }

}



/*  */









// Register the component hook to weex native render engine.

// The hook will be triggered by native, not javascript.





// Updates the state of the component to weex native render engine.



/*  */



// https://github.com/Hanks10100/weex-native-directive/tree/master/component



// listening on native callback



/*  */



/*  */



// hooks to be invoked on component VNodes during patch

var componentVNodeHooks = {

  init: function init (

    vnode,

    hydrating,

    parentElm,

    refElm

  ) {

    if (!vnode.componentInstance || vnode.componentInstance._isDestroyed) {

      var child = vnode.componentInstance = createComponentInstanceForVnode(

        vnode,

        activeInstance,

        parentElm,

        refElm

      );

      child.$mount(hydrating ? vnode.elm : undefined, hydrating);

    } else if (vnode.data.keepAlive) {

      // kept-alive components, treat as a patch

      var mountedNode = vnode; // work around flow

      componentVNodeHooks.prepatch(mountedNode, mountedNode);

    }

  },



  prepatch: function prepatch (oldVnode, vnode) {

    var options = vnode.componentOptions;

    var child = vnode.componentInstance = oldVnode.componentInstance;

    updateChildComponent(

      child,

      options.propsData, // updated props

      options.listeners, // updated listeners

      vnode, // new parent vnode

      options.children // new children

    );

  },



  insert: function insert (vnode) {

    var context = vnode.context;

    var componentInstance = vnode.componentInstance;

    if (!componentInstance._isMounted) {

      componentInstance._isMounted = true;

      callHook(componentInstance, 'mounted');

    }

    if (vnode.data.keepAlive) {

      if (context._isMounted) {

        // vue-router#1212

        // During updates, a kept-alive component's child components may

        // change, so directly walking the tree here may call activated hooks

        // on incorrect children. Instead we push them into a queue which will

        // be processed after the whole patch process ended.

        queueActivatedComponent(componentInstance);

      } else {

        activateChildComponent(componentInstance, true /* direct */);

      }

    }

  },



  destroy: function destroy (vnode) {

    var componentInstance = vnode.componentInstance;

    if (!componentInstance._isDestroyed) {

      if (!vnode.data.keepAlive) {

        componentInstance.$destroy();

      } else {

        deactivateChildComponent(componentInstance, true /* direct */);

      }

    }

  }

};



var hooksToMerge = Object.keys(componentVNodeHooks);



function createComponent (

  Ctor,

  data,

  context,

  children,

  tag

) {

  if (isUndef(Ctor)) {

    return

  }



  var baseCtor = context.$options._base;



  // plain options object: turn it into a constructor

  if (isObject(Ctor)) {

    Ctor = baseCtor.extend(Ctor);

  }



  // if at this stage it's not a constructor or an async component factory,

  // reject.

  if (typeof Ctor !== 'function') {

    if (true) {

      warn(("Invalid Component definition: " + (String(Ctor))), context);

    }

    return

  }



  // async component

  var asyncFactory;

  if (isUndef(Ctor.cid)) {

    asyncFactory = Ctor;

    Ctor = resolveAsyncComponent(asyncFactory, baseCtor, context);

    if (Ctor === undefined) {

      // return a placeholder node for async component, which is rendered

      // as a comment node but preserves all the raw information for the node.

      // the information will be used for async server-rendering and hydration.

      return createAsyncPlaceholder(

        asyncFactory,

        data,

        context,

        children,

        tag

      )

    }

  }



  data = data || {};



  // resolve constructor options in case global mixins are applied after

  // component constructor creation

  resolveConstructorOptions(Ctor);



  // transform component v-model data into props & events

  if (isDef(data.model)) {

    transformModel(Ctor.options, data);

  }



  // extract props

  var propsData = extractPropsFromVNodeData(data, Ctor, tag);



  // functional component

  if (isTrue(Ctor.options.functional)) {

    return createFunctionalComponent(Ctor, propsData, data, context, children)

  }



  // extract listeners, since these needs to be treated as

  // child component listeners instead of DOM listeners

  var listeners = data.on;

  // replace with listeners with .native modifier

  // so it gets processed during parent component patch.

  data.on = data.nativeOn;



  if (isTrue(Ctor.options.abstract)) {

    // abstract components do not keep anything

    // other than props & listeners & slot



    // work around flow

    var slot = data.slot;

    data = {};

    if (slot) {

      data.slot = slot;

    }

  }



  // merge component management hooks onto the placeholder node

  mergeHooks(data);



  // return a placeholder vnode

  var name = Ctor.options.name || tag;

  var vnode = new VNode(

    ("vue-component-" + (Ctor.cid) + (name ? ("-" + name) : '')),

    data, undefined, undefined, undefined, context,

    { Ctor: Ctor, propsData: propsData, listeners: listeners, tag: tag, children: children },

    asyncFactory

  );



  // Weex specific: invoke recycle-list optimized @render function for

  // extracting cell-slot template.

  // https://github.com/Hanks10100/weex-native-directive/tree/master/component

  /* istanbul ignore if */

  return vnode

}



function createComponentInstanceForVnode (

  vnode, // we know it's MountedComponentVNode but flow doesn't

  parent, // activeInstance in lifecycle state

  parentElm,

  refElm

) {

  var options = {

    _isComponent: true,

    parent: parent,

    _parentVnode: vnode,

    _parentElm: parentElm || null,

    _refElm: refElm || null

  };

  // check inline-template render functions

  var inlineTemplate = vnode.data.inlineTemplate;

  if (isDef(inlineTemplate)) {

    options.render = inlineTemplate.render;

    options.staticRenderFns = inlineTemplate.staticRenderFns;

  }

  return new vnode.componentOptions.Ctor(options)

}



function mergeHooks (data) {

  if (!data.hook) {

    data.hook = {};

  }

  for (var i = 0; i < hooksToMerge.length; i++) {

    var key = hooksToMerge[i];

    var fromParent = data.hook[key];

    var ours = componentVNodeHooks[key];

    data.hook[key] = fromParent ? mergeHook$1(ours, fromParent) : ours;

  }

}



function mergeHook$1 (one, two) {

  return function (a, b, c, d) {

    one(a, b, c, d);

    two(a, b, c, d);

  }

}



// transform component v-model info (value and callback) into

// prop and event handler respectively.

function transformModel (options, data) {

  var prop = (options.model && options.model.prop) || 'value';

  var event = (options.model && options.model.event) || 'input';(data.props || (data.props = {}))[prop] = data.model.value;

  var on = data.on || (data.on = {});

  if (isDef(on[event])) {

    on[event] = [data.model.callback].concat(on[event]);

  } else {

    on[event] = data.model.callback;

  }

}



/*  */



var SIMPLE_NORMALIZE = 1;

var ALWAYS_NORMALIZE = 2;



// wrapper function for providing a more flexible interface

// without getting yelled at by flow

function createElement (

  context,

  tag,

  data,

  children,

  normalizationType,

  alwaysNormalize

) {

  if (Array.isArray(data) || isPrimitive(data)) {

    normalizationType = children;

    children = data;

    data = undefined;

  }

  if (isTrue(alwaysNormalize)) {

    normalizationType = ALWAYS_NORMALIZE;

  }

  return _createElement(context, tag, data, children, normalizationType)

}



function _createElement (

  context,

  tag,

  data,

  children,

  normalizationType

) {

  if (isDef(data) && isDef((data).__ob__)) {

    "development" !== 'production' && warn(

      "Avoid using observed data object as vnode data: " + (JSON.stringify(data)) + "\n" +

      'Always create fresh vnode data objects in each render!',

      context

    );

    return createEmptyVNode()

  }

  // object syntax in v-bind

  if (isDef(data) && isDef(data.is)) {

    tag = data.is;

  }

  if (!tag) {

    // in case of component :is set to falsy value

    return createEmptyVNode()

  }

  // warn against non-primitive key

  if ("development" !== 'production' &&

    isDef(data) && isDef(data.key) && !isPrimitive(data.key)

  ) {

    {

      warn(

        'Avoid using non-primitive value as key, ' +

        'use string/number value instead.',

        context

      );

    }

  }

  // support single function children as default scoped slot

  if (Array.isArray(children) &&

    typeof children[0] === 'function'

  ) {

    data = data || {};

    data.scopedSlots = { default: children[0] };

    children.length = 0;

  }

  if (normalizationType === ALWAYS_NORMALIZE) {

    children = normalizeChildren(children);

  } else if (normalizationType === SIMPLE_NORMALIZE) {

    children = simpleNormalizeChildren(children);

  }

  var vnode, ns;

  if (typeof tag === 'string') {

    var Ctor;

    ns = (context.$vnode && context.$vnode.ns) || config.getTagNamespace(tag);

    if (config.isReservedTag(tag)) {

      // platform built-in elements

      vnode = new VNode(

        config.parsePlatformTagName(tag), data, children,

        undefined, undefined, context

      );

    } else if (isDef(Ctor = resolveAsset(context.$options, 'components', tag))) {

      // component

      vnode = createComponent(Ctor, data, context, children, tag);

    } else {

      // unknown or unlisted namespaced elements

      // check at runtime because it may get assigned a namespace when its

      // parent normalizes children

      vnode = new VNode(

        tag, data, children,

        undefined, undefined, context

      );

    }

  } else {

    // direct component options / constructor

    vnode = createComponent(tag, data, context, children);

  }

  if (isDef(vnode)) {

    if (ns) { applyNS(vnode, ns); }

    return vnode

  } else {

    return createEmptyVNode()

  }

}



function applyNS (vnode, ns, force) {

  vnode.ns = ns;

  if (vnode.tag === 'foreignObject') {

    // use default namespace inside foreignObject

    ns = undefined;

    force = true;

  }

  if (isDef(vnode.children)) {

    for (var i = 0, l = vnode.children.length; i < l; i++) {

      var child = vnode.children[i];

      if (isDef(child.tag) && (isUndef(child.ns) || isTrue(force))) {

        applyNS(child, ns, force);

      }

    }

  }

}



/*  */



function initRender (vm) {

  vm._vnode = null; // the root of the child tree

  vm._staticTrees = null; // v-once cached trees

  var options = vm.$options;

  var parentVnode = vm.$vnode = options._parentVnode; // the placeholder node in parent tree

  var renderContext = parentVnode && parentVnode.context;

  vm.$slots = resolveSlots(options._renderChildren, renderContext);

  vm.$scopedSlots = emptyObject;

  // bind the createElement fn to this instance

  // so that we get proper render context inside it.

  // args order: tag, data, children, normalizationType, alwaysNormalize

  // internal version is used by render functions compiled from templates

  vm._c = function (a, b, c, d) { return createElement(vm, a, b, c, d, false); };

  // normalization is always applied for the public version, used in

  // user-written render functions.

  vm.$createElement = function (a, b, c, d) { return createElement(vm, a, b, c, d, true); };



  // $attrs & $listeners are exposed for easier HOC creation.

  // they need to be reactive so that HOCs using them are always updated

  var parentData = parentVnode && parentVnode.data;



  /* istanbul ignore else */

  if (true) {

    defineReactive(vm, '$attrs', parentData && parentData.attrs || emptyObject, function () {

      !isUpdatingChildComponent && warn("$attrs is readonly.", vm);

    }, true);

    defineReactive(vm, '$listeners', options._parentListeners || emptyObject, function () {

      !isUpdatingChildComponent && warn("$listeners is readonly.", vm);

    }, true);

  } else {

    defineReactive(vm, '$attrs', parentData && parentData.attrs || emptyObject, null, true);

    defineReactive(vm, '$listeners', options._parentListeners || emptyObject, null, true);

  }

}



function renderMixin (Vue) {

  // install runtime convenience helpers

  installRenderHelpers(Vue.prototype);



  Vue.prototype.$nextTick = function (fn) {

    return nextTick(fn, this)

  };



  Vue.prototype._render = function () {

    var vm = this;

    var ref = vm.$options;

    var render = ref.render;

    var _parentVnode = ref._parentVnode;



    if (vm._isMounted) {

      // if the parent didn't update, the slot nodes will be the ones from

      // last render. They need to be cloned to ensure "freshness" for this render.

      for (var key in vm.$slots) {

        var slot = vm.$slots[key];

        // _rendered is a flag added by renderSlot, but may not be present

        // if the slot is passed from manually written render functions

        if (slot._rendered || (slot[0] && slot[0].elm)) {

          vm.$slots[key] = cloneVNodes(slot, true /* deep */);

        }

      }

    }



    vm.$scopedSlots = (_parentVnode && _parentVnode.data.scopedSlots) || emptyObject;



    // set parent vnode. this allows render functions to have access

    // to the data on the placeholder node.

    vm.$vnode = _parentVnode;

    // render self

    var vnode;

    try {

      vnode = render.call(vm._renderProxy, vm.$createElement);

    } catch (e) {

      handleError(e, vm, "render");

      // return error render result,

      // or previous vnode to prevent render error causing blank component

      /* istanbul ignore else */

      if (true) {

        if (vm.$options.renderError) {

          try {

            vnode = vm.$options.renderError.call(vm._renderProxy, vm.$createElement, e);

          } catch (e) {

            handleError(e, vm, "renderError");

            vnode = vm._vnode;

          }

        } else {

          vnode = vm._vnode;

        }

      } else {

        vnode = vm._vnode;

      }

    }

    // return empty vnode in case the render function errored out

    if (!(vnode instanceof VNode)) {

      if ("development" !== 'production' && Array.isArray(vnode)) {

        warn(

          'Multiple root nodes returned from render function. Render function ' +

          'should return a single root node.',

          vm

        );

      }

      vnode = createEmptyVNode();

    }

    // set parent

    vnode.parent = _parentVnode;

    return vnode

  };

}



/*  */



var uid$1 = 0;



function initMixin (Vue) {

  Vue.prototype._init = function (options) {

    var vm = this;

    // a uid

    vm._uid = uid$1++;



    var startTag, endTag;

    /* istanbul ignore if */

    if ("development" !== 'production' && config.performance && mark) {

      startTag = "vue-perf-start:" + (vm._uid);

      endTag = "vue-perf-end:" + (vm._uid);

      mark(startTag);

    }



    // a flag to avoid this being observed

    vm._isVue = true;

    // merge options

    if (options && options._isComponent) {

      // optimize internal component instantiation

      // since dynamic options merging is pretty slow, and none of the

      // internal component options needs special treatment.

      initInternalComponent(vm, options);

    } else {

      vm.$options = mergeOptions(

        resolveConstructorOptions(vm.constructor),

        options || {},

        vm

      );

    }

    /* istanbul ignore else */

    if (true) {

      initProxy(vm);

    } else {

      vm._renderProxy = vm;

    }

    // expose real self

    vm._self = vm;

    initLifecycle(vm);

    initEvents(vm);

    initRender(vm);

    callHook(vm, 'beforeCreate');

    initInjections(vm); // resolve injections before data/props

    initState(vm);

    initProvide(vm); // resolve provide after data/props

    callHook(vm, 'created');



    /* istanbul ignore if */

    if ("development" !== 'production' && config.performance && mark) {

      vm._name = formatComponentName(vm, false);

      mark(endTag);

      measure(("vue " + (vm._name) + " init"), startTag, endTag);

    }



    if (vm.$options.el) {

      vm.$mount(vm.$options.el);

    }

  };

}



function initInternalComponent (vm, options) {

  var opts = vm.$options = Object.create(vm.constructor.options);

  // doing this because it's faster than dynamic enumeration.

  var parentVnode = options._parentVnode;

  opts.parent = options.parent;

  opts._parentVnode = parentVnode;

  opts._parentElm = options._parentElm;

  opts._refElm = options._refElm;



  var vnodeComponentOptions = parentVnode.componentOptions;

  opts.propsData = vnodeComponentOptions.propsData;

  opts._parentListeners = vnodeComponentOptions.listeners;

  opts._renderChildren = vnodeComponentOptions.children;

  opts._componentTag = vnodeComponentOptions.tag;



  if (options.render) {

    opts.render = options.render;

    opts.staticRenderFns = options.staticRenderFns;

  }

}



function resolveConstructorOptions (Ctor) {

  var options = Ctor.options;

  if (Ctor.super) {

    var superOptions = resolveConstructorOptions(Ctor.super);

    var cachedSuperOptions = Ctor.superOptions;

    if (superOptions !== cachedSuperOptions) {

      // super option changed,

      // need to resolve new options.

      Ctor.superOptions = superOptions;

      // check if there are any late-modified/attached options (#4976)

      var modifiedOptions = resolveModifiedOptions(Ctor);

      // update base extend options

      if (modifiedOptions) {

        extend(Ctor.extendOptions, modifiedOptions);

      }

      options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions);

      if (options.name) {

        options.components[options.name] = Ctor;

      }

    }

  }

  return options

}



function resolveModifiedOptions (Ctor) {

  var modified;

  var latest = Ctor.options;

  var extended = Ctor.extendOptions;

  var sealed = Ctor.sealedOptions;

  for (var key in latest) {

    if (latest[key] !== sealed[key]) {

      if (!modified) { modified = {}; }

      modified[key] = dedupe(latest[key], extended[key], sealed[key]);

    }

  }

  return modified

}



function dedupe (latest, extended, sealed) {

  // compare latest and sealed to ensure lifecycle hooks won't be duplicated

  // between merges

  if (Array.isArray(latest)) {

    var res = [];

    sealed = Array.isArray(sealed) ? sealed : [sealed];

    extended = Array.isArray(extended) ? extended : [extended];

    for (var i = 0; i < latest.length; i++) {

      // push original options and not sealed options to exclude duplicated options

      if (extended.indexOf(latest[i]) >= 0 || sealed.indexOf(latest[i]) < 0) {

        res.push(latest[i]);

      }

    }

    return res

  } else {

    return latest

  }

}



function Vue$3 (options) {

  if ("development" !== 'production' &&

    !(this instanceof Vue$3)

  ) {

    warn('Vue is a constructor and should be called with the `new` keyword');

  }

  this._init(options);

}



initMixin(Vue$3);

stateMixin(Vue$3);

eventsMixin(Vue$3);

lifecycleMixin(Vue$3);

renderMixin(Vue$3);



/*  */



function initUse (Vue) {

  Vue.use = function (plugin) {

    var installedPlugins = (this._installedPlugins || (this._installedPlugins = []));

    if (installedPlugins.indexOf(plugin) > -1) {

      return this

    }



    // additional parameters

    var args = toArray(arguments, 1);

    args.unshift(this);

    if (typeof plugin.install === 'function') {

      plugin.install.apply(plugin, args);

    } else if (typeof plugin === 'function') {

      plugin.apply(null, args);

    }

    installedPlugins.push(plugin);

    return this

  };

}



/*  */



function initMixin$1 (Vue) {

  Vue.mixin = function (mixin) {

    this.options = mergeOptions(this.options, mixin);

    return this

  };

}



/*  */



function initExtend (Vue) {

  /**

   * Each instance constructor, including Vue, has a unique

   * cid. This enables us to create wrapped "child

   * constructors" for prototypal inheritance and cache them.

   */

  Vue.cid = 0;

  var cid = 1;



  /**

   * Class inheritance

   */

  Vue.extend = function (extendOptions) {

    extendOptions = extendOptions || {};

    var Super = this;

    var SuperId = Super.cid;

    var cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {});

    if (cachedCtors[SuperId]) {

      return cachedCtors[SuperId]

    }



    var name = extendOptions.name || Super.options.name;

    if ("development" !== 'production' && name) {

      validateComponentName(name);

    }



    var Sub = function VueComponent (options) {

      this._init(options);

    };

    Sub.prototype = Object.create(Super.prototype);

    Sub.prototype.constructor = Sub;

    Sub.cid = cid++;

    Sub.options = mergeOptions(

      Super.options,

      extendOptions

    );

    Sub['super'] = Super;



    // For props and computed properties, we define the proxy getters on

    // the Vue instances at extension time, on the extended prototype. This

    // avoids Object.defineProperty calls for each instance created.

    if (Sub.options.props) {

      initProps$1(Sub);

    }

    if (Sub.options.computed) {

      initComputed$1(Sub);

    }



    // allow further extension/mixin/plugin usage

    Sub.extend = Super.extend;

    Sub.mixin = Super.mixin;

    Sub.use = Super.use;



    // create asset registers, so extended classes

    // can have their private assets too.

    ASSET_TYPES.forEach(function (type) {

      Sub[type] = Super[type];

    });

    // enable recursive self-lookup

    if (name) {

      Sub.options.components[name] = Sub;

    }



    // keep a reference to the super options at extension time.

    // later at instantiation we can check if Super's options have

    // been updated.

    Sub.superOptions = Super.options;

    Sub.extendOptions = extendOptions;

    Sub.sealedOptions = extend({}, Sub.options);



    // cache constructor

    cachedCtors[SuperId] = Sub;

    return Sub

  };

}



function initProps$1 (Comp) {

  var props = Comp.options.props;

  for (var key in props) {

    proxy(Comp.prototype, "_props", key);

  }

}



function initComputed$1 (Comp) {

  var computed = Comp.options.computed;

  for (var key in computed) {

    defineComputed(Comp.prototype, key, computed[key]);

  }

}



/*  */



function initAssetRegisters (Vue) {

  /**

   * Create asset registration methods.

   */

  ASSET_TYPES.forEach(function (type) {

    Vue[type] = function (

      id,

      definition

    ) {

      if (!definition) {

        return this.options[type + 's'][id]

      } else {

        /* istanbul ignore if */

        if ("development" !== 'production' && type === 'component') {

          validateComponentName(id);

        }

        if (type === 'component' && isPlainObject(definition)) {

          definition.name = definition.name || id;

          definition = this.options._base.extend(definition);

        }

        if (type === 'directive' && typeof definition === 'function') {

          definition = { bind: definition, update: definition };

        }

        this.options[type + 's'][id] = definition;

        return definition

      }

    };

  });

}



/*  */



function getComponentName (opts) {

  return opts && (opts.Ctor.options.name || opts.tag)

}



function matches (pattern, name) {

  if (Array.isArray(pattern)) {

    return pattern.indexOf(name) > -1

  } else if (typeof pattern === 'string') {

    return pattern.split(',').indexOf(name) > -1

  } else if (isRegExp(pattern)) {

    return pattern.test(name)

  }

  /* istanbul ignore next */

  return false

}



function pruneCache (keepAliveInstance, filter) {

  var cache = keepAliveInstance.cache;

  var keys = keepAliveInstance.keys;

  var _vnode = keepAliveInstance._vnode;

  for (var key in cache) {

    var cachedNode = cache[key];

    if (cachedNode) {

      var name = getComponentName(cachedNode.componentOptions);

      if (name && !filter(name)) {

        pruneCacheEntry(cache, key, keys, _vnode);

      }

    }

  }

}



function pruneCacheEntry (

  cache,

  key,

  keys,

  current

) {

  var cached$$1 = cache[key];

  if (cached$$1 && (!current || cached$$1.tag !== current.tag)) {

    cached$$1.componentInstance.$destroy();

  }

  cache[key] = null;

  remove(keys, key);

}



var patternTypes = [String, RegExp, Array];



var KeepAlive = {

  name: 'keep-alive',

  abstract: true,



  props: {

    include: patternTypes,

    exclude: patternTypes,

    max: [String, Number]

  },



  created: function created () {

    this.cache = Object.create(null);

    this.keys = [];

  },



  destroyed: function destroyed () {

    var this$1 = this;



    for (var key in this$1.cache) {

      pruneCacheEntry(this$1.cache, key, this$1.keys);

    }

  },



  watch: {

    include: function include (val) {

      pruneCache(this, function (name) { return matches(val, name); });

    },

    exclude: function exclude (val) {

      pruneCache(this, function (name) { return !matches(val, name); });

    }

  },



  render: function render () {

    var slot = this.$slots.default;

    var vnode = getFirstComponentChild(slot);

    var componentOptions = vnode && vnode.componentOptions;

    if (componentOptions) {

      // check pattern

      var name = getComponentName(componentOptions);

      var ref = this;

      var include = ref.include;

      var exclude = ref.exclude;

      if (

        // not included

        (include && (!name || !matches(include, name))) ||

        // excluded

        (exclude && name && matches(exclude, name))

      ) {

        return vnode

      }



      var ref$1 = this;

      var cache = ref$1.cache;

      var keys = ref$1.keys;

      var key = vnode.key == null

        // same constructor may get registered as different local components

        // so cid alone is not enough (#3269)

        ? componentOptions.Ctor.cid + (componentOptions.tag ? ("::" + (componentOptions.tag)) : '')

        : vnode.key;

      if (cache[key]) {

        vnode.componentInstance = cache[key].componentInstance;

        // make current key freshest

        remove(keys, key);

        keys.push(key);

      } else {

        cache[key] = vnode;

        keys.push(key);

        // prune oldest entry

        if (this.max && keys.length > parseInt(this.max)) {

          pruneCacheEntry(cache, keys[0], keys, this._vnode);

        }

      }



      vnode.data.keepAlive = true;

    }

    return vnode || (slot && slot[0])

  }

};



var builtInComponents = {

  KeepAlive: KeepAlive

};



/*  */



function initGlobalAPI (Vue) {

  // config

  var configDef = {};

  configDef.get = function () { return config; };

  if (true) {

    configDef.set = function () {

      warn(

        'Do not replace the Vue.config object, set individual fields instead.'

      );

    };

  }

  Object.defineProperty(Vue, 'config', configDef);



  // exposed util methods.

  // NOTE: these are not considered part of the public API - avoid relying on

  // them unless you are aware of the risk.

  Vue.util = {

    warn: warn,

    extend: extend,

    mergeOptions: mergeOptions,

    defineReactive: defineReactive

  };



  Vue.set = set;

  Vue.delete = del;

  Vue.nextTick = nextTick;



  Vue.options = Object.create(null);

  ASSET_TYPES.forEach(function (type) {

    Vue.options[type + 's'] = Object.create(null);

  });



  // this is used to identify the "base" constructor to extend all plain-object

  // components with in Weex's multi-instance scenarios.

  Vue.options._base = Vue;



  extend(Vue.options.components, builtInComponents);



  initUse(Vue);

  initMixin$1(Vue);

  initExtend(Vue);

  initAssetRegisters(Vue);

}



initGlobalAPI(Vue$3);



Object.defineProperty(Vue$3.prototype, '$isServer', {

  get: isServerRendering

});



Object.defineProperty(Vue$3.prototype, '$ssrContext', {

  get: function get () {

    /* istanbul ignore next */

    return this.$vnode && this.$vnode.ssrContext

  }

});



Vue$3.version = '2.5.13';



/*  */



// these are reserved for web because they are directly compiled away

// during template compilation

var isReservedAttr = makeMap('style,class');



// attributes that should be using props for binding

var acceptValue = makeMap('input,textarea,option,select,progress');

var mustUseProp = function (tag, type, attr) {

  return (

    (attr === 'value' && acceptValue(tag)) && type !== 'button' ||

    (attr === 'selected' && tag === 'option') ||

    (attr === 'checked' && tag === 'input') ||

    (attr === 'muted' && tag === 'video')

  )

};



var isEnumeratedAttr = makeMap('contenteditable,draggable,spellcheck');



var isBooleanAttr = makeMap(

  'allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,' +

  'default,defaultchecked,defaultmuted,defaultselected,defer,disabled,' +

  'enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,' +

  'muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,' +

  'required,reversed,scoped,seamless,selected,sortable,translate,' +

  'truespeed,typemustmatch,visible'

);



var xlinkNS = 'http://www.w3.org/1999/xlink';



var isXlink = function (name) {

  return name.charAt(5) === ':' && name.slice(0, 5) === 'xlink'

};



var getXlinkProp = function (name) {

  return isXlink(name) ? name.slice(6, name.length) : ''

};



var isFalsyAttrValue = function (val) {

  return val == null || val === false

};



/*  */



function genClassForVnode (vnode) {

  var data = vnode.data;

  var parentNode = vnode;

  var childNode = vnode;

  while (isDef(childNode.componentInstance)) {

    childNode = childNode.componentInstance._vnode;

    if (childNode && childNode.data) {

      data = mergeClassData(childNode.data, data);

    }

  }

  while (isDef(parentNode = parentNode.parent)) {

    if (parentNode && parentNode.data) {

      data = mergeClassData(data, parentNode.data);

    }

  }

  return renderClass(data.staticClass, data.class)

}



function mergeClassData (child, parent) {

  return {

    staticClass: concat(child.staticClass, parent.staticClass),

    class: isDef(child.class)

      ? [child.class, parent.class]

      : parent.class

  }

}



function renderClass (

  staticClass,

  dynamicClass

) {

  if (isDef(staticClass) || isDef(dynamicClass)) {

    return concat(staticClass, stringifyClass(dynamicClass))

  }

  /* istanbul ignore next */

  return ''

}



function concat (a, b) {

  return a ? b ? (a + ' ' + b) : a : (b || '')

}



function stringifyClass (value) {

  if (Array.isArray(value)) {

    return stringifyArray(value)

  }

  if (isObject(value)) {

    return stringifyObject(value)

  }

  if (typeof value === 'string') {

    return value

  }

  /* istanbul ignore next */

  return ''

}



function stringifyArray (value) {

  var res = '';

  var stringified;

  for (var i = 0, l = value.length; i < l; i++) {

    if (isDef(stringified = stringifyClass(value[i])) && stringified !== '') {

      if (res) { res += ' '; }

      res += stringified;

    }

  }

  return res

}



function stringifyObject (value) {

  var res = '';

  for (var key in value) {

    if (value[key]) {

      if (res) { res += ' '; }

      res += key;

    }

  }

  return res

}



/*  */



var namespaceMap = {

  svg: 'http://www.w3.org/2000/svg',

  math: 'http://www.w3.org/1998/Math/MathML'

};



var isHTMLTag = makeMap(

  'html,body,base,head,link,meta,style,title,' +

  'address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,' +

  'div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,' +

  'a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,' +

  's,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,' +

  'embed,object,param,source,canvas,script,noscript,del,ins,' +

  'caption,col,colgroup,table,thead,tbody,td,th,tr,' +

  'button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,' +

  'output,progress,select,textarea,' +

  'details,dialog,menu,menuitem,summary,' +

  'content,element,shadow,template,blockquote,iframe,tfoot'

);



// this map is intentionally selective, only covering SVG elements that may

// contain child elements.

var isSVG = makeMap(

  'svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,' +

  'foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,' +

  'polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view',

  true

);



var isPreTag = function (tag) { return tag === 'pre'; };



var isReservedTag = function (tag) {

  return isHTMLTag(tag) || isSVG(tag)

};



function getTagNamespace (tag) {

  if (isSVG(tag)) {

    return 'svg'

  }

  // basic support for MathML

  // note it doesn't support other MathML elements being component roots

  if (tag === 'math') {

    return 'math'

  }

}



var unknownElementCache = Object.create(null);

function isUnknownElement (tag) {

  /* istanbul ignore if */

  if (!inBrowser) {

    return true

  }

  if (isReservedTag(tag)) {

    return false

  }

  tag = tag.toLowerCase();

  /* istanbul ignore if */

  if (unknownElementCache[tag] != null) {

    return unknownElementCache[tag]

  }

  var el = document.createElement(tag);

  if (tag.indexOf('-') > -1) {

    // http://stackoverflow.com/a/28210364/1070244

    return (unknownElementCache[tag] = (

      el.constructor === window.HTMLUnknownElement ||

      el.constructor === window.HTMLElement

    ))

  } else {

    return (unknownElementCache[tag] = /HTMLUnknownElement/.test(el.toString()))

  }

}



var isTextInputType = makeMap('text,number,password,search,email,tel,url');



/*  */



/**

 * Query an element selector if it's not an element already.

 */

function query (el) {

  if (typeof el === 'string') {

    var selected = document.querySelector(el);

    if (!selected) {

      "development" !== 'production' && warn(

        'Cannot find element: ' + el

      );

      return document.createElement('div')

    }

    return selected

  } else {

    return el

  }

}



/*  */



function createElement$1 (tagName, vnode) {

  var elm = document.createElement(tagName);

  if (tagName !== 'select') {

    return elm

  }

  // false or null will remove the attribute but undefined will not

  if (vnode.data && vnode.data.attrs && vnode.data.attrs.multiple !== undefined) {

    elm.setAttribute('multiple', 'multiple');

  }

  return elm

}



function createElementNS (namespace, tagName) {

  return document.createElementNS(namespaceMap[namespace], tagName)

}



function createTextNode (text) {

  return document.createTextNode(text)

}



function createComment (text) {

  return document.createComment(text)

}



function insertBefore (parentNode, newNode, referenceNode) {

  parentNode.insertBefore(newNode, referenceNode);

}



function removeChild (node, child) {

  node.removeChild(child);

}



function appendChild (node, child) {

  node.appendChild(child);

}



function parentNode (node) {

  return node.parentNode

}



function nextSibling (node) {

  return node.nextSibling

}



function tagName (node) {

  return node.tagName

}



function setTextContent (node, text) {

  node.textContent = text;

}



function setAttribute (node, key, val) {

  node.setAttribute(key, val);

}





var nodeOps = Object.freeze({

	createElement: createElement$1,

	createElementNS: createElementNS,

	createTextNode: createTextNode,

	createComment: createComment,

	insertBefore: insertBefore,

	removeChild: removeChild,

	appendChild: appendChild,

	parentNode: parentNode,

	nextSibling: nextSibling,

	tagName: tagName,

	setTextContent: setTextContent,

	setAttribute: setAttribute

});



/*  */



var ref = {

  create: function create (_, vnode) {

    registerRef(vnode);

  },

  update: function update (oldVnode, vnode) {

    if (oldVnode.data.ref !== vnode.data.ref) {

      registerRef(oldVnode, true);

      registerRef(vnode);

    }

  },

  destroy: function destroy (vnode) {

    registerRef(vnode, true);

  }

};



function registerRef (vnode, isRemoval) {

  var key = vnode.data.ref;

  if (!key) { return }



  var vm = vnode.context;

  var ref = vnode.componentInstance || vnode.elm;

  var refs = vm.$refs;

  if (isRemoval) {

    if (Array.isArray(refs[key])) {

      remove(refs[key], ref);

    } else if (refs[key] === ref) {

      refs[key] = undefined;

    }

  } else {

    if (vnode.data.refInFor) {

      if (!Array.isArray(refs[key])) {

        refs[key] = [ref];

      } else if (refs[key].indexOf(ref) < 0) {

        // $flow-disable-line

        refs[key].push(ref);

      }

    } else {

      refs[key] = ref;

    }

  }

}



/**

 * Virtual DOM patching algorithm based on Snabbdom by

 * Simon Friis Vindum (@paldepind)

 * Licensed under the MIT License

 * https://github.com/paldepind/snabbdom/blob/master/LICENSE

 *

 * modified by Evan You (@yyx990803)

 *

 * Not type-checking this because this file is perf-critical and the cost

 * of making flow understand it is not worth it.

 */



var emptyNode = new VNode('', {}, []);



var hooks = ['create', 'activate', 'update', 'remove', 'destroy'];



function sameVnode (a, b) {

  return (

    a.key === b.key && (

      (

        a.tag === b.tag &&

        a.isComment === b.isComment &&

        isDef(a.data) === isDef(b.data) &&

        sameInputType(a, b)

      ) || (

        isTrue(a.isAsyncPlaceholder) &&

        a.asyncFactory === b.asyncFactory &&

        isUndef(b.asyncFactory.error)

      )

    )

  )

}



function sameInputType (a, b) {

  if (a.tag !== 'input') { return true }

  var i;

  var typeA = isDef(i = a.data) && isDef(i = i.attrs) && i.type;

  var typeB = isDef(i = b.data) && isDef(i = i.attrs) && i.type;

  return typeA === typeB || isTextInputType(typeA) && isTextInputType(typeB)

}



function createKeyToOldIdx (children, beginIdx, endIdx) {

  var i, key;

  var map = {};

  for (i = beginIdx; i <= endIdx; ++i) {

    key = children[i].key;

    if (isDef(key)) { map[key] = i; }

  }

  return map

}



function createPatchFunction (backend) {

  var i, j;

  var cbs = {};



  var modules = backend.modules;

  var nodeOps = backend.nodeOps;



  for (i = 0; i < hooks.length; ++i) {

    cbs[hooks[i]] = [];

    for (j = 0; j < modules.length; ++j) {

      if (isDef(modules[j][hooks[i]])) {

        cbs[hooks[i]].push(modules[j][hooks[i]]);

      }

    }

  }



  function emptyNodeAt (elm) {

    return new VNode(nodeOps.tagName(elm).toLowerCase(), {}, [], undefined, elm)

  }



  function createRmCb (childElm, listeners) {

    function remove () {

      if (--remove.listeners === 0) {

        removeNode(childElm);

      }

    }

    remove.listeners = listeners;

    return remove

  }



  function removeNode (el) {

    var parent = nodeOps.parentNode(el);

    // element may have already been removed due to v-html / v-text

    if (isDef(parent)) {

      nodeOps.removeChild(parent, el);

    }

  }



  function isUnknownElement$$1 (vnode, inVPre) {

    return (

      !inVPre &&

      !vnode.ns &&

      !(

        config.ignoredElements.length &&

        config.ignoredElements.some(function (ignore) {

          return isRegExp(ignore)

            ? ignore.test(vnode.tag)

            : ignore === vnode.tag

        })

      ) &&

      config.isUnknownElement(vnode.tag)

    )

  }



  var creatingElmInVPre = 0;

  function createElm (vnode, insertedVnodeQueue, parentElm, refElm, nested) {

    vnode.isRootInsert = !nested; // for transition enter check

    if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) {

      return

    }



    var data = vnode.data;

    var children = vnode.children;

    var tag = vnode.tag;

    if (isDef(tag)) {

      if (true) {

        if (data && data.pre) {

          creatingElmInVPre++;

        }

        if (isUnknownElement$$1(vnode, creatingElmInVPre)) {

          warn(

            'Unknown custom element: <' + tag + '> - did you ' +

            'register the component correctly? For recursive components, ' +

            'make sure to provide the "name" option.',

            vnode.context

          );

        }

      }

      vnode.elm = vnode.ns

        ? nodeOps.createElementNS(vnode.ns, tag)

        : nodeOps.createElement(tag, vnode);

      setScope(vnode);



      /* istanbul ignore if */

      {

        createChildren(vnode, children, insertedVnodeQueue);

        if (isDef(data)) {

          invokeCreateHooks(vnode, insertedVnodeQueue);

        }

        insert(parentElm, vnode.elm, refElm);

      }



      if ("development" !== 'production' && data && data.pre) {

        creatingElmInVPre--;

      }

    } else if (isTrue(vnode.isComment)) {

      vnode.elm = nodeOps.createComment(vnode.text);

      insert(parentElm, vnode.elm, refElm);

    } else {

      vnode.elm = nodeOps.createTextNode(vnode.text);

      insert(parentElm, vnode.elm, refElm);

    }

  }



  function createComponent (vnode, insertedVnodeQueue, parentElm, refElm) {

    var i = vnode.data;

    if (isDef(i)) {

      var isReactivated = isDef(vnode.componentInstance) && i.keepAlive;

      if (isDef(i = i.hook) && isDef(i = i.init)) {

        i(vnode, false /* hydrating */, parentElm, refElm);

      }

      // after calling the init hook, if the vnode is a child component

      // it should've created a child instance and mounted it. the child

      // component also has set the placeholder vnode's elm.

      // in that case we can just return the element and be done.

      if (isDef(vnode.componentInstance)) {

        initComponent(vnode, insertedVnodeQueue);

        if (isTrue(isReactivated)) {

          reactivateComponent(vnode, insertedVnodeQueue, parentElm, refElm);

        }

        return true

      }

    }

  }



  function initComponent (vnode, insertedVnodeQueue) {

    if (isDef(vnode.data.pendingInsert)) {

      insertedVnodeQueue.push.apply(insertedVnodeQueue, vnode.data.pendingInsert);

      vnode.data.pendingInsert = null;

    }

    vnode.elm = vnode.componentInstance.$el;

    if (isPatchable(vnode)) {

      invokeCreateHooks(vnode, insertedVnodeQueue);

      setScope(vnode);

    } else {

      // empty component root.

      // skip all element-related modules except for ref (#3455)

      registerRef(vnode);

      // make sure to invoke the insert hook

      insertedVnodeQueue.push(vnode);

    }

  }



  function reactivateComponent (vnode, insertedVnodeQueue, parentElm, refElm) {

    var i;

    // hack for #4339: a reactivated component with inner transition

    // does not trigger because the inner node's created hooks are not called

    // again. It's not ideal to involve module-specific logic in here but

    // there doesn't seem to be a better way to do it.

    var innerNode = vnode;

    while (innerNode.componentInstance) {

      innerNode = innerNode.componentInstance._vnode;

      if (isDef(i = innerNode.data) && isDef(i = i.transition)) {

        for (i = 0; i < cbs.activate.length; ++i) {

          cbs.activate[i](emptyNode, innerNode);

        }

        insertedVnodeQueue.push(innerNode);

        break

      }

    }

    // unlike a newly created component,

    // a reactivated keep-alive component doesn't insert itself

    insert(parentElm, vnode.elm, refElm);

  }



  function insert (parent, elm, ref$$1) {

    if (isDef(parent)) {

      if (isDef(ref$$1)) {

        if (ref$$1.parentNode === parent) {

          nodeOps.insertBefore(parent, elm, ref$$1);

        }

      } else {

        nodeOps.appendChild(parent, elm);

      }

    }

  }



  function createChildren (vnode, children, insertedVnodeQueue) {

    if (Array.isArray(children)) {

      if (true) {

        checkDuplicateKeys(children);

      }

      for (var i = 0; i < children.length; ++i) {

        createElm(children[i], insertedVnodeQueue, vnode.elm, null, true);

      }

    } else if (isPrimitive(vnode.text)) {

      nodeOps.appendChild(vnode.elm, nodeOps.createTextNode(String(vnode.text)));

    }

  }



  function isPatchable (vnode) {

    while (vnode.componentInstance) {

      vnode = vnode.componentInstance._vnode;

    }

    return isDef(vnode.tag)

  }



  function invokeCreateHooks (vnode, insertedVnodeQueue) {

    for (var i$1 = 0; i$1 < cbs.create.length; ++i$1) {

      cbs.create[i$1](emptyNode, vnode);

    }

    i = vnode.data.hook; // Reuse variable

    if (isDef(i)) {

      if (isDef(i.create)) { i.create(emptyNode, vnode); }

      if (isDef(i.insert)) { insertedVnodeQueue.push(vnode); }

    }

  }



  // set scope id attribute for scoped CSS.

  // this is implemented as a special case to avoid the overhead

  // of going through the normal attribute patching process.

  function setScope (vnode) {

    var i;

    if (isDef(i = vnode.fnScopeId)) {

      nodeOps.setAttribute(vnode.elm, i, '');

    } else {

      var ancestor = vnode;

      while (ancestor) {

        if (isDef(i = ancestor.context) && isDef(i = i.$options._scopeId)) {

          nodeOps.setAttribute(vnode.elm, i, '');

        }

        ancestor = ancestor.parent;

      }

    }

    // for slot content they should also get the scopeId from the host instance.

    if (isDef(i = activeInstance) &&

      i !== vnode.context &&

      i !== vnode.fnContext &&

      isDef(i = i.$options._scopeId)

    ) {

      nodeOps.setAttribute(vnode.elm, i, '');

    }

  }



  function addVnodes (parentElm, refElm, vnodes, startIdx, endIdx, insertedVnodeQueue) {

    for (; startIdx <= endIdx; ++startIdx) {

      createElm(vnodes[startIdx], insertedVnodeQueue, parentElm, refElm);

    }

  }



  function invokeDestroyHook (vnode) {

    var i, j;

    var data = vnode.data;

    if (isDef(data)) {

      if (isDef(i = data.hook) && isDef(i = i.destroy)) { i(vnode); }

      for (i = 0; i < cbs.destroy.length; ++i) { cbs.destroy[i](vnode); }

    }

    if (isDef(i = vnode.children)) {

      for (j = 0; j < vnode.children.length; ++j) {

        invokeDestroyHook(vnode.children[j]);

      }

    }

  }



  function removeVnodes (parentElm, vnodes, startIdx, endIdx) {

    for (; startIdx <= endIdx; ++startIdx) {

      var ch = vnodes[startIdx];

      if (isDef(ch)) {

        if (isDef(ch.tag)) {

          removeAndInvokeRemoveHook(ch);

          invokeDestroyHook(ch);

        } else { // Text node

          removeNode(ch.elm);

        }

      }

    }

  }



  function removeAndInvokeRemoveHook (vnode, rm) {

    if (isDef(rm) || isDef(vnode.data)) {

      var i;

      var listeners = cbs.remove.length + 1;

      if (isDef(rm)) {

        // we have a recursively passed down rm callback

        // increase the listeners count

        rm.listeners += listeners;

      } else {

        // directly removing

        rm = createRmCb(vnode.elm, listeners);

      }

      // recursively invoke hooks on child component root node

      if (isDef(i = vnode.componentInstance) && isDef(i = i._vnode) && isDef(i.data)) {

        removeAndInvokeRemoveHook(i, rm);

      }

      for (i = 0; i < cbs.remove.length; ++i) {

        cbs.remove[i](vnode, rm);

      }

      if (isDef(i = vnode.data.hook) && isDef(i = i.remove)) {

        i(vnode, rm);

      } else {

        rm();

      }

    } else {

      removeNode(vnode.elm);

    }

  }



  function updateChildren (parentElm, oldCh, newCh, insertedVnodeQueue, removeOnly) {

    var oldStartIdx = 0;

    var newStartIdx = 0;

    var oldEndIdx = oldCh.length - 1;

    var oldStartVnode = oldCh[0];

    var oldEndVnode = oldCh[oldEndIdx];

    var newEndIdx = newCh.length - 1;

    var newStartVnode = newCh[0];

    var newEndVnode = newCh[newEndIdx];

    var oldKeyToIdx, idxInOld, vnodeToMove, refElm;



    // removeOnly is a special flag used only by <transition-group>

    // to ensure removed elements stay in correct relative positions

    // during leaving transitions

    var canMove = !removeOnly;



    if (true) {

      checkDuplicateKeys(newCh);

    }



    while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {

      if (isUndef(oldStartVnode)) {

        oldStartVnode = oldCh[++oldStartIdx]; // Vnode has been moved left

      } else if (isUndef(oldEndVnode)) {

        oldEndVnode = oldCh[--oldEndIdx];

      } else if (sameVnode(oldStartVnode, newStartVnode)) {

        patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue);

        oldStartVnode = oldCh[++oldStartIdx];

        newStartVnode = newCh[++newStartIdx];

      } else if (sameVnode(oldEndVnode, newEndVnode)) {

        patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue);

        oldEndVnode = oldCh[--oldEndIdx];

        newEndVnode = newCh[--newEndIdx];

      } else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right

        patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue);

        canMove && nodeOps.insertBefore(parentElm, oldStartVnode.elm, nodeOps.nextSibling(oldEndVnode.elm));

        oldStartVnode = oldCh[++oldStartIdx];

        newEndVnode = newCh[--newEndIdx];

      } else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left

        patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue);

        canMove && nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm);

        oldEndVnode = oldCh[--oldEndIdx];

        newStartVnode = newCh[++newStartIdx];

      } else {

        if (isUndef(oldKeyToIdx)) { oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx); }

        idxInOld = isDef(newStartVnode.key)

          ? oldKeyToIdx[newStartVnode.key]

          : findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx);

        if (isUndef(idxInOld)) { // New element

          createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm);

        } else {

          vnodeToMove = oldCh[idxInOld];

          if (sameVnode(vnodeToMove, newStartVnode)) {

            patchVnode(vnodeToMove, newStartVnode, insertedVnodeQueue);

            oldCh[idxInOld] = undefined;

            canMove && nodeOps.insertBefore(parentElm, vnodeToMove.elm, oldStartVnode.elm);

          } else {

            // same key but different element. treat as new element

            createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm);

          }

        }

        newStartVnode = newCh[++newStartIdx];

      }

    }

    if (oldStartIdx > oldEndIdx) {

      refElm = isUndef(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1].elm;

      addVnodes(parentElm, refElm, newCh, newStartIdx, newEndIdx, insertedVnodeQueue);

    } else if (newStartIdx > newEndIdx) {

      removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx);

    }

  }



  function checkDuplicateKeys (children) {

    var seenKeys = {};

    for (var i = 0; i < children.length; i++) {

      var vnode = children[i];

      var key = vnode.key;

      if (isDef(key)) {

        if (seenKeys[key]) {

          warn(

            ("Duplicate keys detected: '" + key + "'. This may cause an update error."),

            vnode.context

          );

        } else {

          seenKeys[key] = true;

        }

      }

    }

  }



  function findIdxInOld (node, oldCh, start, end) {

    for (var i = start; i < end; i++) {

      var c = oldCh[i];

      if (isDef(c) && sameVnode(node, c)) { return i }

    }

  }



  function patchVnode (oldVnode, vnode, insertedVnodeQueue, removeOnly) {

    if (oldVnode === vnode) {

      return

    }



    var elm = vnode.elm = oldVnode.elm;



    if (isTrue(oldVnode.isAsyncPlaceholder)) {

      if (isDef(vnode.asyncFactory.resolved)) {

        hydrate(oldVnode.elm, vnode, insertedVnodeQueue);

      } else {

        vnode.isAsyncPlaceholder = true;

      }

      return

    }



    // reuse element for static trees.

    // note we only do this if the vnode is cloned -

    // if the new node is not cloned it means the render functions have been

    // reset by the hot-reload-api and we need to do a proper re-render.

    if (isTrue(vnode.isStatic) &&

      isTrue(oldVnode.isStatic) &&

      vnode.key === oldVnode.key &&

      (isTrue(vnode.isCloned) || isTrue(vnode.isOnce))

    ) {

      vnode.componentInstance = oldVnode.componentInstance;

      return

    }



    var i;

    var data = vnode.data;

    if (isDef(data) && isDef(i = data.hook) && isDef(i = i.prepatch)) {

      i(oldVnode, vnode);

    }



    var oldCh = oldVnode.children;

    var ch = vnode.children;

    if (isDef(data) && isPatchable(vnode)) {

      for (i = 0; i < cbs.update.length; ++i) { cbs.update[i](oldVnode, vnode); }

      if (isDef(i = data.hook) && isDef(i = i.update)) { i(oldVnode, vnode); }

    }

    if (isUndef(vnode.text)) {

      if (isDef(oldCh) && isDef(ch)) {

        if (oldCh !== ch) { updateChildren(elm, oldCh, ch, insertedVnodeQueue, removeOnly); }

      } else if (isDef(ch)) {

        if (isDef(oldVnode.text)) { nodeOps.setTextContent(elm, ''); }

        addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue);

      } else if (isDef(oldCh)) {

        removeVnodes(elm, oldCh, 0, oldCh.length - 1);

      } else if (isDef(oldVnode.text)) {

        nodeOps.setTextContent(elm, '');

      }

    } else if (oldVnode.text !== vnode.text) {

      nodeOps.setTextContent(elm, vnode.text);

    }

    if (isDef(data)) {

      if (isDef(i = data.hook) && isDef(i = i.postpatch)) { i(oldVnode, vnode); }

    }

  }



  function invokeInsertHook (vnode, queue, initial) {

    // delay insert hooks for component root nodes, invoke them after the

    // element is really inserted

    if (isTrue(initial) && isDef(vnode.parent)) {

      vnode.parent.data.pendingInsert = queue;

    } else {

      for (var i = 0; i < queue.length; ++i) {

        queue[i].data.hook.insert(queue[i]);

      }

    }

  }



  var hydrationBailed = false;

  // list of modules that can skip create hook during hydration because they

  // are already rendered on the client or has no need for initialization

  // Note: style is excluded because it relies on initial clone for future

  // deep updates (#7063).

  var isRenderedModule = makeMap('attrs,class,staticClass,staticStyle,key');



  // Note: this is a browser-only function so we can assume elms are DOM nodes.

  function hydrate (elm, vnode, insertedVnodeQueue, inVPre) {

    var i;

    var tag = vnode.tag;

    var data = vnode.data;

    var children = vnode.children;

    inVPre = inVPre || (data && data.pre);

    vnode.elm = elm;



    if (isTrue(vnode.isComment) && isDef(vnode.asyncFactory)) {

      vnode.isAsyncPlaceholder = true;

      return true

    }

    // assert node match

    if (true) {

      if (!assertNodeMatch(elm, vnode, inVPre)) {

        return false

      }

    }

    if (isDef(data)) {

      if (isDef(i = data.hook) && isDef(i = i.init)) { i(vnode, true /* hydrating */); }

      if (isDef(i = vnode.componentInstance)) {

        // child component. it should have hydrated its own tree.

        initComponent(vnode, insertedVnodeQueue);

        return true

      }

    }

    if (isDef(tag)) {

      if (isDef(children)) {

        // empty element, allow client to pick up and populate children

        if (!elm.hasChildNodes()) {

          createChildren(vnode, children, insertedVnodeQueue);

        } else {

          // v-html and domProps: innerHTML

          if (isDef(i = data) && isDef(i = i.domProps) && isDef(i = i.innerHTML)) {

            if (i !== elm.innerHTML) {

              /* istanbul ignore if */

              if ("development" !== 'production' &&

                typeof console !== 'undefined' &&

                !hydrationBailed

              ) {

                hydrationBailed = true;

                console.warn('Parent: ', elm);

                console.warn('server innerHTML: ', i);

                console.warn('client innerHTML: ', elm.innerHTML);

              }

              return false

            }

          } else {

            // iterate and compare children lists

            var childrenMatch = true;

            var childNode = elm.firstChild;

            for (var i$1 = 0; i$1 < children.length; i$1++) {

              if (!childNode || !hydrate(childNode, children[i$1], insertedVnodeQueue, inVPre)) {

                childrenMatch = false;

                break

              }

              childNode = childNode.nextSibling;

            }

            // if childNode is not null, it means the actual childNodes list is

            // longer than the virtual children list.

            if (!childrenMatch || childNode) {

              /* istanbul ignore if */

              if ("development" !== 'production' &&

                typeof console !== 'undefined' &&

                !hydrationBailed

              ) {

                hydrationBailed = true;

                console.warn('Parent: ', elm);

                console.warn('Mismatching childNodes vs. VNodes: ', elm.childNodes, children);

              }

              return false

            }

          }

        }

      }

      if (isDef(data)) {

        var fullInvoke = false;

        for (var key in data) {

          if (!isRenderedModule(key)) {

            fullInvoke = true;

            invokeCreateHooks(vnode, insertedVnodeQueue);

            break

          }

        }

        if (!fullInvoke && data['class']) {

          // ensure collecting deps for deep class bindings for future updates

          traverse(data['class']);

        }

      }

    } else if (elm.data !== vnode.text) {

      elm.data = vnode.text;

    }

    return true

  }



  function assertNodeMatch (node, vnode, inVPre) {

    if (isDef(vnode.tag)) {

      return vnode.tag.indexOf('vue-component') === 0 || (

        !isUnknownElement$$1(vnode, inVPre) &&

        vnode.tag.toLowerCase() === (node.tagName && node.tagName.toLowerCase())

      )

    } else {

      return node.nodeType === (vnode.isComment ? 8 : 3)

    }

  }



  return function patch (oldVnode, vnode, hydrating, removeOnly, parentElm, refElm) {

    if (isUndef(vnode)) {

      if (isDef(oldVnode)) { invokeDestroyHook(oldVnode); }

      return

    }



    var isInitialPatch = false;

    var insertedVnodeQueue = [];



    if (isUndef(oldVnode)) {

      // empty mount (likely as component), create new root element

      isInitialPatch = true;

      createElm(vnode, insertedVnodeQueue, parentElm, refElm);

    } else {

      var isRealElement = isDef(oldVnode.nodeType);

      if (!isRealElement && sameVnode(oldVnode, vnode)) {

        // patch existing root node

        patchVnode(oldVnode, vnode, insertedVnodeQueue, removeOnly);

      } else {

        if (isRealElement) {

          // mounting to a real element

          // check if this is server-rendered content and if we can perform

          // a successful hydration.

          if (oldVnode.nodeType === 1 && oldVnode.hasAttribute(SSR_ATTR)) {

            oldVnode.removeAttribute(SSR_ATTR);

            hydrating = true;

          }

          if (isTrue(hydrating)) {

            if (hydrate(oldVnode, vnode, insertedVnodeQueue)) {

              invokeInsertHook(vnode, insertedVnodeQueue, true);

              return oldVnode

            } else if (true) {

              warn(

                'The client-side rendered virtual DOM tree is not matching ' +

                'server-rendered content. This is likely caused by incorrect ' +

                'HTML markup, for example nesting block-level elements inside ' +

                '<p>, or missing <tbody>. Bailing hydration and performing ' +

                'full client-side render.'

              );

            }

          }

          // either not server-rendered, or hydration failed.

          // create an empty node and replace it

          oldVnode = emptyNodeAt(oldVnode);

        }



        // replacing existing element

        var oldElm = oldVnode.elm;

        var parentElm$1 = nodeOps.parentNode(oldElm);



        // create new node

        createElm(

          vnode,

          insertedVnodeQueue,

          // extremely rare edge case: do not insert if old element is in a

          // leaving transition. Only happens when combining transition +

          // keep-alive + HOCs. (#4590)

          oldElm._leaveCb ? null : parentElm$1,

          nodeOps.nextSibling(oldElm)

        );



        // update parent placeholder node element, recursively

        if (isDef(vnode.parent)) {

          var ancestor = vnode.parent;

          var patchable = isPatchable(vnode);

          while (ancestor) {

            for (var i = 0; i < cbs.destroy.length; ++i) {

              cbs.destroy[i](ancestor);

            }

            ancestor.elm = vnode.elm;

            if (patchable) {

              for (var i$1 = 0; i$1 < cbs.create.length; ++i$1) {

                cbs.create[i$1](emptyNode, ancestor);

              }

              // #6513

              // invoke insert hooks that may have been merged by create hooks.

              // e.g. for directives that uses the "inserted" hook.

              var insert = ancestor.data.hook.insert;

              if (insert.merged) {

                // start at index 1 to avoid re-invoking component mounted hook

                for (var i$2 = 1; i$2 < insert.fns.length; i$2++) {

                  insert.fns[i$2]();

                }

              }

            } else {

              registerRef(ancestor);

            }

            ancestor = ancestor.parent;

          }

        }



        // destroy old node

        if (isDef(parentElm$1)) {

          removeVnodes(parentElm$1, [oldVnode], 0, 0);

        } else if (isDef(oldVnode.tag)) {

          invokeDestroyHook(oldVnode);

        }

      }

    }



    invokeInsertHook(vnode, insertedVnodeQueue, isInitialPatch);

    return vnode.elm

  }

}



/*  */



var directives = {

  create: updateDirectives,

  update: updateDirectives,

  destroy: function unbindDirectives (vnode) {

    updateDirectives(vnode, emptyNode);

  }

};



function updateDirectives (oldVnode, vnode) {

  if (oldVnode.data.directives || vnode.data.directives) {

    _update(oldVnode, vnode);

  }

}



function _update (oldVnode, vnode) {

  var isCreate = oldVnode === emptyNode;

  var isDestroy = vnode === emptyNode;

  var oldDirs = normalizeDirectives$1(oldVnode.data.directives, oldVnode.context);

  var newDirs = normalizeDirectives$1(vnode.data.directives, vnode.context);



  var dirsWithInsert = [];

  var dirsWithPostpatch = [];



  var key, oldDir, dir;

  for (key in newDirs) {

    oldDir = oldDirs[key];

    dir = newDirs[key];

    if (!oldDir) {

      // new directive, bind

      callHook$1(dir, 'bind', vnode, oldVnode);

      if (dir.def && dir.def.inserted) {

        dirsWithInsert.push(dir);

      }

    } else {

      // existing directive, update

      dir.oldValue = oldDir.value;

      callHook$1(dir, 'update', vnode, oldVnode);

      if (dir.def && dir.def.componentUpdated) {

        dirsWithPostpatch.push(dir);

      }

    }

  }



  if (dirsWithInsert.length) {

    var callInsert = function () {

      for (var i = 0; i < dirsWithInsert.length; i++) {

        callHook$1(dirsWithInsert[i], 'inserted', vnode, oldVnode);

      }

    };

    if (isCreate) {

      mergeVNodeHook(vnode, 'insert', callInsert);

    } else {

      callInsert();

    }

  }



  if (dirsWithPostpatch.length) {

    mergeVNodeHook(vnode, 'postpatch', function () {

      for (var i = 0; i < dirsWithPostpatch.length; i++) {

        callHook$1(dirsWithPostpatch[i], 'componentUpdated', vnode, oldVnode);

      }

    });

  }



  if (!isCreate) {

    for (key in oldDirs) {

      if (!newDirs[key]) {

        // no longer present, unbind

        callHook$1(oldDirs[key], 'unbind', oldVnode, oldVnode, isDestroy);

      }

    }

  }

}



var emptyModifiers = Object.create(null);



function normalizeDirectives$1 (

  dirs,

  vm

) {

  var res = Object.create(null);

  if (!dirs) {

    // $flow-disable-line

    return res

  }

  var i, dir;

  for (i = 0; i < dirs.length; i++) {

    dir = dirs[i];

    if (!dir.modifiers) {

      // $flow-disable-line

      dir.modifiers = emptyModifiers;

    }

    res[getRawDirName(dir)] = dir;

    dir.def = resolveAsset(vm.$options, 'directives', dir.name, true);

  }

  // $flow-disable-line

  return res

}



function getRawDirName (dir) {

  return dir.rawName || ((dir.name) + "." + (Object.keys(dir.modifiers || {}).join('.')))

}



function callHook$1 (dir, hook, vnode, oldVnode, isDestroy) {

  var fn = dir.def && dir.def[hook];

  if (fn) {

    try {

      fn(vnode.elm, dir, vnode, oldVnode, isDestroy);

    } catch (e) {

      handleError(e, vnode.context, ("directive " + (dir.name) + " " + hook + " hook"));

    }

  }

}



var baseModules = [

  ref,

  directives

];



/*  */



function updateAttrs (oldVnode, vnode) {

  var opts = vnode.componentOptions;

  if (isDef(opts) && opts.Ctor.options.inheritAttrs === false) {

    return

  }

  if (isUndef(oldVnode.data.attrs) && isUndef(vnode.data.attrs)) {

    return

  }

  var key, cur, old;

  var elm = vnode.elm;

  var oldAttrs = oldVnode.data.attrs || {};

  var attrs = vnode.data.attrs || {};

  // clone observed objects, as the user probably wants to mutate it

  if (isDef(attrs.__ob__)) {

    attrs = vnode.data.attrs = extend({}, attrs);

  }



  for (key in attrs) {

    cur = attrs[key];

    old = oldAttrs[key];

    if (old !== cur) {

      setAttr(elm, key, cur);

    }

  }

  // #4391: in IE9, setting type can reset value for input[type=radio]

  // #6666: IE/Edge forces progress value down to 1 before setting a max

  /* istanbul ignore if */

  if ((isIE || isEdge) && attrs.value !== oldAttrs.value) {

    setAttr(elm, 'value', attrs.value);

  }

  for (key in oldAttrs) {

    if (isUndef(attrs[key])) {

      if (isXlink(key)) {

        elm.removeAttributeNS(xlinkNS, getXlinkProp(key));

      } else if (!isEnumeratedAttr(key)) {

        elm.removeAttribute(key);

      }

    }

  }

}



function setAttr (el, key, value) {

  if (isBooleanAttr(key)) {

    // set attribute for blank value

    // e.g. <option disabled>Select one</option>

    if (isFalsyAttrValue(value)) {

      el.removeAttribute(key);

    } else {

      // technically allowfullscreen is a boolean attribute for <iframe>,

      // but Flash expects a value of "true" when used on <embed> tag

      value = key === 'allowfullscreen' && el.tagName === 'EMBED'

        ? 'true'

        : key;

      el.setAttribute(key, value);

    }

  } else if (isEnumeratedAttr(key)) {

    el.setAttribute(key, isFalsyAttrValue(value) || value === 'false' ? 'false' : 'true');

  } else if (isXlink(key)) {

    if (isFalsyAttrValue(value)) {

      el.removeAttributeNS(xlinkNS, getXlinkProp(key));

    } else {

      el.setAttributeNS(xlinkNS, key, value);

    }

  } else {

    if (isFalsyAttrValue(value)) {

      el.removeAttribute(key);

    } else {

      // #7138: IE10 & 11 fires input event when setting placeholder on

      // <textarea>... block the first input event and remove the blocker

      // immediately.

      /* istanbul ignore if */

      if (

        isIE && !isIE9 &&

        el.tagName === 'TEXTAREA' &&

        key === 'placeholder' && !el.__ieph

      ) {

        var blocker = function (e) {

          e.stopImmediatePropagation();

          el.removeEventListener('input', blocker);

        };

        el.addEventListener('input', blocker);

        // $flow-disable-line

        el.__ieph = true; /* IE placeholder patched */

      }

      el.setAttribute(key, value);

    }

  }

}



var attrs = {

  create: updateAttrs,

  update: updateAttrs

};



/*  */



function updateClass (oldVnode, vnode) {

  var el = vnode.elm;

  var data = vnode.data;

  var oldData = oldVnode.data;

  if (

    isUndef(data.staticClass) &&

    isUndef(data.class) && (

      isUndef(oldData) || (

        isUndef(oldData.staticClass) &&

        isUndef(oldData.class)

      )

    )

  ) {

    return

  }



  var cls = genClassForVnode(vnode);



  // handle transition classes

  var transitionClass = el._transitionClasses;

  if (isDef(transitionClass)) {

    cls = concat(cls, stringifyClass(transitionClass));

  }



  // set the class

  if (cls !== el._prevClass) {

    el.setAttribute('class', cls);

    el._prevClass = cls;

  }

}



var klass = {

  create: updateClass,

  update: updateClass

};



/*  */



var validDivisionCharRE = /[\w).+\-_$\]]/;



function parseFilters (exp) {

  var inSingle = false;

  var inDouble = false;

  var inTemplateString = false;

  var inRegex = false;

  var curly = 0;

  var square = 0;

  var paren = 0;

  var lastFilterIndex = 0;

  var c, prev, i, expression, filters;



  for (i = 0; i < exp.length; i++) {

    prev = c;

    c = exp.charCodeAt(i);

    if (inSingle) {

      if (c === 0x27 && prev !== 0x5C) { inSingle = false; }

    } else if (inDouble) {

      if (c === 0x22 && prev !== 0x5C) { inDouble = false; }

    } else if (inTemplateString) {

      if (c === 0x60 && prev !== 0x5C) { inTemplateString = false; }

    } else if (inRegex) {

      if (c === 0x2f && prev !== 0x5C) { inRegex = false; }

    } else if (

      c === 0x7C && // pipe

      exp.charCodeAt(i + 1) !== 0x7C &&

      exp.charCodeAt(i - 1) !== 0x7C &&

      !curly && !square && !paren

    ) {

      if (expression === undefined) {

        // first filter, end of expression

        lastFilterIndex = i + 1;

        expression = exp.slice(0, i).trim();

      } else {

        pushFilter();

      }

    } else {

      switch (c) {

        case 0x22: inDouble = true; break         // "

        case 0x27: inSingle = true; break         // '

        case 0x60: inTemplateString = true; break // `

        case 0x28: paren++; break                 // (

        case 0x29: paren--; break                 // )

        case 0x5B: square++; break                // [

        case 0x5D: square--; break                // ]

        case 0x7B: curly++; break                 // {

        case 0x7D: curly--; break                 // }

      }

      if (c === 0x2f) { // /

        var j = i - 1;

        var p = (void 0);

        // find first non-whitespace prev char

        for (; j >= 0; j--) {

          p = exp.charAt(j);

          if (p !== ' ') { break }

        }

        if (!p || !validDivisionCharRE.test(p)) {

          inRegex = true;

        }

      }

    }

  }



  if (expression === undefined) {

    expression = exp.slice(0, i).trim();

  } else if (lastFilterIndex !== 0) {

    pushFilter();

  }



  function pushFilter () {

    (filters || (filters = [])).push(exp.slice(lastFilterIndex, i).trim());

    lastFilterIndex = i + 1;

  }



  if (filters) {

    for (i = 0; i < filters.length; i++) {

      expression = wrapFilter(expression, filters[i]);

    }

  }



  return expression

}



function wrapFilter (exp, filter) {

  var i = filter.indexOf('(');

  if (i < 0) {

    // _f: resolveFilter

    return ("_f(\"" + filter + "\")(" + exp + ")")

  } else {

    var name = filter.slice(0, i);

    var args = filter.slice(i + 1);

    return ("_f(\"" + name + "\")(" + exp + "," + args)

  }

}



/*  */



function baseWarn (msg) {

  console.error(("[Vue compiler]: " + msg));

}



function pluckModuleFunction (

  modules,

  key

) {

  return modules

    ? modules.map(function (m) { return m[key]; }).filter(function (_) { return _; })

    : []

}



function addProp (el, name, value) {

  (el.props || (el.props = [])).push({ name: name, value: value });

  el.plain = false;

}



function addAttr (el, name, value) {

  (el.attrs || (el.attrs = [])).push({ name: name, value: value });

  el.plain = false;

}



// add a raw attr (use this in preTransforms)

function addRawAttr (el, name, value) {

  el.attrsMap[name] = value;

  el.attrsList.push({ name: name, value: value });

}



function addDirective (

  el,

  name,

  rawName,

  value,

  arg,

  modifiers

) {

  (el.directives || (el.directives = [])).push({ name: name, rawName: rawName, value: value, arg: arg, modifiers: modifiers });

  el.plain = false;

}



function addHandler (

  el,

  name,

  value,

  modifiers,

  important,

  warn

) {

  modifiers = modifiers || emptyObject;

  // warn prevent and passive modifier

  /* istanbul ignore if */

  if (

    "development" !== 'production' && warn &&

    modifiers.prevent && modifiers.passive

  ) {

    warn(

      'passive and prevent can\'t be used together. ' +

      'Passive handler can\'t prevent default event.'

    );

  }



  // check capture modifier

  if (modifiers.capture) {

    delete modifiers.capture;

    name = '!' + name; // mark the event as captured

  }

  if (modifiers.once) {

    delete modifiers.once;

    name = '~' + name; // mark the event as once

  }

  /* istanbul ignore if */

  if (modifiers.passive) {

    delete modifiers.passive;

    name = '&' + name; // mark the event as passive

  }



  // normalize click.right and click.middle since they don't actually fire

  // this is technically browser-specific, but at least for now browsers are

  // the only target envs that have right/middle clicks.

  if (name === 'click') {

    if (modifiers.right) {

      name = 'contextmenu';

      delete modifiers.right;

    } else if (modifiers.middle) {

      name = 'mouseup';

    }

  }



  var events;

  if (modifiers.native) {

    delete modifiers.native;

    events = el.nativeEvents || (el.nativeEvents = {});

  } else {

    events = el.events || (el.events = {});

  }



  var newHandler = { value: value };

  if (modifiers !== emptyObject) {

    newHandler.modifiers = modifiers;

  }



  var handlers = events[name];

  /* istanbul ignore if */

  if (Array.isArray(handlers)) {

    important ? handlers.unshift(newHandler) : handlers.push(newHandler);

  } else if (handlers) {

    events[name] = important ? [newHandler, handlers] : [handlers, newHandler];

  } else {

    events[name] = newHandler;

  }



  el.plain = false;

}



function getBindingAttr (

  el,

  name,

  getStatic

) {

  var dynamicValue =

    getAndRemoveAttr(el, ':' + name) ||

    getAndRemoveAttr(el, 'v-bind:' + name);

  if (dynamicValue != null) {

    return parseFilters(dynamicValue)

  } else if (getStatic !== false) {

    var staticValue = getAndRemoveAttr(el, name);

    if (staticValue != null) {

      return JSON.stringify(staticValue)

    }

  }

}



// note: this only removes the attr from the Array (attrsList) so that it

// doesn't get processed by processAttrs.

// By default it does NOT remove it from the map (attrsMap) because the map is

// needed during codegen.

function getAndRemoveAttr (

  el,

  name,

  removeFromMap

) {

  var val;

  if ((val = el.attrsMap[name]) != null) {

    var list = el.attrsList;

    for (var i = 0, l = list.length; i < l; i++) {

      if (list[i].name === name) {

        list.splice(i, 1);

        break

      }

    }

  }

  if (removeFromMap) {

    delete el.attrsMap[name];

  }

  return val

}



/*  */



/**

 * Cross-platform code generation for component v-model

 */

function genComponentModel (

  el,

  value,

  modifiers

) {

  var ref = modifiers || {};

  var number = ref.number;

  var trim = ref.trim;



  var baseValueExpression = '$$v';

  var valueExpression = baseValueExpression;

  if (trim) {

    valueExpression =

      "(typeof " + baseValueExpression + " === 'string'" +

        "? " + baseValueExpression + ".trim()" +

        ": " + baseValueExpression + ")";

  }

  if (number) {

    valueExpression = "_n(" + valueExpression + ")";

  }

  var assignment = genAssignmentCode(value, valueExpression);



  el.model = {

    value: ("(" + value + ")"),

    expression: ("\"" + value + "\""),

    callback: ("function (" + baseValueExpression + ") {" + assignment + "}")

  };

}



/**

 * Cross-platform codegen helper for generating v-model value assignment code.

 */

function genAssignmentCode (

  value,

  assignment

) {

  var res = parseModel(value);

  if (res.key === null) {

    return (value + "=" + assignment)

  } else {

    return ("$set(" + (res.exp) + ", " + (res.key) + ", " + assignment + ")")

  }

}



/**

 * Parse a v-model expression into a base path and a final key segment.

 * Handles both dot-path and possible square brackets.

 *

 * Possible cases:

 *

 * - test

 * - test[key]

 * - test[test1[key]]

 * - test["a"][key]

 * - xxx.test[a[a].test1[key]]

 * - test.xxx.a["asa"][test1[key]]

 *

 */



var len;

var str;

var chr;

var index$1;

var expressionPos;

var expressionEndPos;







function parseModel (val) {

  len = val.length;



  if (val.indexOf('[') < 0 || val.lastIndexOf(']') < len - 1) {

    index$1 = val.lastIndexOf('.');

    if (index$1 > -1) {

      return {

        exp: val.slice(0, index$1),

        key: '"' + val.slice(index$1 + 1) + '"'

      }

    } else {

      return {

        exp: val,

        key: null

      }

    }

  }



  str = val;

  index$1 = expressionPos = expressionEndPos = 0;



  while (!eof()) {

    chr = next();

    /* istanbul ignore if */

    if (isStringStart(chr)) {

      parseString(chr);

    } else if (chr === 0x5B) {

      parseBracket(chr);

    }

  }



  return {

    exp: val.slice(0, expressionPos),

    key: val.slice(expressionPos + 1, expressionEndPos)

  }

}



function next () {

  return str.charCodeAt(++index$1)

}



function eof () {

  return index$1 >= len

}



function isStringStart (chr) {

  return chr === 0x22 || chr === 0x27

}



function parseBracket (chr) {

  var inBracket = 1;

  expressionPos = index$1;

  while (!eof()) {

    chr = next();

    if (isStringStart(chr)) {

      parseString(chr);

      continue

    }

    if (chr === 0x5B) { inBracket++; }

    if (chr === 0x5D) { inBracket--; }

    if (inBracket === 0) {

      expressionEndPos = index$1;

      break

    }

  }

}



function parseString (chr) {

  var stringQuote = chr;

  while (!eof()) {

    chr = next();

    if (chr === stringQuote) {

      break

    }

  }

}



/*  */



var warn$1;



// in some cases, the event used has to be determined at runtime

// so we used some reserved tokens during compile.

var RANGE_TOKEN = '__r';

var CHECKBOX_RADIO_TOKEN = '__c';



function model (

  el,

  dir,

  _warn

) {

  warn$1 = _warn;

  var value = dir.value;

  var modifiers = dir.modifiers;

  var tag = el.tag;

  var type = el.attrsMap.type;



  if (true) {

    // inputs with type="file" are read only and setting the input's

    // value will throw an error.

    if (tag === 'input' && type === 'file') {

      warn$1(

        "<" + (el.tag) + " v-model=\"" + value + "\" type=\"file\">:\n" +

        "File inputs are read only. Use a v-on:change listener instead."

      );

    }

  }



  if (el.component) {

    genComponentModel(el, value, modifiers);

    // component v-model doesn't need extra runtime

    return false

  } else if (tag === 'select') {

    genSelect(el, value, modifiers);

  } else if (tag === 'input' && type === 'checkbox') {

    genCheckboxModel(el, value, modifiers);

  } else if (tag === 'input' && type === 'radio') {

    genRadioModel(el, value, modifiers);

  } else if (tag === 'input' || tag === 'textarea') {

    genDefaultModel(el, value, modifiers);

  } else if (!config.isReservedTag(tag)) {

    genComponentModel(el, value, modifiers);

    // component v-model doesn't need extra runtime

    return false

  } else if (true) {

    warn$1(

      "<" + (el.tag) + " v-model=\"" + value + "\">: " +

      "v-model is not supported on this element type. " +

      'If you are working with contenteditable, it\'s recommended to ' +

      'wrap a library dedicated for that purpose inside a custom component.'

    );

  }



  // ensure runtime directive metadata

  return true

}



function genCheckboxModel (

  el,

  value,

  modifiers

) {

  var number = modifiers && modifiers.number;

  var valueBinding = getBindingAttr(el, 'value') || 'null';

  var trueValueBinding = getBindingAttr(el, 'true-value') || 'true';

  var falseValueBinding = getBindingAttr(el, 'false-value') || 'false';

  addProp(el, 'checked',

    "Array.isArray(" + value + ")" +

    "?_i(" + value + "," + valueBinding + ")>-1" + (

      trueValueBinding === 'true'

        ? (":(" + value + ")")

        : (":_q(" + value + "," + trueValueBinding + ")")

    )

  );

  addHandler(el, 'change',

    "var $$a=" + value + "," +

        '$$el=$event.target,' +

        "$$c=$$el.checked?(" + trueValueBinding + "):(" + falseValueBinding + ");" +

    'if(Array.isArray($$a)){' +

      "var $$v=" + (number ? '_n(' + valueBinding + ')' : valueBinding) + "," +

          '$$i=_i($$a,$$v);' +

      "if($$el.checked){$$i<0&&(" + value + "=$$a.concat([$$v]))}" +

      "else{$$i>-1&&(" + value + "=$$a.slice(0,$$i).concat($$a.slice($$i+1)))}" +

    "}else{" + (genAssignmentCode(value, '$$c')) + "}",

    null, true

  );

}



function genRadioModel (

  el,

  value,

  modifiers

) {

  var number = modifiers && modifiers.number;

  var valueBinding = getBindingAttr(el, 'value') || 'null';

  valueBinding = number ? ("_n(" + valueBinding + ")") : valueBinding;

  addProp(el, 'checked', ("_q(" + value + "," + valueBinding + ")"));

  addHandler(el, 'change', genAssignmentCode(value, valueBinding), null, true);

}



function genSelect (

  el,

  value,

  modifiers

) {

  var number = modifiers && modifiers.number;

  var selectedVal = "Array.prototype.filter" +

    ".call($event.target.options,function(o){return o.selected})" +

    ".map(function(o){var val = \"_value\" in o ? o._value : o.value;" +

    "return " + (number ? '_n(val)' : 'val') + "})";



  var assignment = '$event.target.multiple ? $$selectedVal : $$selectedVal[0]';

  var code = "var $$selectedVal = " + selectedVal + ";";

  code = code + " " + (genAssignmentCode(value, assignment));

  addHandler(el, 'change', code, null, true);

}



function genDefaultModel (

  el,

  value,

  modifiers

) {

  var type = el.attrsMap.type;



  // warn if v-bind:value conflicts with v-model

  if (true) {

    var value$1 = el.attrsMap['v-bind:value'] || el.attrsMap[':value'];

    if (value$1) {

      var binding = el.attrsMap['v-bind:value'] ? 'v-bind:value' : ':value';

      warn$1(

        binding + "=\"" + value$1 + "\" conflicts with v-model on the same element " +

        'because the latter already expands to a value binding internally'

      );

    }

  }



  var ref = modifiers || {};

  var lazy = ref.lazy;

  var number = ref.number;

  var trim = ref.trim;

  var needCompositionGuard = !lazy && type !== 'range';

  var event = lazy

    ? 'change'

    : type === 'range'

      ? RANGE_TOKEN

      : 'input';



  var valueExpression = '$event.target.value';

  if (trim) {

    valueExpression = "$event.target.value.trim()";

  }

  if (number) {

    valueExpression = "_n(" + valueExpression + ")";

  }



  var code = genAssignmentCode(value, valueExpression);

  if (needCompositionGuard) {

    code = "if($event.target.composing)return;" + code;

  }



  addProp(el, 'value', ("(" + value + ")"));

  addHandler(el, event, code, null, true);

  if (trim || number) {

    addHandler(el, 'blur', '$forceUpdate()');

  }

}



/*  */



// normalize v-model event tokens that can only be determined at runtime.

// it's important to place the event as the first in the array because

// the whole point is ensuring the v-model callback gets called before

// user-attached handlers.

function normalizeEvents (on) {

  /* istanbul ignore if */

  if (isDef(on[RANGE_TOKEN])) {

    // IE input[type=range] only supports `change` event

    var event = isIE ? 'change' : 'input';

    on[event] = [].concat(on[RANGE_TOKEN], on[event] || []);

    delete on[RANGE_TOKEN];

  }

  // This was originally intended to fix #4521 but no longer necessary

  // after 2.5. Keeping it for backwards compat with generated code from < 2.4

  /* istanbul ignore if */

  if (isDef(on[CHECKBOX_RADIO_TOKEN])) {

    on.change = [].concat(on[CHECKBOX_RADIO_TOKEN], on.change || []);

    delete on[CHECKBOX_RADIO_TOKEN];

  }

}



var target$1;



function createOnceHandler (handler, event, capture) {

  var _target = target$1; // save current target element in closure

  return function onceHandler () {

    var res = handler.apply(null, arguments);

    if (res !== null) {

      remove$2(event, onceHandler, capture, _target);

    }

  }

}



function add$1 (

  event,

  handler,

  once$$1,

  capture,

  passive

) {

  handler = withMacroTask(handler);

  if (once$$1) { handler = createOnceHandler(handler, event, capture); }

  target$1.addEventListener(

    event,

    handler,

    supportsPassive

      ? { capture: capture, passive: passive }

      : capture

  );

}



function remove$2 (

  event,

  handler,

  capture,

  _target

) {

  (_target || target$1).removeEventListener(

    event,

    handler._withTask || handler,

    capture

  );

}



function updateDOMListeners (oldVnode, vnode) {

  if (isUndef(oldVnode.data.on) && isUndef(vnode.data.on)) {

    return

  }

  var on = vnode.data.on || {};

  var oldOn = oldVnode.data.on || {};

  target$1 = vnode.elm;

  normalizeEvents(on);

  updateListeners(on, oldOn, add$1, remove$2, vnode.context);

  target$1 = undefined;

}



var events = {

  create: updateDOMListeners,

  update: updateDOMListeners

};



/*  */



function updateDOMProps (oldVnode, vnode) {

  if (isUndef(oldVnode.data.domProps) && isUndef(vnode.data.domProps)) {

    return

  }

  var key, cur;

  var elm = vnode.elm;

  var oldProps = oldVnode.data.domProps || {};

  var props = vnode.data.domProps || {};

  // clone observed objects, as the user probably wants to mutate it

  if (isDef(props.__ob__)) {

    props = vnode.data.domProps = extend({}, props);

  }



  for (key in oldProps) {

    if (isUndef(props[key])) {

      elm[key] = '';

    }

  }

  for (key in props) {

    cur = props[key];

    // ignore children if the node has textContent or innerHTML,

    // as these will throw away existing DOM nodes and cause removal errors

    // on subsequent patches (#3360)

    if (key === 'textContent' || key === 'innerHTML') {

      if (vnode.children) { vnode.children.length = 0; }

      if (cur === oldProps[key]) { continue }

      // #6601 work around Chrome version <= 55 bug where single textNode

      // replaced by innerHTML/textContent retains its parentNode property

      if (elm.childNodes.length === 1) {

        elm.removeChild(elm.childNodes[0]);

      }

    }



    if (key === 'value') {

      // store value as _value as well since

      // non-string values will be stringified

      elm._value = cur;

      // avoid resetting cursor position when value is the same

      var strCur = isUndef(cur) ? '' : String(cur);

      if (shouldUpdateValue(elm, strCur)) {

        elm.value = strCur;

      }

    } else {

      elm[key] = cur;

    }

  }

}



// check platforms/web/util/attrs.js acceptValue





function shouldUpdateValue (elm, checkVal) {

  return (!elm.composing && (

    elm.tagName === 'OPTION' ||

    isNotInFocusAndDirty(elm, checkVal) ||

    isDirtyWithModifiers(elm, checkVal)

  ))

}



function isNotInFocusAndDirty (elm, checkVal) {

  // return true when textbox (.number and .trim) loses focus and its value is

  // not equal to the updated value

  var notInFocus = true;

  // #6157

  // work around IE bug when accessing document.activeElement in an iframe

  try { notInFocus = document.activeElement !== elm; } catch (e) {}

  return notInFocus && elm.value !== checkVal

}



function isDirtyWithModifiers (elm, newVal) {

  var value = elm.value;

  var modifiers = elm._vModifiers; // injected by v-model runtime

  if (isDef(modifiers)) {

    if (modifiers.lazy) {

      // inputs with lazy should only be updated when not in focus

      return false

    }

    if (modifiers.number) {

      return toNumber(value) !== toNumber(newVal)

    }

    if (modifiers.trim) {

      return value.trim() !== newVal.trim()

    }

  }

  return value !== newVal

}



var domProps = {

  create: updateDOMProps,

  update: updateDOMProps

};



/*  */



var parseStyleText = cached(function (cssText) {

  var res = {};

  var listDelimiter = /;(?![^(]*\))/g;

  var propertyDelimiter = /:(.+)/;

  cssText.split(listDelimiter).forEach(function (item) {

    if (item) {

      var tmp = item.split(propertyDelimiter);

      tmp.length > 1 && (res[tmp[0].trim()] = tmp[1].trim());

    }

  });

  return res

});



// merge static and dynamic style data on the same vnode

function normalizeStyleData (data) {

  var style = normalizeStyleBinding(data.style);

  // static style is pre-processed into an object during compilation

  // and is always a fresh object, so it's safe to merge into it

  return data.staticStyle

    ? extend(data.staticStyle, style)

    : style

}



// normalize possible array / string values into Object

function normalizeStyleBinding (bindingStyle) {

  if (Array.isArray(bindingStyle)) {

    return toObject(bindingStyle)

  }

  if (typeof bindingStyle === 'string') {

    return parseStyleText(bindingStyle)

  }

  return bindingStyle

}



/**

 * parent component style should be after child's

 * so that parent component's style could override it

 */

function getStyle (vnode, checkChild) {

  var res = {};

  var styleData;



  if (checkChild) {

    var childNode = vnode;

    while (childNode.componentInstance) {

      childNode = childNode.componentInstance._vnode;

      if (

        childNode && childNode.data &&

        (styleData = normalizeStyleData(childNode.data))

      ) {

        extend(res, styleData);

      }

    }

  }



  if ((styleData = normalizeStyleData(vnode.data))) {

    extend(res, styleData);

  }



  var parentNode = vnode;

  while ((parentNode = parentNode.parent)) {

    if (parentNode.data && (styleData = normalizeStyleData(parentNode.data))) {

      extend(res, styleData);

    }

  }

  return res

}



/*  */



var cssVarRE = /^--/;

var importantRE = /\s*!important$/;

var setProp = function (el, name, val) {

  /* istanbul ignore if */

  if (cssVarRE.test(name)) {

    el.style.setProperty(name, val);

  } else if (importantRE.test(val)) {

    el.style.setProperty(name, val.replace(importantRE, ''), 'important');

  } else {

    var normalizedName = normalize(name);

    if (Array.isArray(val)) {

      // Support values array created by autoprefixer, e.g.

      // {display: ["-webkit-box", "-ms-flexbox", "flex"]}

      // Set them one by one, and the browser will only set those it can recognize

      for (var i = 0, len = val.length; i < len; i++) {

        el.style[normalizedName] = val[i];

      }

    } else {

      el.style[normalizedName] = val;

    }

  }

};



var vendorNames = ['Webkit', 'Moz', 'ms'];



var emptyStyle;

var normalize = cached(function (prop) {

  emptyStyle = emptyStyle || document.createElement('div').style;

  prop = camelize(prop);

  if (prop !== 'filter' && (prop in emptyStyle)) {

    return prop

  }

  var capName = prop.charAt(0).toUpperCase() + prop.slice(1);

  for (var i = 0; i < vendorNames.length; i++) {

    var name = vendorNames[i] + capName;

    if (name in emptyStyle) {

      return name

    }

  }

});



function updateStyle (oldVnode, vnode) {

  var data = vnode.data;

  var oldData = oldVnode.data;



  if (isUndef(data.staticStyle) && isUndef(data.style) &&

    isUndef(oldData.staticStyle) && isUndef(oldData.style)

  ) {

    return

  }



  var cur, name;

  var el = vnode.elm;

  var oldStaticStyle = oldData.staticStyle;

  var oldStyleBinding = oldData.normalizedStyle || oldData.style || {};



  // if static style exists, stylebinding already merged into it when doing normalizeStyleData

  var oldStyle = oldStaticStyle || oldStyleBinding;



  var style = normalizeStyleBinding(vnode.data.style) || {};



  // store normalized style under a different key for next diff

  // make sure to clone it if it's reactive, since the user likely wants

  // to mutate it.

  vnode.data.normalizedStyle = isDef(style.__ob__)

    ? extend({}, style)

    : style;



  var newStyle = getStyle(vnode, true);



  for (name in oldStyle) {

    if (isUndef(newStyle[name])) {

      setProp(el, name, '');

    }

  }

  for (name in newStyle) {

    cur = newStyle[name];

    if (cur !== oldStyle[name]) {

      // ie9 setting to null has no effect, must use empty string

      setProp(el, name, cur == null ? '' : cur);

    }

  }

}



var style = {

  create: updateStyle,

  update: updateStyle

};



/*  */



/**

 * Add class with compatibility for SVG since classList is not supported on

 * SVG elements in IE

 */

function addClass (el, cls) {

  /* istanbul ignore if */

  if (!cls || !(cls = cls.trim())) {

    return

  }



  /* istanbul ignore else */

  if (el.classList) {

    if (cls.indexOf(' ') > -1) {

      cls.split(/\s+/).forEach(function (c) { return el.classList.add(c); });

    } else {

      el.classList.add(cls);

    }

  } else {

    var cur = " " + (el.getAttribute('class') || '') + " ";

    if (cur.indexOf(' ' + cls + ' ') < 0) {

      el.setAttribute('class', (cur + cls).trim());

    }

  }

}



/**

 * Remove class with compatibility for SVG since classList is not supported on

 * SVG elements in IE

 */

function removeClass (el, cls) {

  /* istanbul ignore if */

  if (!cls || !(cls = cls.trim())) {

    return

  }



  /* istanbul ignore else */

  if (el.classList) {

    if (cls.indexOf(' ') > -1) {

      cls.split(/\s+/).forEach(function (c) { return el.classList.remove(c); });

    } else {

      el.classList.remove(cls);

    }

    if (!el.classList.length) {

      el.removeAttribute('class');

    }

  } else {

    var cur = " " + (el.getAttribute('class') || '') + " ";

    var tar = ' ' + cls + ' ';

    while (cur.indexOf(tar) >= 0) {

      cur = cur.replace(tar, ' ');

    }

    cur = cur.trim();

    if (cur) {

      el.setAttribute('class', cur);

    } else {

      el.removeAttribute('class');

    }

  }

}



/*  */



function resolveTransition (def) {

  if (!def) {

    return

  }

  /* istanbul ignore else */

  if (typeof def === 'object') {

    var res = {};

    if (def.css !== false) {

      extend(res, autoCssTransition(def.name || 'v'));

    }

    extend(res, def);

    return res

  } else if (typeof def === 'string') {

    return autoCssTransition(def)

  }

}



var autoCssTransition = cached(function (name) {

  return {

    enterClass: (name + "-enter"),

    enterToClass: (name + "-enter-to"),

    enterActiveClass: (name + "-enter-active"),

    leaveClass: (name + "-leave"),

    leaveToClass: (name + "-leave-to"),

    leaveActiveClass: (name + "-leave-active")

  }

});



var hasTransition = inBrowser && !isIE9;

var TRANSITION = 'transition';

var ANIMATION = 'animation';



// Transition property/event sniffing

var transitionProp = 'transition';

var transitionEndEvent = 'transitionend';

var animationProp = 'animation';

var animationEndEvent = 'animationend';

if (hasTransition) {

  /* istanbul ignore if */

  if (window.ontransitionend === undefined &&

    window.onwebkittransitionend !== undefined

  ) {

    transitionProp = 'WebkitTransition';

    transitionEndEvent = 'webkitTransitionEnd';

  }

  if (window.onanimationend === undefined &&

    window.onwebkitanimationend !== undefined

  ) {

    animationProp = 'WebkitAnimation';

    animationEndEvent = 'webkitAnimationEnd';

  }

}



// binding to window is necessary to make hot reload work in IE in strict mode

var raf = inBrowser

  ? window.requestAnimationFrame

    ? window.requestAnimationFrame.bind(window)

    : setTimeout

  : /* istanbul ignore next */ function (fn) { return fn(); };



function nextFrame (fn) {

  raf(function () {

    raf(fn);

  });

}



function addTransitionClass (el, cls) {

  var transitionClasses = el._transitionClasses || (el._transitionClasses = []);

  if (transitionClasses.indexOf(cls) < 0) {

    transitionClasses.push(cls);

    addClass(el, cls);

  }

}



function removeTransitionClass (el, cls) {

  if (el._transitionClasses) {

    remove(el._transitionClasses, cls);

  }

  removeClass(el, cls);

}



function whenTransitionEnds (

  el,

  expectedType,

  cb

) {

  var ref = getTransitionInfo(el, expectedType);

  var type = ref.type;

  var timeout = ref.timeout;

  var propCount = ref.propCount;

  if (!type) { return cb() }

  var event = type === TRANSITION ? transitionEndEvent : animationEndEvent;

  var ended = 0;

  var end = function () {

    el.removeEventListener(event, onEnd);

    cb();

  };

  var onEnd = function (e) {

    if (e.target === el) {

      if (++ended >= propCount) {

        end();

      }

    }

  };

  setTimeout(function () {

    if (ended < propCount) {

      end();

    }

  }, timeout + 1);

  el.addEventListener(event, onEnd);

}



var transformRE = /\b(transform|all)(,|$)/;



function getTransitionInfo (el, expectedType) {

  var styles = window.getComputedStyle(el);

  var transitionDelays = styles[transitionProp + 'Delay'].split(', ');

  var transitionDurations = styles[transitionProp + 'Duration'].split(', ');

  var transitionTimeout = getTimeout(transitionDelays, transitionDurations);

  var animationDelays = styles[animationProp + 'Delay'].split(', ');

  var animationDurations = styles[animationProp + 'Duration'].split(', ');

  var animationTimeout = getTimeout(animationDelays, animationDurations);



  var type;

  var timeout = 0;

  var propCount = 0;

  /* istanbul ignore if */

  if (expectedType === TRANSITION) {

    if (transitionTimeout > 0) {

      type = TRANSITION;

      timeout = transitionTimeout;

      propCount = transitionDurations.length;

    }

  } else if (expectedType === ANIMATION) {

    if (animationTimeout > 0) {

      type = ANIMATION;

      timeout = animationTimeout;

      propCount = animationDurations.length;

    }

  } else {

    timeout = Math.max(transitionTimeout, animationTimeout);

    type = timeout > 0

      ? transitionTimeout > animationTimeout

        ? TRANSITION

        : ANIMATION

      : null;

    propCount = type

      ? type === TRANSITION

        ? transitionDurations.length

        : animationDurations.length

      : 0;

  }

  var hasTransform =

    type === TRANSITION &&

    transformRE.test(styles[transitionProp + 'Property']);

  return {

    type: type,

    timeout: timeout,

    propCount: propCount,

    hasTransform: hasTransform

  }

}



function getTimeout (delays, durations) {

  /* istanbul ignore next */

  while (delays.length < durations.length) {

    delays = delays.concat(delays);

  }



  return Math.max.apply(null, durations.map(function (d, i) {

    return toMs(d) + toMs(delays[i])

  }))

}



function toMs (s) {

  return Number(s.slice(0, -1)) * 1000

}



/*  */



function enter (vnode, toggleDisplay) {

  var el = vnode.elm;



  // call leave callback now

  if (isDef(el._leaveCb)) {

    el._leaveCb.cancelled = true;

    el._leaveCb();

  }



  var data = resolveTransition(vnode.data.transition);

  if (isUndef(data)) {

    return

  }



  /* istanbul ignore if */

  if (isDef(el._enterCb) || el.nodeType !== 1) {

    return

  }



  var css = data.css;

  var type = data.type;

  var enterClass = data.enterClass;

  var enterToClass = data.enterToClass;

  var enterActiveClass = data.enterActiveClass;

  var appearClass = data.appearClass;

  var appearToClass = data.appearToClass;

  var appearActiveClass = data.appearActiveClass;

  var beforeEnter = data.beforeEnter;

  var enter = data.enter;

  var afterEnter = data.afterEnter;

  var enterCancelled = data.enterCancelled;

  var beforeAppear = data.beforeAppear;

  var appear = data.appear;

  var afterAppear = data.afterAppear;

  var appearCancelled = data.appearCancelled;

  var duration = data.duration;



  // activeInstance will always be the <transition> component managing this

  // transition. One edge case to check is when the <transition> is placed

  // as the root node of a child component. In that case we need to check

  // <transition>'s parent for appear check.

  var context = activeInstance;

  var transitionNode = activeInstance.$vnode;

  while (transitionNode && transitionNode.parent) {

    transitionNode = transitionNode.parent;

    context = transitionNode.context;

  }



  var isAppear = !context._isMounted || !vnode.isRootInsert;



  if (isAppear && !appear && appear !== '') {

    return

  }



  var startClass = isAppear && appearClass

    ? appearClass

    : enterClass;

  var activeClass = isAppear && appearActiveClass

    ? appearActiveClass

    : enterActiveClass;

  var toClass = isAppear && appearToClass

    ? appearToClass

    : enterToClass;



  var beforeEnterHook = isAppear

    ? (beforeAppear || beforeEnter)

    : beforeEnter;

  var enterHook = isAppear

    ? (typeof appear === 'function' ? appear : enter)

    : enter;

  var afterEnterHook = isAppear

    ? (afterAppear || afterEnter)

    : afterEnter;

  var enterCancelledHook = isAppear

    ? (appearCancelled || enterCancelled)

    : enterCancelled;



  var explicitEnterDuration = toNumber(

    isObject(duration)

      ? duration.enter

      : duration

  );



  if ("development" !== 'production' && explicitEnterDuration != null) {

    checkDuration(explicitEnterDuration, 'enter', vnode);

  }



  var expectsCSS = css !== false && !isIE9;

  var userWantsControl = getHookArgumentsLength(enterHook);



  var cb = el._enterCb = once(function () {

    if (expectsCSS) {

      removeTransitionClass(el, toClass);

      removeTransitionClass(el, activeClass);

    }

    if (cb.cancelled) {

      if (expectsCSS) {

        removeTransitionClass(el, startClass);

      }

      enterCancelledHook && enterCancelledHook(el);

    } else {

      afterEnterHook && afterEnterHook(el);

    }

    el._enterCb = null;

  });



  if (!vnode.data.show) {

    // remove pending leave element on enter by injecting an insert hook

    mergeVNodeHook(vnode, 'insert', function () {

      var parent = el.parentNode;

      var pendingNode = parent && parent._pending && parent._pending[vnode.key];

      if (pendingNode &&

        pendingNode.tag === vnode.tag &&

        pendingNode.elm._leaveCb

      ) {

        pendingNode.elm._leaveCb();

      }

      enterHook && enterHook(el, cb);

    });

  }



  // start enter transition

  beforeEnterHook && beforeEnterHook(el);

  if (expectsCSS) {

    addTransitionClass(el, startClass);

    addTransitionClass(el, activeClass);

    nextFrame(function () {

      addTransitionClass(el, toClass);

      removeTransitionClass(el, startClass);

      if (!cb.cancelled && !userWantsControl) {

        if (isValidDuration(explicitEnterDuration)) {

          setTimeout(cb, explicitEnterDuration);

        } else {

          whenTransitionEnds(el, type, cb);

        }

      }

    });

  }



  if (vnode.data.show) {

    toggleDisplay && toggleDisplay();

    enterHook && enterHook(el, cb);

  }



  if (!expectsCSS && !userWantsControl) {

    cb();

  }

}



function leave (vnode, rm) {

  var el = vnode.elm;



  // call enter callback now

  if (isDef(el._enterCb)) {

    el._enterCb.cancelled = true;

    el._enterCb();

  }



  var data = resolveTransition(vnode.data.transition);

  if (isUndef(data) || el.nodeType !== 1) {

    return rm()

  }



  /* istanbul ignore if */

  if (isDef(el._leaveCb)) {

    return

  }



  var css = data.css;

  var type = data.type;

  var leaveClass = data.leaveClass;

  var leaveToClass = data.leaveToClass;

  var leaveActiveClass = data.leaveActiveClass;

  var beforeLeave = data.beforeLeave;

  var leave = data.leave;

  var afterLeave = data.afterLeave;

  var leaveCancelled = data.leaveCancelled;

  var delayLeave = data.delayLeave;

  var duration = data.duration;



  var expectsCSS = css !== false && !isIE9;

  var userWantsControl = getHookArgumentsLength(leave);



  var explicitLeaveDuration = toNumber(

    isObject(duration)

      ? duration.leave

      : duration

  );



  if ("development" !== 'production' && isDef(explicitLeaveDuration)) {

    checkDuration(explicitLeaveDuration, 'leave', vnode);

  }



  var cb = el._leaveCb = once(function () {

    if (el.parentNode && el.parentNode._pending) {

      el.parentNode._pending[vnode.key] = null;

    }

    if (expectsCSS) {

      removeTransitionClass(el, leaveToClass);

      removeTransitionClass(el, leaveActiveClass);

    }

    if (cb.cancelled) {

      if (expectsCSS) {

        removeTransitionClass(el, leaveClass);

      }

      leaveCancelled && leaveCancelled(el);

    } else {

      rm();

      afterLeave && afterLeave(el);

    }

    el._leaveCb = null;

  });



  if (delayLeave) {

    delayLeave(performLeave);

  } else {

    performLeave();

  }



  function performLeave () {

    // the delayed leave may have already been cancelled

    if (cb.cancelled) {

      return

    }

    // record leaving element

    if (!vnode.data.show) {

      (el.parentNode._pending || (el.parentNode._pending = {}))[(vnode.key)] = vnode;

    }

    beforeLeave && beforeLeave(el);

    if (expectsCSS) {

      addTransitionClass(el, leaveClass);

      addTransitionClass(el, leaveActiveClass);

      nextFrame(function () {

        addTransitionClass(el, leaveToClass);

        removeTransitionClass(el, leaveClass);

        if (!cb.cancelled && !userWantsControl) {

          if (isValidDuration(explicitLeaveDuration)) {

            setTimeout(cb, explicitLeaveDuration);

          } else {

            whenTransitionEnds(el, type, cb);

          }

        }

      });

    }

    leave && leave(el, cb);

    if (!expectsCSS && !userWantsControl) {

      cb();

    }

  }

}



// only used in dev mode

function checkDuration (val, name, vnode) {

  if (typeof val !== 'number') {

    warn(

      "<transition> explicit " + name + " duration is not a valid number - " +

      "got " + (JSON.stringify(val)) + ".",

      vnode.context

    );

  } else if (isNaN(val)) {

    warn(

      "<transition> explicit " + name + " duration is NaN - " +

      'the duration expression might be incorrect.',

      vnode.context

    );

  }

}



function isValidDuration (val) {

  return typeof val === 'number' && !isNaN(val)

}



/**

 * Normalize a transition hook's argument length. The hook may be:

 * - a merged hook (invoker) with the original in .fns

 * - a wrapped component method (check ._length)

 * - a plain function (.length)

 */

function getHookArgumentsLength (fn) {

  if (isUndef(fn)) {

    return false

  }

  var invokerFns = fn.fns;

  if (isDef(invokerFns)) {

    // invoker

    return getHookArgumentsLength(

      Array.isArray(invokerFns)

        ? invokerFns[0]

        : invokerFns

    )

  } else {

    return (fn._length || fn.length) > 1

  }

}



function _enter (_, vnode) {

  if (vnode.data.show !== true) {

    enter(vnode);

  }

}



var transition = inBrowser ? {

  create: _enter,

  activate: _enter,

  remove: function remove$$1 (vnode, rm) {

    /* istanbul ignore else */

    if (vnode.data.show !== true) {

      leave(vnode, rm);

    } else {

      rm();

    }

  }

} : {};



var platformModules = [

  attrs,

  klass,

  events,

  domProps,

  style,

  transition

];



/*  */



// the directive module should be applied last, after all

// built-in modules have been applied.

var modules = platformModules.concat(baseModules);



var patch = createPatchFunction({ nodeOps: nodeOps, modules: modules });



/**

 * Not type checking this file because flow doesn't like attaching

 * properties to Elements.

 */



/* istanbul ignore if */

if (isIE9) {

  // http://www.matts411.com/post/internet-explorer-9-oninput/

  document.addEventListener('selectionchange', function () {

    var el = document.activeElement;

    if (el && el.vmodel) {

      trigger(el, 'input');

    }

  });

}



var directive = {

  inserted: function inserted (el, binding, vnode, oldVnode) {

    if (vnode.tag === 'select') {

      // #6903

      if (oldVnode.elm && !oldVnode.elm._vOptions) {

        mergeVNodeHook(vnode, 'postpatch', function () {

          directive.componentUpdated(el, binding, vnode);

        });

      } else {

        setSelected(el, binding, vnode.context);

      }

      el._vOptions = [].map.call(el.options, getValue);

    } else if (vnode.tag === 'textarea' || isTextInputType(el.type)) {

      el._vModifiers = binding.modifiers;

      if (!binding.modifiers.lazy) {

        // Safari < 10.2 & UIWebView doesn't fire compositionend when

        // switching focus before confirming composition choice

        // this also fixes the issue where some browsers e.g. iOS Chrome

        // fires "change" instead of "input" on autocomplete.

        el.addEventListener('change', onCompositionEnd);

        if (!isAndroid) {

          el.addEventListener('compositionstart', onCompositionStart);

          el.addEventListener('compositionend', onCompositionEnd);

        }

        /* istanbul ignore if */

        if (isIE9) {

          el.vmodel = true;

        }

      }

    }

  },



  componentUpdated: function componentUpdated (el, binding, vnode) {

    if (vnode.tag === 'select') {

      setSelected(el, binding, vnode.context);

      // in case the options rendered by v-for have changed,

      // it's possible that the value is out-of-sync with the rendered options.

      // detect such cases and filter out values that no longer has a matching

      // option in the DOM.

      var prevOptions = el._vOptions;

      var curOptions = el._vOptions = [].map.call(el.options, getValue);

      if (curOptions.some(function (o, i) { return !looseEqual(o, prevOptions[i]); })) {

        // trigger change event if

        // no matching option found for at least one value

        var needReset = el.multiple

          ? binding.value.some(function (v) { return hasNoMatchingOption(v, curOptions); })

          : binding.value !== binding.oldValue && hasNoMatchingOption(binding.value, curOptions);

        if (needReset) {

          trigger(el, 'change');

        }

      }

    }

  }

};



function setSelected (el, binding, vm) {

  actuallySetSelected(el, binding, vm);

  /* istanbul ignore if */

  if (isIE || isEdge) {

    setTimeout(function () {

      actuallySetSelected(el, binding, vm);

    }, 0);

  }

}



function actuallySetSelected (el, binding, vm) {

  var value = binding.value;

  var isMultiple = el.multiple;

  if (isMultiple && !Array.isArray(value)) {

    "development" !== 'production' && warn(

      "<select multiple v-model=\"" + (binding.expression) + "\"> " +

      "expects an Array value for its binding, but got " + (Object.prototype.toString.call(value).slice(8, -1)),

      vm

    );

    return

  }

  var selected, option;

  for (var i = 0, l = el.options.length; i < l; i++) {

    option = el.options[i];

    if (isMultiple) {

      selected = looseIndexOf(value, getValue(option)) > -1;

      if (option.selected !== selected) {

        option.selected = selected;

      }

    } else {

      if (looseEqual(getValue(option), value)) {

        if (el.selectedIndex !== i) {

          el.selectedIndex = i;

        }

        return

      }

    }

  }

  if (!isMultiple) {

    el.selectedIndex = -1;

  }

}



function hasNoMatchingOption (value, options) {

  return options.every(function (o) { return !looseEqual(o, value); })

}



function getValue (option) {

  return '_value' in option

    ? option._value

    : option.value

}



function onCompositionStart (e) {

  e.target.composing = true;

}



function onCompositionEnd (e) {

  // prevent triggering an input event for no reason

  if (!e.target.composing) { return }

  e.target.composing = false;

  trigger(e.target, 'input');

}



function trigger (el, type) {

  var e = document.createEvent('HTMLEvents');

  e.initEvent(type, true, true);

  el.dispatchEvent(e);

}



/*  */



// recursively search for possible transition defined inside the component root

function locateNode (vnode) {

  return vnode.componentInstance && (!vnode.data || !vnode.data.transition)

    ? locateNode(vnode.componentInstance._vnode)

    : vnode

}



var show = {

  bind: function bind (el, ref, vnode) {

    var value = ref.value;



    vnode = locateNode(vnode);

    var transition$$1 = vnode.data && vnode.data.transition;

    var originalDisplay = el.__vOriginalDisplay =

      el.style.display === 'none' ? '' : el.style.display;

    if (value && transition$$1) {

      vnode.data.show = true;

      enter(vnode, function () {

        el.style.display = originalDisplay;

      });

    } else {

      el.style.display = value ? originalDisplay : 'none';

    }

  },



  update: function update (el, ref, vnode) {

    var value = ref.value;

    var oldValue = ref.oldValue;



    /* istanbul ignore if */

    if (value === oldValue) { return }

    vnode = locateNode(vnode);

    var transition$$1 = vnode.data && vnode.data.transition;

    if (transition$$1) {

      vnode.data.show = true;

      if (value) {

        enter(vnode, function () {

          el.style.display = el.__vOriginalDisplay;

        });

      } else {

        leave(vnode, function () {

          el.style.display = 'none';

        });

      }

    } else {

      el.style.display = value ? el.__vOriginalDisplay : 'none';

    }

  },



  unbind: function unbind (

    el,

    binding,

    vnode,

    oldVnode,

    isDestroy

  ) {

    if (!isDestroy) {

      el.style.display = el.__vOriginalDisplay;

    }

  }

};



var platformDirectives = {

  model: directive,

  show: show

};



/*  */



// Provides transition support for a single element/component.

// supports transition mode (out-in / in-out)



var transitionProps = {

  name: String,

  appear: Boolean,

  css: Boolean,

  mode: String,

  type: String,

  enterClass: String,

  leaveClass: String,

  enterToClass: String,

  leaveToClass: String,

  enterActiveClass: String,

  leaveActiveClass: String,

  appearClass: String,

  appearActiveClass: String,

  appearToClass: String,

  duration: [Number, String, Object]

};



// in case the child is also an abstract component, e.g. <keep-alive>

// we want to recursively retrieve the real component to be rendered

function getRealChild (vnode) {

  var compOptions = vnode && vnode.componentOptions;

  if (compOptions && compOptions.Ctor.options.abstract) {

    return getRealChild(getFirstComponentChild(compOptions.children))

  } else {

    return vnode

  }

}



function extractTransitionData (comp) {

  var data = {};

  var options = comp.$options;

  // props

  for (var key in options.propsData) {

    data[key] = comp[key];

  }

  // events.

  // extract listeners and pass them directly to the transition methods

  var listeners = options._parentListeners;

  for (var key$1 in listeners) {

    data[camelize(key$1)] = listeners[key$1];

  }

  return data

}



function placeholder (h, rawChild) {

  if (/\d-keep-alive$/.test(rawChild.tag)) {

    return h('keep-alive', {

      props: rawChild.componentOptions.propsData

    })

  }

}



function hasParentTransition (vnode) {

  while ((vnode = vnode.parent)) {

    if (vnode.data.transition) {

      return true

    }

  }

}



function isSameChild (child, oldChild) {

  return oldChild.key === child.key && oldChild.tag === child.tag

}



var Transition = {

  name: 'transition',

  props: transitionProps,

  abstract: true,



  render: function render (h) {

    var this$1 = this;



    var children = this.$slots.default;

    if (!children) {

      return

    }



    // filter out text nodes (possible whitespaces)

    children = children.filter(function (c) { return c.tag || isAsyncPlaceholder(c); });

    /* istanbul ignore if */

    if (!children.length) {

      return

    }



    // warn multiple elements

    if ("development" !== 'production' && children.length > 1) {

      warn(

        '<transition> can only be used on a single element. Use ' +

        '<transition-group> for lists.',

        this.$parent

      );

    }



    var mode = this.mode;



    // warn invalid mode

    if ("development" !== 'production' &&

      mode && mode !== 'in-out' && mode !== 'out-in'

    ) {

      warn(

        'invalid <transition> mode: ' + mode,

        this.$parent

      );

    }



    var rawChild = children[0];



    // if this is a component root node and the component's

    // parent container node also has transition, skip.

    if (hasParentTransition(this.$vnode)) {

      return rawChild

    }



    // apply transition data to child

    // use getRealChild() to ignore abstract components e.g. keep-alive

    var child = getRealChild(rawChild);

    /* istanbul ignore if */

    if (!child) {

      return rawChild

    }



    if (this._leaving) {

      return placeholder(h, rawChild)

    }



    // ensure a key that is unique to the vnode type and to this transition

    // component instance. This key will be used to remove pending leaving nodes

    // during entering.

    var id = "__transition-" + (this._uid) + "-";

    child.key = child.key == null

      ? child.isComment

        ? id + 'comment'

        : id + child.tag

      : isPrimitive(child.key)

        ? (String(child.key).indexOf(id) === 0 ? child.key : id + child.key)

        : child.key;



    var data = (child.data || (child.data = {})).transition = extractTransitionData(this);

    var oldRawChild = this._vnode;

    var oldChild = getRealChild(oldRawChild);



    // mark v-show

    // so that the transition module can hand over the control to the directive

    if (child.data.directives && child.data.directives.some(function (d) { return d.name === 'show'; })) {

      child.data.show = true;

    }



    if (

      oldChild &&

      oldChild.data &&

      !isSameChild(child, oldChild) &&

      !isAsyncPlaceholder(oldChild) &&

      // #6687 component root is a comment node

      !(oldChild.componentInstance && oldChild.componentInstance._vnode.isComment)

    ) {

      // replace old child transition data with fresh one

      // important for dynamic transitions!

      var oldData = oldChild.data.transition = extend({}, data);

      // handle transition mode

      if (mode === 'out-in') {

        // return placeholder node and queue update when leave finishes

        this._leaving = true;

        mergeVNodeHook(oldData, 'afterLeave', function () {

          this$1._leaving = false;

          this$1.$forceUpdate();

        });

        return placeholder(h, rawChild)

      } else if (mode === 'in-out') {

        if (isAsyncPlaceholder(child)) {

          return oldRawChild

        }

        var delayedLeave;

        var performLeave = function () { delayedLeave(); };

        mergeVNodeHook(data, 'afterEnter', performLeave);

        mergeVNodeHook(data, 'enterCancelled', performLeave);

        mergeVNodeHook(oldData, 'delayLeave', function (leave) { delayedLeave = leave; });

      }

    }



    return rawChild

  }

};



/*  */



// Provides transition support for list items.

// supports move transitions using the FLIP technique.



// Because the vdom's children update algorithm is "unstable" - i.e.

// it doesn't guarantee the relative positioning of removed elements,

// we force transition-group to update its children into two passes:

// in the first pass, we remove all nodes that need to be removed,

// triggering their leaving transition; in the second pass, we insert/move

// into the final desired state. This way in the second pass removed

// nodes will remain where they should be.



var props = extend({

  tag: String,

  moveClass: String

}, transitionProps);



delete props.mode;



var TransitionGroup = {

  props: props,



  render: function render (h) {

    var tag = this.tag || this.$vnode.data.tag || 'span';

    var map = Object.create(null);

    var prevChildren = this.prevChildren = this.children;

    var rawChildren = this.$slots.default || [];

    var children = this.children = [];

    var transitionData = extractTransitionData(this);



    for (var i = 0; i < rawChildren.length; i++) {

      var c = rawChildren[i];

      if (c.tag) {

        if (c.key != null && String(c.key).indexOf('__vlist') !== 0) {

          children.push(c);

          map[c.key] = c

          ;(c.data || (c.data = {})).transition = transitionData;

        } else if (true) {

          var opts = c.componentOptions;

          var name = opts ? (opts.Ctor.options.name || opts.tag || '') : c.tag;

          warn(("<transition-group> children must be keyed: <" + name + ">"));

        }

      }

    }



    if (prevChildren) {

      var kept = [];

      var removed = [];

      for (var i$1 = 0; i$1 < prevChildren.length; i$1++) {

        var c$1 = prevChildren[i$1];

        c$1.data.transition = transitionData;

        c$1.data.pos = c$1.elm.getBoundingClientRect();

        if (map[c$1.key]) {

          kept.push(c$1);

        } else {

          removed.push(c$1);

        }

      }

      this.kept = h(tag, null, kept);

      this.removed = removed;

    }



    return h(tag, null, children)

  },



  beforeUpdate: function beforeUpdate () {

    // force removing pass

    this.__patch__(

      this._vnode,

      this.kept,

      false, // hydrating

      true // removeOnly (!important avoids unnecessary moves)

    );

    this._vnode = this.kept;

  },



  updated: function updated () {

    var children = this.prevChildren;

    var moveClass = this.moveClass || ((this.name || 'v') + '-move');

    if (!children.length || !this.hasMove(children[0].elm, moveClass)) {

      return

    }



    // we divide the work into three loops to avoid mixing DOM reads and writes

    // in each iteration - which helps prevent layout thrashing.

    children.forEach(callPendingCbs);

    children.forEach(recordPosition);

    children.forEach(applyTranslation);



    // force reflow to put everything in position

    // assign to this to avoid being removed in tree-shaking

    // $flow-disable-line

    this._reflow = document.body.offsetHeight;



    children.forEach(function (c) {

      if (c.data.moved) {

        var el = c.elm;

        var s = el.style;

        addTransitionClass(el, moveClass);

        s.transform = s.WebkitTransform = s.transitionDuration = '';

        el.addEventListener(transitionEndEvent, el._moveCb = function cb (e) {

          if (!e || /transform$/.test(e.propertyName)) {

            el.removeEventListener(transitionEndEvent, cb);

            el._moveCb = null;

            removeTransitionClass(el, moveClass);

          }

        });

      }

    });

  },



  methods: {

    hasMove: function hasMove (el, moveClass) {

      /* istanbul ignore if */

      if (!hasTransition) {

        return false

      }

      /* istanbul ignore if */

      if (this._hasMove) {

        return this._hasMove

      }

      // Detect whether an element with the move class applied has

      // CSS transitions. Since the element may be inside an entering

      // transition at this very moment, we make a clone of it and remove

      // all other transition classes applied to ensure only the move class

      // is applied.

      var clone = el.cloneNode();

      if (el._transitionClasses) {

        el._transitionClasses.forEach(function (cls) { removeClass(clone, cls); });

      }

      addClass(clone, moveClass);

      clone.style.display = 'none';

      this.$el.appendChild(clone);

      var info = getTransitionInfo(clone);

      this.$el.removeChild(clone);

      return (this._hasMove = info.hasTransform)

    }

  }

};



function callPendingCbs (c) {

  /* istanbul ignore if */

  if (c.elm._moveCb) {

    c.elm._moveCb();

  }

  /* istanbul ignore if */

  if (c.elm._enterCb) {

    c.elm._enterCb();

  }

}



function recordPosition (c) {

  c.data.newPos = c.elm.getBoundingClientRect();

}



function applyTranslation (c) {

  var oldPos = c.data.pos;

  var newPos = c.data.newPos;

  var dx = oldPos.left - newPos.left;

  var dy = oldPos.top - newPos.top;

  if (dx || dy) {

    c.data.moved = true;

    var s = c.elm.style;

    s.transform = s.WebkitTransform = "translate(" + dx + "px," + dy + "px)";

    s.transitionDuration = '0s';

  }

}



var platformComponents = {

  Transition: Transition,

  TransitionGroup: TransitionGroup

};



/*  */



// install platform specific utils

Vue$3.config.mustUseProp = mustUseProp;

Vue$3.config.isReservedTag = isReservedTag;

Vue$3.config.isReservedAttr = isReservedAttr;

Vue$3.config.getTagNamespace = getTagNamespace;

Vue$3.config.isUnknownElement = isUnknownElement;



// install platform runtime directives & components

extend(Vue$3.options.directives, platformDirectives);

extend(Vue$3.options.components, platformComponents);



// install platform patch function

Vue$3.prototype.__patch__ = inBrowser ? patch : noop;



// public mount method

Vue$3.prototype.$mount = function (

  el,

  hydrating

) {

  el = el && inBrowser ? query(el) : undefined;

  return mountComponent(this, el, hydrating)

};



// devtools global hook

/* istanbul ignore next */

Vue$3.nextTick(function () {

  if (config.devtools) {

    if (devtools) {

      devtools.emit('init', Vue$3);

    } else if ("development" !== 'production' && isChrome) {

      console[console.info ? 'info' : 'log'](

        'Download the Vue Devtools extension for a better development experience:\n' +

        'https://github.com/vuejs/vue-devtools'

      );

    }

  }

  if ("development" !== 'production' &&

    config.productionTip !== false &&

    inBrowser && typeof console !== 'undefined'

  ) {

    console[console.info ? 'info' : 'log'](

      "You are running Vue in development mode.\n" +

      "Make sure to turn on production mode when deploying for production.\n" +

      "See more tips at https://vuejs.org/guide/deployment.html"

    );

  }

}, 0);



/*  */



var defaultTagRE = /\{\{((?:.|\n)+?)\}\}/g;

var regexEscapeRE = /[-.*+?^${}()|[\]\/\\]/g;



var buildRegex = cached(function (delimiters) {

  var open = delimiters[0].replace(regexEscapeRE, '\\$&');

  var close = delimiters[1].replace(regexEscapeRE, '\\$&');

  return new RegExp(open + '((?:.|\\n)+?)' + close, 'g')

});







function parseText (

  text,

  delimiters

) {

  var tagRE = delimiters ? buildRegex(delimiters) : defaultTagRE;

  if (!tagRE.test(text)) {

    return

  }

  var tokens = [];

  var rawTokens = [];

  var lastIndex = tagRE.lastIndex = 0;

  var match, index, tokenValue;

  while ((match = tagRE.exec(text))) {

    index = match.index;

    // push text token

    if (index > lastIndex) {

      rawTokens.push(tokenValue = text.slice(lastIndex, index));

      tokens.push(JSON.stringify(tokenValue));

    }

    // tag token

    var exp = parseFilters(match[1].trim());

    tokens.push(("_s(" + exp + ")"));

    rawTokens.push({ '@binding': exp });

    lastIndex = index + match[0].length;

  }

  if (lastIndex < text.length) {

    rawTokens.push(tokenValue = text.slice(lastIndex));

    tokens.push(JSON.stringify(tokenValue));

  }

  return {

    expression: tokens.join('+'),

    tokens: rawTokens

  }

}



/*  */



function transformNode (el, options) {

  var warn = options.warn || baseWarn;

  var staticClass = getAndRemoveAttr(el, 'class');

  if ("development" !== 'production' && staticClass) {

    var res = parseText(staticClass, options.delimiters);

    if (res) {

      warn(

        "class=\"" + staticClass + "\": " +

        'Interpolation inside attributes has been removed. ' +

        'Use v-bind or the colon shorthand instead. For example, ' +

        'instead of <div class="{{ val }}">, use <div :class="val">.'

      );

    }

  }

  if (staticClass) {

    el.staticClass = JSON.stringify(staticClass);

  }

  var classBinding = getBindingAttr(el, 'class', false /* getStatic */);

  if (classBinding) {

    el.classBinding = classBinding;

  }

}



function genData (el) {

  var data = '';

  if (el.staticClass) {

    data += "staticClass:" + (el.staticClass) + ",";

  }

  if (el.classBinding) {

    data += "class:" + (el.classBinding) + ",";

  }

  return data

}



var klass$1 = {

  staticKeys: ['staticClass'],

  transformNode: transformNode,

  genData: genData

};



/*  */



function transformNode$1 (el, options) {

  var warn = options.warn || baseWarn;

  var staticStyle = getAndRemoveAttr(el, 'style');

  if (staticStyle) {

    /* istanbul ignore if */

    if (true) {

      var res = parseText(staticStyle, options.delimiters);

      if (res) {

        warn(

          "style=\"" + staticStyle + "\": " +

          'Interpolation inside attributes has been removed. ' +

          'Use v-bind or the colon shorthand instead. For example, ' +

          'instead of <div style="{{ val }}">, use <div :style="val">.'

        );

      }

    }

    el.staticStyle = JSON.stringify(parseStyleText(staticStyle));

  }



  var styleBinding = getBindingAttr(el, 'style', false /* getStatic */);

  if (styleBinding) {

    el.styleBinding = styleBinding;

  }

}



function genData$1 (el) {

  var data = '';

  if (el.staticStyle) {

    data += "staticStyle:" + (el.staticStyle) + ",";

  }

  if (el.styleBinding) {

    data += "style:(" + (el.styleBinding) + "),";

  }

  return data

}



var style$1 = {

  staticKeys: ['staticStyle'],

  transformNode: transformNode$1,

  genData: genData$1

};



/*  */



var decoder;



var he = {

  decode: function decode (html) {

    decoder = decoder || document.createElement('div');

    decoder.innerHTML = html;

    return decoder.textContent

  }

};



/*  */



var isUnaryTag = makeMap(

  'area,base,br,col,embed,frame,hr,img,input,isindex,keygen,' +

  'link,meta,param,source,track,wbr'

);



// Elements that you can, intentionally, leave open

// (and which close themselves)

var canBeLeftOpenTag = makeMap(

  'colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source'

);



// HTML5 tags https://html.spec.whatwg.org/multipage/indices.html#elements-3

// Phrasing Content https://html.spec.whatwg.org/multipage/dom.html#phrasing-content

var isNonPhrasingTag = makeMap(

  'address,article,aside,base,blockquote,body,caption,col,colgroup,dd,' +

  'details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,' +

  'h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,' +

  'optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,' +

  'title,tr,track'

);



/**

 * Not type-checking this file because it's mostly vendor code.

 */



/*!

 * HTML Parser By John Resig (ejohn.org)

 * Modified by Juriy "kangax" Zaytsev

 * Original code by Erik Arvidsson, Mozilla Public License

 * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js

 */



// Regular Expressions for parsing tags and attributes

var attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/;

// could use https://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-QName

// but for Vue templates we can enforce a simple charset

var ncname = '[a-zA-Z_][\\w\\-\\.]*';

var qnameCapture = "((?:" + ncname + "\\:)?" + ncname + ")";

var startTagOpen = new RegExp(("^<" + qnameCapture));

var startTagClose = /^\s*(\/?)>/;

var endTag = new RegExp(("^<\\/" + qnameCapture + "[^>]*>"));

var doctype = /^<!DOCTYPE [^>]+>/i;

var comment = /^<!--/;

var conditionalComment = /^<!\[/;



var IS_REGEX_CAPTURING_BROKEN = false;

'x'.replace(/x(.)?/g, function (m, g) {

  IS_REGEX_CAPTURING_BROKEN = g === '';

});



// Special Elements (can contain anything)

var isPlainTextElement = makeMap('script,style,textarea', true);

var reCache = {};



var decodingMap = {

  '&lt;': '<',

  '&gt;': '>',

  '&quot;': '"',

  '&amp;': '&',

  '&#10;': '\n',

  '&#9;': '\t'

};

var encodedAttr = /&(?:lt|gt|quot|amp);/g;

var encodedAttrWithNewLines = /&(?:lt|gt|quot|amp|#10|#9);/g;



// #5992

var isIgnoreNewlineTag = makeMap('pre,textarea', true);

var shouldIgnoreFirstNewline = function (tag, html) { return tag && isIgnoreNewlineTag(tag) && html[0] === '\n'; };



function decodeAttr (value, shouldDecodeNewlines) {

  var re = shouldDecodeNewlines ? encodedAttrWithNewLines : encodedAttr;

  return value.replace(re, function (match) { return decodingMap[match]; })

}



function parseHTML (html, options) {

  var stack = [];

  var expectHTML = options.expectHTML;

  var isUnaryTag$$1 = options.isUnaryTag || no;

  var canBeLeftOpenTag$$1 = options.canBeLeftOpenTag || no;

  var index = 0;

  var last, lastTag;

  while (html) {

    last = html;

    // Make sure we're not in a plaintext content element like script/style

    if (!lastTag || !isPlainTextElement(lastTag)) {

      var textEnd = html.indexOf('<');

      if (textEnd === 0) {

        // Comment:

        if (comment.test(html)) {

          var commentEnd = html.indexOf('-->');



          if (commentEnd >= 0) {

            if (options.shouldKeepComment) {

              options.comment(html.substring(4, commentEnd));

            }

            advance(commentEnd + 3);

            continue

          }

        }



        // http://en.wikipedia.org/wiki/Conditional_comment#Downlevel-revealed_conditional_comment

        if (conditionalComment.test(html)) {

          var conditionalEnd = html.indexOf(']>');



          if (conditionalEnd >= 0) {

            advance(conditionalEnd + 2);

            continue

          }

        }



        // Doctype:

        var doctypeMatch = html.match(doctype);

        if (doctypeMatch) {

          advance(doctypeMatch[0].length);

          continue

        }



        // End tag:

        var endTagMatch = html.match(endTag);

        if (endTagMatch) {

          var curIndex = index;

          advance(endTagMatch[0].length);

          parseEndTag(endTagMatch[1], curIndex, index);

          continue

        }



        // Start tag:

        var startTagMatch = parseStartTag();

        if (startTagMatch) {

          handleStartTag(startTagMatch);

          if (shouldIgnoreFirstNewline(lastTag, html)) {

            advance(1);

          }

          continue

        }

      }



      var text = (void 0), rest = (void 0), next = (void 0);

      if (textEnd >= 0) {

        rest = html.slice(textEnd);

        while (

          !endTag.test(rest) &&

          !startTagOpen.test(rest) &&

          !comment.test(rest) &&

          !conditionalComment.test(rest)

        ) {

          // < in plain text, be forgiving and treat it as text

          next = rest.indexOf('<', 1);

          if (next < 0) { break }

          textEnd += next;

          rest = html.slice(textEnd);

        }

        text = html.substring(0, textEnd);

        advance(textEnd);

      }



      if (textEnd < 0) {

        text = html;

        html = '';

      }



      if (options.chars && text) {

        options.chars(text);

      }

    } else {

      var endTagLength = 0;

      var stackedTag = lastTag.toLowerCase();

      var reStackedTag = reCache[stackedTag] || (reCache[stackedTag] = new RegExp('([\\s\\S]*?)(</' + stackedTag + '[^>]*>)', 'i'));

      var rest$1 = html.replace(reStackedTag, function (all, text, endTag) {

        endTagLength = endTag.length;

        if (!isPlainTextElement(stackedTag) && stackedTag !== 'noscript') {

          text = text

            .replace(/<!--([\s\S]*?)-->/g, '$1')

            .replace(/<!\[CDATA\[([\s\S]*?)]]>/g, '$1');

        }

        if (shouldIgnoreFirstNewline(stackedTag, text)) {

          text = text.slice(1);

        }

        if (options.chars) {

          options.chars(text);

        }

        return ''

      });

      index += html.length - rest$1.length;

      html = rest$1;

      parseEndTag(stackedTag, index - endTagLength, index);

    }



    if (html === last) {

      options.chars && options.chars(html);

      if ("development" !== 'production' && !stack.length && options.warn) {

        options.warn(("Mal-formatted tag at end of template: \"" + html + "\""));

      }

      break

    }

  }



  // Clean up any remaining tags

  parseEndTag();



  function advance (n) {

    index += n;

    html = html.substring(n);

  }



  function parseStartTag () {

    var start = html.match(startTagOpen);

    if (start) {

      var match = {

        tagName: start[1],

        attrs: [],

        start: index

      };

      advance(start[0].length);

      var end, attr;

      while (!(end = html.match(startTagClose)) && (attr = html.match(attribute))) {

        advance(attr[0].length);

        match.attrs.push(attr);

      }

      if (end) {

        match.unarySlash = end[1];

        advance(end[0].length);

        match.end = index;

        return match

      }

    }

  }



  function handleStartTag (match) {

    var tagName = match.tagName;

    var unarySlash = match.unarySlash;



    if (expectHTML) {

      if (lastTag === 'p' && isNonPhrasingTag(tagName)) {

        parseEndTag(lastTag);

      }

      if (canBeLeftOpenTag$$1(tagName) && lastTag === tagName) {

        parseEndTag(tagName);

      }

    }



    var unary = isUnaryTag$$1(tagName) || !!unarySlash;



    var l = match.attrs.length;

    var attrs = new Array(l);

    for (var i = 0; i < l; i++) {

      var args = match.attrs[i];

      // hackish work around FF bug https://bugzilla.mozilla.org/show_bug.cgi?id=369778

      if (IS_REGEX_CAPTURING_BROKEN && args[0].indexOf('""') === -1) {

        if (args[3] === '') { delete args[3]; }

        if (args[4] === '') { delete args[4]; }

        if (args[5] === '') { delete args[5]; }

      }

      var value = args[3] || args[4] || args[5] || '';

      var shouldDecodeNewlines = tagName === 'a' && args[1] === 'href'

        ? options.shouldDecodeNewlinesForHref

        : options.shouldDecodeNewlines;

      attrs[i] = {

        name: args[1],

        value: decodeAttr(value, shouldDecodeNewlines)

      };

    }



    if (!unary) {

      stack.push({ tag: tagName, lowerCasedTag: tagName.toLowerCase(), attrs: attrs });

      lastTag = tagName;

    }



    if (options.start) {

      options.start(tagName, attrs, unary, match.start, match.end);

    }

  }



  function parseEndTag (tagName, start, end) {

    var pos, lowerCasedTagName;

    if (start == null) { start = index; }

    if (end == null) { end = index; }



    if (tagName) {

      lowerCasedTagName = tagName.toLowerCase();

    }



    // Find the closest opened tag of the same type

    if (tagName) {

      for (pos = stack.length - 1; pos >= 0; pos--) {

        if (stack[pos].lowerCasedTag === lowerCasedTagName) {

          break

        }

      }

    } else {

      // If no tag name is provided, clean shop

      pos = 0;

    }



    if (pos >= 0) {

      // Close all the open elements, up the stack

      for (var i = stack.length - 1; i >= pos; i--) {

        if ("development" !== 'production' &&

          (i > pos || !tagName) &&

          options.warn

        ) {

          options.warn(

            ("tag <" + (stack[i].tag) + "> has no matching end tag.")

          );

        }

        if (options.end) {

          options.end(stack[i].tag, start, end);

        }

      }



      // Remove the open elements from the stack

      stack.length = pos;

      lastTag = pos && stack[pos - 1].tag;

    } else if (lowerCasedTagName === 'br') {

      if (options.start) {

        options.start(tagName, [], true, start, end);

      }

    } else if (lowerCasedTagName === 'p') {

      if (options.start) {

        options.start(tagName, [], false, start, end);

      }

      if (options.end) {

        options.end(tagName, start, end);

      }

    }

  }

}



/*  */



var onRE = /^@|^v-on:/;

var dirRE = /^v-|^@|^:/;

var forAliasRE = /(.*?)\s+(?:in|of)\s+(.*)/;

var forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;

var stripParensRE = /^\(|\)$/g;



var argRE = /:(.*)$/;

var bindRE = /^:|^v-bind:/;

var modifierRE = /\.[^.]+/g;



var decodeHTMLCached = cached(he.decode);



// configurable state

var warn$2;

var delimiters;

var transforms;

var preTransforms;

var postTransforms;

var platformIsPreTag;

var platformMustUseProp;

var platformGetTagNamespace;







function createASTElement (

  tag,

  attrs,

  parent

) {

  return {

    type: 1,

    tag: tag,

    attrsList: attrs,

    attrsMap: makeAttrsMap(attrs),

    parent: parent,

    children: []

  }

}



/**

 * Convert HTML string to AST.

 */

function parse (

  template,

  options

) {

  warn$2 = options.warn || baseWarn;



  platformIsPreTag = options.isPreTag || no;

  platformMustUseProp = options.mustUseProp || no;

  platformGetTagNamespace = options.getTagNamespace || no;



  transforms = pluckModuleFunction(options.modules, 'transformNode');

  preTransforms = pluckModuleFunction(options.modules, 'preTransformNode');

  postTransforms = pluckModuleFunction(options.modules, 'postTransformNode');



  delimiters = options.delimiters;



  var stack = [];

  var preserveWhitespace = options.preserveWhitespace !== false;

  var root;

  var currentParent;

  var inVPre = false;

  var inPre = false;

  var warned = false;



  function warnOnce (msg) {

    if (!warned) {

      warned = true;

      warn$2(msg);

    }

  }



  function closeElement (element) {

    // check pre state

    if (element.pre) {

      inVPre = false;

    }

    if (platformIsPreTag(element.tag)) {

      inPre = false;

    }

    // apply post-transforms

    for (var i = 0; i < postTransforms.length; i++) {

      postTransforms[i](element, options);

    }

  }



  parseHTML(template, {

    warn: warn$2,

    expectHTML: options.expectHTML,

    isUnaryTag: options.isUnaryTag,

    canBeLeftOpenTag: options.canBeLeftOpenTag,

    shouldDecodeNewlines: options.shouldDecodeNewlines,

    shouldDecodeNewlinesForHref: options.shouldDecodeNewlinesForHref,

    shouldKeepComment: options.comments,

    start: function start (tag, attrs, unary) {

      // check namespace.

      // inherit parent ns if there is one

      var ns = (currentParent && currentParent.ns) || platformGetTagNamespace(tag);



      // handle IE svg bug

      /* istanbul ignore if */

      if (isIE && ns === 'svg') {

        attrs = guardIESVGBug(attrs);

      }



      var element = createASTElement(tag, attrs, currentParent);

      if (ns) {

        element.ns = ns;

      }



      if (isForbiddenTag(element) && !isServerRendering()) {

        element.forbidden = true;

        "development" !== 'production' && warn$2(

          'Templates should only be responsible for mapping the state to the ' +

          'UI. Avoid placing tags with side-effects in your templates, such as ' +

          "<" + tag + ">" + ', as they will not be parsed.'

        );

      }



      // apply pre-transforms

      for (var i = 0; i < preTransforms.length; i++) {

        element = preTransforms[i](element, options) || element;

      }



      if (!inVPre) {

        processPre(element);

        if (element.pre) {

          inVPre = true;

        }

      }

      if (platformIsPreTag(element.tag)) {

        inPre = true;

      }

      if (inVPre) {

        processRawAttrs(element);

      } else if (!element.processed) {

        // structural directives

        processFor(element);

        processIf(element);

        processOnce(element);

        // element-scope stuff

        processElement(element, options);

      }



      function checkRootConstraints (el) {

        if (true) {

          if (el.tag === 'slot' || el.tag === 'template') {

            warnOnce(

              "Cannot use <" + (el.tag) + "> as component root element because it may " +

              'contain multiple nodes.'

            );

          }

          if (el.attrsMap.hasOwnProperty('v-for')) {

            warnOnce(

              'Cannot use v-for on stateful component root element because ' +

              'it renders multiple elements.'

            );

          }

        }

      }



      // tree management

      if (!root) {

        root = element;

        checkRootConstraints(root);

      } else if (!stack.length) {

        // allow root elements with v-if, v-else-if and v-else

        if (root.if && (element.elseif || element.else)) {

          checkRootConstraints(element);

          addIfCondition(root, {

            exp: element.elseif,

            block: element

          });

        } else if (true) {

          warnOnce(

            "Component template should contain exactly one root element. " +

            "If you are using v-if on multiple elements, " +

            "use v-else-if to chain them instead."

          );

        }

      }

      if (currentParent && !element.forbidden) {

        if (element.elseif || element.else) {

          processIfConditions(element, currentParent);

        } else if (element.slotScope) { // scoped slot

          currentParent.plain = false;

          var name = element.slotTarget || '"default"';(currentParent.scopedSlots || (currentParent.scopedSlots = {}))[name] = element;

        } else {

          currentParent.children.push(element);

          element.parent = currentParent;

        }

      }

      if (!unary) {

        currentParent = element;

        stack.push(element);

      } else {

        closeElement(element);

      }

    },



    end: function end () {

      // remove trailing whitespace

      var element = stack[stack.length - 1];

      var lastNode = element.children[element.children.length - 1];

      if (lastNode && lastNode.type === 3 && lastNode.text === ' ' && !inPre) {

        element.children.pop();

      }

      // pop stack

      stack.length -= 1;

      currentParent = stack[stack.length - 1];

      closeElement(element);

    },



    chars: function chars (text) {

      if (!currentParent) {

        if (true) {

          if (text === template) {

            warnOnce(

              'Component template requires a root element, rather than just text.'

            );

          } else if ((text = text.trim())) {

            warnOnce(

              ("text \"" + text + "\" outside root element will be ignored.")

            );

          }

        }

        return

      }

      // IE textarea placeholder bug

      /* istanbul ignore if */

      if (isIE &&

        currentParent.tag === 'textarea' &&

        currentParent.attrsMap.placeholder === text

      ) {

        return

      }

      var children = currentParent.children;

      text = inPre || text.trim()

        ? isTextTag(currentParent) ? text : decodeHTMLCached(text)

        // only preserve whitespace if its not right after a starting tag

        : preserveWhitespace && children.length ? ' ' : '';

      if (text) {

        var res;

        if (!inVPre && text !== ' ' && (res = parseText(text, delimiters))) {

          children.push({

            type: 2,

            expression: res.expression,

            tokens: res.tokens,

            text: text

          });

        } else if (text !== ' ' || !children.length || children[children.length - 1].text !== ' ') {

          children.push({

            type: 3,

            text: text

          });

        }

      }

    },

    comment: function comment (text) {

      currentParent.children.push({

        type: 3,

        text: text,

        isComment: true

      });

    }

  });

  return root

}



function processPre (el) {

  if (getAndRemoveAttr(el, 'v-pre') != null) {

    el.pre = true;

  }

}



function processRawAttrs (el) {

  var l = el.attrsList.length;

  if (l) {

    var attrs = el.attrs = new Array(l);

    for (var i = 0; i < l; i++) {

      attrs[i] = {

        name: el.attrsList[i].name,

        value: JSON.stringify(el.attrsList[i].value)

      };

    }

  } else if (!el.pre) {

    // non root node in pre blocks with no attributes

    el.plain = true;

  }

}



function processElement (element, options) {

  processKey(element);



  // determine whether this is a plain element after

  // removing structural attributes

  element.plain = !element.key && !element.attrsList.length;



  processRef(element);

  processSlot(element);

  processComponent(element);

  for (var i = 0; i < transforms.length; i++) {

    element = transforms[i](element, options) || element;

  }

  processAttrs(element);

}



function processKey (el) {

  var exp = getBindingAttr(el, 'key');

  if (exp) {

    if ("development" !== 'production' && el.tag === 'template') {

      warn$2("<template> cannot be keyed. Place the key on real elements instead.");

    }

    el.key = exp;

  }

}



function processRef (el) {

  var ref = getBindingAttr(el, 'ref');

  if (ref) {

    el.ref = ref;

    el.refInFor = checkInFor(el);

  }

}



function processFor (el) {

  var exp;

  if ((exp = getAndRemoveAttr(el, 'v-for'))) {

    var res = parseFor(exp);

    if (res) {

      extend(el, res);

    } else if (true) {

      warn$2(

        ("Invalid v-for expression: " + exp)

      );

    }

  }

}



function parseFor (exp) {

  var inMatch = exp.match(forAliasRE);

  if (!inMatch) { return }

  var res = {};

  res.for = inMatch[2].trim();

  var alias = inMatch[1].trim().replace(stripParensRE, '');

  var iteratorMatch = alias.match(forIteratorRE);

  if (iteratorMatch) {

    res.alias = alias.replace(forIteratorRE, '');

    res.iterator1 = iteratorMatch[1].trim();

    if (iteratorMatch[2]) {

      res.iterator2 = iteratorMatch[2].trim();

    }

  } else {

    res.alias = alias;

  }

  return res

}



function processIf (el) {

  var exp = getAndRemoveAttr(el, 'v-if');

  if (exp) {

    el.if = exp;

    addIfCondition(el, {

      exp: exp,

      block: el

    });

  } else {

    if (getAndRemoveAttr(el, 'v-else') != null) {

      el.else = true;

    }

    var elseif = getAndRemoveAttr(el, 'v-else-if');

    if (elseif) {

      el.elseif = elseif;

    }

  }

}



function processIfConditions (el, parent) {

  var prev = findPrevElement(parent.children);

  if (prev && prev.if) {

    addIfCondition(prev, {

      exp: el.elseif,

      block: el

    });

  } else if (true) {

    warn$2(

      "v-" + (el.elseif ? ('else-if="' + el.elseif + '"') : 'else') + " " +

      "used on element <" + (el.tag) + "> without corresponding v-if."

    );

  }

}



function findPrevElement (children) {

  var i = children.length;

  while (i--) {

    if (children[i].type === 1) {

      return children[i]

    } else {

      if ("development" !== 'production' && children[i].text !== ' ') {

        warn$2(

          "text \"" + (children[i].text.trim()) + "\" between v-if and v-else(-if) " +

          "will be ignored."

        );

      }

      children.pop();

    }

  }

}



function addIfCondition (el, condition) {

  if (!el.ifConditions) {

    el.ifConditions = [];

  }

  el.ifConditions.push(condition);

}



function processOnce (el) {

  var once$$1 = getAndRemoveAttr(el, 'v-once');

  if (once$$1 != null) {

    el.once = true;

  }

}



function processSlot (el) {

  if (el.tag === 'slot') {

    el.slotName = getBindingAttr(el, 'name');

    if ("development" !== 'production' && el.key) {

      warn$2(

        "`key` does not work on <slot> because slots are abstract outlets " +

        "and can possibly expand into multiple elements. " +

        "Use the key on a wrapping element instead."

      );

    }

  } else {

    var slotScope;

    if (el.tag === 'template') {

      slotScope = getAndRemoveAttr(el, 'scope');

      /* istanbul ignore if */

      if ("development" !== 'production' && slotScope) {

        warn$2(

          "the \"scope\" attribute for scoped slots have been deprecated and " +

          "replaced by \"slot-scope\" since 2.5. The new \"slot-scope\" attribute " +

          "can also be used on plain elements in addition to <template> to " +

          "denote scoped slots.",

          true

        );

      }

      el.slotScope = slotScope || getAndRemoveAttr(el, 'slot-scope');

    } else if ((slotScope = getAndRemoveAttr(el, 'slot-scope'))) {

      /* istanbul ignore if */

      if ("development" !== 'production' && el.attrsMap['v-for']) {

        warn$2(

          "Ambiguous combined usage of slot-scope and v-for on <" + (el.tag) + "> " +

          "(v-for takes higher priority). Use a wrapper <template> for the " +

          "scoped slot to make it clearer.",

          true

        );

      }

      el.slotScope = slotScope;

    }

    var slotTarget = getBindingAttr(el, 'slot');

    if (slotTarget) {

      el.slotTarget = slotTarget === '""' ? '"default"' : slotTarget;

      // preserve slot as an attribute for native shadow DOM compat

      // only for non-scoped slots.

      if (el.tag !== 'template' && !el.slotScope) {

        addAttr(el, 'slot', slotTarget);

      }

    }

  }

}



function processComponent (el) {

  var binding;

  if ((binding = getBindingAttr(el, 'is'))) {

    el.component = binding;

  }

  if (getAndRemoveAttr(el, 'inline-template') != null) {

    el.inlineTemplate = true;

  }

}



function processAttrs (el) {

  var list = el.attrsList;

  var i, l, name, rawName, value, modifiers, isProp;

  for (i = 0, l = list.length; i < l; i++) {

    name = rawName = list[i].name;

    value = list[i].value;

    if (dirRE.test(name)) {

      // mark element as dynamic

      el.hasBindings = true;

      // modifiers

      modifiers = parseModifiers(name);

      if (modifiers) {

        name = name.replace(modifierRE, '');

      }

      if (bindRE.test(name)) { // v-bind

        name = name.replace(bindRE, '');

        value = parseFilters(value);

        isProp = false;

        if (modifiers) {

          if (modifiers.prop) {

            isProp = true;

            name = camelize(name);

            if (name === 'innerHtml') { name = 'innerHTML'; }

          }

          if (modifiers.camel) {

            name = camelize(name);

          }

          if (modifiers.sync) {

            addHandler(

              el,

              ("update:" + (camelize(name))),

              genAssignmentCode(value, "$event")

            );

          }

        }

        if (isProp || (

          !el.component && platformMustUseProp(el.tag, el.attrsMap.type, name)

        )) {

          addProp(el, name, value);

        } else {

          addAttr(el, name, value);

        }

      } else if (onRE.test(name)) { // v-on

        name = name.replace(onRE, '');

        addHandler(el, name, value, modifiers, false, warn$2);

      } else { // normal directives

        name = name.replace(dirRE, '');

        // parse arg

        var argMatch = name.match(argRE);

        var arg = argMatch && argMatch[1];

        if (arg) {

          name = name.slice(0, -(arg.length + 1));

        }

        addDirective(el, name, rawName, value, arg, modifiers);

        if ("development" !== 'production' && name === 'model') {

          checkForAliasModel(el, value);

        }

      }

    } else {

      // literal attribute

      if (true) {

        var res = parseText(value, delimiters);

        if (res) {

          warn$2(

            name + "=\"" + value + "\": " +

            'Interpolation inside attributes has been removed. ' +

            'Use v-bind or the colon shorthand instead. For example, ' +

            'instead of <div id="{{ val }}">, use <div :id="val">.'

          );

        }

      }

      addAttr(el, name, JSON.stringify(value));

      // #6887 firefox doesn't update muted state if set via attribute

      // even immediately after element creation

      if (!el.component &&

          name === 'muted' &&

          platformMustUseProp(el.tag, el.attrsMap.type, name)) {

        addProp(el, name, 'true');

      }

    }

  }

}



function checkInFor (el) {

  var parent = el;

  while (parent) {

    if (parent.for !== undefined) {

      return true

    }

    parent = parent.parent;

  }

  return false

}



function parseModifiers (name) {

  var match = name.match(modifierRE);

  if (match) {

    var ret = {};

    match.forEach(function (m) { ret[m.slice(1)] = true; });

    return ret

  }

}



function makeAttrsMap (attrs) {

  var map = {};

  for (var i = 0, l = attrs.length; i < l; i++) {

    if (

      "development" !== 'production' &&

      map[attrs[i].name] && !isIE && !isEdge

    ) {

      warn$2('duplicate attribute: ' + attrs[i].name);

    }

    map[attrs[i].name] = attrs[i].value;

  }

  return map

}



// for script (e.g. type="x/template") or style, do not decode content

function isTextTag (el) {

  return el.tag === 'script' || el.tag === 'style'

}



function isForbiddenTag (el) {

  return (

    el.tag === 'style' ||

    (el.tag === 'script' && (

      !el.attrsMap.type ||

      el.attrsMap.type === 'text/javascript'

    ))

  )

}



var ieNSBug = /^xmlns:NS\d+/;

var ieNSPrefix = /^NS\d+:/;



/* istanbul ignore next */

function guardIESVGBug (attrs) {

  var res = [];

  for (var i = 0; i < attrs.length; i++) {

    var attr = attrs[i];

    if (!ieNSBug.test(attr.name)) {

      attr.name = attr.name.replace(ieNSPrefix, '');

      res.push(attr);

    }

  }

  return res

}



function checkForAliasModel (el, value) {

  var _el = el;

  while (_el) {

    if (_el.for && _el.alias === value) {

      warn$2(

        "<" + (el.tag) + " v-model=\"" + value + "\">: " +

        "You are binding v-model directly to a v-for iteration alias. " +

        "This will not be able to modify the v-for source array because " +

        "writing to the alias is like modifying a function local variable. " +

        "Consider using an array of objects and use v-model on an object property instead."

      );

    }

    _el = _el.parent;

  }

}



/*  */



/**

 * Expand input[v-model] with dyanmic type bindings into v-if-else chains

 * Turn this:

 *   <input v-model="data[type]" :type="type">

 * into this:

 *   <input v-if="type === 'checkbox'" type="checkbox" v-model="data[type]">

 *   <input v-else-if="type === 'radio'" type="radio" v-model="data[type]">

 *   <input v-else :type="type" v-model="data[type]">

 */



function preTransformNode (el, options) {

  if (el.tag === 'input') {

    var map = el.attrsMap;

    if (map['v-model'] && (map['v-bind:type'] || map[':type'])) {

      var typeBinding = getBindingAttr(el, 'type');

      var ifCondition = getAndRemoveAttr(el, 'v-if', true);

      var ifConditionExtra = ifCondition ? ("&&(" + ifCondition + ")") : "";

      var hasElse = getAndRemoveAttr(el, 'v-else', true) != null;

      var elseIfCondition = getAndRemoveAttr(el, 'v-else-if', true);

      // 1. checkbox

      var branch0 = cloneASTElement(el);

      // process for on the main node

      processFor(branch0);

      addRawAttr(branch0, 'type', 'checkbox');

      processElement(branch0, options);

      branch0.processed = true; // prevent it from double-processed

      branch0.if = "(" + typeBinding + ")==='checkbox'" + ifConditionExtra;

      addIfCondition(branch0, {

        exp: branch0.if,

        block: branch0

      });

      // 2. add radio else-if condition

      var branch1 = cloneASTElement(el);

      getAndRemoveAttr(branch1, 'v-for', true);

      addRawAttr(branch1, 'type', 'radio');

      processElement(branch1, options);

      addIfCondition(branch0, {

        exp: "(" + typeBinding + ")==='radio'" + ifConditionExtra,

        block: branch1

      });

      // 3. other

      var branch2 = cloneASTElement(el);

      getAndRemoveAttr(branch2, 'v-for', true);

      addRawAttr(branch2, ':type', typeBinding);

      processElement(branch2, options);

      addIfCondition(branch0, {

        exp: ifCondition,

        block: branch2

      });



      if (hasElse) {

        branch0.else = true;

      } else if (elseIfCondition) {

        branch0.elseif = elseIfCondition;

      }



      return branch0

    }

  }

}



function cloneASTElement (el) {

  return createASTElement(el.tag, el.attrsList.slice(), el.parent)

}



var model$2 = {

  preTransformNode: preTransformNode

};



var modules$1 = [

  klass$1,

  style$1,

  model$2

];



/*  */



function text (el, dir) {

  if (dir.value) {

    addProp(el, 'textContent', ("_s(" + (dir.value) + ")"));

  }

}



/*  */



function html (el, dir) {

  if (dir.value) {

    addProp(el, 'innerHTML', ("_s(" + (dir.value) + ")"));

  }

}



var directives$1 = {

  model: model,

  text: text,

  html: html

};



/*  */



var baseOptions = {

  expectHTML: true,

  modules: modules$1,

  directives: directives$1,

  isPreTag: isPreTag,

  isUnaryTag: isUnaryTag,

  mustUseProp: mustUseProp,

  canBeLeftOpenTag: canBeLeftOpenTag,

  isReservedTag: isReservedTag,

  getTagNamespace: getTagNamespace,

  staticKeys: genStaticKeys(modules$1)

};



/*  */



var isStaticKey;

var isPlatformReservedTag;



var genStaticKeysCached = cached(genStaticKeys$1);



/**

 * Goal of the optimizer: walk the generated template AST tree

 * and detect sub-trees that are purely static, i.e. parts of

 * the DOM that never needs to change.

 *

 * Once we detect these sub-trees, we can:

 *

 * 1. Hoist them into constants, so that we no longer need to

 *    create fresh nodes for them on each re-render;

 * 2. Completely skip them in the patching process.

 */

function optimize (root, options) {

  if (!root) { return }

  isStaticKey = genStaticKeysCached(options.staticKeys || '');

  isPlatformReservedTag = options.isReservedTag || no;

  // first pass: mark all non-static nodes.

  markStatic$1(root);

  // second pass: mark static roots.

  markStaticRoots(root, false);

}



function genStaticKeys$1 (keys) {

  return makeMap(

    'type,tag,attrsList,attrsMap,plain,parent,children,attrs' +

    (keys ? ',' + keys : '')

  )

}



function markStatic$1 (node) {

  node.static = isStatic(node);

  if (node.type === 1) {

    // do not make component slot content static. this avoids

    // 1. components not able to mutate slot nodes

    // 2. static slot content fails for hot-reloading

    if (

      !isPlatformReservedTag(node.tag) &&

      node.tag !== 'slot' &&

      node.attrsMap['inline-template'] == null

    ) {

      return

    }

    for (var i = 0, l = node.children.length; i < l; i++) {

      var child = node.children[i];

      markStatic$1(child);

      if (!child.static) {

        node.static = false;

      }

    }

    if (node.ifConditions) {

      for (var i$1 = 1, l$1 = node.ifConditions.length; i$1 < l$1; i$1++) {

        var block = node.ifConditions[i$1].block;

        markStatic$1(block);

        if (!block.static) {

          node.static = false;

        }

      }

    }

  }

}



function markStaticRoots (node, isInFor) {

  if (node.type === 1) {

    if (node.static || node.once) {

      node.staticInFor = isInFor;

    }

    // For a node to qualify as a static root, it should have children that

    // are not just static text. Otherwise the cost of hoisting out will

    // outweigh the benefits and it's better off to just always render it fresh.

    if (node.static && node.children.length && !(

      node.children.length === 1 &&

      node.children[0].type === 3

    )) {

      node.staticRoot = true;

      return

    } else {

      node.staticRoot = false;

    }

    if (node.children) {

      for (var i = 0, l = node.children.length; i < l; i++) {

        markStaticRoots(node.children[i], isInFor || !!node.for);

      }

    }

    if (node.ifConditions) {

      for (var i$1 = 1, l$1 = node.ifConditions.length; i$1 < l$1; i$1++) {

        markStaticRoots(node.ifConditions[i$1].block, isInFor);

      }

    }

  }

}



function isStatic (node) {

  if (node.type === 2) { // expression

    return false

  }

  if (node.type === 3) { // text

    return true

  }

  return !!(node.pre || (

    !node.hasBindings && // no dynamic bindings

    !node.if && !node.for && // not v-if or v-for or v-else

    !isBuiltInTag(node.tag) && // not a built-in

    isPlatformReservedTag(node.tag) && // not a component

    !isDirectChildOfTemplateFor(node) &&

    Object.keys(node).every(isStaticKey)

  ))

}



function isDirectChildOfTemplateFor (node) {

  while (node.parent) {

    node = node.parent;

    if (node.tag !== 'template') {

      return false

    }

    if (node.for) {

      return true

    }

  }

  return false

}



/*  */



var fnExpRE = /^\s*([\w$_]+|\([^)]*?\))\s*=>|^function\s*\(/;

var simplePathRE = /^\s*[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['.*?']|\[".*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*\s*$/;



// keyCode aliases

var keyCodes = {

  esc: 27,

  tab: 9,

  enter: 13,

  space: 32,

  up: 38,

  left: 37,

  right: 39,

  down: 40,

  'delete': [8, 46]

};



// #4868: modifiers that prevent the execution of the listener

// need to explicitly return null so that we can determine whether to remove

// the listener for .once

var genGuard = function (condition) { return ("if(" + condition + ")return null;"); };



var modifierCode = {

  stop: '$event.stopPropagation();',

  prevent: '$event.preventDefault();',

  self: genGuard("$event.target !== $event.currentTarget"),

  ctrl: genGuard("!$event.ctrlKey"),

  shift: genGuard("!$event.shiftKey"),

  alt: genGuard("!$event.altKey"),

  meta: genGuard("!$event.metaKey"),

  left: genGuard("'button' in $event && $event.button !== 0"),

  middle: genGuard("'button' in $event && $event.button !== 1"),

  right: genGuard("'button' in $event && $event.button !== 2")

};



function genHandlers (

  events,

  isNative,

  warn

) {

  var res = isNative ? 'nativeOn:{' : 'on:{';

  for (var name in events) {

    res += "\"" + name + "\":" + (genHandler(name, events[name])) + ",";

  }

  return res.slice(0, -1) + '}'

}



function genHandler (

  name,

  handler

) {

  if (!handler) {

    return 'function(){}'

  }



  if (Array.isArray(handler)) {

    return ("[" + (handler.map(function (handler) { return genHandler(name, handler); }).join(',')) + "]")

  }



  var isMethodPath = simplePathRE.test(handler.value);

  var isFunctionExpression = fnExpRE.test(handler.value);



  if (!handler.modifiers) {

    if (isMethodPath || isFunctionExpression) {

      return handler.value

    }

    /* istanbul ignore if */

    return ("function($event){" + (handler.value) + "}") // inline statement

  } else {

    var code = '';

    var genModifierCode = '';

    var keys = [];

    for (var key in handler.modifiers) {

      if (modifierCode[key]) {

        genModifierCode += modifierCode[key];

        // left/right

        if (keyCodes[key]) {

          keys.push(key);

        }

      } else if (key === 'exact') {

        var modifiers = (handler.modifiers);

        genModifierCode += genGuard(

          ['ctrl', 'shift', 'alt', 'meta']

            .filter(function (keyModifier) { return !modifiers[keyModifier]; })

            .map(function (keyModifier) { return ("$event." + keyModifier + "Key"); })

            .join('||')

        );

      } else {

        keys.push(key);

      }

    }

    if (keys.length) {

      code += genKeyFilter(keys);

    }

    // Make sure modifiers like prevent and stop get executed after key filtering

    if (genModifierCode) {

      code += genModifierCode;

    }

    var handlerCode = isMethodPath

      ? handler.value + '($event)'

      : isFunctionExpression

        ? ("(" + (handler.value) + ")($event)")

        : handler.value;

    /* istanbul ignore if */

    return ("function($event){" + code + handlerCode + "}")

  }

}



function genKeyFilter (keys) {

  return ("if(!('button' in $event)&&" + (keys.map(genFilterCode).join('&&')) + ")return null;")

}



function genFilterCode (key) {

  var keyVal = parseInt(key, 10);

  if (keyVal) {

    return ("$event.keyCode!==" + keyVal)

  }

  var code = keyCodes[key];

  return (

    "_k($event.keyCode," +

    (JSON.stringify(key)) + "," +

    (JSON.stringify(code)) + "," +

    "$event.key)"

  )

}



/*  */



function on (el, dir) {

  if ("development" !== 'production' && dir.modifiers) {

    warn("v-on without argument does not support modifiers.");

  }

  el.wrapListeners = function (code) { return ("_g(" + code + "," + (dir.value) + ")"); };

}



/*  */



function bind$1 (el, dir) {

  el.wrapData = function (code) {

    return ("_b(" + code + ",'" + (el.tag) + "'," + (dir.value) + "," + (dir.modifiers && dir.modifiers.prop ? 'true' : 'false') + (dir.modifiers && dir.modifiers.sync ? ',true' : '') + ")")

  };

}



/*  */



var baseDirectives = {

  on: on,

  bind: bind$1,

  cloak: noop

};



/*  */



var CodegenState = function CodegenState (options) {

  this.options = options;

  this.warn = options.warn || baseWarn;

  this.transforms = pluckModuleFunction(options.modules, 'transformCode');

  this.dataGenFns = pluckModuleFunction(options.modules, 'genData');

  this.directives = extend(extend({}, baseDirectives), options.directives);

  var isReservedTag = options.isReservedTag || no;

  this.maybeComponent = function (el) { return !isReservedTag(el.tag); };

  this.onceId = 0;

  this.staticRenderFns = [];

};







function generate (

  ast,

  options

) {

  var state = new CodegenState(options);

  var code = ast ? genElement(ast, state) : '_c("div")';

  return {

    render: ("with(this){return " + code + "}"),

    staticRenderFns: state.staticRenderFns

  }

}



function genElement (el, state) {

  if (el.staticRoot && !el.staticProcessed) {

    return genStatic(el, state)

  } else if (el.once && !el.onceProcessed) {

    return genOnce(el, state)

  } else if (el.for && !el.forProcessed) {

    return genFor(el, state)

  } else if (el.if && !el.ifProcessed) {

    return genIf(el, state)

  } else if (el.tag === 'template' && !el.slotTarget) {

    return genChildren(el, state) || 'void 0'

  } else if (el.tag === 'slot') {

    return genSlot(el, state)

  } else {

    // component or element

    var code;

    if (el.component) {

      code = genComponent(el.component, el, state);

    } else {

      var data = el.plain ? undefined : genData$2(el, state);



      var children = el.inlineTemplate ? null : genChildren(el, state, true);

      code = "_c('" + (el.tag) + "'" + (data ? ("," + data) : '') + (children ? ("," + children) : '') + ")";

    }

    // module transforms

    for (var i = 0; i < state.transforms.length; i++) {

      code = state.transforms[i](el, code);

    }

    return code

  }

}



// hoist static sub-trees out

function genStatic (el, state) {

  el.staticProcessed = true;

  state.staticRenderFns.push(("with(this){return " + (genElement(el, state)) + "}"));

  return ("_m(" + (state.staticRenderFns.length - 1) + (el.staticInFor ? ',true' : '') + ")")

}



// v-once

function genOnce (el, state) {

  el.onceProcessed = true;

  if (el.if && !el.ifProcessed) {

    return genIf(el, state)

  } else if (el.staticInFor) {

    var key = '';

    var parent = el.parent;

    while (parent) {

      if (parent.for) {

        key = parent.key;

        break

      }

      parent = parent.parent;

    }

    if (!key) {

      "development" !== 'production' && state.warn(

        "v-once can only be used inside v-for that is keyed. "

      );

      return genElement(el, state)

    }

    return ("_o(" + (genElement(el, state)) + "," + (state.onceId++) + "," + key + ")")

  } else {

    return genStatic(el, state)

  }

}



function genIf (

  el,

  state,

  altGen,

  altEmpty

) {

  el.ifProcessed = true; // avoid recursion

  return genIfConditions(el.ifConditions.slice(), state, altGen, altEmpty)

}



function genIfConditions (

  conditions,

  state,

  altGen,

  altEmpty

) {

  if (!conditions.length) {

    return altEmpty || '_e()'

  }



  var condition = conditions.shift();

  if (condition.exp) {

    return ("(" + (condition.exp) + ")?" + (genTernaryExp(condition.block)) + ":" + (genIfConditions(conditions, state, altGen, altEmpty)))

  } else {

    return ("" + (genTernaryExp(condition.block)))

  }



  // v-if with v-once should generate code like (a)?_m(0):_m(1)

  function genTernaryExp (el) {

    return altGen

      ? altGen(el, state)

      : el.once

        ? genOnce(el, state)

        : genElement(el, state)

  }

}



function genFor (

  el,

  state,

  altGen,

  altHelper

) {

  var exp = el.for;

  var alias = el.alias;

  var iterator1 = el.iterator1 ? ("," + (el.iterator1)) : '';

  var iterator2 = el.iterator2 ? ("," + (el.iterator2)) : '';



  if ("development" !== 'production' &&

    state.maybeComponent(el) &&

    el.tag !== 'slot' &&

    el.tag !== 'template' &&

    !el.key

  ) {

    state.warn(

      "<" + (el.tag) + " v-for=\"" + alias + " in " + exp + "\">: component lists rendered with " +

      "v-for should have explicit keys. " +

      "See https://vuejs.org/guide/list.html#key for more info.",

      true /* tip */

    );

  }



  el.forProcessed = true; // avoid recursion

  return (altHelper || '_l') + "((" + exp + ")," +

    "function(" + alias + iterator1 + iterator2 + "){" +

      "return " + ((altGen || genElement)(el, state)) +

    '})'

}



function genData$2 (el, state) {

  var data = '{';



  // directives first.

  // directives may mutate the el's other properties before they are generated.

  var dirs = genDirectives(el, state);

  if (dirs) { data += dirs + ','; }



  // key

  if (el.key) {

    data += "key:" + (el.key) + ",";

  }

  // ref

  if (el.ref) {

    data += "ref:" + (el.ref) + ",";

  }

  if (el.refInFor) {

    data += "refInFor:true,";

  }

  // pre

  if (el.pre) {

    data += "pre:true,";

  }

  // record original tag name for components using "is" attribute

  if (el.component) {

    data += "tag:\"" + (el.tag) + "\",";

  }

  // module data generation functions

  for (var i = 0; i < state.dataGenFns.length; i++) {

    data += state.dataGenFns[i](el);

  }

  // attributes

  if (el.attrs) {

    data += "attrs:{" + (genProps(el.attrs)) + "},";

  }

  // DOM props

  if (el.props) {

    data += "domProps:{" + (genProps(el.props)) + "},";

  }

  // event handlers

  if (el.events) {

    data += (genHandlers(el.events, false, state.warn)) + ",";

  }

  if (el.nativeEvents) {

    data += (genHandlers(el.nativeEvents, true, state.warn)) + ",";

  }

  // slot target

  // only for non-scoped slots

  if (el.slotTarget && !el.slotScope) {

    data += "slot:" + (el.slotTarget) + ",";

  }

  // scoped slots

  if (el.scopedSlots) {

    data += (genScopedSlots(el.scopedSlots, state)) + ",";

  }

  // component v-model

  if (el.model) {

    data += "model:{value:" + (el.model.value) + ",callback:" + (el.model.callback) + ",expression:" + (el.model.expression) + "},";

  }

  // inline-template

  if (el.inlineTemplate) {

    var inlineTemplate = genInlineTemplate(el, state);

    if (inlineTemplate) {

      data += inlineTemplate + ",";

    }

  }

  data = data.replace(/,$/, '') + '}';

  // v-bind data wrap

  if (el.wrapData) {

    data = el.wrapData(data);

  }

  // v-on data wrap

  if (el.wrapListeners) {

    data = el.wrapListeners(data);

  }

  return data

}



function genDirectives (el, state) {

  var dirs = el.directives;

  if (!dirs) { return }

  var res = 'directives:[';

  var hasRuntime = false;

  var i, l, dir, needRuntime;

  for (i = 0, l = dirs.length; i < l; i++) {

    dir = dirs[i];

    needRuntime = true;

    var gen = state.directives[dir.name];

    if (gen) {

      // compile-time directive that manipulates AST.

      // returns true if it also needs a runtime counterpart.

      needRuntime = !!gen(el, dir, state.warn);

    }

    if (needRuntime) {

      hasRuntime = true;

      res += "{name:\"" + (dir.name) + "\",rawName:\"" + (dir.rawName) + "\"" + (dir.value ? (",value:(" + (dir.value) + "),expression:" + (JSON.stringify(dir.value))) : '') + (dir.arg ? (",arg:\"" + (dir.arg) + "\"") : '') + (dir.modifiers ? (",modifiers:" + (JSON.stringify(dir.modifiers))) : '') + "},";

    }

  }

  if (hasRuntime) {

    return res.slice(0, -1) + ']'

  }

}



function genInlineTemplate (el, state) {

  var ast = el.children[0];

  if ("development" !== 'production' && (

    el.children.length !== 1 || ast.type !== 1

  )) {

    state.warn('Inline-template components must have exactly one child element.');

  }

  if (ast.type === 1) {

    var inlineRenderFns = generate(ast, state.options);

    return ("inlineTemplate:{render:function(){" + (inlineRenderFns.render) + "},staticRenderFns:[" + (inlineRenderFns.staticRenderFns.map(function (code) { return ("function(){" + code + "}"); }).join(',')) + "]}")

  }

}



function genScopedSlots (

  slots,

  state

) {

  return ("scopedSlots:_u([" + (Object.keys(slots).map(function (key) {

      return genScopedSlot(key, slots[key], state)

    }).join(',')) + "])")

}



function genScopedSlot (

  key,

  el,

  state

) {

  if (el.for && !el.forProcessed) {

    return genForScopedSlot(key, el, state)

  }

  var fn = "function(" + (String(el.slotScope)) + "){" +

    "return " + (el.tag === 'template'

      ? el.if

        ? ((el.if) + "?" + (genChildren(el, state) || 'undefined') + ":undefined")

        : genChildren(el, state) || 'undefined'

      : genElement(el, state)) + "}";

  return ("{key:" + key + ",fn:" + fn + "}")

}



function genForScopedSlot (

  key,

  el,

  state

) {

  var exp = el.for;

  var alias = el.alias;

  var iterator1 = el.iterator1 ? ("," + (el.iterator1)) : '';

  var iterator2 = el.iterator2 ? ("," + (el.iterator2)) : '';

  el.forProcessed = true; // avoid recursion

  return "_l((" + exp + ")," +

    "function(" + alias + iterator1 + iterator2 + "){" +

      "return " + (genScopedSlot(key, el, state)) +

    '})'

}



function genChildren (

  el,

  state,

  checkSkip,

  altGenElement,

  altGenNode

) {

  var children = el.children;

  if (children.length) {

    var el$1 = children[0];

    // optimize single v-for

    if (children.length === 1 &&

      el$1.for &&

      el$1.tag !== 'template' &&

      el$1.tag !== 'slot'

    ) {

      return (altGenElement || genElement)(el$1, state)

    }

    var normalizationType = checkSkip

      ? getNormalizationType(children, state.maybeComponent)

      : 0;

    var gen = altGenNode || genNode;

    return ("[" + (children.map(function (c) { return gen(c, state); }).join(',')) + "]" + (normalizationType ? ("," + normalizationType) : ''))

  }

}



// determine the normalization needed for the children array.

// 0: no normalization needed

// 1: simple normalization needed (possible 1-level deep nested array)

// 2: full normalization needed

function getNormalizationType (

  children,

  maybeComponent

) {

  var res = 0;

  for (var i = 0; i < children.length; i++) {

    var el = children[i];

    if (el.type !== 1) {

      continue

    }

    if (needsNormalization(el) ||

        (el.ifConditions && el.ifConditions.some(function (c) { return needsNormalization(c.block); }))) {

      res = 2;

      break

    }

    if (maybeComponent(el) ||

        (el.ifConditions && el.ifConditions.some(function (c) { return maybeComponent(c.block); }))) {

      res = 1;

    }

  }

  return res

}



function needsNormalization (el) {

  return el.for !== undefined || el.tag === 'template' || el.tag === 'slot'

}



function genNode (node, state) {

  if (node.type === 1) {

    return genElement(node, state)

  } if (node.type === 3 && node.isComment) {

    return genComment(node)

  } else {

    return genText(node)

  }

}



function genText (text) {

  return ("_v(" + (text.type === 2

    ? text.expression // no need for () because already wrapped in _s()

    : transformSpecialNewlines(JSON.stringify(text.text))) + ")")

}



function genComment (comment) {

  return ("_e(" + (JSON.stringify(comment.text)) + ")")

}



function genSlot (el, state) {

  var slotName = el.slotName || '"default"';

  var children = genChildren(el, state);

  var res = "_t(" + slotName + (children ? ("," + children) : '');

  var attrs = el.attrs && ("{" + (el.attrs.map(function (a) { return ((camelize(a.name)) + ":" + (a.value)); }).join(',')) + "}");

  var bind$$1 = el.attrsMap['v-bind'];

  if ((attrs || bind$$1) && !children) {

    res += ",null";

  }

  if (attrs) {

    res += "," + attrs;

  }

  if (bind$$1) {

    res += (attrs ? '' : ',null') + "," + bind$$1;

  }

  return res + ')'

}



// componentName is el.component, take it as argument to shun flow's pessimistic refinement

function genComponent (

  componentName,

  el,

  state

) {

  var children = el.inlineTemplate ? null : genChildren(el, state, true);

  return ("_c(" + componentName + "," + (genData$2(el, state)) + (children ? ("," + children) : '') + ")")

}



function genProps (props) {

  var res = '';

  for (var i = 0; i < props.length; i++) {

    var prop = props[i];

    /* istanbul ignore if */

    {

      res += "\"" + (prop.name) + "\":" + (transformSpecialNewlines(prop.value)) + ",";

    }

  }

  return res.slice(0, -1)

}



// #3895, #4268

function transformSpecialNewlines (text) {

  return text

    .replace(/\u2028/g, '\\u2028')

    .replace(/\u2029/g, '\\u2029')

}



/*  */



// these keywords should not appear inside expressions, but operators like

// typeof, instanceof and in are allowed

var prohibitedKeywordRE = new RegExp('\\b' + (

  'do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +

  'super,throw,while,yield,delete,export,import,return,switch,default,' +

  'extends,finally,continue,debugger,function,arguments'

).split(',').join('\\b|\\b') + '\\b');



// these unary operators should not be used as property/method names

var unaryOperatorsRE = new RegExp('\\b' + (

  'delete,typeof,void'

).split(',').join('\\s*\\([^\\)]*\\)|\\b') + '\\s*\\([^\\)]*\\)');



// strip strings in expressions

var stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;



// detect problematic expressions in a template

function detectErrors (ast) {

  var errors = [];

  if (ast) {

    checkNode(ast, errors);

  }

  return errors

}



function checkNode (node, errors) {

  if (node.type === 1) {

    for (var name in node.attrsMap) {

      if (dirRE.test(name)) {

        var value = node.attrsMap[name];

        if (value) {

          if (name === 'v-for') {

            checkFor(node, ("v-for=\"" + value + "\""), errors);

          } else if (onRE.test(name)) {

            checkEvent(value, (name + "=\"" + value + "\""), errors);

          } else {

            checkExpression(value, (name + "=\"" + value + "\""), errors);

          }

        }

      }

    }

    if (node.children) {

      for (var i = 0; i < node.children.length; i++) {

        checkNode(node.children[i], errors);

      }

    }

  } else if (node.type === 2) {

    checkExpression(node.expression, node.text, errors);

  }

}



function checkEvent (exp, text, errors) {

  var stipped = exp.replace(stripStringRE, '');

  var keywordMatch = stipped.match(unaryOperatorsRE);

  if (keywordMatch && stipped.charAt(keywordMatch.index - 1) !== '$') {

    errors.push(

      "avoid using JavaScript unary operator as property name: " +

      "\"" + (keywordMatch[0]) + "\" in expression " + (text.trim())

    );

  }

  checkExpression(exp, text, errors);

}



function checkFor (node, text, errors) {

  checkExpression(node.for || '', text, errors);

  checkIdentifier(node.alias, 'v-for alias', text, errors);

  checkIdentifier(node.iterator1, 'v-for iterator', text, errors);

  checkIdentifier(node.iterator2, 'v-for iterator', text, errors);

}



function checkIdentifier (

  ident,

  type,

  text,

  errors

) {

  if (typeof ident === 'string') {

    try {

      new Function(("var " + ident + "=_"));

    } catch (e) {

      errors.push(("invalid " + type + " \"" + ident + "\" in expression: " + (text.trim())));

    }

  }

}



function checkExpression (exp, text, errors) {

  try {

    new Function(("return " + exp));

  } catch (e) {

    var keywordMatch = exp.replace(stripStringRE, '').match(prohibitedKeywordRE);

    if (keywordMatch) {

      errors.push(

        "avoid using JavaScript keyword as property name: " +

        "\"" + (keywordMatch[0]) + "\"\n  Raw expression: " + (text.trim())

      );

    } else {

      errors.push(

        "invalid expression: " + (e.message) + " in\n\n" +

        "    " + exp + "\n\n" +

        "  Raw expression: " + (text.trim()) + "\n"

      );

    }

  }

}



/*  */



function createFunction (code, errors) {

  try {

    return new Function(code)

  } catch (err) {

    errors.push({ err: err, code: code });

    return noop

  }

}



function createCompileToFunctionFn (compile) {

  var cache = Object.create(null);



  return function compileToFunctions (

    template,

    options,

    vm

  ) {

    options = extend({}, options);

    var warn$$1 = options.warn || warn;

    delete options.warn;



    /* istanbul ignore if */

    if (true) {

      // detect possible CSP restriction

      try {

        new Function('return 1');

      } catch (e) {

        if (e.toString().match(/unsafe-eval|CSP/)) {

          warn$$1(

            'It seems you are using the standalone build of Vue.js in an ' +

            'environment with Content Security Policy that prohibits unsafe-eval. ' +

            'The template compiler cannot work in this environment. Consider ' +

            'relaxing the policy to allow unsafe-eval or pre-compiling your ' +

            'templates into render functions.'

          );

        }

      }

    }



    // check cache

    var key = options.delimiters

      ? String(options.delimiters) + template

      : template;

    if (cache[key]) {

      return cache[key]

    }



    // compile

    var compiled = compile(template, options);



    // check compilation errors/tips

    if (true) {

      if (compiled.errors && compiled.errors.length) {

        warn$$1(

          "Error compiling template:\n\n" + template + "\n\n" +

          compiled.errors.map(function (e) { return ("- " + e); }).join('\n') + '\n',

          vm

        );

      }

      if (compiled.tips && compiled.tips.length) {

        compiled.tips.forEach(function (msg) { return tip(msg, vm); });

      }

    }



    // turn code into functions

    var res = {};

    var fnGenErrors = [];

    res.render = createFunction(compiled.render, fnGenErrors);

    res.staticRenderFns = compiled.staticRenderFns.map(function (code) {

      return createFunction(code, fnGenErrors)

    });



    // check function generation errors.

    // this should only happen if there is a bug in the compiler itself.

    // mostly for codegen development use

    /* istanbul ignore if */

    if (true) {

      if ((!compiled.errors || !compiled.errors.length) && fnGenErrors.length) {

        warn$$1(

          "Failed to generate render function:\n\n" +

          fnGenErrors.map(function (ref) {

            var err = ref.err;

            var code = ref.code;



            return ((err.toString()) + " in\n\n" + code + "\n");

        }).join('\n'),

          vm

        );

      }

    }



    return (cache[key] = res)

  }

}



/*  */



function createCompilerCreator (baseCompile) {

  return function createCompiler (baseOptions) {

    function compile (

      template,

      options

    ) {

      var finalOptions = Object.create(baseOptions);

      var errors = [];

      var tips = [];

      finalOptions.warn = function (msg, tip) {

        (tip ? tips : errors).push(msg);

      };



      if (options) {

        // merge custom modules

        if (options.modules) {

          finalOptions.modules =

            (baseOptions.modules || []).concat(options.modules);

        }

        // merge custom directives

        if (options.directives) {

          finalOptions.directives = extend(

            Object.create(baseOptions.directives || null),

            options.directives

          );

        }

        // copy other options

        for (var key in options) {

          if (key !== 'modules' && key !== 'directives') {

            finalOptions[key] = options[key];

          }

        }

      }



      var compiled = baseCompile(template, finalOptions);

      if (true) {

        errors.push.apply(errors, detectErrors(compiled.ast));

      }

      compiled.errors = errors;

      compiled.tips = tips;

      return compiled

    }



    return {

      compile: compile,

      compileToFunctions: createCompileToFunctionFn(compile)

    }

  }

}



/*  */



// `createCompilerCreator` allows creating compilers that use alternative

// parser/optimizer/codegen, e.g the SSR optimizing compiler.

// Here we just export a default compiler using the default parts.

var createCompiler = createCompilerCreator(function baseCompile (

  template,

  options

) {

  var ast = parse(template.trim(), options);

  if (options.optimize !== false) {

    optimize(ast, options);

  }

  var code = generate(ast, options);

  return {

    ast: ast,

    render: code.render,

    staticRenderFns: code.staticRenderFns

  }

});



/*  */



var ref$1 = createCompiler(baseOptions);

var compileToFunctions = ref$1.compileToFunctions;



/*  */



// check whether current browser encodes a char inside attribute values

var div;

function getShouldDecode (href) {

  div = div || document.createElement('div');

  div.innerHTML = href ? "<a href=\"\n\"/>" : "<div a=\"\n\"/>";

  return div.innerHTML.indexOf('&#10;') > 0

}



// #3663: IE encodes newlines inside attribute values while other browsers don't

var shouldDecodeNewlines = inBrowser ? getShouldDecode(false) : false;

// #6828: chrome encodes content in a[href]

var shouldDecodeNewlinesForHref = inBrowser ? getShouldDecode(true) : false;



/*  */



var idToTemplate = cached(function (id) {

  var el = query(id);

  return el && el.innerHTML

});



var mount = Vue$3.prototype.$mount;

Vue$3.prototype.$mount = function (

  el,

  hydrating

) {

  el = el && query(el);



  /* istanbul ignore if */

  if (el === document.body || el === document.documentElement) {

    "development" !== 'production' && warn(

      "Do not mount Vue to <html> or <body> - mount to normal elements instead."

    );

    return this

  }



  var options = this.$options;

  // resolve template/el and convert to render function

  if (!options.render) {

    var template = options.template;

    if (template) {

      if (typeof template === 'string') {

        if (template.charAt(0) === '#') {

          template = idToTemplate(template);

          /* istanbul ignore if */

          if ("development" !== 'production' && !template) {

            warn(

              ("Template element not found or is empty: " + (options.template)),

              this

            );

          }

        }

      } else if (template.nodeType) {

        template = template.innerHTML;

      } else {

        if (true) {

          warn('invalid template option:' + template, this);

        }

        return this

      }

    } else if (el) {

      template = getOuterHTML(el);

    }

    if (template) {

      /* istanbul ignore if */

      if ("development" !== 'production' && config.performance && mark) {

        mark('compile');

      }



      var ref = compileToFunctions(template, {

        shouldDecodeNewlines: shouldDecodeNewlines,

        shouldDecodeNewlinesForHref: shouldDecodeNewlinesForHref,

        delimiters: options.delimiters,

        comments: options.comments

      }, this);

      var render = ref.render;

      var staticRenderFns = ref.staticRenderFns;

      options.render = render;

      options.staticRenderFns = staticRenderFns;



      /* istanbul ignore if */

      if ("development" !== 'production' && config.performance && mark) {

        mark('compile end');

        measure(("vue " + (this._name) + " compile"), 'compile', 'compile end');

      }

    }

  }

  return mount.call(this, el, hydrating)

};



/**

 * Get outerHTML of elements, taking care

 * of SVG elements in IE as well.

 */

function getOuterHTML (el) {

  if (el.outerHTML) {

    return el.outerHTML

  } else {

    var container = document.createElement('div');

    container.appendChild(el.cloneNode(true));

    return container.innerHTML

  }

}



Vue$3.compile = compileToFunctions;



module.exports = Vue$3;



/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1), __webpack_require__(37).setImmediate))



/***/ }),

/* 37 */

/***/ (function(module, exports, __webpack_require__) {



var apply = Function.prototype.apply;



// DOM APIs, for completeness



exports.setTimeout = function() {

  return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);

};

exports.setInterval = function() {

  return new Timeout(apply.call(setInterval, window, arguments), clearInterval);

};

exports.clearTimeout =

exports.clearInterval = function(timeout) {

  if (timeout) {

    timeout.close();

  }

};



function Timeout(id, clearFn) {

  this._id = id;

  this._clearFn = clearFn;

}

Timeout.prototype.unref = Timeout.prototype.ref = function() {};

Timeout.prototype.close = function() {

  this._clearFn.call(window, this._id);

};



// Does not start the time, just sets up the members needed.

exports.enroll = function(item, msecs) {

  clearTimeout(item._idleTimeoutId);

  item._idleTimeout = msecs;

};



exports.unenroll = function(item) {

  clearTimeout(item._idleTimeoutId);

  item._idleTimeout = -1;

};



exports._unrefActive = exports.active = function(item) {

  clearTimeout(item._idleTimeoutId);



  var msecs = item._idleTimeout;

  if (msecs >= 0) {

    item._idleTimeoutId = setTimeout(function onTimeout() {

      if (item._onTimeout)

        item._onTimeout();

    }, msecs);

  }

};



// setimmediate attaches itself to the global object

__webpack_require__(38);

exports.setImmediate = setImmediate;

exports.clearImmediate = clearImmediate;





/***/ }),

/* 38 */

/***/ (function(module, exports, __webpack_require__) {



/* WEBPACK VAR INJECTION */(function(global, process) {(function (global, undefined) {

    "use strict";



    if (global.setImmediate) {

        return;

    }



    var nextHandle = 1; // Spec says greater than zero

    var tasksByHandle = {};

    var currentlyRunningATask = false;

    var doc = global.document;

    var registerImmediate;



    function setImmediate(callback) {

      // Callback can either be a function or a string

      if (typeof callback !== "function") {

        callback = new Function("" + callback);

      }

      // Copy function arguments

      var args = new Array(arguments.length - 1);

      for (var i = 0; i < args.length; i++) {

          args[i] = arguments[i + 1];

      }

      // Store and register the task

      var task = { callback: callback, args: args };

      tasksByHandle[nextHandle] = task;

      registerImmediate(nextHandle);

      return nextHandle++;

    }



    function clearImmediate(handle) {

        delete tasksByHandle[handle];

    }



    function run(task) {

        var callback = task.callback;

        var args = task.args;

        switch (args.length) {

        case 0:

            callback();

            break;

        case 1:

            callback(args[0]);

            break;

        case 2:

            callback(args[0], args[1]);

            break;

        case 3:

            callback(args[0], args[1], args[2]);

            break;

        default:

            callback.apply(undefined, args);

            break;

        }

    }



    function runIfPresent(handle) {

        // From the spec: "Wait until any invocations of this algorithm started before this one have completed."

        // So if we're currently running a task, we'll need to delay this invocation.

        if (currentlyRunningATask) {

            // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a

            // "too much recursion" error.

            setTimeout(runIfPresent, 0, handle);

        } else {

            var task = tasksByHandle[handle];

            if (task) {

                currentlyRunningATask = true;

                try {

                    run(task);

                } finally {

                    clearImmediate(handle);

                    currentlyRunningATask = false;

                }

            }

        }

    }



    function installNextTickImplementation() {

        registerImmediate = function(handle) {

            process.nextTick(function () { runIfPresent(handle); });

        };

    }



    function canUsePostMessage() {

        // The test against `importScripts` prevents this implementation from being installed inside a web worker,

        // where `global.postMessage` means something completely different and can't be used for this purpose.

        if (global.postMessage && !global.importScripts) {

            var postMessageIsAsynchronous = true;

            var oldOnMessage = global.onmessage;

            global.onmessage = function() {

                postMessageIsAsynchronous = false;

            };

            global.postMessage("", "*");

            global.onmessage = oldOnMessage;

            return postMessageIsAsynchronous;

        }

    }



    function installPostMessageImplementation() {

        // Installs an event handler on `global` for the `message` event: see

        // * https://developer.mozilla.org/en/DOM/window.postMessage

        // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages



        var messagePrefix = "setImmediate$" + Math.random() + "$";

        var onGlobalMessage = function(event) {

            if (event.source === global &&

                typeof event.data === "string" &&

                event.data.indexOf(messagePrefix) === 0) {

                runIfPresent(+event.data.slice(messagePrefix.length));

            }

        };



        if (global.addEventListener) {

            global.addEventListener("message", onGlobalMessage, false);

        } else {

            global.attachEvent("onmessage", onGlobalMessage);

        }



        registerImmediate = function(handle) {

            global.postMessage(messagePrefix + handle, "*");

        };

    }



    function installMessageChannelImplementation() {

        var channel = new MessageChannel();

        channel.port1.onmessage = function(event) {

            var handle = event.data;

            runIfPresent(handle);

        };



        registerImmediate = function(handle) {

            channel.port2.postMessage(handle);

        };

    }



    function installReadyStateChangeImplementation() {

        var html = doc.documentElement;

        registerImmediate = function(handle) {

            // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted

            // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.

            var script = doc.createElement("script");

            script.onreadystatechange = function () {

                runIfPresent(handle);

                script.onreadystatechange = null;

                html.removeChild(script);

                script = null;

            };

            html.appendChild(script);

        };

    }



    function installSetTimeoutImplementation() {

        registerImmediate = function(handle) {

            setTimeout(runIfPresent, 0, handle);

        };

    }



    // If supported, we should attach to the prototype of global, since that is where setTimeout et al. live.

    var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global);

    attachTo = attachTo && attachTo.setTimeout ? attachTo : global;



    // Don't get fooled by e.g. browserify environments.

    if ({}.toString.call(global.process) === "[object process]") {

        // For Node.js before 0.9

        installNextTickImplementation();



    } else if (canUsePostMessage()) {

        // For non-IE10 modern browsers

        installPostMessageImplementation();



    } else if (global.MessageChannel) {

        // For web workers, where supported

        installMessageChannelImplementation();



    } else if (doc && "onreadystatechange" in doc.createElement("script")) {

        // For IE 6–8

        installReadyStateChangeImplementation();



    } else {

        // For older browsers

        installSetTimeoutImplementation();

    }



    attachTo.setImmediate = setImmediate;

    attachTo.clearImmediate = clearImmediate;

}(typeof self === "undefined" ? typeof global === "undefined" ? this : global : self));



/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1), __webpack_require__(6)))



/***/ }),

/* 39 */

/***/ (function(module, exports) {



// removed by extract-text-webpack-plugin



/***/ }),

/* 40 */

/***/ (function(module, exports) {



// removed by extract-text-webpack-plugin



/***/ }),

/* 41 */

/***/ (function(module, exports) {



// removed by extract-text-webpack-plugin



/***/ })

/******/ ]);

Anon7 - 2022
SCDN GOK