(function webpackUniversalModuleDefinition(root, factory) {
	if(typeof exports === 'object' && typeof module === 'object')
		module.exports = factory();
	else if(typeof define === 'function' && define.amd)
		define([], factory);
	else if(typeof exports === 'object')
		exports["SimpleYoutubeAPI"] = factory();
	else
		root["SimpleYoutubeAPI"] = factory();
})(window, function() {
return /******/ (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, { enumerable: true, get: getter });
/******/ 		}
/******/ 	};
/******/
/******/ 	// define __esModule on exports
/******/ 	__webpack_require__.r = function(exports) {
/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 		}
/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
/******/ 	};
/******/
/******/ 	// create a fake namespace object
/******/ 	// mode & 1: value is a module id, require it
/******/ 	// mode & 2: merge all properties of value into the ns
/******/ 	// mode & 4: return value when already ns object
/******/ 	// mode & 8|1: behave like require
/******/ 	__webpack_require__.t = function(value, mode) {
/******/ 		if(mode & 1) value = __webpack_require__(value);
/******/ 		if(mode & 8) return value;
/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ 		var ns = Object.create(null);
/******/ 		__webpack_require__.r(ns);
/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ 		return ns;
/******/ 	};
/******/
/******/ 	// 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 = "./src/index.js");
/******/ })
/************************************************************************/
/******/ ({

/***/ "./node_modules/iso8601-duration/lib/index.js":
/*!****************************************************!*\
  !*** ./node_modules/iso8601-duration/lib/index.js ***!
  \****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\n/**\n * @description A module for parsing ISO8601 durations\n */\n\n/**\n * The pattern used for parsing ISO8601 duration (PnYnMnDTnHnMnS).\n * This does not cover the week format PnW.\n */\n\n// PnYnMnDTnHnMnS\nvar numbers = '\\\\d+(?:[\\\\.,]\\\\d{0,3})?';\nvar weekPattern = '(' + numbers + 'W)';\nvar datePattern = '(' + numbers + 'Y)?(' + numbers + 'M)?(' + numbers + 'D)?';\nvar timePattern = 'T(' + numbers + 'H)?(' + numbers + 'M)?(' + numbers + 'S)?';\n\nvar iso8601 = 'P(?:' + weekPattern + '|' + datePattern + '(?:' + timePattern + ')?)';\nvar objMap = ['weeks', 'years', 'months', 'days', 'hours', 'minutes', 'seconds'];\n\n/**\n * The ISO8601 regex for matching / testing durations\n */\nvar pattern = exports.pattern = new RegExp(iso8601);\n\n/** Parse PnYnMnDTnHnMnS format to object\n * @param {string} durationString - PnYnMnDTnHnMnS formatted string\n * @return {Object} - With a property for each part of the pattern\n */\nvar parse = exports.parse = function parse(durationString) {\n\t// slice away first entry in match-array\n\treturn durationString.match(pattern).slice(1).reduce(function (prev, next, idx) {\n\t\tprev[objMap[idx]] = parseFloat(next) || 0;\n\t\treturn prev;\n\t}, {});\n};\n\n/**\n * Convert ISO8601 duration object to an end Date.\n *\n * @param {Object} duration - The duration object\n * @param {Date} startDate - The starting Date for calculating the duration\n * @return {Date} - The resulting end Date\n */\nvar end = exports.end = function end(duration, startDate) {\n\t// create two equal timestamps, add duration to 'then' and return time difference\n\tvar timestamp = startDate ? startDate.getTime() : Date.now();\n\tvar then = new Date(timestamp);\n\n\tthen.setFullYear(then.getFullYear() + duration.years);\n\tthen.setMonth(then.getMonth() + duration.months);\n\tthen.setDate(then.getDate() + duration.days);\n\tthen.setHours(then.getHours() + duration.hours);\n\tthen.setMinutes(then.getMinutes() + duration.minutes);\n\t// then.setSeconds(then.getSeconds() + duration.seconds);\n\tthen.setMilliseconds(then.getMilliseconds() + duration.seconds * 1000);\n\t// special case weeks\n\tthen.setDate(then.getDate() + duration.weeks * 7);\n\n\treturn then;\n};\n\n/**\n * Convert ISO8601 duration object to seconds\n *\n * @param {Object} duration - The duration object\n * @param {Date} startDate - The starting point for calculating the duration\n * @return {Number}\n */\nvar toSeconds = exports.toSeconds = function toSeconds(duration, startDate) {\n\tvar timestamp = startDate ? startDate.getTime() : Date.now();\n\tvar now = new Date(timestamp);\n\tvar then = end(duration, startDate);\n\n\tvar seconds = (then.getTime() - now.getTime()) / 1000;\n\treturn seconds;\n};\n\nexports.default = {\n\tend: end,\n\ttoSeconds: toSeconds,\n\tpattern: pattern,\n\tparse: parse\n};\n\n//# sourceURL=webpack://SimpleYoutubeAPI/./node_modules/iso8601-duration/lib/index.js?");

/***/ }),

/***/ "./node_modules/node-fetch/browser.js":
/*!********************************************!*\
  !*** ./node_modules/node-fetch/browser.js ***!
  \********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
eval("\n\nmodule.exports = exports = self.fetch;\n\n// Needed for TypeScript and Webpack.\nexports.default = self.fetch.bind(self);\n\nexports.Headers = self.Headers;\nexports.Request = self.Request;\nexports.Response = self.Response;\n\n\n//# sourceURL=webpack://SimpleYoutubeAPI/./node_modules/node-fetch/browser.js?");

/***/ }),

/***/ "./node_modules/node-libs-browser/node_modules/punycode/punycode.js":
/*!**************************************************************************!*\
  !*** ./node_modules/node-libs-browser/node_modules/punycode/punycode.js ***!
  \**************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

eval("/* WEBPACK VAR INJECTION */(function(module, global) {var __WEBPACK_AMD_DEFINE_RESULT__;/*! https://mths.be/punycode v1.4.1 by @mathias */\n;(function(root) {\n\n\t/** Detect free variables */\n\tvar freeExports =  true && exports &&\n\t\t!exports.nodeType && exports;\n\tvar freeModule =  true && module &&\n\t\t!module.nodeType && module;\n\tvar freeGlobal = typeof global == 'object' && global;\n\tif (\n\t\tfreeGlobal.global === freeGlobal ||\n\t\tfreeGlobal.window === freeGlobal ||\n\t\tfreeGlobal.self === freeGlobal\n\t) {\n\t\troot = freeGlobal;\n\t}\n\n\t/**\n\t * The `punycode` object.\n\t * @name punycode\n\t * @type Object\n\t */\n\tvar punycode,\n\n\t/** Highest positive signed 32-bit float value */\n\tmaxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1\n\n\t/** Bootstring parameters */\n\tbase = 36,\n\ttMin = 1,\n\ttMax = 26,\n\tskew = 38,\n\tdamp = 700,\n\tinitialBias = 72,\n\tinitialN = 128, // 0x80\n\tdelimiter = '-', // '\\x2D'\n\n\t/** Regular expressions */\n\tregexPunycode = /^xn--/,\n\tregexNonASCII = /[^\\x20-\\x7E]/, // unprintable ASCII chars + non-ASCII chars\n\tregexSeparators = /[\\x2E\\u3002\\uFF0E\\uFF61]/g, // RFC 3490 separators\n\n\t/** Error messages */\n\terrors = {\n\t\t'overflow': 'Overflow: input needs wider integers to process',\n\t\t'not-basic': 'Illegal input >= 0x80 (not a basic code point)',\n\t\t'invalid-input': 'Invalid input'\n\t},\n\n\t/** Convenience shortcuts */\n\tbaseMinusTMin = base - tMin,\n\tfloor = Math.floor,\n\tstringFromCharCode = String.fromCharCode,\n\n\t/** Temporary variable */\n\tkey;\n\n\t/*--------------------------------------------------------------------------*/\n\n\t/**\n\t * A generic error utility function.\n\t * @private\n\t * @param {String} type The error type.\n\t * @returns {Error} Throws a `RangeError` with the applicable error message.\n\t */\n\tfunction error(type) {\n\t\tthrow new RangeError(errors[type]);\n\t}\n\n\t/**\n\t * A generic `Array#map` utility function.\n\t * @private\n\t * @param {Array} array The array to iterate over.\n\t * @param {Function} callback The function that gets called for every array\n\t * item.\n\t * @returns {Array} A new array of values returned by the callback function.\n\t */\n\tfunction map(array, fn) {\n\t\tvar length = array.length;\n\t\tvar result = [];\n\t\twhile (length--) {\n\t\t\tresult[length] = fn(array[length]);\n\t\t}\n\t\treturn result;\n\t}\n\n\t/**\n\t * A simple `Array#map`-like wrapper to work with domain name strings or email\n\t * addresses.\n\t * @private\n\t * @param {String} domain The domain name or email address.\n\t * @param {Function} callback The function that gets called for every\n\t * character.\n\t * @returns {Array} A new string of characters returned by the callback\n\t * function.\n\t */\n\tfunction mapDomain(string, fn) {\n\t\tvar parts = string.split('@');\n\t\tvar result = '';\n\t\tif (parts.length > 1) {\n\t\t\t// In email addresses, only the domain name should be punycoded. Leave\n\t\t\t// the local part (i.e. everything up to `@`) intact.\n\t\t\tresult = parts[0] + '@';\n\t\t\tstring = parts[1];\n\t\t}\n\t\t// Avoid `split(regex)` for IE8 compatibility. See #17.\n\t\tstring = string.replace(regexSeparators, '\\x2E');\n\t\tvar labels = string.split('.');\n\t\tvar encoded = map(labels, fn).join('.');\n\t\treturn result + encoded;\n\t}\n\n\t/**\n\t * Creates an array containing the numeric code points of each Unicode\n\t * character in the string. While JavaScript uses UCS-2 internally,\n\t * this function will convert a pair of surrogate halves (each of which\n\t * UCS-2 exposes as separate characters) into a single code point,\n\t * matching UTF-16.\n\t * @see `punycode.ucs2.encode`\n\t * @see <https://mathiasbynens.be/notes/javascript-encoding>\n\t * @memberOf punycode.ucs2\n\t * @name decode\n\t * @param {String} string The Unicode input string (UCS-2).\n\t * @returns {Array} The new array of code points.\n\t */\n\tfunction ucs2decode(string) {\n\t\tvar output = [],\n\t\t    counter = 0,\n\t\t    length = string.length,\n\t\t    value,\n\t\t    extra;\n\t\twhile (counter < length) {\n\t\t\tvalue = string.charCodeAt(counter++);\n\t\t\tif (value >= 0xD800 && value <= 0xDBFF && counter < length) {\n\t\t\t\t// high surrogate, and there is a next character\n\t\t\t\textra = string.charCodeAt(counter++);\n\t\t\t\tif ((extra & 0xFC00) == 0xDC00) { // low surrogate\n\t\t\t\t\toutput.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);\n\t\t\t\t} else {\n\t\t\t\t\t// unmatched surrogate; only append this code unit, in case the next\n\t\t\t\t\t// code unit is the high surrogate of a surrogate pair\n\t\t\t\t\toutput.push(value);\n\t\t\t\t\tcounter--;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\toutput.push(value);\n\t\t\t}\n\t\t}\n\t\treturn output;\n\t}\n\n\t/**\n\t * Creates a string based on an array of numeric code points.\n\t * @see `punycode.ucs2.decode`\n\t * @memberOf punycode.ucs2\n\t * @name encode\n\t * @param {Array} codePoints The array of numeric code points.\n\t * @returns {String} The new Unicode string (UCS-2).\n\t */\n\tfunction ucs2encode(array) {\n\t\treturn map(array, function(value) {\n\t\t\tvar output = '';\n\t\t\tif (value > 0xFFFF) {\n\t\t\t\tvalue -= 0x10000;\n\t\t\t\toutput += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);\n\t\t\t\tvalue = 0xDC00 | value & 0x3FF;\n\t\t\t}\n\t\t\toutput += stringFromCharCode(value);\n\t\t\treturn output;\n\t\t}).join('');\n\t}\n\n\t/**\n\t * Converts a basic code point into a digit/integer.\n\t * @see `digitToBasic()`\n\t * @private\n\t * @param {Number} codePoint The basic numeric code point value.\n\t * @returns {Number} The numeric value of a basic code point (for use in\n\t * representing integers) in the range `0` to `base - 1`, or `base` if\n\t * the code point does not represent a value.\n\t */\n\tfunction basicToDigit(codePoint) {\n\t\tif (codePoint - 48 < 10) {\n\t\t\treturn codePoint - 22;\n\t\t}\n\t\tif (codePoint - 65 < 26) {\n\t\t\treturn codePoint - 65;\n\t\t}\n\t\tif (codePoint - 97 < 26) {\n\t\t\treturn codePoint - 97;\n\t\t}\n\t\treturn base;\n\t}\n\n\t/**\n\t * Converts a digit/integer into a basic code point.\n\t * @see `basicToDigit()`\n\t * @private\n\t * @param {Number} digit The numeric value of a basic code point.\n\t * @returns {Number} The basic code point whose value (when used for\n\t * representing integers) is `digit`, which needs to be in the range\n\t * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is\n\t * used; else, the lowercase form is used. The behavior is undefined\n\t * if `flag` is non-zero and `digit` has no uppercase form.\n\t */\n\tfunction digitToBasic(digit, flag) {\n\t\t//  0..25 map to ASCII a..z or A..Z\n\t\t// 26..35 map to ASCII 0..9\n\t\treturn digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);\n\t}\n\n\t/**\n\t * Bias adaptation function as per section 3.4 of RFC 3492.\n\t * https://tools.ietf.org/html/rfc3492#section-3.4\n\t * @private\n\t */\n\tfunction adapt(delta, numPoints, firstTime) {\n\t\tvar k = 0;\n\t\tdelta = firstTime ? floor(delta / damp) : delta >> 1;\n\t\tdelta += floor(delta / numPoints);\n\t\tfor (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {\n\t\t\tdelta = floor(delta / baseMinusTMin);\n\t\t}\n\t\treturn floor(k + (baseMinusTMin + 1) * delta / (delta + skew));\n\t}\n\n\t/**\n\t * Converts a Punycode string of ASCII-only symbols to a string of Unicode\n\t * symbols.\n\t * @memberOf punycode\n\t * @param {String} input The Punycode string of ASCII-only symbols.\n\t * @returns {String} The resulting string of Unicode symbols.\n\t */\n\tfunction decode(input) {\n\t\t// Don't use UCS-2\n\t\tvar output = [],\n\t\t    inputLength = input.length,\n\t\t    out,\n\t\t    i = 0,\n\t\t    n = initialN,\n\t\t    bias = initialBias,\n\t\t    basic,\n\t\t    j,\n\t\t    index,\n\t\t    oldi,\n\t\t    w,\n\t\t    k,\n\t\t    digit,\n\t\t    t,\n\t\t    /** Cached calculation results */\n\t\t    baseMinusT;\n\n\t\t// Handle the basic code points: let `basic` be the number of input code\n\t\t// points before the last delimiter, or `0` if there is none, then copy\n\t\t// the first basic code points to the output.\n\n\t\tbasic = input.lastIndexOf(delimiter);\n\t\tif (basic < 0) {\n\t\t\tbasic = 0;\n\t\t}\n\n\t\tfor (j = 0; j < basic; ++j) {\n\t\t\t// if it's not a basic code point\n\t\t\tif (input.charCodeAt(j) >= 0x80) {\n\t\t\t\terror('not-basic');\n\t\t\t}\n\t\t\toutput.push(input.charCodeAt(j));\n\t\t}\n\n\t\t// Main decoding loop: start just after the last delimiter if any basic code\n\t\t// points were copied; start at the beginning otherwise.\n\n\t\tfor (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {\n\n\t\t\t// `index` is the index of the next character to be consumed.\n\t\t\t// Decode a generalized variable-length integer into `delta`,\n\t\t\t// which gets added to `i`. The overflow checking is easier\n\t\t\t// if we increase `i` as we go, then subtract off its starting\n\t\t\t// value at the end to obtain `delta`.\n\t\t\tfor (oldi = i, w = 1, k = base; /* no condition */; k += base) {\n\n\t\t\t\tif (index >= inputLength) {\n\t\t\t\t\terror('invalid-input');\n\t\t\t\t}\n\n\t\t\t\tdigit = basicToDigit(input.charCodeAt(index++));\n\n\t\t\t\tif (digit >= base || digit > floor((maxInt - i) / w)) {\n\t\t\t\t\terror('overflow');\n\t\t\t\t}\n\n\t\t\t\ti += digit * w;\n\t\t\t\tt = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);\n\n\t\t\t\tif (digit < t) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tbaseMinusT = base - t;\n\t\t\t\tif (w > floor(maxInt / baseMinusT)) {\n\t\t\t\t\terror('overflow');\n\t\t\t\t}\n\n\t\t\t\tw *= baseMinusT;\n\n\t\t\t}\n\n\t\t\tout = output.length + 1;\n\t\t\tbias = adapt(i - oldi, out, oldi == 0);\n\n\t\t\t// `i` was supposed to wrap around from `out` to `0`,\n\t\t\t// incrementing `n` each time, so we'll fix that now:\n\t\t\tif (floor(i / out) > maxInt - n) {\n\t\t\t\terror('overflow');\n\t\t\t}\n\n\t\t\tn += floor(i / out);\n\t\t\ti %= out;\n\n\t\t\t// Insert `n` at position `i` of the output\n\t\t\toutput.splice(i++, 0, n);\n\n\t\t}\n\n\t\treturn ucs2encode(output);\n\t}\n\n\t/**\n\t * Converts a string of Unicode symbols (e.g. a domain name label) to a\n\t * Punycode string of ASCII-only symbols.\n\t * @memberOf punycode\n\t * @param {String} input The string of Unicode symbols.\n\t * @returns {String} The resulting Punycode string of ASCII-only symbols.\n\t */\n\tfunction encode(input) {\n\t\tvar n,\n\t\t    delta,\n\t\t    handledCPCount,\n\t\t    basicLength,\n\t\t    bias,\n\t\t    j,\n\t\t    m,\n\t\t    q,\n\t\t    k,\n\t\t    t,\n\t\t    currentValue,\n\t\t    output = [],\n\t\t    /** `inputLength` will hold the number of code points in `input`. */\n\t\t    inputLength,\n\t\t    /** Cached calculation results */\n\t\t    handledCPCountPlusOne,\n\t\t    baseMinusT,\n\t\t    qMinusT;\n\n\t\t// Convert the input in UCS-2 to Unicode\n\t\tinput = ucs2decode(input);\n\n\t\t// Cache the length\n\t\tinputLength = input.length;\n\n\t\t// Initialize the state\n\t\tn = initialN;\n\t\tdelta = 0;\n\t\tbias = initialBias;\n\n\t\t// Handle the basic code points\n\t\tfor (j = 0; j < inputLength; ++j) {\n\t\t\tcurrentValue = input[j];\n\t\t\tif (currentValue < 0x80) {\n\t\t\t\toutput.push(stringFromCharCode(currentValue));\n\t\t\t}\n\t\t}\n\n\t\thandledCPCount = basicLength = output.length;\n\n\t\t// `handledCPCount` is the number of code points that have been handled;\n\t\t// `basicLength` is the number of basic code points.\n\n\t\t// Finish the basic string - if it is not empty - with a delimiter\n\t\tif (basicLength) {\n\t\t\toutput.push(delimiter);\n\t\t}\n\n\t\t// Main encoding loop:\n\t\twhile (handledCPCount < inputLength) {\n\n\t\t\t// All non-basic code points < n have been handled already. Find the next\n\t\t\t// larger one:\n\t\t\tfor (m = maxInt, j = 0; j < inputLength; ++j) {\n\t\t\t\tcurrentValue = input[j];\n\t\t\t\tif (currentValue >= n && currentValue < m) {\n\t\t\t\t\tm = currentValue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,\n\t\t\t// but guard against overflow\n\t\t\thandledCPCountPlusOne = handledCPCount + 1;\n\t\t\tif (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {\n\t\t\t\terror('overflow');\n\t\t\t}\n\n\t\t\tdelta += (m - n) * handledCPCountPlusOne;\n\t\t\tn = m;\n\n\t\t\tfor (j = 0; j < inputLength; ++j) {\n\t\t\t\tcurrentValue = input[j];\n\n\t\t\t\tif (currentValue < n && ++delta > maxInt) {\n\t\t\t\t\terror('overflow');\n\t\t\t\t}\n\n\t\t\t\tif (currentValue == n) {\n\t\t\t\t\t// Represent delta as a generalized variable-length integer\n\t\t\t\t\tfor (q = delta, k = base; /* no condition */; k += base) {\n\t\t\t\t\t\tt = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);\n\t\t\t\t\t\tif (q < t) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tqMinusT = q - t;\n\t\t\t\t\t\tbaseMinusT = base - t;\n\t\t\t\t\t\toutput.push(\n\t\t\t\t\t\t\tstringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))\n\t\t\t\t\t\t);\n\t\t\t\t\t\tq = floor(qMinusT / baseMinusT);\n\t\t\t\t\t}\n\n\t\t\t\t\toutput.push(stringFromCharCode(digitToBasic(q, 0)));\n\t\t\t\t\tbias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);\n\t\t\t\t\tdelta = 0;\n\t\t\t\t\t++handledCPCount;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t++delta;\n\t\t\t++n;\n\n\t\t}\n\t\treturn output.join('');\n\t}\n\n\t/**\n\t * Converts a Punycode string representing a domain name or an email address\n\t * to Unicode. Only the Punycoded parts of the input will be converted, i.e.\n\t * it doesn't matter if you call it on a string that has already been\n\t * converted to Unicode.\n\t * @memberOf punycode\n\t * @param {String} input The Punycoded domain name or email address to\n\t * convert to Unicode.\n\t * @returns {String} The Unicode representation of the given Punycode\n\t * string.\n\t */\n\tfunction toUnicode(input) {\n\t\treturn mapDomain(input, function(string) {\n\t\t\treturn regexPunycode.test(string)\n\t\t\t\t? decode(string.slice(4).toLowerCase())\n\t\t\t\t: string;\n\t\t});\n\t}\n\n\t/**\n\t * Converts a Unicode string representing a domain name or an email address to\n\t * Punycode. Only the non-ASCII parts of the domain name will be converted,\n\t * i.e. it doesn't matter if you call it with a domain that's already in\n\t * ASCII.\n\t * @memberOf punycode\n\t * @param {String} input The domain name or email address to convert, as a\n\t * Unicode string.\n\t * @returns {String} The Punycode representation of the given domain name or\n\t * email address.\n\t */\n\tfunction toASCII(input) {\n\t\treturn mapDomain(input, function(string) {\n\t\t\treturn regexNonASCII.test(string)\n\t\t\t\t? 'xn--' + encode(string)\n\t\t\t\t: string;\n\t\t});\n\t}\n\n\t/*--------------------------------------------------------------------------*/\n\n\t/** Define the public API */\n\tpunycode = {\n\t\t/**\n\t\t * A string representing the current Punycode.js version number.\n\t\t * @memberOf punycode\n\t\t * @type String\n\t\t */\n\t\t'version': '1.4.1',\n\t\t/**\n\t\t * An object of methods to convert from JavaScript's internal character\n\t\t * representation (UCS-2) to Unicode code points, and back.\n\t\t * @see <https://mathiasbynens.be/notes/javascript-encoding>\n\t\t * @memberOf punycode\n\t\t * @type Object\n\t\t */\n\t\t'ucs2': {\n\t\t\t'decode': ucs2decode,\n\t\t\t'encode': ucs2encode\n\t\t},\n\t\t'decode': decode,\n\t\t'encode': encode,\n\t\t'toASCII': toASCII,\n\t\t'toUnicode': toUnicode\n\t};\n\n\t/** Expose `punycode` */\n\t// Some AMD build optimizers, like r.js, check for specific condition patterns\n\t// like the following:\n\tif (\n\t\ttrue\n\t) {\n\t\t!(__WEBPACK_AMD_DEFINE_RESULT__ = (function() {\n\t\t\treturn punycode;\n\t\t}).call(exports, __webpack_require__, exports, module),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t} else {}\n\n}(this));\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../webpack/buildin/module.js */ \"./node_modules/webpack/buildin/module.js\")(module), __webpack_require__(/*! ./../../../webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))\n\n//# sourceURL=webpack://SimpleYoutubeAPI/./node_modules/node-libs-browser/node_modules/punycode/punycode.js?");

/***/ }),

/***/ "./node_modules/querystring-es3/decode.js":
/*!************************************************!*\
  !*** ./node_modules/querystring-es3/decode.js ***!
  \************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
eval("// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\n\n// If obj.hasOwnProperty has been overridden, then calling\n// obj.hasOwnProperty(prop) will break.\n// See: https://github.com/joyent/node/issues/1707\nfunction hasOwnProperty(obj, prop) {\n  return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n\nmodule.exports = function(qs, sep, eq, options) {\n  sep = sep || '&';\n  eq = eq || '=';\n  var obj = {};\n\n  if (typeof qs !== 'string' || qs.length === 0) {\n    return obj;\n  }\n\n  var regexp = /\\+/g;\n  qs = qs.split(sep);\n\n  var maxKeys = 1000;\n  if (options && typeof options.maxKeys === 'number') {\n    maxKeys = options.maxKeys;\n  }\n\n  var len = qs.length;\n  // maxKeys <= 0 means that we should not limit keys count\n  if (maxKeys > 0 && len > maxKeys) {\n    len = maxKeys;\n  }\n\n  for (var i = 0; i < len; ++i) {\n    var x = qs[i].replace(regexp, '%20'),\n        idx = x.indexOf(eq),\n        kstr, vstr, k, v;\n\n    if (idx >= 0) {\n      kstr = x.substr(0, idx);\n      vstr = x.substr(idx + 1);\n    } else {\n      kstr = x;\n      vstr = '';\n    }\n\n    k = decodeURIComponent(kstr);\n    v = decodeURIComponent(vstr);\n\n    if (!hasOwnProperty(obj, k)) {\n      obj[k] = v;\n    } else if (isArray(obj[k])) {\n      obj[k].push(v);\n    } else {\n      obj[k] = [obj[k], v];\n    }\n  }\n\n  return obj;\n};\n\nvar isArray = Array.isArray || function (xs) {\n  return Object.prototype.toString.call(xs) === '[object Array]';\n};\n\n\n//# sourceURL=webpack://SimpleYoutubeAPI/./node_modules/querystring-es3/decode.js?");

/***/ }),

/***/ "./node_modules/querystring-es3/encode.js":
/*!************************************************!*\
  !*** ./node_modules/querystring-es3/encode.js ***!
  \************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
eval("// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\n\nvar stringifyPrimitive = function(v) {\n  switch (typeof v) {\n    case 'string':\n      return v;\n\n    case 'boolean':\n      return v ? 'true' : 'false';\n\n    case 'number':\n      return isFinite(v) ? v : '';\n\n    default:\n      return '';\n  }\n};\n\nmodule.exports = function(obj, sep, eq, name) {\n  sep = sep || '&';\n  eq = eq || '=';\n  if (obj === null) {\n    obj = undefined;\n  }\n\n  if (typeof obj === 'object') {\n    return map(objectKeys(obj), function(k) {\n      var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;\n      if (isArray(obj[k])) {\n        return map(obj[k], function(v) {\n          return ks + encodeURIComponent(stringifyPrimitive(v));\n        }).join(sep);\n      } else {\n        return ks + encodeURIComponent(stringifyPrimitive(obj[k]));\n      }\n    }).join(sep);\n\n  }\n\n  if (!name) return '';\n  return encodeURIComponent(stringifyPrimitive(name)) + eq +\n         encodeURIComponent(stringifyPrimitive(obj));\n};\n\nvar isArray = Array.isArray || function (xs) {\n  return Object.prototype.toString.call(xs) === '[object Array]';\n};\n\nfunction map (xs, f) {\n  if (xs.map) return xs.map(f);\n  var res = [];\n  for (var i = 0; i < xs.length; i++) {\n    res.push(f(xs[i], i));\n  }\n  return res;\n}\n\nvar objectKeys = Object.keys || function (obj) {\n  var res = [];\n  for (var key in obj) {\n    if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);\n  }\n  return res;\n};\n\n\n//# sourceURL=webpack://SimpleYoutubeAPI/./node_modules/querystring-es3/encode.js?");

/***/ }),

/***/ "./node_modules/querystring-es3/index.js":
/*!***********************************************!*\
  !*** ./node_modules/querystring-es3/index.js ***!
  \***********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
eval("\n\nexports.decode = exports.parse = __webpack_require__(/*! ./decode */ \"./node_modules/querystring-es3/decode.js\");\nexports.encode = exports.stringify = __webpack_require__(/*! ./encode */ \"./node_modules/querystring-es3/encode.js\");\n\n\n//# sourceURL=webpack://SimpleYoutubeAPI/./node_modules/querystring-es3/index.js?");

/***/ }),

/***/ "./node_modules/url/url.js":
/*!*********************************!*\
  !*** ./node_modules/url/url.js ***!
  \*********************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
eval("// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\n\nvar punycode = __webpack_require__(/*! punycode */ \"./node_modules/node-libs-browser/node_modules/punycode/punycode.js\");\nvar util = __webpack_require__(/*! ./util */ \"./node_modules/url/util.js\");\n\nexports.parse = urlParse;\nexports.resolve = urlResolve;\nexports.resolveObject = urlResolveObject;\nexports.format = urlFormat;\n\nexports.Url = Url;\n\nfunction Url() {\n  this.protocol = null;\n  this.slashes = null;\n  this.auth = null;\n  this.host = null;\n  this.port = null;\n  this.hostname = null;\n  this.hash = null;\n  this.search = null;\n  this.query = null;\n  this.pathname = null;\n  this.path = null;\n  this.href = null;\n}\n\n// Reference: RFC 3986, RFC 1808, RFC 2396\n\n// define these here so at least they only have to be\n// compiled once on the first module load.\nvar protocolPattern = /^([a-z0-9.+-]+:)/i,\n    portPattern = /:[0-9]*$/,\n\n    // Special case for a simple path URL\n    simplePathPattern = /^(\\/\\/?(?!\\/)[^\\?\\s]*)(\\?[^\\s]*)?$/,\n\n    // RFC 2396: characters reserved for delimiting URLs.\n    // We actually just auto-escape these.\n    delims = ['<', '>', '\"', '`', ' ', '\\r', '\\n', '\\t'],\n\n    // RFC 2396: characters not allowed for various reasons.\n    unwise = ['{', '}', '|', '\\\\', '^', '`'].concat(delims),\n\n    // Allowed by RFCs, but cause of XSS attacks.  Always escape these.\n    autoEscape = ['\\''].concat(unwise),\n    // Characters that are never ever allowed in a hostname.\n    // Note that any invalid chars are also handled, but these\n    // are the ones that are *expected* to be seen, so we fast-path\n    // them.\n    nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),\n    hostEndingChars = ['/', '?', '#'],\n    hostnameMaxLen = 255,\n    hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/,\n    hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/,\n    // protocols that can allow \"unsafe\" and \"unwise\" chars.\n    unsafeProtocol = {\n      'javascript': true,\n      'javascript:': true\n    },\n    // protocols that never have a hostname.\n    hostlessProtocol = {\n      'javascript': true,\n      'javascript:': true\n    },\n    // protocols that always contain a // bit.\n    slashedProtocol = {\n      'http': true,\n      'https': true,\n      'ftp': true,\n      'gopher': true,\n      'file': true,\n      'http:': true,\n      'https:': true,\n      'ftp:': true,\n      'gopher:': true,\n      'file:': true\n    },\n    querystring = __webpack_require__(/*! querystring */ \"./node_modules/querystring-es3/index.js\");\n\nfunction urlParse(url, parseQueryString, slashesDenoteHost) {\n  if (url && util.isObject(url) && url instanceof Url) return url;\n\n  var u = new Url;\n  u.parse(url, parseQueryString, slashesDenoteHost);\n  return u;\n}\n\nUrl.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {\n  if (!util.isString(url)) {\n    throw new TypeError(\"Parameter 'url' must be a string, not \" + typeof url);\n  }\n\n  // Copy chrome, IE, opera backslash-handling behavior.\n  // Back slashes before the query string get converted to forward slashes\n  // See: https://code.google.com/p/chromium/issues/detail?id=25916\n  var queryIndex = url.indexOf('?'),\n      splitter =\n          (queryIndex !== -1 && queryIndex < url.indexOf('#')) ? '?' : '#',\n      uSplit = url.split(splitter),\n      slashRegex = /\\\\/g;\n  uSplit[0] = uSplit[0].replace(slashRegex, '/');\n  url = uSplit.join(splitter);\n\n  var rest = url;\n\n  // trim before proceeding.\n  // This is to support parse stuff like \"  http://foo.com  \\n\"\n  rest = rest.trim();\n\n  if (!slashesDenoteHost && url.split('#').length === 1) {\n    // Try fast path regexp\n    var simplePath = simplePathPattern.exec(rest);\n    if (simplePath) {\n      this.path = rest;\n      this.href = rest;\n      this.pathname = simplePath[1];\n      if (simplePath[2]) {\n        this.search = simplePath[2];\n        if (parseQueryString) {\n          this.query = querystring.parse(this.search.substr(1));\n        } else {\n          this.query = this.search.substr(1);\n        }\n      } else if (parseQueryString) {\n        this.search = '';\n        this.query = {};\n      }\n      return this;\n    }\n  }\n\n  var proto = protocolPattern.exec(rest);\n  if (proto) {\n    proto = proto[0];\n    var lowerProto = proto.toLowerCase();\n    this.protocol = lowerProto;\n    rest = rest.substr(proto.length);\n  }\n\n  // figure out if it's got a host\n  // user@server is *always* interpreted as a hostname, and url\n  // resolution will treat //foo/bar as host=foo,path=bar because that's\n  // how the browser resolves relative URLs.\n  if (slashesDenoteHost || proto || rest.match(/^\\/\\/[^@\\/]+@[^@\\/]+/)) {\n    var slashes = rest.substr(0, 2) === '//';\n    if (slashes && !(proto && hostlessProtocol[proto])) {\n      rest = rest.substr(2);\n      this.slashes = true;\n    }\n  }\n\n  if (!hostlessProtocol[proto] &&\n      (slashes || (proto && !slashedProtocol[proto]))) {\n\n    // there's a hostname.\n    // the first instance of /, ?, ;, or # ends the host.\n    //\n    // If there is an @ in the hostname, then non-host chars *are* allowed\n    // to the left of the last @ sign, unless some host-ending character\n    // comes *before* the @-sign.\n    // URLs are obnoxious.\n    //\n    // ex:\n    // http://a@b@c/ => user:a@b host:c\n    // http://a@b?@c => user:a host:c path:/?@c\n\n    // v0.12 TODO(isaacs): This is not quite how Chrome does things.\n    // Review our test case against browsers more comprehensively.\n\n    // find the first instance of any hostEndingChars\n    var hostEnd = -1;\n    for (var i = 0; i < hostEndingChars.length; i++) {\n      var hec = rest.indexOf(hostEndingChars[i]);\n      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))\n        hostEnd = hec;\n    }\n\n    // at this point, either we have an explicit point where the\n    // auth portion cannot go past, or the last @ char is the decider.\n    var auth, atSign;\n    if (hostEnd === -1) {\n      // atSign can be anywhere.\n      atSign = rest.lastIndexOf('@');\n    } else {\n      // atSign must be in auth portion.\n      // http://a@b/c@d => host:b auth:a path:/c@d\n      atSign = rest.lastIndexOf('@', hostEnd);\n    }\n\n    // Now we have a portion which is definitely the auth.\n    // Pull that off.\n    if (atSign !== -1) {\n      auth = rest.slice(0, atSign);\n      rest = rest.slice(atSign + 1);\n      this.auth = decodeURIComponent(auth);\n    }\n\n    // the host is the remaining to the left of the first non-host char\n    hostEnd = -1;\n    for (var i = 0; i < nonHostChars.length; i++) {\n      var hec = rest.indexOf(nonHostChars[i]);\n      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))\n        hostEnd = hec;\n    }\n    // if we still have not hit it, then the entire thing is a host.\n    if (hostEnd === -1)\n      hostEnd = rest.length;\n\n    this.host = rest.slice(0, hostEnd);\n    rest = rest.slice(hostEnd);\n\n    // pull out port.\n    this.parseHost();\n\n    // we've indicated that there is a hostname,\n    // so even if it's empty, it has to be present.\n    this.hostname = this.hostname || '';\n\n    // if hostname begins with [ and ends with ]\n    // assume that it's an IPv6 address.\n    var ipv6Hostname = this.hostname[0] === '[' &&\n        this.hostname[this.hostname.length - 1] === ']';\n\n    // validate a little.\n    if (!ipv6Hostname) {\n      var hostparts = this.hostname.split(/\\./);\n      for (var i = 0, l = hostparts.length; i < l; i++) {\n        var part = hostparts[i];\n        if (!part) continue;\n        if (!part.match(hostnamePartPattern)) {\n          var newpart = '';\n          for (var j = 0, k = part.length; j < k; j++) {\n            if (part.charCodeAt(j) > 127) {\n              // we replace non-ASCII char with a temporary placeholder\n              // we need this to make sure size of hostname is not\n              // broken by replacing non-ASCII by nothing\n              newpart += 'x';\n            } else {\n              newpart += part[j];\n            }\n          }\n          // we test again with ASCII char only\n          if (!newpart.match(hostnamePartPattern)) {\n            var validParts = hostparts.slice(0, i);\n            var notHost = hostparts.slice(i + 1);\n            var bit = part.match(hostnamePartStart);\n            if (bit) {\n              validParts.push(bit[1]);\n              notHost.unshift(bit[2]);\n            }\n            if (notHost.length) {\n              rest = '/' + notHost.join('.') + rest;\n            }\n            this.hostname = validParts.join('.');\n            break;\n          }\n        }\n      }\n    }\n\n    if (this.hostname.length > hostnameMaxLen) {\n      this.hostname = '';\n    } else {\n      // hostnames are always lower case.\n      this.hostname = this.hostname.toLowerCase();\n    }\n\n    if (!ipv6Hostname) {\n      // IDNA Support: Returns a punycoded representation of \"domain\".\n      // It only converts parts of the domain name that\n      // have non-ASCII characters, i.e. it doesn't matter if\n      // you call it with a domain that already is ASCII-only.\n      this.hostname = punycode.toASCII(this.hostname);\n    }\n\n    var p = this.port ? ':' + this.port : '';\n    var h = this.hostname || '';\n    this.host = h + p;\n    this.href += this.host;\n\n    // strip [ and ] from the hostname\n    // the host field still retains them, though\n    if (ipv6Hostname) {\n      this.hostname = this.hostname.substr(1, this.hostname.length - 2);\n      if (rest[0] !== '/') {\n        rest = '/' + rest;\n      }\n    }\n  }\n\n  // now rest is set to the post-host stuff.\n  // chop off any delim chars.\n  if (!unsafeProtocol[lowerProto]) {\n\n    // First, make 100% sure that any \"autoEscape\" chars get\n    // escaped, even if encodeURIComponent doesn't think they\n    // need to be.\n    for (var i = 0, l = autoEscape.length; i < l; i++) {\n      var ae = autoEscape[i];\n      if (rest.indexOf(ae) === -1)\n        continue;\n      var esc = encodeURIComponent(ae);\n      if (esc === ae) {\n        esc = escape(ae);\n      }\n      rest = rest.split(ae).join(esc);\n    }\n  }\n\n\n  // chop off from the tail first.\n  var hash = rest.indexOf('#');\n  if (hash !== -1) {\n    // got a fragment string.\n    this.hash = rest.substr(hash);\n    rest = rest.slice(0, hash);\n  }\n  var qm = rest.indexOf('?');\n  if (qm !== -1) {\n    this.search = rest.substr(qm);\n    this.query = rest.substr(qm + 1);\n    if (parseQueryString) {\n      this.query = querystring.parse(this.query);\n    }\n    rest = rest.slice(0, qm);\n  } else if (parseQueryString) {\n    // no query string, but parseQueryString still requested\n    this.search = '';\n    this.query = {};\n  }\n  if (rest) this.pathname = rest;\n  if (slashedProtocol[lowerProto] &&\n      this.hostname && !this.pathname) {\n    this.pathname = '/';\n  }\n\n  //to support http.request\n  if (this.pathname || this.search) {\n    var p = this.pathname || '';\n    var s = this.search || '';\n    this.path = p + s;\n  }\n\n  // finally, reconstruct the href based on what has been validated.\n  this.href = this.format();\n  return this;\n};\n\n// format a parsed object into a url string\nfunction urlFormat(obj) {\n  // ensure it's an object, and not a string url.\n  // If it's an obj, this is a no-op.\n  // this way, you can call url_format() on strings\n  // to clean up potentially wonky urls.\n  if (util.isString(obj)) obj = urlParse(obj);\n  if (!(obj instanceof Url)) return Url.prototype.format.call(obj);\n  return obj.format();\n}\n\nUrl.prototype.format = function() {\n  var auth = this.auth || '';\n  if (auth) {\n    auth = encodeURIComponent(auth);\n    auth = auth.replace(/%3A/i, ':');\n    auth += '@';\n  }\n\n  var protocol = this.protocol || '',\n      pathname = this.pathname || '',\n      hash = this.hash || '',\n      host = false,\n      query = '';\n\n  if (this.host) {\n    host = auth + this.host;\n  } else if (this.hostname) {\n    host = auth + (this.hostname.indexOf(':') === -1 ?\n        this.hostname :\n        '[' + this.hostname + ']');\n    if (this.port) {\n      host += ':' + this.port;\n    }\n  }\n\n  if (this.query &&\n      util.isObject(this.query) &&\n      Object.keys(this.query).length) {\n    query = querystring.stringify(this.query);\n  }\n\n  var search = this.search || (query && ('?' + query)) || '';\n\n  if (protocol && protocol.substr(-1) !== ':') protocol += ':';\n\n  // only the slashedProtocols get the //.  Not mailto:, xmpp:, etc.\n  // unless they had them to begin with.\n  if (this.slashes ||\n      (!protocol || slashedProtocol[protocol]) && host !== false) {\n    host = '//' + (host || '');\n    if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;\n  } else if (!host) {\n    host = '';\n  }\n\n  if (hash && hash.charAt(0) !== '#') hash = '#' + hash;\n  if (search && search.charAt(0) !== '?') search = '?' + search;\n\n  pathname = pathname.replace(/[?#]/g, function(match) {\n    return encodeURIComponent(match);\n  });\n  search = search.replace('#', '%23');\n\n  return protocol + host + pathname + search + hash;\n};\n\nfunction urlResolve(source, relative) {\n  return urlParse(source, false, true).resolve(relative);\n}\n\nUrl.prototype.resolve = function(relative) {\n  return this.resolveObject(urlParse(relative, false, true)).format();\n};\n\nfunction urlResolveObject(source, relative) {\n  if (!source) return relative;\n  return urlParse(source, false, true).resolveObject(relative);\n}\n\nUrl.prototype.resolveObject = function(relative) {\n  if (util.isString(relative)) {\n    var rel = new Url();\n    rel.parse(relative, false, true);\n    relative = rel;\n  }\n\n  var result = new Url();\n  var tkeys = Object.keys(this);\n  for (var tk = 0; tk < tkeys.length; tk++) {\n    var tkey = tkeys[tk];\n    result[tkey] = this[tkey];\n  }\n\n  // hash is always overridden, no matter what.\n  // even href=\"\" will remove it.\n  result.hash = relative.hash;\n\n  // if the relative url is empty, then there's nothing left to do here.\n  if (relative.href === '') {\n    result.href = result.format();\n    return result;\n  }\n\n  // hrefs like //foo/bar always cut to the protocol.\n  if (relative.slashes && !relative.protocol) {\n    // take everything except the protocol from relative\n    var rkeys = Object.keys(relative);\n    for (var rk = 0; rk < rkeys.length; rk++) {\n      var rkey = rkeys[rk];\n      if (rkey !== 'protocol')\n        result[rkey] = relative[rkey];\n    }\n\n    //urlParse appends trailing / to urls like http://www.example.com\n    if (slashedProtocol[result.protocol] &&\n        result.hostname && !result.pathname) {\n      result.path = result.pathname = '/';\n    }\n\n    result.href = result.format();\n    return result;\n  }\n\n  if (relative.protocol && relative.protocol !== result.protocol) {\n    // if it's a known url protocol, then changing\n    // the protocol does weird things\n    // first, if it's not file:, then we MUST have a host,\n    // and if there was a path\n    // to begin with, then we MUST have a path.\n    // if it is file:, then the host is dropped,\n    // because that's known to be hostless.\n    // anything else is assumed to be absolute.\n    if (!slashedProtocol[relative.protocol]) {\n      var keys = Object.keys(relative);\n      for (var v = 0; v < keys.length; v++) {\n        var k = keys[v];\n        result[k] = relative[k];\n      }\n      result.href = result.format();\n      return result;\n    }\n\n    result.protocol = relative.protocol;\n    if (!relative.host && !hostlessProtocol[relative.protocol]) {\n      var relPath = (relative.pathname || '').split('/');\n      while (relPath.length && !(relative.host = relPath.shift()));\n      if (!relative.host) relative.host = '';\n      if (!relative.hostname) relative.hostname = '';\n      if (relPath[0] !== '') relPath.unshift('');\n      if (relPath.length < 2) relPath.unshift('');\n      result.pathname = relPath.join('/');\n    } else {\n      result.pathname = relative.pathname;\n    }\n    result.search = relative.search;\n    result.query = relative.query;\n    result.host = relative.host || '';\n    result.auth = relative.auth;\n    result.hostname = relative.hostname || relative.host;\n    result.port = relative.port;\n    // to support http.request\n    if (result.pathname || result.search) {\n      var p = result.pathname || '';\n      var s = result.search || '';\n      result.path = p + s;\n    }\n    result.slashes = result.slashes || relative.slashes;\n    result.href = result.format();\n    return result;\n  }\n\n  var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'),\n      isRelAbs = (\n          relative.host ||\n          relative.pathname && relative.pathname.charAt(0) === '/'\n      ),\n      mustEndAbs = (isRelAbs || isSourceAbs ||\n                    (result.host && relative.pathname)),\n      removeAllDots = mustEndAbs,\n      srcPath = result.pathname && result.pathname.split('/') || [],\n      relPath = relative.pathname && relative.pathname.split('/') || [],\n      psychotic = result.protocol && !slashedProtocol[result.protocol];\n\n  // if the url is a non-slashed url, then relative\n  // links like ../.. should be able\n  // to crawl up to the hostname, as well.  This is strange.\n  // result.protocol has already been set by now.\n  // Later on, put the first path part into the host field.\n  if (psychotic) {\n    result.hostname = '';\n    result.port = null;\n    if (result.host) {\n      if (srcPath[0] === '') srcPath[0] = result.host;\n      else srcPath.unshift(result.host);\n    }\n    result.host = '';\n    if (relative.protocol) {\n      relative.hostname = null;\n      relative.port = null;\n      if (relative.host) {\n        if (relPath[0] === '') relPath[0] = relative.host;\n        else relPath.unshift(relative.host);\n      }\n      relative.host = null;\n    }\n    mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');\n  }\n\n  if (isRelAbs) {\n    // it's absolute.\n    result.host = (relative.host || relative.host === '') ?\n                  relative.host : result.host;\n    result.hostname = (relative.hostname || relative.hostname === '') ?\n                      relative.hostname : result.hostname;\n    result.search = relative.search;\n    result.query = relative.query;\n    srcPath = relPath;\n    // fall through to the dot-handling below.\n  } else if (relPath.length) {\n    // it's relative\n    // throw away the existing file, and take the new path instead.\n    if (!srcPath) srcPath = [];\n    srcPath.pop();\n    srcPath = srcPath.concat(relPath);\n    result.search = relative.search;\n    result.query = relative.query;\n  } else if (!util.isNullOrUndefined(relative.search)) {\n    // just pull out the search.\n    // like href='?foo'.\n    // Put this after the other two cases because it simplifies the booleans\n    if (psychotic) {\n      result.hostname = result.host = srcPath.shift();\n      //occationaly the auth can get stuck only in host\n      //this especially happens in cases like\n      //url.resolveObject('mailto:local1@domain1', 'local2@domain2')\n      var authInHost = result.host && result.host.indexOf('@') > 0 ?\n                       result.host.split('@') : false;\n      if (authInHost) {\n        result.auth = authInHost.shift();\n        result.host = result.hostname = authInHost.shift();\n      }\n    }\n    result.search = relative.search;\n    result.query = relative.query;\n    //to support http.request\n    if (!util.isNull(result.pathname) || !util.isNull(result.search)) {\n      result.path = (result.pathname ? result.pathname : '') +\n                    (result.search ? result.search : '');\n    }\n    result.href = result.format();\n    return result;\n  }\n\n  if (!srcPath.length) {\n    // no path at all.  easy.\n    // we've already handled the other stuff above.\n    result.pathname = null;\n    //to support http.request\n    if (result.search) {\n      result.path = '/' + result.search;\n    } else {\n      result.path = null;\n    }\n    result.href = result.format();\n    return result;\n  }\n\n  // if a url ENDs in . or .., then it must get a trailing slash.\n  // however, if it ends in anything else non-slashy,\n  // then it must NOT get a trailing slash.\n  var last = srcPath.slice(-1)[0];\n  var hasTrailingSlash = (\n      (result.host || relative.host || srcPath.length > 1) &&\n      (last === '.' || last === '..') || last === '');\n\n  // strip single dots, resolve double dots to parent dir\n  // if the path tries to go above the root, `up` ends up > 0\n  var up = 0;\n  for (var i = srcPath.length; i >= 0; i--) {\n    last = srcPath[i];\n    if (last === '.') {\n      srcPath.splice(i, 1);\n    } else if (last === '..') {\n      srcPath.splice(i, 1);\n      up++;\n    } else if (up) {\n      srcPath.splice(i, 1);\n      up--;\n    }\n  }\n\n  // if the path is allowed to go above the root, restore leading ..s\n  if (!mustEndAbs && !removeAllDots) {\n    for (; up--; up) {\n      srcPath.unshift('..');\n    }\n  }\n\n  if (mustEndAbs && srcPath[0] !== '' &&\n      (!srcPath[0] || srcPath[0].charAt(0) !== '/')) {\n    srcPath.unshift('');\n  }\n\n  if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {\n    srcPath.push('');\n  }\n\n  var isAbsolute = srcPath[0] === '' ||\n      (srcPath[0] && srcPath[0].charAt(0) === '/');\n\n  // put the host back\n  if (psychotic) {\n    result.hostname = result.host = isAbsolute ? '' :\n                                    srcPath.length ? srcPath.shift() : '';\n    //occationaly the auth can get stuck only in host\n    //this especially happens in cases like\n    //url.resolveObject('mailto:local1@domain1', 'local2@domain2')\n    var authInHost = result.host && result.host.indexOf('@') > 0 ?\n                     result.host.split('@') : false;\n    if (authInHost) {\n      result.auth = authInHost.shift();\n      result.host = result.hostname = authInHost.shift();\n    }\n  }\n\n  mustEndAbs = mustEndAbs || (result.host && srcPath.length);\n\n  if (mustEndAbs && !isAbsolute) {\n    srcPath.unshift('');\n  }\n\n  if (!srcPath.length) {\n    result.pathname = null;\n    result.path = null;\n  } else {\n    result.pathname = srcPath.join('/');\n  }\n\n  //to support request.http\n  if (!util.isNull(result.pathname) || !util.isNull(result.search)) {\n    result.path = (result.pathname ? result.pathname : '') +\n                  (result.search ? result.search : '');\n  }\n  result.auth = relative.auth || result.auth;\n  result.slashes = result.slashes || relative.slashes;\n  result.href = result.format();\n  return result;\n};\n\nUrl.prototype.parseHost = function() {\n  var host = this.host;\n  var port = portPattern.exec(host);\n  if (port) {\n    port = port[0];\n    if (port !== ':') {\n      this.port = port.substr(1);\n    }\n    host = host.substr(0, host.length - port.length);\n  }\n  if (host) this.hostname = host;\n};\n\n\n//# sourceURL=webpack://SimpleYoutubeAPI/./node_modules/url/url.js?");

/***/ }),

/***/ "./node_modules/url/util.js":
/*!**********************************!*\
  !*** ./node_modules/url/util.js ***!
  \**********************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
eval("\n\nmodule.exports = {\n  isString: function(arg) {\n    return typeof(arg) === 'string';\n  },\n  isObject: function(arg) {\n    return typeof(arg) === 'object' && arg !== null;\n  },\n  isNull: function(arg) {\n    return arg === null;\n  },\n  isNullOrUndefined: function(arg) {\n    return arg == null;\n  }\n};\n\n\n//# sourceURL=webpack://SimpleYoutubeAPI/./node_modules/url/util.js?");

/***/ }),

/***/ "./node_modules/webpack/buildin/global.js":
/*!***********************************!*\
  !*** (webpack)/buildin/global.js ***!
  \***********************************/
/*! no static exports found */
/***/ (function(module, exports) {

eval("var g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || Function(\"return this\")() || (1, eval)(\"this\");\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n\n\n//# sourceURL=webpack://SimpleYoutubeAPI/(webpack)/buildin/global.js?");

/***/ }),

/***/ "./node_modules/webpack/buildin/module.js":
/*!***********************************!*\
  !*** (webpack)/buildin/module.js ***!
  \***********************************/
/*! no static exports found */
/***/ (function(module, exports) {

eval("module.exports = function(module) {\n\tif (!module.webpackPolyfill) {\n\t\tmodule.deprecate = function() {};\n\t\tmodule.paths = [];\n\t\t// module.parent = undefined by default\n\t\tif (!module.children) module.children = [];\n\t\tObject.defineProperty(module, \"loaded\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.l;\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(module, \"id\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.i;\n\t\t\t}\n\t\t});\n\t\tmodule.webpackPolyfill = 1;\n\t}\n\treturn module;\n};\n\n\n//# sourceURL=webpack://SimpleYoutubeAPI/(webpack)/buildin/module.js?");

/***/ }),

/***/ "./src/Request.js":
/*!************************!*\
  !*** ./src/Request.js ***!
  \************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

eval("const fetch = __webpack_require__(/*! node-fetch */ \"./node_modules/node-fetch/browser.js\");\nconst Constants = __webpack_require__(/*! ./util/Constants */ \"./src/util/Constants.js\");\n\nclass Request {\n    constructor(youtube) {\n        this.youtube = youtube;\n    }\n\n    /**\n     * Make a request to the YouTube API\n     * @param {string} endpoint The endpoint to query\n     * @param {object} [qs={}] Query strings\n     * @returns {Promise<object>}\n     */\n    make(endpoint, qs = {}) {\n        qs = Object.assign({ key: this.youtube.key }, qs);\n        const params = Object.keys(qs).filter(k => qs[k]).map(k => `${k}=${qs[k]}`);\n        return fetch(encodeURI(`https://www.googleapis.com/youtube/v3/${endpoint}${params.length ? `?${params.join('&')}` : ''}`))\n            .then(result => result.json())\n            .then(result => {\n                if (result.error) return Promise.reject(result.error);\n                return result;\n            });\n    }\n\n    /**\n     * Get a resource from the YouTube API\n     * @param {string} type The type of resource to get\n     * @param {object} [qs={}] Any other query options\n     * @returns {Promise<object>}\n     */\n    getResource(type, qs = {}) {\n        qs = Object.assign({ part: Constants.PARTS[type] }, qs);\n        return this.make(Constants.ENDPOINTS[type], qs).then(result =>\n            result.items.length ? result.items[0] : Promise.reject(new Error(`resource ${result.kind} not found`))\n        );\n    }\n\n    /**\n     * Get a resource from the YouTube API, by ID\n     * @param {string} type The type of resource to get\n     * @param {string} id The ID of the resource to get\n     * @param {object} [qs={}] Any other query options\n     * @returns {Promise<object>}\n     */\n    getResourceByID(type, id, qs = {}) {\n        return this.getResource(type, Object.assign(qs, { id }));\n    }\n\n    /**\n     * Get a video from the YouTube API\n     * @param {string} id The video to get\n     * @param {object} [options] Any request options\n     * @returns {Promise<object>}\n     */\n    getVideo(id, options) {\n        return this.getResourceByID('Videos', id, options);\n    }\n\n    /**\n     * Get a playlist from the YouTube API\n     * @param {string} id The playlist to get\n     * @param {object} [options] Any request options\n     * @returns {Promise<object>}\n     */\n    getPlaylist(id, options) {\n        return this.getResourceByID('Playlists', id, options);\n    }\n\n    /**\n     * Get a channel from the YouTube API\n     * @param {string} id The channel to get\n     * @param {object} [options] Any request options\n     * @returns {Promise<object>}\n     */\n    getChannel(id, options) {\n        return this.getResourceByID('Channels', id, options);\n    }\n\n    /**\n     * Fetch a paginated resource.\n     * @param {string} endpoint The endpoint to query.\n     * @param {number} [count=Infinity] How many results to retrieve.\n     * @param {Object} [options={}] Additional options to send.\n     * @param {Array} [fetched=[]] Previously fetched resources.\n     * @param {?string} [pageToken] The page token to retrieve.\n     * @returns {Promise<Array<object>>}\n     */\n    getPaginated(endpoint, count = Infinity, options = {}, fetched = [], pageToken = null) {\n        if(count < 1) return Promise.reject('Cannot fetch less than 1.');\n\n        const limit = count > 50 ? 50 : count;\n        return this.make(endpoint, Object.assign(options, { pageToken, maxResults: limit })).then(result => {\n            const results = fetched.concat(result.items);\n            if(result.nextPageToken && limit !== count) return this.getPaginated(endpoint, count - limit, options, results, result.nextPageToken);\n            return results;\n        });\n    }\n}\n\nmodule.exports = Request;\n\n\n//# sourceURL=webpack://SimpleYoutubeAPI/./src/Request.js?");

/***/ }),

/***/ "./src/index.js":
/*!**********************!*\
  !*** ./src/index.js ***!
  \**********************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

eval("const Request = __webpack_require__(/*! ./Request */ \"./src/Request.js\");\n\nconst Video = __webpack_require__(/*! ./structures/Video */ \"./src/structures/Video.js\");\nconst Playlist = __webpack_require__(/*! ./structures/Playlist */ \"./src/structures/Playlist.js\");\nconst Channel = __webpack_require__(/*! ./structures/Channel */ \"./src/structures/Channel.js\");\n\nconst util = __webpack_require__(/*! ./util */ \"./src/util/index.js\");\nconst Constants = __webpack_require__(/*! ./util/Constants */ \"./src/util/Constants.js\");\n\n/**\n * Information about a thumbnail\n * @typedef {Object} Thumbnail\n * @property {string} url The URL of this thumbnail\n * @property {number} width The width of this thumbnail\n * @property {number} height The height of this thumbnail\n */\n\n/**\n * The YouTube API module\n */\nclass YouTube {\n    /**\n     * @param {string} key The YouTube Data API v3 key to use\n     */\n    constructor(key) {\n        if (typeof key !== 'string') throw new Error('The YouTube API key you provided was not a string.');\n        /**\n         * The YouTube Data API v3 key\n         * @type {?string}\n         */\n        this.key = key;\n        Object.defineProperty(this, 'key', { enumerable: false });\n\n        this.request = new Request(this);\n    }\n\n    /**\n     * Make a request to the YouTube API\n     * @param {string} endpoint The endpoint of the API\n     * @param {Object} qs The query string options\n     * @returns {Promise<Object>}\n     */\n\n    /**\n     * Get a video by URL or ID\n     * @param {string} url The video URL or ID\n     * @param {Object} [options = {}] Options to request with the video.\n     * @returns {Promise<?Video>}\n     * @example\n     * API.getVideo('https://www.youtube.com/watch?v=dQw4w9WgXcQ')\n     *  .then(results => {\n     *    console.log(`The video's title is ${results[0].title}`);\n     *  })\n     *  .catch(console.error);\n     */\n    getVideo(url, options = {}) {\n        const id = Video.extractID(url);\n        if (!id) return Promise.reject(new Error(`No video ID found in URL: ${url}`));\n        return this.getVideoByID(id, options);\n    }\n\n    /**\n     * Get a video by ID\n     * @param {string} id The video ID\n     * @param {Object} [options = {}] Options to request with the video.\n     * @returns {Promise<?Video>}\n     * @example\n     * API.getVideoByID('3odIdmuFfEY')\n     *  .then(results => {\n     *    console.log(`The video's title is ${results[0].title}`);\n     *  })\n     *  .catch(console.error);\n     */\n    getVideoByID(id, options = {}) {\n        return this.request.getVideo(id, options).then(result => result ? new Video(this, result) : null);\n    }\n\n    /**\n     * Get a playlist by URL or ID\n     * @param {string} url The playlist URL or ID\n     * @param {Object} [options = {}] Options to request with the playlist.\n     * @returns {Promise<?Playlist>}\n     * @example\n     * API.getPlaylist('https://www.youtube.com/playlist?list=PLuY9odN8x9puRuCxiddyRzJ3F5jR-Gun9')\n     *  .then(results => {\n     *    console.log(`The playlist's title is ${results[0].title}`);\n     *  })\n     *  .catch(console.error);\n     */\n    getPlaylist(url, options = {}) {\n        const id = Playlist.extractID(url);\n        if (!id) return Promise.reject(new Error(`No playlist ID found in URL: ${url}`));\n        return this.getPlaylistByID(id, options);\n    }\n\n    /**\n     * Get a playlist by ID\n     * @param {string} id The playlist ID\n     * @param {Object} [options = {}] Options to request with the playlist.\n     * @returns {Promise<?Playlist>}\n     * @example\n     * API.getPlaylistByID('PL2BN1Zd8U_MsyMeK8r9Vdv1lnQGtoJaSa')\n     *  .then(results => {\n     *    console.log(`The playlist's title is ${results[0].title}`);\n     *  })\n     *  .catch(console.error);\n     */\n    getPlaylistByID(id, options = {}) {\n        return this.request.getPlaylist(id, options).then(result => result ? new Playlist(this, result) : null);\n    }\n\n    /**\n     * Get a channel by URL or ID\n     * @param {string} url The channel URL or ID\n     * @param {Object} [options = {}] Options to request with the channel.\n     * @returns {Promise<?Channel>}\n     * @example\n     * API.getChannel('https://www.youtube.com/channel/UC477Kvszl9JivqOxN1dFgPQ')\n     *  .then(results => {\n     *    console.log(`The channel's title is ${results[0].title}`);\n     *  })\n     *  .catch(console.error);\n     */\n    getChannel(url, options = {}) {\n        const id = Channel.extractID(url);\n        if (!id) return Promise.reject(new Error(`No channel ID found in URL: ${url}`));\n        return this.getChannelByID(id, options);\n    }\n\n    /**\n     * Get a channel by ID\n     * @param {string} id The channel ID\n     * @param {Object} [options = {}] Options to request with the channel.\n     * @returns {Promise<?Channel>}\n     * @example\n     * API.getChannelByID('UC477Kvszl9JivqOxN1dFgPQ')\n     *  .then(results => {\n     *    console.log(`The channel's title is ${results[0].title}`);\n     *  })\n     *  .catch(console.error);\n     */\n    getChannelByID(id, options = {}) {\n        return this.request.getChannel(id, options).then(result => result ? new Channel(this, result) : null);\n    }\n\n    /**\n     * Search YouTube for videos, playlists, and channels\n     * @param {string} query The string to search for\n     * @param {number} [limit = 5] Maximum results to obtain\n     * @param {Object} [options] Additional options to pass to the API request\n     * @returns {Promise<Array<Video|Playlist|Channel|null>>}\n     * @example\n     * API.search('Centuries')\n     *  .then(results => {\n     *    console.log(`I got ${results.length} results`);\n     *  })\n     *  .catch(console.error);\n     */\n    search(query, limit = 5, options = {}) {\n        return this.request.getPaginated(Constants.ENDPOINTS.Search, limit, Object.assign(options, { q: query, part: Constants.PARTS.Search }))\n            .then(result => result.map(item => {\n                if (item.id.kind === Constants.KINDS.Video) return new Video(this, item);\n                if (item.id.kind === Constants.KINDS.Playlist) return new Playlist(this, item);\n                if (item.id.kind === Constants.KINDS.Channel) return new Channel(this, item);\n                return null;\n            }));\n    }\n\n    /**\n     * Search YouTube for videos\n     * @param {string} query The string to search for\n     * @param {number} [limit = 5] Maximum results to obtain\n     * @param {Object} [options] Additional options to pass to the API request\n     * @returns {Promise<Video[]>}\n     * @example\n     * API.searchVideos('Centuries')\n     *  .then(results => {\n     *    console.log(`I got ${results.length} videos`);\n     *  })\n     *  .catch(console.error);\n     */\n    searchVideos(query, limit = 5, options = {}) {\n        return this.search(query, limit, Object.assign(options, { type: 'video' }));\n    }\n\n    /**\n     * Search YouTube for playlists\n     * @param {string} query The string to search for\n     * @param {number} [limit = 5] Maximum results to obtain\n     * @param {Object} [options] Additional options to pass to the API request\n     * @returns {Promise<Playlist[]>}\n     * @example\n     * API.searchPlaylists('Centuries')\n     *  .then(results => {\n     *    console.log(`I got ${results.length} playlists`);\n     *  })\n     *  .catch(console.error);\n     */\n    searchPlaylists(query, limit = 5, options = {}) {\n        return this.search(query, limit, Object.assign(options, { type: 'playlist' }));\n    }\n\n    /**\n     * Search YouTube for channels\n     * @param {string} query The string to search for\n     * @param {number} [limit = 5] Maximum results to obtain\n     * @param {Object} [options] Additional options to pass to the API request\n     * @returns {Promise<Channel[]>}\n     * @example\n     * API.searchChannels('Centuries')\n     *  .then(results => {\n     *    console.log(`I got ${results.length} channels`);\n     *  })\n     *  .catch(console.error);\n     */\n    searchChannels(query, limit = 5, options = {}) {\n        return this.search(query, limit, Object.assign(options, { type: 'channel' }));\n    }\n}\n\nYouTube.Video = Video;\nYouTube.Playlist = Playlist;\nYouTube.Channel = Channel;\nYouTube.util = util;\n\nmodule.exports = YouTube;\n\n\n//# sourceURL=webpack://SimpleYoutubeAPI/./src/index.js?");

/***/ }),

/***/ "./src/structures/Channel.js":
/*!***********************************!*\
  !*** ./src/structures/Channel.js ***!
  \***********************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

eval("const { parseURL } = __webpack_require__(/*! ../util */ \"./src/util/index.js\");\nconst Constants = __webpack_require__(/*! ../util/Constants */ \"./src/util/Constants.js\");\n\n/**\n * Represents a YouTube channel\n * @class\n */\nclass Channel {\n    /**\n     * @param {YouTube} youtube The YouTube instance creating this\n     * @param {Object} data The data of the channel\n     */\n    constructor(youtube, data) {\n        /**\n         * The YouTube instance that created this\n         * @type {YouTube}\n         */\n        this.youtube = youtube;\n        Object.defineProperty(this, 'youtube', { enumerable: false });\n\n        /**\n         * The type to filter search results\n         * @type {string}\n         */\n        this.type = 'channel';\n\n        this._patch(data);\n    }\n\n    _patch(data) {\n        if (!data) return;\n\n        /**\n         * Raw data from the YouTube API\n         * @type {object}\n         */\n        this.raw = data;\n\n        /**\n         * Whether this is a full channel object.\n         * @type {boolean}\n         */\n        this.full = data.kind === Constants.KINDS.Channel;\n\n        /**\n         * The YouTube resource from which this channel was created.\n         * @type {string}\n         */\n        this.kind = data.kind;\n\n        /**\n         * This channel's ID\n         * @type {string}\n         * @name Channel#id\n         */\n\n        /**\n         * This channel's title\n         * @type {?string}\n         * @name Channel#title\n         */\n\n        switch (data.kind) {\n            case Constants.KINDS.Playlist:\n            case Constants.KINDS.PlaylistItem:\n            case Constants.KINDS.Video:\n                if (data.snippet) {\n                    this.id = data.snippet.channelId;\n                    this.title = data.snippet.channelTitle;\n                    break;\n                } else {\n                    throw new Error('Attempted to make a channel out of a resource with no channel data.');\n                }\n            case Constants.KINDS.SearchResult:\n                if (data.id.kind === Constants.KINDS.Channel) {\n                    this.id = data.id.channelId;\n                    break;\n                } else if (data.snippet) {\n                    this.id = data.snippet.channelId;\n                    this.title = data.snippet.channelTitle;\n                    break;\n                } else {\n                    throw new Error('Attempted to make a channel out of a search result with no channel data.');\n                }\n            case Constants.KINDS.Channel:\n                this.id = data.id;\n                if (data.snippet) {\n                    this.title = data.snippet.title;\n\n                    /**\n                     * This channel's description\n                     * @type {?string}\n                     * @name Channel#description\n                     */\n                    this.description = data.snippet.description;\n\n                    /**\n                     * The channel's custom URL if it has one\n                     * @type {?string}\n                     */\n                    this.customURL = data.snippet.customUrl;\n\n                    /**\n                     * The channel's creation date\n                     * @type {?Date}\n                     * @name Channel#publishedAt\n                     */\n                    this.publishedAt = new Date(data.snippet.publishedAt);\n\n                    /**\n                     * The channel's thumbnails: available types are 'default', 'medium', and 'high'\n                     * @type {?Object.<string, Thumbnail>}\n                     */\n                    this.thumbnails = data.snippet.thumbnails;\n\n                    /**\n                     * The channel's default language\n                     * @type {?string}\n                     */\n                    this.defaultLanguage = data.snippet.defaultLanguage;\n\n                    /**\n                     * Information about the channel as specified in the `hl` query parameter\n                     * @type {?{title: string, description: string}}\n                     */\n                    this.localized = data.snippet.localized;\n\n                    /**\n                     * The country of the channel\n                     * @type {?string}\n                     */\n                    this.country = data.snippet.country;\n                }\n\n                if (data.contentDetails) {\n                    /**\n                     * Playlists associated with this channel; all values are playlist IDs\n                     * @type {?Object}\n                     * @property {?string} likes The channel's liked videos\n                     * @property {?string} favorites The channel's favorited videos (note: favorited videos are deprecated)\n                     * @property {?string} uploads The channel's uploaded videos\n                     */\n                    this.relatedPlaylists = data.contentDetails.relatedPlaylists;\n                }\n\n                if (data.statistics) {\n                    /**\n                     * The number of times the channel has been viewed\n                     * @type {?number}\n                     */\n                    this.viewCount = data.statistics.viewCount;\n\n                    /**\n                     * The number of comments on the channel\n                     * @type {?number}\n                     */\n                    this.commentCount = data.statistics.commentCount;\n\n                    /**\n                     * The number of subscribers the channel has\n                     * @type {?number}\n                     */\n                    this.subscriberCount = data.statistics.subscriberCount;\n\n                    /**\n                     * Whether the channel's subscriber count is public\n                     * @type {?boolean}\n                     */\n                    this.hiddenSubscriberCount = data.statistics.hiddenSubscriberCount;\n\n                    /**\n                     * The number of videos this channel has uploaded\n                     * @type {?number}\n                     */\n                    this.videoCount = data.statistics.videoCount;\n                }\n                break;\n            default:\n                throw new Error(`Unknown channel kind: ${data.kind}.`);\n        }\n\n        return this;\n    }\n\n    /**\n     * Fetch the full representation of this channel.\n     * @param {object} [options] Any extra query params\n     * @returns {Channel}\n     */\n    fetch(options) {\n        return this.youtube.request.getChannel(this.id, options).then(this._patch.bind(this));\n    }\n\n    /**\n     * The URL to this channel\n     * @type {string}\n     */\n    get url() {\n        return `https://www.youtube.com/channel/${this.id}`;\n    }\n\n    /**\n     * Get a channel ID from a string (URL or ID)\n     * @param {string} url The string to get the ID from\n     * @returns {?string}\n     */\n    static extractID(url) {\n        return parseURL(url).channel;\n    }\n}\n\nmodule.exports = Channel;\n\n\n//# sourceURL=webpack://SimpleYoutubeAPI/./src/structures/Channel.js?");

/***/ }),

/***/ "./src/structures/Playlist.js":
/*!************************************!*\
  !*** ./src/structures/Playlist.js ***!
  \************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

eval("const { parseURL } = __webpack_require__(/*! ../util */ \"./src/util/index.js\");\nconst Constants = __webpack_require__(/*! ../util/Constants */ \"./src/util/Constants.js\");\nconst Video = __webpack_require__(/*! ./Video */ \"./src/structures/Video.js\");\nconst Channel = __webpack_require__(/*! ./Channel */ \"./src/structures/Channel.js\");\n\n/** Represents a YouTube playlist */\nclass Playlist {\n    /**\n     * @param {YouTube} youtube The YouTube instance creating this\n     * @param {Object} data The data of the playlist\n     */\n    constructor(youtube, data) {\n        /**\n         * The YouTube instance that created this\n         * @type {YouTube}\n         */\n        this.youtube = youtube;\n        Object.defineProperty(this, 'youtube', { enumerable: false });\n\n        /**\n         * The type to filter search results\n         * @type {string}\n         */\n        this.type = 'playlist';\n\n        /**\n         * Videos in this playlist.  Available after calling {@link Playlist#getVideos}.\n         * @type {Array<Video>}\n         */\n        this.videos = [];\n\n        this._patch(data);\n    }\n\n    _patch(data) {\n        if (!data) return;\n\n        this.raw = data;\n\n        /**\n         * The channel this playlist is in\n         * @type {Channel}\n         */\n        this.channel = new Channel(this.youtube, data);\n\n        /**\n         * This playlist's ID\n         * @type {string}\n         * @name Playlist#id\n         */\n\n        switch (data.kind) {\n            case Constants.KINDS.SearchResult:\n                if (data.id.kind === Constants.KINDS.Playlist) this.id = data.id.playlistId;\n                else throw new Error('Attempted to make a playlist out of a non-playlist search result.');\n                break;\n            case Constants.KINDS.Playlist:\n                this.id = data.id;\n                break;\n            case Constants.KINDS.PlaylistItem:\n                if (data.snippet) this.id = data.snippet.playlistId;\n                else throw new Error('Attempted to make a playlist out of a resource with no playlist data.');\n                return this; // don't pull extra info from playlist item info\n            default:\n                throw new Error(`Unknown playlist kind: ${data.kind}.`);\n        }\n\n        if (data.snippet) {\n            /**\n             * This playlist's title\n             * @type {?string}\n             */\n            this.title = data.snippet.title;\n\n            /**\n             * This playlist's description\n             * @type {?string}\n             */\n            this.description = data.snippet.description;\n\n            /**\n             * The date/time this playlist was published\n             * @type {?Date}\n             */\n            this.publishedAt = new Date(data.snippet.publishedAt);\n\n            /**\n             * Thumbnails for this playlist\n             * @type {?Object.<string, Thumbnail>}\n             */\n            this.thumbnails = data.snippet.thumbnails;\n\n            /**\n             * Channel title of this playlist\n             * @type {?string}\n             */\n            this.channelTitle = data.snippet.channelTitle;\n\n            /**\n             * The language in this playlist's title and description\n             * @type {?string}\n             */\n            this.defaultLanguage = data.snippet.defaultLanguage;\n\n            /**\n             * Information about the playlist as specified in the `hl` parameter\n             * @type {?{title: string, description: string}}\n             */\n            this.localized = data.snippet.localized;\n        }\n\n        if (data.status) {\n            /**\n             * The privacy status of this video\n             * @type {string}\n             */\n            this.privacy = data.status.privacyStatus;\n        }\n\n        if (data.contentDetails) {\n            /**\n             * The total number of videos in this playlist\n             * @type {number}\n             */\n            this.length = data.contentDetails.itemCount;\n        }\n\n        if (data.player) {\n            /**\n             * A string with an iframe tag for embedding this playlist\n             * @type {string}\n             */\n            this.embedHTML = data.player.embedHtml;\n        }\n\n        return this;\n    }\n\n    /**\n     * The URL to this playlist\n     * @type {string}\n     */\n    get url() {\n        return `https://www.youtube.com/playlist?list=${this.id}`;\n    }\n\n    /**\n     * Fetch the full representation of this playlist.\n     * @param {object} [options] Any extra query params\n     * @returns {Playlist}\n     */\n    fetch(options) {\n        return this.youtube.request.getPlaylist(this.id, options).then(this._patch.bind(this));\n    }\n\n    /**\n     * Gets videos in the playlist\n     * @param {Number} [limit] Maximum number of videos to obtain.  Fetches all if not provided.\n     * @param {Object} [options] Options to retrieve for each video.\n     * @returns {Promise<Video[]>}\n     */\n    getVideos(limit, options) {\n        return this.youtube.request.getPaginated(\n            Constants.ENDPOINTS.PlaylistItems,\n            limit,\n            Object.assign({ playlistId: this.id, part: Constants.PARTS.PlaylistItems }, options)\n        ).then(items => this.videos = items.map(i => new Video(this.youtube, i)));\n    }\n\n    /**\n     * Get a playlist ID from a string (URL or ID)\n     * @param {string} url The string to get the ID from\n     * @returns {?string}\n     */\n    static extractID(url) {\n        return parseURL(url).playlist;\n    }\n}\n\nmodule.exports = Playlist;\n\n\n//# sourceURL=webpack://SimpleYoutubeAPI/./src/structures/Playlist.js?");

/***/ }),

/***/ "./src/structures/Video.js":
/*!*********************************!*\
  !*** ./src/structures/Video.js ***!
  \*********************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

eval("const duration = __webpack_require__(/*! iso8601-duration */ \"./node_modules/iso8601-duration/lib/index.js\");\r\nconst { parseURL } = __webpack_require__(/*! ../util */ \"./src/util/index.js\");\r\nconst Constants = __webpack_require__(/*! ../util/Constants */ \"./src/util/Constants.js\");\r\nconst Channel = __webpack_require__(/*! ./Channel */ \"./src/structures/Channel.js\");\r\n\r\n/** Represents a YouTube video */\r\nclass Video {\r\n    /**\r\n     * @param {YouTube} youtube The YouTube instance creating this\r\n     * @param {Object} data The data of the video\r\n     */\r\n    constructor(youtube, data) {\r\n        /**\r\n         * The YouTube instance that created this\r\n         * @type {YouTube}\r\n         */\r\n        this.youtube = youtube;\r\n        Object.defineProperty(this, 'youtube', { enumerable: false });\r\n\r\n        /**\r\n         * The type to filter search results\r\n         * @type {string}\r\n         */\r\n        this.type = 'video';\r\n\r\n        this._patch(data);\r\n    }\r\n\r\n    _patch(data) {\r\n        if (!data) return;\r\n\r\n        /**\r\n         * The raw data from the YouTube API.\r\n         * @type {object}\r\n         */\r\n        this.raw = data;\r\n\r\n        /**\r\n         * Whether this is a full (returned from the videos API end point) or partial video (returned\r\n         * as part of another resource).\r\n         * @type {boolean}\r\n         */\r\n        this.full = data.kind === Constants.KINDS.Video;\r\n\r\n        /**\r\n         * The resource that this video was created from.\r\n         * @type {string}\r\n         */\r\n        this.kind = data.kind;\r\n\r\n        /**\r\n         * This video's ID\r\n         * @type {string}\r\n         * @name Video#id\r\n         */\r\n\r\n        switch (data.kind) {\r\n            case Constants.KINDS.PlaylistItem:\r\n                if (data.snippet) {\r\n                    if (data.snippet.resourceId.kind === Constants.KINDS.Video) this.id = data.snippet.resourceId.videoId;\r\n                    else throw new Error('Attempted to make a video out of a non-video playlist item.');\r\n                    break;\r\n                } else {\r\n                    throw new Error('Attempted to make a video out of a playlist item with no video data.');\r\n                }\r\n            case Constants.KINDS.Video:\r\n                this.id = data.id;\r\n                break;\r\n            case Constants.KINDS.SearchResult:\r\n                if (data.id.kind === Constants.KINDS.Video) this.id = data.id.videoId;\r\n                else throw new Error('Attempted to make a video out of a non-video search result.');\r\n                break;\r\n            default:\r\n                throw new Error(`Unknown video kind: ${data.kind}.`);\r\n        }\r\n\r\n        if (data.snippet) {\r\n            /**\r\n             * This video's title\r\n             * @type {string}\r\n             */\r\n            this.title = data.snippet.title;\r\n\r\n            /**\r\n             * This video's description\r\n             * @type {string}\r\n             */\r\n            this.description = data.snippet.description;\r\n\r\n            /**\r\n             * The thumbnails of this video.\r\n             * @type {Object.<'default', 'medium', 'high', 'standard', 'maxres'>}\r\n             */\r\n            this.thumbnails = data.snippet.thumbnails;\r\n\r\n            /**\r\n             * The date/time this video was published\r\n             * @type {Date}\r\n             */\r\n            this.publishedAt = new Date(data.snippet.publishedAt);\r\n\r\n            /**\r\n             * The channel this video is in.\r\n             * @type {Channel}\r\n             */\r\n            this.channel = new Channel(this.youtube, data);\r\n        }\r\n\r\n        if(data.contentDetails) {\r\n            /**\r\n             * An object containing time period information. All properties are integers, and do not include the lower\r\n             * precision ones.\r\n             * @typedef {Object} DurationObject\r\n             * @property {number} [hours] How many hours the video is long\r\n             * @property {number} [minutes] How many minutes the video is long\r\n             * @property {number} [seconds] How many seconds the video is long\r\n             */\r\n\r\n            /**\r\n             * The duration of the video\r\n             * @type {?DurationObject}\r\n             */\r\n            this.duration = data.contentDetails.duration ? duration.parse(data.contentDetails.duration) : null;\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * The maxiumum available resolution thumbnail.\r\n     * @type {object}\r\n     */\r\n    get maxRes() {\r\n        const t = this.thumbnails;\r\n        return t.maxres || t.standard || t.high || t.medium || t.default;\r\n    }\r\n\r\n    /**\r\n     * The URL to this video\r\n     * @type {string}\r\n     */\r\n    get url() {\r\n        return `https://www.youtube.com/watch?v=${this.id}`;\r\n    }\r\n\r\n    /**\r\n     * The short URL to this video\r\n     * @type {string}\r\n     */\r\n    get shortURL() {\r\n        return `https://youtu.be/${this.id}`;\r\n    }\r\n\r\n    /**\r\n     * The duration of the video in seconds\r\n     * @type {number}\r\n     */\r\n    get durationSeconds() {\r\n        return this.duration ? duration.toSeconds(this.duration) : -1;\r\n    }\r\n\r\n    /**\r\n     * Fetch the full representation of this video.\r\n     * @param {object} [options] Any extra query params\r\n     * @returns {Video}\r\n     */\r\n    fetch(options) {\r\n        return this.youtube.request.getVideo(this.id, options).then(this._patch.bind(this));\r\n    }\r\n\r\n    /**\r\n     * Get a video ID from a string (URL or ID)\r\n     * @param {string} url The string to get the ID from\r\n     * @returns {?string}\r\n     */\r\n    static extractID(url) {\r\n        return parseURL(url).video;\r\n    }\r\n}\r\n\r\nmodule.exports = Video;\r\n\n\n//# sourceURL=webpack://SimpleYoutubeAPI/./src/structures/Video.js?");

/***/ }),

/***/ "./src/util/Constants.js":
/*!*******************************!*\
  !*** ./src/util/Constants.js ***!
  \*******************************/
/*! no static exports found */
/***/ (function(module, exports) {

eval("exports.PARTS = {\n    Search: 'snippet',\n    Videos: 'snippet,contentDetails',\n    Playlists: 'snippet',\n    PlaylistItems: 'snippet,status',\n    Channels: 'snippet'\n};\n\nexports.KINDS = {\n    Video: 'youtube#video',\n    PlaylistItem: 'youtube#playlistItem',\n    Playlist: 'youtube#playlist',\n    SearchResult: 'youtube#searchResult',\n    Channel: 'youtube#channel'\n};\n\nexports.ENDPOINTS = {\n    PlaylistItems: 'playlistItems',\n    Channels: 'channels',\n    Videos: 'videos',\n    Playlists: 'playlists',\n    Search: 'search'\n};\n\n\n//# sourceURL=webpack://SimpleYoutubeAPI/./src/util/Constants.js?");

/***/ }),

/***/ "./src/util/index.js":
/*!***************************!*\
  !*** ./src/util/index.js ***!
  \***************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

eval("const { parse } = __webpack_require__(/*! url */ \"./node_modules/url/url.js\");\n\n/**\n * Parse a string as a potential YouTube resource URL.\n * @param {string} url\n * @returns {{video: ?string, channel: ?string, playlist: ?string}}\n */\nexports.parseURL = (url) => {\n    const parsed = parse(url, true);\n    switch (parsed.hostname) {\n        case 'www.youtube.com':\n        case 'youtube.com':\n        case 'm.youtube.com': {\n            const idRegex = /^[a-zA-Z0-9-_]+$/;\n            if (parsed.pathname === '/watch') {\n                if (!idRegex.test(parsed.query.v)) return {};\n                const response = { video: parsed.query.v };\n                if (parsed.query.list) response.playlist = parsed.query.list;\n                return response;\n            } else if (parsed.pathname === '/playlist') {\n                if(!idRegex.test(parsed.query.list)) return {};\n                return { playlist: parsed.query.list };\n            } else if (parsed.pathname.startsWith('/channel/')) {\n                const id = parsed.pathname.replace('/channel/', '');\n                if (!idRegex.test(id)) return {};\n                return { channel: id };\n            }\n\n            return {};\n        }\n        case 'youtu.be':\n            return { video: /^\\/[a-zA-Z0-9-_]+$/.test(parsed.pathname) ? parsed.pathname.slice(1) : null };\n        default:\n            return {};\n    }\n};\n\n\n//# sourceURL=webpack://SimpleYoutubeAPI/./src/util/index.js?");

/***/ })

/******/ });
});