.',\n list[i]\n );\n }\n }\n addAttr(el, name, JSON.stringify(value), list[i]);\n // #6887 firefox doesn't update muted state if set via attribute\n // even immediately after element creation\n if (!el.component &&\n name === 'muted' &&\n platformMustUseProp(el.tag, el.attrsMap.type, name)) {\n addProp(el, name, 'true', list[i]);\n }\n }\n }\n}\n\nfunction checkInFor (el) {\n var parent = el;\n while (parent) {\n if (parent.for !== undefined) {\n return true\n }\n parent = parent.parent;\n }\n return false\n}\n\nfunction parseModifiers (name) {\n var match = name.match(modifierRE);\n if (match) {\n var ret = {};\n match.forEach(function (m) { ret[m.slice(1)] = true; });\n return ret\n }\n}\n\nfunction makeAttrsMap (attrs) {\n var map = {};\n for (var i = 0, l = attrs.length; i < l; i++) {\n if (\n process.env.NODE_ENV !== 'production' &&\n map[attrs[i].name] && !isIE && !isEdge\n ) {\n warn$2('duplicate attribute: ' + attrs[i].name, attrs[i]);\n }\n map[attrs[i].name] = attrs[i].value;\n }\n return map\n}\n\n// for script (e.g. type=\"x/template\") or style, do not decode content\nfunction isTextTag (el) {\n return el.tag === 'script' || el.tag === 'style'\n}\n\nfunction isForbiddenTag (el) {\n return (\n el.tag === 'style' ||\n (el.tag === 'script' && (\n !el.attrsMap.type ||\n el.attrsMap.type === 'text/javascript'\n ))\n )\n}\n\nvar ieNSBug = /^xmlns:NS\\d+/;\nvar ieNSPrefix = /^NS\\d+:/;\n\n/* istanbul ignore next */\nfunction guardIESVGBug (attrs) {\n var res = [];\n for (var i = 0; i < attrs.length; i++) {\n var attr = attrs[i];\n if (!ieNSBug.test(attr.name)) {\n attr.name = attr.name.replace(ieNSPrefix, '');\n res.push(attr);\n }\n }\n return res\n}\n\nfunction checkForAliasModel (el, value) {\n var _el = el;\n while (_el) {\n if (_el.for && _el.alias === value) {\n warn$2(\n \"<\" + (el.tag) + \" v-model=\\\"\" + value + \"\\\">: \" +\n \"You are binding v-model directly to a v-for iteration alias. \" +\n \"This will not be able to modify the v-for source array because \" +\n \"writing to the alias is like modifying a function local variable. \" +\n \"Consider using an array of objects and use v-model on an object property instead.\",\n el.rawAttrsMap['v-model']\n );\n }\n _el = _el.parent;\n }\n}\n\n/* */\n\nfunction preTransformNode (el, options) {\n if (el.tag === 'input') {\n var map = el.attrsMap;\n if (!map['v-model']) {\n return\n }\n\n var typeBinding;\n if (map[':type'] || map['v-bind:type']) {\n typeBinding = getBindingAttr(el, 'type');\n }\n if (!map.type && !typeBinding && map['v-bind']) {\n typeBinding = \"(\" + (map['v-bind']) + \").type\";\n }\n\n if (typeBinding) {\n var ifCondition = getAndRemoveAttr(el, 'v-if', true);\n var ifConditionExtra = ifCondition ? (\"&&(\" + ifCondition + \")\") : \"\";\n var hasElse = getAndRemoveAttr(el, 'v-else', true) != null;\n var elseIfCondition = getAndRemoveAttr(el, 'v-else-if', true);\n // 1. checkbox\n var branch0 = cloneASTElement(el);\n // process for on the main node\n processFor(branch0);\n addRawAttr(branch0, 'type', 'checkbox');\n processElement(branch0, options);\n branch0.processed = true; // prevent it from double-processed\n branch0.if = \"(\" + typeBinding + \")==='checkbox'\" + ifConditionExtra;\n addIfCondition(branch0, {\n exp: branch0.if,\n block: branch0\n });\n // 2. add radio else-if condition\n var branch1 = cloneASTElement(el);\n getAndRemoveAttr(branch1, 'v-for', true);\n addRawAttr(branch1, 'type', 'radio');\n processElement(branch1, options);\n addIfCondition(branch0, {\n exp: \"(\" + typeBinding + \")==='radio'\" + ifConditionExtra,\n block: branch1\n });\n // 3. other\n var branch2 = cloneASTElement(el);\n getAndRemoveAttr(branch2, 'v-for', true);\n addRawAttr(branch2, ':type', typeBinding);\n processElement(branch2, options);\n addIfCondition(branch0, {\n exp: ifCondition,\n block: branch2\n });\n\n if (hasElse) {\n branch0.else = true;\n } else if (elseIfCondition) {\n branch0.elseif = elseIfCondition;\n }\n\n return branch0\n }\n }\n}\n\nfunction cloneASTElement (el) {\n return createASTElement(el.tag, el.attrsList.slice(), el.parent)\n}\n\nvar model$1 = {\n preTransformNode: preTransformNode\n};\n\nvar modules$1 = [\n klass$1,\n style$1,\n model$1\n];\n\n/* */\n\nfunction text (el, dir) {\n if (dir.value) {\n addProp(el, 'textContent', (\"_s(\" + (dir.value) + \")\"), dir);\n }\n}\n\n/* */\n\nfunction html (el, dir) {\n if (dir.value) {\n addProp(el, 'innerHTML', (\"_s(\" + (dir.value) + \")\"), dir);\n }\n}\n\nvar directives$1 = {\n model: model,\n text: text,\n html: html\n};\n\n/* */\n\nvar baseOptions = {\n expectHTML: true,\n modules: modules$1,\n directives: directives$1,\n isPreTag: isPreTag,\n isUnaryTag: isUnaryTag,\n mustUseProp: mustUseProp,\n canBeLeftOpenTag: canBeLeftOpenTag,\n isReservedTag: isReservedTag,\n getTagNamespace: getTagNamespace,\n staticKeys: genStaticKeys(modules$1)\n};\n\n/* */\n\nvar isStaticKey;\nvar isPlatformReservedTag;\n\nvar genStaticKeysCached = cached(genStaticKeys$1);\n\n/**\n * Goal of the optimizer: walk the generated template AST tree\n * and detect sub-trees that are purely static, i.e. parts of\n * the DOM that never needs to change.\n *\n * Once we detect these sub-trees, we can:\n *\n * 1. Hoist them into constants, so that we no longer need to\n * create fresh nodes for them on each re-render;\n * 2. Completely skip them in the patching process.\n */\nfunction optimize (root, options) {\n if (!root) { return }\n isStaticKey = genStaticKeysCached(options.staticKeys || '');\n isPlatformReservedTag = options.isReservedTag || no;\n // first pass: mark all non-static nodes.\n markStatic$1(root);\n // second pass: mark static roots.\n markStaticRoots(root, false);\n}\n\nfunction genStaticKeys$1 (keys) {\n return makeMap(\n 'type,tag,attrsList,attrsMap,plain,parent,children,attrs,start,end,rawAttrsMap' +\n (keys ? ',' + keys : '')\n )\n}\n\nfunction markStatic$1 (node) {\n node.static = isStatic(node);\n if (node.type === 1) {\n // do not make component slot content static. this avoids\n // 1. components not able to mutate slot nodes\n // 2. static slot content fails for hot-reloading\n if (\n !isPlatformReservedTag(node.tag) &&\n node.tag !== 'slot' &&\n node.attrsMap['inline-template'] == null\n ) {\n return\n }\n for (var i = 0, l = node.children.length; i < l; i++) {\n var child = node.children[i];\n markStatic$1(child);\n if (!child.static) {\n node.static = false;\n }\n }\n if (node.ifConditions) {\n for (var i$1 = 1, l$1 = node.ifConditions.length; i$1 < l$1; i$1++) {\n var block = node.ifConditions[i$1].block;\n markStatic$1(block);\n if (!block.static) {\n node.static = false;\n }\n }\n }\n }\n}\n\nfunction markStaticRoots (node, isInFor) {\n if (node.type === 1) {\n if (node.static || node.once) {\n node.staticInFor = isInFor;\n }\n // For a node to qualify as a static root, it should have children that\n // are not just static text. Otherwise the cost of hoisting out will\n // outweigh the benefits and it's better off to just always render it fresh.\n if (node.static && node.children.length && !(\n node.children.length === 1 &&\n node.children[0].type === 3\n )) {\n node.staticRoot = true;\n return\n } else {\n node.staticRoot = false;\n }\n if (node.children) {\n for (var i = 0, l = node.children.length; i < l; i++) {\n markStaticRoots(node.children[i], isInFor || !!node.for);\n }\n }\n if (node.ifConditions) {\n for (var i$1 = 1, l$1 = node.ifConditions.length; i$1 < l$1; i$1++) {\n markStaticRoots(node.ifConditions[i$1].block, isInFor);\n }\n }\n }\n}\n\nfunction isStatic (node) {\n if (node.type === 2) { // expression\n return false\n }\n if (node.type === 3) { // text\n return true\n }\n return !!(node.pre || (\n !node.hasBindings && // no dynamic bindings\n !node.if && !node.for && // not v-if or v-for or v-else\n !isBuiltInTag(node.tag) && // not a built-in\n isPlatformReservedTag(node.tag) && // not a component\n !isDirectChildOfTemplateFor(node) &&\n Object.keys(node).every(isStaticKey)\n ))\n}\n\nfunction isDirectChildOfTemplateFor (node) {\n while (node.parent) {\n node = node.parent;\n if (node.tag !== 'template') {\n return false\n }\n if (node.for) {\n return true\n }\n }\n return false\n}\n\n/* */\n\nvar fnExpRE = /^([\\w$_]+|\\([^)]*?\\))\\s*=>|^function\\s*(?:[\\w$]+)?\\s*\\(/;\nvar fnInvokeRE = /\\([^)]*?\\);*$/;\nvar simplePathRE = /^[A-Za-z_$][\\w$]*(?:\\.[A-Za-z_$][\\w$]*|\\['[^']*?']|\\[\"[^\"]*?\"]|\\[\\d+]|\\[[A-Za-z_$][\\w$]*])*$/;\n\n// KeyboardEvent.keyCode aliases\nvar keyCodes = {\n esc: 27,\n tab: 9,\n enter: 13,\n space: 32,\n up: 38,\n left: 37,\n right: 39,\n down: 40,\n 'delete': [8, 46]\n};\n\n// KeyboardEvent.key aliases\nvar keyNames = {\n // #7880: IE11 and Edge use `Esc` for Escape key name.\n esc: ['Esc', 'Escape'],\n tab: 'Tab',\n enter: 'Enter',\n // #9112: IE11 uses `Spacebar` for Space key name.\n space: [' ', 'Spacebar'],\n // #7806: IE11 uses key names without `Arrow` prefix for arrow keys.\n up: ['Up', 'ArrowUp'],\n left: ['Left', 'ArrowLeft'],\n right: ['Right', 'ArrowRight'],\n down: ['Down', 'ArrowDown'],\n // #9112: IE11 uses `Del` for Delete key name.\n 'delete': ['Backspace', 'Delete', 'Del']\n};\n\n// #4868: modifiers that prevent the execution of the listener\n// need to explicitly return null so that we can determine whether to remove\n// the listener for .once\nvar genGuard = function (condition) { return (\"if(\" + condition + \")return null;\"); };\n\nvar modifierCode = {\n stop: '$event.stopPropagation();',\n prevent: '$event.preventDefault();',\n self: genGuard(\"$event.target !== $event.currentTarget\"),\n ctrl: genGuard(\"!$event.ctrlKey\"),\n shift: genGuard(\"!$event.shiftKey\"),\n alt: genGuard(\"!$event.altKey\"),\n meta: genGuard(\"!$event.metaKey\"),\n left: genGuard(\"'button' in $event && $event.button !== 0\"),\n middle: genGuard(\"'button' in $event && $event.button !== 1\"),\n right: genGuard(\"'button' in $event && $event.button !== 2\")\n};\n\nfunction genHandlers (\n events,\n isNative\n) {\n var prefix = isNative ? 'nativeOn:' : 'on:';\n var staticHandlers = \"\";\n var dynamicHandlers = \"\";\n for (var name in events) {\n var handlerCode = genHandler(events[name]);\n if (events[name] && events[name].dynamic) {\n dynamicHandlers += name + \",\" + handlerCode + \",\";\n } else {\n staticHandlers += \"\\\"\" + name + \"\\\":\" + handlerCode + \",\";\n }\n }\n staticHandlers = \"{\" + (staticHandlers.slice(0, -1)) + \"}\";\n if (dynamicHandlers) {\n return prefix + \"_d(\" + staticHandlers + \",[\" + (dynamicHandlers.slice(0, -1)) + \"])\"\n } else {\n return prefix + staticHandlers\n }\n}\n\nfunction genHandler (handler) {\n if (!handler) {\n return 'function(){}'\n }\n\n if (Array.isArray(handler)) {\n return (\"[\" + (handler.map(function (handler) { return genHandler(handler); }).join(',')) + \"]\")\n }\n\n var isMethodPath = simplePathRE.test(handler.value);\n var isFunctionExpression = fnExpRE.test(handler.value);\n var isFunctionInvocation = simplePathRE.test(handler.value.replace(fnInvokeRE, ''));\n\n if (!handler.modifiers) {\n if (isMethodPath || isFunctionExpression) {\n return handler.value\n }\n return (\"function($event){\" + (isFunctionInvocation ? (\"return \" + (handler.value)) : handler.value) + \"}\") // inline statement\n } else {\n var code = '';\n var genModifierCode = '';\n var keys = [];\n for (var key in handler.modifiers) {\n if (modifierCode[key]) {\n genModifierCode += modifierCode[key];\n // left/right\n if (keyCodes[key]) {\n keys.push(key);\n }\n } else if (key === 'exact') {\n var modifiers = (handler.modifiers);\n genModifierCode += genGuard(\n ['ctrl', 'shift', 'alt', 'meta']\n .filter(function (keyModifier) { return !modifiers[keyModifier]; })\n .map(function (keyModifier) { return (\"$event.\" + keyModifier + \"Key\"); })\n .join('||')\n );\n } else {\n keys.push(key);\n }\n }\n if (keys.length) {\n code += genKeyFilter(keys);\n }\n // Make sure modifiers like prevent and stop get executed after key filtering\n if (genModifierCode) {\n code += genModifierCode;\n }\n var handlerCode = isMethodPath\n ? (\"return \" + (handler.value) + \"($event)\")\n : isFunctionExpression\n ? (\"return (\" + (handler.value) + \")($event)\")\n : isFunctionInvocation\n ? (\"return \" + (handler.value))\n : handler.value;\n return (\"function($event){\" + code + handlerCode + \"}\")\n }\n}\n\nfunction genKeyFilter (keys) {\n return (\n // make sure the key filters only apply to KeyboardEvents\n // #9441: can't use 'keyCode' in $event because Chrome autofill fires fake\n // key events that do not have keyCode property...\n \"if(!$event.type.indexOf('key')&&\" +\n (keys.map(genFilterCode).join('&&')) + \")return null;\"\n )\n}\n\nfunction genFilterCode (key) {\n var keyVal = parseInt(key, 10);\n if (keyVal) {\n return (\"$event.keyCode!==\" + keyVal)\n }\n var keyCode = keyCodes[key];\n var keyName = keyNames[key];\n return (\n \"_k($event.keyCode,\" +\n (JSON.stringify(key)) + \",\" +\n (JSON.stringify(keyCode)) + \",\" +\n \"$event.key,\" +\n \"\" + (JSON.stringify(keyName)) +\n \")\"\n )\n}\n\n/* */\n\nfunction on (el, dir) {\n if (process.env.NODE_ENV !== 'production' && dir.modifiers) {\n warn(\"v-on without argument does not support modifiers.\");\n }\n el.wrapListeners = function (code) { return (\"_g(\" + code + \",\" + (dir.value) + \")\"); };\n}\n\n/* */\n\nfunction bind$1 (el, dir) {\n el.wrapData = function (code) {\n return (\"_b(\" + code + \",'\" + (el.tag) + \"',\" + (dir.value) + \",\" + (dir.modifiers && dir.modifiers.prop ? 'true' : 'false') + (dir.modifiers && dir.modifiers.sync ? ',true' : '') + \")\")\n };\n}\n\n/* */\n\nvar baseDirectives = {\n on: on,\n bind: bind$1,\n cloak: noop\n};\n\n/* */\n\n\n\n\n\nvar CodegenState = function CodegenState (options) {\n this.options = options;\n this.warn = options.warn || baseWarn;\n this.transforms = pluckModuleFunction(options.modules, 'transformCode');\n this.dataGenFns = pluckModuleFunction(options.modules, 'genData');\n this.directives = extend(extend({}, baseDirectives), options.directives);\n var isReservedTag = options.isReservedTag || no;\n this.maybeComponent = function (el) { return !!el.component || !isReservedTag(el.tag); };\n this.onceId = 0;\n this.staticRenderFns = [];\n this.pre = false;\n};\n\n\n\nfunction generate (\n ast,\n options\n) {\n var state = new CodegenState(options);\n var code = ast ? genElement(ast, state) : '_c(\"div\")';\n return {\n render: (\"with(this){return \" + code + \"}\"),\n staticRenderFns: state.staticRenderFns\n }\n}\n\nfunction genElement (el, state) {\n if (el.parent) {\n el.pre = el.pre || el.parent.pre;\n }\n\n if (el.staticRoot && !el.staticProcessed) {\n return genStatic(el, state)\n } else if (el.once && !el.onceProcessed) {\n return genOnce(el, state)\n } else if (el.for && !el.forProcessed) {\n return genFor(el, state)\n } else if (el.if && !el.ifProcessed) {\n return genIf(el, state)\n } else if (el.tag === 'template' && !el.slotTarget && !state.pre) {\n return genChildren(el, state) || 'void 0'\n } else if (el.tag === 'slot') {\n return genSlot(el, state)\n } else {\n // component or element\n var code;\n if (el.component) {\n code = genComponent(el.component, el, state);\n } else {\n var data;\n if (!el.plain || (el.pre && state.maybeComponent(el))) {\n data = genData$2(el, state);\n }\n\n var children = el.inlineTemplate ? null : genChildren(el, state, true);\n code = \"_c('\" + (el.tag) + \"'\" + (data ? (\",\" + data) : '') + (children ? (\",\" + children) : '') + \")\";\n }\n // module transforms\n for (var i = 0; i < state.transforms.length; i++) {\n code = state.transforms[i](el, code);\n }\n return code\n }\n}\n\n// hoist static sub-trees out\nfunction genStatic (el, state) {\n el.staticProcessed = true;\n // Some elements (templates) need to behave differently inside of a v-pre\n // node. All pre nodes are static roots, so we can use this as a location to\n // wrap a state change and reset it upon exiting the pre node.\n var originalPreState = state.pre;\n if (el.pre) {\n state.pre = el.pre;\n }\n state.staticRenderFns.push((\"with(this){return \" + (genElement(el, state)) + \"}\"));\n state.pre = originalPreState;\n return (\"_m(\" + (state.staticRenderFns.length - 1) + (el.staticInFor ? ',true' : '') + \")\")\n}\n\n// v-once\nfunction genOnce (el, state) {\n el.onceProcessed = true;\n if (el.if && !el.ifProcessed) {\n return genIf(el, state)\n } else if (el.staticInFor) {\n var key = '';\n var parent = el.parent;\n while (parent) {\n if (parent.for) {\n key = parent.key;\n break\n }\n parent = parent.parent;\n }\n if (!key) {\n process.env.NODE_ENV !== 'production' && state.warn(\n \"v-once can only be used inside v-for that is keyed. \",\n el.rawAttrsMap['v-once']\n );\n return genElement(el, state)\n }\n return (\"_o(\" + (genElement(el, state)) + \",\" + (state.onceId++) + \",\" + key + \")\")\n } else {\n return genStatic(el, state)\n }\n}\n\nfunction genIf (\n el,\n state,\n altGen,\n altEmpty\n) {\n el.ifProcessed = true; // avoid recursion\n return genIfConditions(el.ifConditions.slice(), state, altGen, altEmpty)\n}\n\nfunction genIfConditions (\n conditions,\n state,\n altGen,\n altEmpty\n) {\n if (!conditions.length) {\n return altEmpty || '_e()'\n }\n\n var condition = conditions.shift();\n if (condition.exp) {\n return (\"(\" + (condition.exp) + \")?\" + (genTernaryExp(condition.block)) + \":\" + (genIfConditions(conditions, state, altGen, altEmpty)))\n } else {\n return (\"\" + (genTernaryExp(condition.block)))\n }\n\n // v-if with v-once should generate code like (a)?_m(0):_m(1)\n function genTernaryExp (el) {\n return altGen\n ? altGen(el, state)\n : el.once\n ? genOnce(el, state)\n : genElement(el, state)\n }\n}\n\nfunction genFor (\n el,\n state,\n altGen,\n altHelper\n) {\n var exp = el.for;\n var alias = el.alias;\n var iterator1 = el.iterator1 ? (\",\" + (el.iterator1)) : '';\n var iterator2 = el.iterator2 ? (\",\" + (el.iterator2)) : '';\n\n if (process.env.NODE_ENV !== 'production' &&\n state.maybeComponent(el) &&\n el.tag !== 'slot' &&\n el.tag !== 'template' &&\n !el.key\n ) {\n state.warn(\n \"<\" + (el.tag) + \" v-for=\\\"\" + alias + \" in \" + exp + \"\\\">: component lists rendered with \" +\n \"v-for should have explicit keys. \" +\n \"See https://vuejs.org/guide/list.html#key for more info.\",\n el.rawAttrsMap['v-for'],\n true /* tip */\n );\n }\n\n el.forProcessed = true; // avoid recursion\n return (altHelper || '_l') + \"((\" + exp + \"),\" +\n \"function(\" + alias + iterator1 + iterator2 + \"){\" +\n \"return \" + ((altGen || genElement)(el, state)) +\n '})'\n}\n\nfunction genData$2 (el, state) {\n var data = '{';\n\n // directives first.\n // directives may mutate the el's other properties before they are generated.\n var dirs = genDirectives(el, state);\n if (dirs) { data += dirs + ','; }\n\n // key\n if (el.key) {\n data += \"key:\" + (el.key) + \",\";\n }\n // ref\n if (el.ref) {\n data += \"ref:\" + (el.ref) + \",\";\n }\n if (el.refInFor) {\n data += \"refInFor:true,\";\n }\n // pre\n if (el.pre) {\n data += \"pre:true,\";\n }\n // record original tag name for components using \"is\" attribute\n if (el.component) {\n data += \"tag:\\\"\" + (el.tag) + \"\\\",\";\n }\n // module data generation functions\n for (var i = 0; i < state.dataGenFns.length; i++) {\n data += state.dataGenFns[i](el);\n }\n // attributes\n if (el.attrs) {\n data += \"attrs:\" + (genProps(el.attrs)) + \",\";\n }\n // DOM props\n if (el.props) {\n data += \"domProps:\" + (genProps(el.props)) + \",\";\n }\n // event handlers\n if (el.events) {\n data += (genHandlers(el.events, false)) + \",\";\n }\n if (el.nativeEvents) {\n data += (genHandlers(el.nativeEvents, true)) + \",\";\n }\n // slot target\n // only for non-scoped slots\n if (el.slotTarget && !el.slotScope) {\n data += \"slot:\" + (el.slotTarget) + \",\";\n }\n // scoped slots\n if (el.scopedSlots) {\n data += (genScopedSlots(el, el.scopedSlots, state)) + \",\";\n }\n // component v-model\n if (el.model) {\n data += \"model:{value:\" + (el.model.value) + \",callback:\" + (el.model.callback) + \",expression:\" + (el.model.expression) + \"},\";\n }\n // inline-template\n if (el.inlineTemplate) {\n var inlineTemplate = genInlineTemplate(el, state);\n if (inlineTemplate) {\n data += inlineTemplate + \",\";\n }\n }\n data = data.replace(/,$/, '') + '}';\n // v-bind dynamic argument wrap\n // v-bind with dynamic arguments must be applied using the same v-bind object\n // merge helper so that class/style/mustUseProp attrs are handled correctly.\n if (el.dynamicAttrs) {\n data = \"_b(\" + data + \",\\\"\" + (el.tag) + \"\\\",\" + (genProps(el.dynamicAttrs)) + \")\";\n }\n // v-bind data wrap\n if (el.wrapData) {\n data = el.wrapData(data);\n }\n // v-on data wrap\n if (el.wrapListeners) {\n data = el.wrapListeners(data);\n }\n return data\n}\n\nfunction genDirectives (el, state) {\n var dirs = el.directives;\n if (!dirs) { return }\n var res = 'directives:[';\n var hasRuntime = false;\n var i, l, dir, needRuntime;\n for (i = 0, l = dirs.length; i < l; i++) {\n dir = dirs[i];\n needRuntime = true;\n var gen = state.directives[dir.name];\n if (gen) {\n // compile-time directive that manipulates AST.\n // returns true if it also needs a runtime counterpart.\n needRuntime = !!gen(el, dir, state.warn);\n }\n if (needRuntime) {\n hasRuntime = true;\n res += \"{name:\\\"\" + (dir.name) + \"\\\",rawName:\\\"\" + (dir.rawName) + \"\\\"\" + (dir.value ? (\",value:(\" + (dir.value) + \"),expression:\" + (JSON.stringify(dir.value))) : '') + (dir.arg ? (\",arg:\" + (dir.isDynamicArg ? dir.arg : (\"\\\"\" + (dir.arg) + \"\\\"\"))) : '') + (dir.modifiers ? (\",modifiers:\" + (JSON.stringify(dir.modifiers))) : '') + \"},\";\n }\n }\n if (hasRuntime) {\n return res.slice(0, -1) + ']'\n }\n}\n\nfunction genInlineTemplate (el, state) {\n var ast = el.children[0];\n if (process.env.NODE_ENV !== 'production' && (\n el.children.length !== 1 || ast.type !== 1\n )) {\n state.warn(\n 'Inline-template components must have exactly one child element.',\n { start: el.start }\n );\n }\n if (ast && ast.type === 1) {\n var inlineRenderFns = generate(ast, state.options);\n return (\"inlineTemplate:{render:function(){\" + (inlineRenderFns.render) + \"},staticRenderFns:[\" + (inlineRenderFns.staticRenderFns.map(function (code) { return (\"function(){\" + code + \"}\"); }).join(',')) + \"]}\")\n }\n}\n\nfunction genScopedSlots (\n el,\n slots,\n state\n) {\n // by default scoped slots are considered \"stable\", this allows child\n // components with only scoped slots to skip forced updates from parent.\n // but in some cases we have to bail-out of this optimization\n // for example if the slot contains dynamic names, has v-if or v-for on them...\n var needsForceUpdate = el.for || Object.keys(slots).some(function (key) {\n var slot = slots[key];\n return (\n slot.slotTargetDynamic ||\n slot.if ||\n slot.for ||\n containsSlotChild(slot) // is passing down slot from parent which may be dynamic\n )\n });\n\n // #9534: if a component with scoped slots is inside a conditional branch,\n // it's possible for the same component to be reused but with different\n // compiled slot content. To avoid that, we generate a unique key based on\n // the generated code of all the slot contents.\n var needsKey = !!el.if;\n\n // OR when it is inside another scoped slot or v-for (the reactivity may be\n // disconnected due to the intermediate scope variable)\n // #9438, #9506\n // TODO: this can be further optimized by properly analyzing in-scope bindings\n // and skip force updating ones that do not actually use scope variables.\n if (!needsForceUpdate) {\n var parent = el.parent;\n while (parent) {\n if (\n (parent.slotScope && parent.slotScope !== emptySlotScopeToken) ||\n parent.for\n ) {\n needsForceUpdate = true;\n break\n }\n if (parent.if) {\n needsKey = true;\n }\n parent = parent.parent;\n }\n }\n\n var generatedSlots = Object.keys(slots)\n .map(function (key) { return genScopedSlot(slots[key], state); })\n .join(',');\n\n return (\"scopedSlots:_u([\" + generatedSlots + \"]\" + (needsForceUpdate ? \",null,true\" : \"\") + (!needsForceUpdate && needsKey ? (\",null,false,\" + (hash(generatedSlots))) : \"\") + \")\")\n}\n\nfunction hash(str) {\n var hash = 5381;\n var i = str.length;\n while(i) {\n hash = (hash * 33) ^ str.charCodeAt(--i);\n }\n return hash >>> 0\n}\n\nfunction containsSlotChild (el) {\n if (el.type === 1) {\n if (el.tag === 'slot') {\n return true\n }\n return el.children.some(containsSlotChild)\n }\n return false\n}\n\nfunction genScopedSlot (\n el,\n state\n) {\n var isLegacySyntax = el.attrsMap['slot-scope'];\n if (el.if && !el.ifProcessed && !isLegacySyntax) {\n return genIf(el, state, genScopedSlot, \"null\")\n }\n if (el.for && !el.forProcessed) {\n return genFor(el, state, genScopedSlot)\n }\n var slotScope = el.slotScope === emptySlotScopeToken\n ? \"\"\n : String(el.slotScope);\n var fn = \"function(\" + slotScope + \"){\" +\n \"return \" + (el.tag === 'template'\n ? el.if && isLegacySyntax\n ? (\"(\" + (el.if) + \")?\" + (genChildren(el, state) || 'undefined') + \":undefined\")\n : genChildren(el, state) || 'undefined'\n : genElement(el, state)) + \"}\";\n // reverse proxy v-slot without scope on this.$slots\n var reverseProxy = slotScope ? \"\" : \",proxy:true\";\n return (\"{key:\" + (el.slotTarget || \"\\\"default\\\"\") + \",fn:\" + fn + reverseProxy + \"}\")\n}\n\nfunction genChildren (\n el,\n state,\n checkSkip,\n altGenElement,\n altGenNode\n) {\n var children = el.children;\n if (children.length) {\n var el$1 = children[0];\n // optimize single v-for\n if (children.length === 1 &&\n el$1.for &&\n el$1.tag !== 'template' &&\n el$1.tag !== 'slot'\n ) {\n var normalizationType = checkSkip\n ? state.maybeComponent(el$1) ? \",1\" : \",0\"\n : \"\";\n return (\"\" + ((altGenElement || genElement)(el$1, state)) + normalizationType)\n }\n var normalizationType$1 = checkSkip\n ? getNormalizationType(children, state.maybeComponent)\n : 0;\n var gen = altGenNode || genNode;\n return (\"[\" + (children.map(function (c) { return gen(c, state); }).join(',')) + \"]\" + (normalizationType$1 ? (\",\" + normalizationType$1) : ''))\n }\n}\n\n// determine the normalization needed for the children array.\n// 0: no normalization needed\n// 1: simple normalization needed (possible 1-level deep nested array)\n// 2: full normalization needed\nfunction getNormalizationType (\n children,\n maybeComponent\n) {\n var res = 0;\n for (var i = 0; i < children.length; i++) {\n var el = children[i];\n if (el.type !== 1) {\n continue\n }\n if (needsNormalization(el) ||\n (el.ifConditions && el.ifConditions.some(function (c) { return needsNormalization(c.block); }))) {\n res = 2;\n break\n }\n if (maybeComponent(el) ||\n (el.ifConditions && el.ifConditions.some(function (c) { return maybeComponent(c.block); }))) {\n res = 1;\n }\n }\n return res\n}\n\nfunction needsNormalization (el) {\n return el.for !== undefined || el.tag === 'template' || el.tag === 'slot'\n}\n\nfunction genNode (node, state) {\n if (node.type === 1) {\n return genElement(node, state)\n } else if (node.type === 3 && node.isComment) {\n return genComment(node)\n } else {\n return genText(node)\n }\n}\n\nfunction genText (text) {\n return (\"_v(\" + (text.type === 2\n ? text.expression // no need for () because already wrapped in _s()\n : transformSpecialNewlines(JSON.stringify(text.text))) + \")\")\n}\n\nfunction genComment (comment) {\n return (\"_e(\" + (JSON.stringify(comment.text)) + \")\")\n}\n\nfunction genSlot (el, state) {\n var slotName = el.slotName || '\"default\"';\n var children = genChildren(el, state);\n var res = \"_t(\" + slotName + (children ? (\",\" + children) : '');\n var attrs = el.attrs || el.dynamicAttrs\n ? genProps((el.attrs || []).concat(el.dynamicAttrs || []).map(function (attr) { return ({\n // slot props are camelized\n name: camelize(attr.name),\n value: attr.value,\n dynamic: attr.dynamic\n }); }))\n : null;\n var bind$$1 = el.attrsMap['v-bind'];\n if ((attrs || bind$$1) && !children) {\n res += \",null\";\n }\n if (attrs) {\n res += \",\" + attrs;\n }\n if (bind$$1) {\n res += (attrs ? '' : ',null') + \",\" + bind$$1;\n }\n return res + ')'\n}\n\n// componentName is el.component, take it as argument to shun flow's pessimistic refinement\nfunction genComponent (\n componentName,\n el,\n state\n) {\n var children = el.inlineTemplate ? null : genChildren(el, state, true);\n return (\"_c(\" + componentName + \",\" + (genData$2(el, state)) + (children ? (\",\" + children) : '') + \")\")\n}\n\nfunction genProps (props) {\n var staticProps = \"\";\n var dynamicProps = \"\";\n for (var i = 0; i < props.length; i++) {\n var prop = props[i];\n var value = transformSpecialNewlines(prop.value);\n if (prop.dynamic) {\n dynamicProps += (prop.name) + \",\" + value + \",\";\n } else {\n staticProps += \"\\\"\" + (prop.name) + \"\\\":\" + value + \",\";\n }\n }\n staticProps = \"{\" + (staticProps.slice(0, -1)) + \"}\";\n if (dynamicProps) {\n return (\"_d(\" + staticProps + \",[\" + (dynamicProps.slice(0, -1)) + \"])\")\n } else {\n return staticProps\n }\n}\n\n// #3895, #4268\nfunction transformSpecialNewlines (text) {\n return text\n .replace(/\\u2028/g, '\\\\u2028')\n .replace(/\\u2029/g, '\\\\u2029')\n}\n\n/* */\n\n\n\n// these keywords should not appear inside expressions, but operators like\n// typeof, instanceof and in are allowed\nvar prohibitedKeywordRE = new RegExp('\\\\b' + (\n 'do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +\n 'super,throw,while,yield,delete,export,import,return,switch,default,' +\n 'extends,finally,continue,debugger,function,arguments'\n).split(',').join('\\\\b|\\\\b') + '\\\\b');\n\n// these unary operators should not be used as property/method names\nvar unaryOperatorsRE = new RegExp('\\\\b' + (\n 'delete,typeof,void'\n).split(',').join('\\\\s*\\\\([^\\\\)]*\\\\)|\\\\b') + '\\\\s*\\\\([^\\\\)]*\\\\)');\n\n// strip strings in expressions\nvar stripStringRE = /'(?:[^'\\\\]|\\\\.)*'|\"(?:[^\"\\\\]|\\\\.)*\"|`(?:[^`\\\\]|\\\\.)*\\$\\{|\\}(?:[^`\\\\]|\\\\.)*`|`(?:[^`\\\\]|\\\\.)*`/g;\n\n// detect problematic expressions in a template\nfunction detectErrors (ast, warn) {\n if (ast) {\n checkNode(ast, warn);\n }\n}\n\nfunction checkNode (node, warn) {\n if (node.type === 1) {\n for (var name in node.attrsMap) {\n if (dirRE.test(name)) {\n var value = node.attrsMap[name];\n if (value) {\n var range = node.rawAttrsMap[name];\n if (name === 'v-for') {\n checkFor(node, (\"v-for=\\\"\" + value + \"\\\"\"), warn, range);\n } else if (onRE.test(name)) {\n checkEvent(value, (name + \"=\\\"\" + value + \"\\\"\"), warn, range);\n } else {\n checkExpression(value, (name + \"=\\\"\" + value + \"\\\"\"), warn, range);\n }\n }\n }\n }\n if (node.children) {\n for (var i = 0; i < node.children.length; i++) {\n checkNode(node.children[i], warn);\n }\n }\n } else if (node.type === 2) {\n checkExpression(node.expression, node.text, warn, node);\n }\n}\n\nfunction checkEvent (exp, text, warn, range) {\n var stipped = exp.replace(stripStringRE, '');\n var keywordMatch = stipped.match(unaryOperatorsRE);\n if (keywordMatch && stipped.charAt(keywordMatch.index - 1) !== '$') {\n warn(\n \"avoid using JavaScript unary operator as property name: \" +\n \"\\\"\" + (keywordMatch[0]) + \"\\\" in expression \" + (text.trim()),\n range\n );\n }\n checkExpression(exp, text, warn, range);\n}\n\nfunction checkFor (node, text, warn, range) {\n checkExpression(node.for || '', text, warn, range);\n checkIdentifier(node.alias, 'v-for alias', text, warn, range);\n checkIdentifier(node.iterator1, 'v-for iterator', text, warn, range);\n checkIdentifier(node.iterator2, 'v-for iterator', text, warn, range);\n}\n\nfunction checkIdentifier (\n ident,\n type,\n text,\n warn,\n range\n) {\n if (typeof ident === 'string') {\n try {\n new Function((\"var \" + ident + \"=_\"));\n } catch (e) {\n warn((\"invalid \" + type + \" \\\"\" + ident + \"\\\" in expression: \" + (text.trim())), range);\n }\n }\n}\n\nfunction checkExpression (exp, text, warn, range) {\n try {\n new Function((\"return \" + exp));\n } catch (e) {\n var keywordMatch = exp.replace(stripStringRE, '').match(prohibitedKeywordRE);\n if (keywordMatch) {\n warn(\n \"avoid using JavaScript keyword as property name: \" +\n \"\\\"\" + (keywordMatch[0]) + \"\\\"\\n Raw expression: \" + (text.trim()),\n range\n );\n } else {\n warn(\n \"invalid expression: \" + (e.message) + \" in\\n\\n\" +\n \" \" + exp + \"\\n\\n\" +\n \" Raw expression: \" + (text.trim()) + \"\\n\",\n range\n );\n }\n }\n}\n\n/* */\n\nvar range = 2;\n\nfunction generateCodeFrame (\n source,\n start,\n end\n) {\n if ( start === void 0 ) start = 0;\n if ( end === void 0 ) end = source.length;\n\n var lines = source.split(/\\r?\\n/);\n var count = 0;\n var res = [];\n for (var i = 0; i < lines.length; i++) {\n count += lines[i].length + 1;\n if (count >= start) {\n for (var j = i - range; j <= i + range || end > count; j++) {\n if (j < 0 || j >= lines.length) { continue }\n res.push((\"\" + (j + 1) + (repeat$1(\" \", 3 - String(j + 1).length)) + \"| \" + (lines[j])));\n var lineLength = lines[j].length;\n if (j === i) {\n // push underline\n var pad = start - (count - lineLength) + 1;\n var length = end > count ? lineLength - pad : end - start;\n res.push(\" | \" + repeat$1(\" \", pad) + repeat$1(\"^\", length));\n } else if (j > i) {\n if (end > count) {\n var length$1 = Math.min(end - count, lineLength);\n res.push(\" | \" + repeat$1(\"^\", length$1));\n }\n count += lineLength + 1;\n }\n }\n break\n }\n }\n return res.join('\\n')\n}\n\nfunction repeat$1 (str, n) {\n var result = '';\n if (n > 0) {\n while (true) { // eslint-disable-line\n if (n & 1) { result += str; }\n n >>>= 1;\n if (n <= 0) { break }\n str += str;\n }\n }\n return result\n}\n\n/* */\n\n\n\nfunction createFunction (code, errors) {\n try {\n return new Function(code)\n } catch (err) {\n errors.push({ err: err, code: code });\n return noop\n }\n}\n\nfunction createCompileToFunctionFn (compile) {\n var cache = Object.create(null);\n\n return function compileToFunctions (\n template,\n options,\n vm\n ) {\n options = extend({}, options);\n var warn$$1 = options.warn || warn;\n delete options.warn;\n\n /* istanbul ignore if */\n if (process.env.NODE_ENV !== 'production') {\n // detect possible CSP restriction\n try {\n new Function('return 1');\n } catch (e) {\n if (e.toString().match(/unsafe-eval|CSP/)) {\n warn$$1(\n 'It seems you are using the standalone build of Vue.js in an ' +\n 'environment with Content Security Policy that prohibits unsafe-eval. ' +\n 'The template compiler cannot work in this environment. Consider ' +\n 'relaxing the policy to allow unsafe-eval or pre-compiling your ' +\n 'templates into render functions.'\n );\n }\n }\n }\n\n // check cache\n var key = options.delimiters\n ? String(options.delimiters) + template\n : template;\n if (cache[key]) {\n return cache[key]\n }\n\n // compile\n var compiled = compile(template, options);\n\n // check compilation errors/tips\n if (process.env.NODE_ENV !== 'production') {\n if (compiled.errors && compiled.errors.length) {\n if (options.outputSourceRange) {\n compiled.errors.forEach(function (e) {\n warn$$1(\n \"Error compiling template:\\n\\n\" + (e.msg) + \"\\n\\n\" +\n generateCodeFrame(template, e.start, e.end),\n vm\n );\n });\n } else {\n warn$$1(\n \"Error compiling template:\\n\\n\" + template + \"\\n\\n\" +\n compiled.errors.map(function (e) { return (\"- \" + e); }).join('\\n') + '\\n',\n vm\n );\n }\n }\n if (compiled.tips && compiled.tips.length) {\n if (options.outputSourceRange) {\n compiled.tips.forEach(function (e) { return tip(e.msg, vm); });\n } else {\n compiled.tips.forEach(function (msg) { return tip(msg, vm); });\n }\n }\n }\n\n // turn code into functions\n var res = {};\n var fnGenErrors = [];\n res.render = createFunction(compiled.render, fnGenErrors);\n res.staticRenderFns = compiled.staticRenderFns.map(function (code) {\n return createFunction(code, fnGenErrors)\n });\n\n // check function generation errors.\n // this should only happen if there is a bug in the compiler itself.\n // mostly for codegen development use\n /* istanbul ignore if */\n if (process.env.NODE_ENV !== 'production') {\n if ((!compiled.errors || !compiled.errors.length) && fnGenErrors.length) {\n warn$$1(\n \"Failed to generate render function:\\n\\n\" +\n fnGenErrors.map(function (ref) {\n var err = ref.err;\n var code = ref.code;\n\n return ((err.toString()) + \" in\\n\\n\" + code + \"\\n\");\n }).join('\\n'),\n vm\n );\n }\n }\n\n return (cache[key] = res)\n }\n}\n\n/* */\n\nfunction createCompilerCreator (baseCompile) {\n return function createCompiler (baseOptions) {\n function compile (\n template,\n options\n ) {\n var finalOptions = Object.create(baseOptions);\n var errors = [];\n var tips = [];\n\n var warn = function (msg, range, tip) {\n (tip ? tips : errors).push(msg);\n };\n\n if (options) {\n if (process.env.NODE_ENV !== 'production' && options.outputSourceRange) {\n // $flow-disable-line\n var leadingSpaceLength = template.match(/^\\s*/)[0].length;\n\n warn = function (msg, range, tip) {\n var data = { msg: msg };\n if (range) {\n if (range.start != null) {\n data.start = range.start + leadingSpaceLength;\n }\n if (range.end != null) {\n data.end = range.end + leadingSpaceLength;\n }\n }\n (tip ? tips : errors).push(data);\n };\n }\n // merge custom modules\n if (options.modules) {\n finalOptions.modules =\n (baseOptions.modules || []).concat(options.modules);\n }\n // merge custom directives\n if (options.directives) {\n finalOptions.directives = extend(\n Object.create(baseOptions.directives || null),\n options.directives\n );\n }\n // copy other options\n for (var key in options) {\n if (key !== 'modules' && key !== 'directives') {\n finalOptions[key] = options[key];\n }\n }\n }\n\n finalOptions.warn = warn;\n\n var compiled = baseCompile(template.trim(), finalOptions);\n if (process.env.NODE_ENV !== 'production') {\n detectErrors(compiled.ast, warn);\n }\n compiled.errors = errors;\n compiled.tips = tips;\n return compiled\n }\n\n return {\n compile: compile,\n compileToFunctions: createCompileToFunctionFn(compile)\n }\n }\n}\n\n/* */\n\n// `createCompilerCreator` allows creating compilers that use alternative\n// parser/optimizer/codegen, e.g the SSR optimizing compiler.\n// Here we just export a default compiler using the default parts.\nvar createCompiler = createCompilerCreator(function baseCompile (\n template,\n options\n) {\n var ast = parse(template.trim(), options);\n if (options.optimize !== false) {\n optimize(ast, options);\n }\n var code = generate(ast, options);\n return {\n ast: ast,\n render: code.render,\n staticRenderFns: code.staticRenderFns\n }\n});\n\n/* */\n\nvar ref$1 = createCompiler(baseOptions);\nvar compile = ref$1.compile;\nvar compileToFunctions = ref$1.compileToFunctions;\n\n/* */\n\n// check whether current browser encodes a char inside attribute values\nvar div;\nfunction getShouldDecode (href) {\n div = div || document.createElement('div');\n div.innerHTML = href ? \"
\" : \"\";\n return div.innerHTML.indexOf('
') > 0\n}\n\n// #3663: IE encodes newlines inside attribute values while other browsers don't\nvar shouldDecodeNewlines = inBrowser ? getShouldDecode(false) : false;\n// #6828: chrome encodes content in a[href]\nvar shouldDecodeNewlinesForHref = inBrowser ? getShouldDecode(true) : false;\n\n/* */\n\nvar idToTemplate = cached(function (id) {\n var el = query(id);\n return el && el.innerHTML\n});\n\nvar mount = Vue.prototype.$mount;\nVue.prototype.$mount = function (\n el,\n hydrating\n) {\n el = el && query(el);\n\n /* istanbul ignore if */\n if (el === document.body || el === document.documentElement) {\n process.env.NODE_ENV !== 'production' && warn(\n \"Do not mount Vue to or - mount to normal elements instead.\"\n );\n return this\n }\n\n var options = this.$options;\n // resolve template/el and convert to render function\n if (!options.render) {\n var template = options.template;\n if (template) {\n if (typeof template === 'string') {\n if (template.charAt(0) === '#') {\n template = idToTemplate(template);\n /* istanbul ignore if */\n if (process.env.NODE_ENV !== 'production' && !template) {\n warn(\n (\"Template element not found or is empty: \" + (options.template)),\n this\n );\n }\n }\n } else if (template.nodeType) {\n template = template.innerHTML;\n } else {\n if (process.env.NODE_ENV !== 'production') {\n warn('invalid template option:' + template, this);\n }\n return this\n }\n } else if (el) {\n template = getOuterHTML(el);\n }\n if (template) {\n /* istanbul ignore if */\n if (process.env.NODE_ENV !== 'production' && config.performance && mark) {\n mark('compile');\n }\n\n var ref = compileToFunctions(template, {\n outputSourceRange: process.env.NODE_ENV !== 'production',\n shouldDecodeNewlines: shouldDecodeNewlines,\n shouldDecodeNewlinesForHref: shouldDecodeNewlinesForHref,\n delimiters: options.delimiters,\n comments: options.comments\n }, this);\n var render = ref.render;\n var staticRenderFns = ref.staticRenderFns;\n options.render = render;\n options.staticRenderFns = staticRenderFns;\n\n /* istanbul ignore if */\n if (process.env.NODE_ENV !== 'production' && config.performance && mark) {\n mark('compile end');\n measure((\"vue \" + (this._name) + \" compile\"), 'compile', 'compile end');\n }\n }\n }\n return mount.call(this, el, hydrating)\n};\n\n/**\n * Get outerHTML of elements, taking care\n * of SVG elements in IE as well.\n */\nfunction getOuterHTML (el) {\n if (el.outerHTML) {\n return el.outerHTML\n } else {\n var container = document.createElement('div');\n container.appendChild(el.cloneNode(true));\n return container.innerHTML\n }\n}\n\nVue.compile = compileToFunctions;\n\nexport default Vue;\n","// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])\nvar anObject = require('./_an-object');\nvar dPs = require('./_object-dps');\nvar enumBugKeys = require('./_enum-bug-keys');\nvar IE_PROTO = require('./_shared-key')('IE_PROTO');\nvar Empty = function () { /* empty */ };\nvar PROTOTYPE = 'prototype';\n\n// Create object with fake `null` prototype: use iframe Object with cleared prototype\nvar createDict = function () {\n // Thrash, waste and sodomy: IE GC bug\n var iframe = require('./_dom-create')('iframe');\n var i = enumBugKeys.length;\n var lt = '<';\n var gt = '>';\n var iframeDocument;\n iframe.style.display = 'none';\n require('./_html').appendChild(iframe);\n iframe.src = 'javascript:'; // eslint-disable-line no-script-url\n // createDict = iframe.contentWindow.Object;\n // html.removeChild(iframe);\n iframeDocument = iframe.contentWindow.document;\n iframeDocument.open();\n iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);\n iframeDocument.close();\n createDict = iframeDocument.F;\n while (i--) delete createDict[PROTOTYPE][enumBugKeys[i]];\n return createDict();\n};\n\nmodule.exports = Object.create || function create(O, Properties) {\n var result;\n if (O !== null) {\n Empty[PROTOTYPE] = anObject(O);\n result = new Empty();\n Empty[PROTOTYPE] = null;\n // add \"__proto__\" for Object.getPrototypeOf polyfill\n result[IE_PROTO] = O;\n } else result = createDict();\n return Properties === undefined ? result : dPs(result, Properties);\n};\n","var global = require('./_global');\nvar navigator = global.navigator;\n\nmodule.exports = navigator && navigator.userAgent || '';\n","//! moment.js locale configuration\n\n;(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined'\n && typeof require === 'function' ? factory(require('../moment')) :\n typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\n var arDz = moment.defineLocale('ar-dz', {\n months : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n monthsShort : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n weekdaysShort : 'احد_اثنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n weekdaysMin : 'أح_إث_ثلا_أر_خم_جم_سب'.split('_'),\n weekdaysParseExact : true,\n longDateFormat : {\n LT : 'HH:mm',\n LTS : 'HH:mm:ss',\n L : 'DD/MM/YYYY',\n LL : 'D MMMM YYYY',\n LLL : 'D MMMM YYYY HH:mm',\n LLLL : 'dddd D MMMM YYYY HH:mm'\n },\n calendar : {\n sameDay: '[اليوم على الساعة] LT',\n nextDay: '[غدا على الساعة] LT',\n nextWeek: 'dddd [على الساعة] LT',\n lastDay: '[أمس على الساعة] LT',\n lastWeek: 'dddd [على الساعة] LT',\n sameElse: 'L'\n },\n relativeTime : {\n future : 'في %s',\n past : 'منذ %s',\n s : 'ثوان',\n ss : '%d ثانية',\n m : 'دقيقة',\n mm : '%d دقائق',\n h : 'ساعة',\n hh : '%d ساعات',\n d : 'يوم',\n dd : '%d أيام',\n M : 'شهر',\n MM : '%d أشهر',\n y : 'سنة',\n yy : '%d سنوات'\n },\n week : {\n dow : 0, // Sunday is the first day of the week.\n doy : 4 // The week that contains Jan 4th is the first week of the year.\n }\n });\n\n return arDz;\n\n})));\n","'use strict';\n// 25.4.1.5 NewPromiseCapability(C)\nvar aFunction = require('./_a-function');\n\nfunction PromiseCapability(C) {\n var resolve, reject;\n this.promise = new C(function ($$resolve, $$reject) {\n if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor');\n resolve = $$resolve;\n reject = $$reject;\n });\n this.resolve = aFunction(resolve);\n this.reject = aFunction(reject);\n}\n\nmodule.exports.f = function (C) {\n return new PromiseCapability(C);\n};\n","module.exports = require(\"core-js/library/fn/array/is-array\");","//! moment.js locale configuration\n\n;(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined'\n && typeof require === 'function' ? factory(require('../moment')) :\n typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\n var bm = moment.defineLocale('bm', {\n months : 'Zanwuyekalo_Fewuruyekalo_Marisikalo_Awirilikalo_Mɛkalo_Zuwɛnkalo_Zuluyekalo_Utikalo_Sɛtanburukalo_ɔkutɔburukalo_Nowanburukalo_Desanburukalo'.split('_'),\n monthsShort : 'Zan_Few_Mar_Awi_Mɛ_Zuw_Zul_Uti_Sɛt_ɔku_Now_Des'.split('_'),\n weekdays : 'Kari_Ntɛnɛn_Tarata_Araba_Alamisa_Juma_Sibiri'.split('_'),\n weekdaysShort : 'Kar_Ntɛ_Tar_Ara_Ala_Jum_Sib'.split('_'),\n weekdaysMin : 'Ka_Nt_Ta_Ar_Al_Ju_Si'.split('_'),\n longDateFormat : {\n LT : 'HH:mm',\n LTS : 'HH:mm:ss',\n L : 'DD/MM/YYYY',\n LL : 'MMMM [tile] D [san] YYYY',\n LLL : 'MMMM [tile] D [san] YYYY [lɛrɛ] HH:mm',\n LLLL : 'dddd MMMM [tile] D [san] YYYY [lɛrɛ] HH:mm'\n },\n calendar : {\n sameDay : '[Bi lɛrɛ] LT',\n nextDay : '[Sini lɛrɛ] LT',\n nextWeek : 'dddd [don lɛrɛ] LT',\n lastDay : '[Kunu lɛrɛ] LT',\n lastWeek : 'dddd [tɛmɛnen lɛrɛ] LT',\n sameElse : 'L'\n },\n relativeTime : {\n future : '%s kɔnɔ',\n past : 'a bɛ %s bɔ',\n s : 'sanga dama dama',\n ss : 'sekondi %d',\n m : 'miniti kelen',\n mm : 'miniti %d',\n h : 'lɛrɛ kelen',\n hh : 'lɛrɛ %d',\n d : 'tile kelen',\n dd : 'tile %d',\n M : 'kalo kelen',\n MM : 'kalo %d',\n y : 'san kelen',\n yy : 'san %d'\n },\n week : {\n dow : 1, // Monday is the first day of the week.\n doy : 4 // The week that contains Jan 4th is the first week of the year.\n }\n });\n\n return bm;\n\n})));\n","// 7.2.8 IsRegExp(argument)\nvar isObject = require('./_is-object');\nvar cof = require('./_cof');\nvar MATCH = require('./_wks')('match');\nmodule.exports = function (it) {\n var isRegExp;\n return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : cof(it) == 'RegExp');\n};\n","var $iterators = require('./es6.array.iterator');\nvar getKeys = require('./_object-keys');\nvar redefine = require('./_redefine');\nvar global = require('./_global');\nvar hide = require('./_hide');\nvar Iterators = require('./_iterators');\nvar wks = require('./_wks');\nvar ITERATOR = wks('iterator');\nvar TO_STRING_TAG = wks('toStringTag');\nvar ArrayValues = Iterators.Array;\n\nvar DOMIterables = {\n CSSRuleList: true, // TODO: Not spec compliant, should be false.\n CSSStyleDeclaration: false,\n CSSValueList: false,\n ClientRectList: false,\n DOMRectList: false,\n DOMStringList: false,\n DOMTokenList: true,\n DataTransferItemList: false,\n FileList: false,\n HTMLAllCollection: false,\n HTMLCollection: false,\n HTMLFormElement: false,\n HTMLSelectElement: false,\n MediaList: true, // TODO: Not spec compliant, should be false.\n MimeTypeArray: false,\n NamedNodeMap: false,\n NodeList: true,\n PaintRequestList: false,\n Plugin: false,\n PluginArray: false,\n SVGLengthList: false,\n SVGNumberList: false,\n SVGPathSegList: false,\n SVGPointList: false,\n SVGStringList: false,\n SVGTransformList: false,\n SourceBufferList: false,\n StyleSheetList: true, // TODO: Not spec compliant, should be false.\n TextTrackCueList: false,\n TextTrackList: false,\n TouchList: false\n};\n\nfor (var collections = getKeys(DOMIterables), i = 0; i < collections.length; i++) {\n var NAME = collections[i];\n var explicit = DOMIterables[NAME];\n var Collection = global[NAME];\n var proto = Collection && Collection.prototype;\n var key;\n if (proto) {\n if (!proto[ITERATOR]) hide(proto, ITERATOR, ArrayValues);\n if (!proto[TO_STRING_TAG]) hide(proto, TO_STRING_TAG, NAME);\n Iterators[NAME] = ArrayValues;\n if (explicit) for (key in $iterators) if (!proto[key]) redefine(proto, key, $iterators[key], true);\n }\n}\n","//! moment.js locale configuration\n\n;(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined'\n && typeof require === 'function' ? factory(require('../moment')) :\n typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\n function plural(word, num) {\n var forms = word.split('_');\n return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n }\n function relativeTimeWithPlural(number, withoutSuffix, key) {\n var format = {\n 'ss': withoutSuffix ? 'секунда_секунди_секунд' : 'секунду_секунди_секунд',\n 'mm': withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин',\n 'hh': withoutSuffix ? 'година_години_годин' : 'годину_години_годин',\n 'dd': 'день_дні_днів',\n 'MM': 'місяць_місяці_місяців',\n 'yy': 'рік_роки_років'\n };\n if (key === 'm') {\n return withoutSuffix ? 'хвилина' : 'хвилину';\n }\n else if (key === 'h') {\n return withoutSuffix ? 'година' : 'годину';\n }\n else {\n return number + ' ' + plural(format[key], +number);\n }\n }\n function weekdaysCaseReplace(m, format) {\n var weekdays = {\n 'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'),\n 'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'),\n 'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_')\n };\n\n if (m === true) {\n return weekdays['nominative'].slice(1, 7).concat(weekdays['nominative'].slice(0, 1));\n }\n if (!m) {\n return weekdays['nominative'];\n }\n\n var nounCase = (/(\\[[ВвУу]\\]) ?dddd/).test(format) ?\n 'accusative' :\n ((/\\[?(?:минулої|наступної)? ?\\] ?dddd/).test(format) ?\n 'genitive' :\n 'nominative');\n return weekdays[nounCase][m.day()];\n }\n function processHoursFunction(str) {\n return function () {\n return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';\n };\n }\n\n var uk = moment.defineLocale('uk', {\n months : {\n 'format': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_'),\n 'standalone': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_')\n },\n monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'),\n weekdays : weekdaysCaseReplace,\n weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n longDateFormat : {\n LT : 'HH:mm',\n LTS : 'HH:mm:ss',\n L : 'DD.MM.YYYY',\n LL : 'D MMMM YYYY р.',\n LLL : 'D MMMM YYYY р., HH:mm',\n LLLL : 'dddd, D MMMM YYYY р., HH:mm'\n },\n calendar : {\n sameDay: processHoursFunction('[Сьогодні '),\n nextDay: processHoursFunction('[Завтра '),\n lastDay: processHoursFunction('[Вчора '),\n nextWeek: processHoursFunction('[У] dddd ['),\n lastWeek: function () {\n switch (this.day()) {\n case 0:\n case 3:\n case 5:\n case 6:\n return processHoursFunction('[Минулої] dddd [').call(this);\n case 1:\n case 2:\n case 4:\n return processHoursFunction('[Минулого] dddd [').call(this);\n }\n },\n sameElse: 'L'\n },\n relativeTime : {\n future : 'за %s',\n past : '%s тому',\n s : 'декілька секунд',\n ss : relativeTimeWithPlural,\n m : relativeTimeWithPlural,\n mm : relativeTimeWithPlural,\n h : 'годину',\n hh : relativeTimeWithPlural,\n d : 'день',\n dd : relativeTimeWithPlural,\n M : 'місяць',\n MM : relativeTimeWithPlural,\n y : 'рік',\n yy : relativeTimeWithPlural\n },\n // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason\n meridiemParse: /ночі|ранку|дня|вечора/,\n isPM: function (input) {\n return /^(дня|вечора)$/.test(input);\n },\n meridiem : function (hour, minute, isLower) {\n if (hour < 4) {\n return 'ночі';\n } else if (hour < 12) {\n return 'ранку';\n } else if (hour < 17) {\n return 'дня';\n } else {\n return 'вечора';\n }\n },\n dayOfMonthOrdinalParse: /\\d{1,2}-(й|го)/,\n ordinal: function (number, period) {\n switch (period) {\n case 'M':\n case 'd':\n case 'DDD':\n case 'w':\n case 'W':\n return number + '-й';\n case 'D':\n return number + '-го';\n default:\n return number;\n }\n },\n week : {\n dow : 1, // Monday is the first day of the week.\n doy : 7 // The week that contains Jan 7th is the first week of the year.\n }\n });\n\n return uk;\n\n})));\n","module.exports = function (bitmap, value) {\n return {\n enumerable: !(bitmap & 1),\n configurable: !(bitmap & 2),\n writable: !(bitmap & 4),\n value: value\n };\n};\n","'use strict';\nvar regexpExec = require('./_regexp-exec');\nrequire('./_export')({\n target: 'RegExp',\n proto: true,\n forced: regexpExec !== /./.exec\n}, {\n exec: regexpExec\n});\n","// call something on iterator step with safe closing on error\nvar anObject = require('./_an-object');\nmodule.exports = function (iterator, fn, value, entries) {\n try {\n return entries ? fn(anObject(value)[0], value[1]) : fn(value);\n // 7.4.6 IteratorClose(iterator, completion)\n } catch (e) {\n var ret = iterator['return'];\n if (ret !== undefined) anObject(ret.call(iterator));\n throw e;\n }\n};\n","//! moment.js locale configuration\n\n;(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined'\n && typeof require === 'function' ? factory(require('../moment')) :\n typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\n var lo = moment.defineLocale('lo', {\n months : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'),\n monthsShort : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'),\n weekdays : 'ອາທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),\n weekdaysShort : 'ທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),\n weekdaysMin : 'ທ_ຈ_ອຄ_ພ_ພຫ_ສກ_ສ'.split('_'),\n weekdaysParseExact : true,\n longDateFormat : {\n LT : 'HH:mm',\n LTS : 'HH:mm:ss',\n L : 'DD/MM/YYYY',\n LL : 'D MMMM YYYY',\n LLL : 'D MMMM YYYY HH:mm',\n LLLL : 'ວັນdddd D MMMM YYYY HH:mm'\n },\n meridiemParse: /ຕອນເຊົ້າ|ຕອນແລງ/,\n isPM: function (input) {\n return input === 'ຕອນແລງ';\n },\n meridiem : function (hour, minute, isLower) {\n if (hour < 12) {\n return 'ຕອນເຊົ້າ';\n } else {\n return 'ຕອນແລງ';\n }\n },\n calendar : {\n sameDay : '[ມື້ນີ້ເວລາ] LT',\n nextDay : '[ມື້ອື່ນເວລາ] LT',\n nextWeek : '[ວັນ]dddd[ໜ້າເວລາ] LT',\n lastDay : '[ມື້ວານນີ້ເວລາ] LT',\n lastWeek : '[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT',\n sameElse : 'L'\n },\n relativeTime : {\n future : 'ອີກ %s',\n past : '%sຜ່ານມາ',\n s : 'ບໍ່ເທົ່າໃດວິນາທີ',\n ss : '%d ວິນາທີ' ,\n m : '1 ນາທີ',\n mm : '%d ນາທີ',\n h : '1 ຊົ່ວໂມງ',\n hh : '%d ຊົ່ວໂມງ',\n d : '1 ມື້',\n dd : '%d ມື້',\n M : '1 ເດືອນ',\n MM : '%d ເດືອນ',\n y : '1 ປີ',\n yy : '%d ປີ'\n },\n dayOfMonthOrdinalParse: /(ທີ່)\\d{1,2}/,\n ordinal : function (number) {\n return 'ທີ່' + number;\n }\n });\n\n return lo;\n\n})));\n","var isObject = require('./_is-object');\nmodule.exports = function (it, TYPE) {\n if (!isObject(it) || it._t !== TYPE) throw TypeError('Incompatible receiver, ' + TYPE + ' required!');\n return it;\n};\n","//! moment.js locale configuration\n\n;(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined'\n && typeof require === 'function' ? factory(require('../moment')) :\n typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\n function processRelativeTime(number, withoutSuffix, key, isFuture) {\n var format = {\n 'm': ['eine Minute', 'einer Minute'],\n 'h': ['eine Stunde', 'einer Stunde'],\n 'd': ['ein Tag', 'einem Tag'],\n 'dd': [number + ' Tage', number + ' Tagen'],\n 'M': ['ein Monat', 'einem Monat'],\n 'MM': [number + ' Monate', number + ' Monaten'],\n 'y': ['ein Jahr', 'einem Jahr'],\n 'yy': [number + ' Jahre', number + ' Jahren']\n };\n return withoutSuffix ? format[key][0] : format[key][1];\n }\n\n var deAt = moment.defineLocale('de-at', {\n months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n monthsShort : 'Jän._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split('_'),\n monthsParseExact : true,\n weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n weekdaysParseExact : true,\n longDateFormat : {\n LT: 'HH:mm',\n LTS: 'HH:mm:ss',\n L : 'DD.MM.YYYY',\n LL : 'D. MMMM YYYY',\n LLL : 'D. MMMM YYYY HH:mm',\n LLLL : 'dddd, D. MMMM YYYY HH:mm'\n },\n calendar : {\n sameDay: '[heute um] LT [Uhr]',\n sameElse: 'L',\n nextDay: '[morgen um] LT [Uhr]',\n nextWeek: 'dddd [um] LT [Uhr]',\n lastDay: '[gestern um] LT [Uhr]',\n lastWeek: '[letzten] dddd [um] LT [Uhr]'\n },\n relativeTime : {\n future : 'in %s',\n past : 'vor %s',\n s : 'ein paar Sekunden',\n ss : '%d Sekunden',\n m : processRelativeTime,\n mm : '%d Minuten',\n h : processRelativeTime,\n hh : '%d Stunden',\n d : processRelativeTime,\n dd : processRelativeTime,\n M : processRelativeTime,\n MM : processRelativeTime,\n y : processRelativeTime,\n yy : processRelativeTime\n },\n dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n ordinal : '%d.',\n week : {\n dow : 1, // Monday is the first day of the week.\n doy : 4 // The week that contains Jan 4th is the first week of the year.\n }\n });\n\n return deAt;\n\n})));\n","// 7.1.15 ToLength\nvar toInteger = require('./_to-integer');\nvar min = Math.min;\nmodule.exports = function (it) {\n return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991\n};\n","//! moment.js locale configuration\n\n;(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined'\n && typeof require === 'function' ? factory(require('../moment')) :\n typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\n function processRelativeTime(number, withoutSuffix, key, isFuture) {\n var format = {\n 'm': ['eine Minute', 'einer Minute'],\n 'h': ['eine Stunde', 'einer Stunde'],\n 'd': ['ein Tag', 'einem Tag'],\n 'dd': [number + ' Tage', number + ' Tagen'],\n 'M': ['ein Monat', 'einem Monat'],\n 'MM': [number + ' Monate', number + ' Monaten'],\n 'y': ['ein Jahr', 'einem Jahr'],\n 'yy': [number + ' Jahre', number + ' Jahren']\n };\n return withoutSuffix ? format[key][0] : format[key][1];\n }\n\n var de = moment.defineLocale('de', {\n months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n monthsShort : 'Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split('_'),\n monthsParseExact : true,\n weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n weekdaysParseExact : true,\n longDateFormat : {\n LT: 'HH:mm',\n LTS: 'HH:mm:ss',\n L : 'DD.MM.YYYY',\n LL : 'D. MMMM YYYY',\n LLL : 'D. MMMM YYYY HH:mm',\n LLLL : 'dddd, D. MMMM YYYY HH:mm'\n },\n calendar : {\n sameDay: '[heute um] LT [Uhr]',\n sameElse: 'L',\n nextDay: '[morgen um] LT [Uhr]',\n nextWeek: 'dddd [um] LT [Uhr]',\n lastDay: '[gestern um] LT [Uhr]',\n lastWeek: '[letzten] dddd [um] LT [Uhr]'\n },\n relativeTime : {\n future : 'in %s',\n past : 'vor %s',\n s : 'ein paar Sekunden',\n ss : '%d Sekunden',\n m : processRelativeTime,\n mm : '%d Minuten',\n h : processRelativeTime,\n hh : '%d Stunden',\n d : processRelativeTime,\n dd : processRelativeTime,\n M : processRelativeTime,\n MM : processRelativeTime,\n y : processRelativeTime,\n yy : processRelativeTime\n },\n dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n ordinal : '%d.',\n week : {\n dow : 1, // Monday is the first day of the week.\n doy : 4 // The week that contains Jan 4th is the first week of the year.\n }\n });\n\n return de;\n\n})));\n","'use strict';\n\nvar utils = require('./../utils');\nvar settle = require('./../core/settle');\nvar buildURL = require('./../helpers/buildURL');\nvar parseHeaders = require('./../helpers/parseHeaders');\nvar isURLSameOrigin = require('./../helpers/isURLSameOrigin');\nvar createError = require('../core/createError');\n\nmodule.exports = function xhrAdapter(config) {\n return new Promise(function dispatchXhrRequest(resolve, reject) {\n var requestData = config.data;\n var requestHeaders = config.headers;\n\n if (utils.isFormData(requestData)) {\n delete requestHeaders['Content-Type']; // Let the browser set it\n }\n\n var request = new XMLHttpRequest();\n\n // HTTP basic authentication\n if (config.auth) {\n var username = config.auth.username || '';\n var password = config.auth.password || '';\n requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password);\n }\n\n request.open(config.method.toUpperCase(), buildURL(config.url, config.params, config.paramsSerializer), true);\n\n // Set the request timeout in MS\n request.timeout = config.timeout;\n\n // Listen for ready state\n request.onreadystatechange = function handleLoad() {\n if (!request || request.readyState !== 4) {\n return;\n }\n\n // The request errored out and we didn't get a response, this will be\n // handled by onerror instead\n // With one exception: request that using file: protocol, most browsers\n // will return status as 0 even though it's a successful request\n if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {\n return;\n }\n\n // Prepare the response\n var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null;\n var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response;\n var response = {\n data: responseData,\n status: request.status,\n statusText: request.statusText,\n headers: responseHeaders,\n config: config,\n request: request\n };\n\n settle(resolve, reject, response);\n\n // Clean up request\n request = null;\n };\n\n // Handle browser request cancellation (as opposed to a manual cancellation)\n request.onabort = function handleAbort() {\n if (!request) {\n return;\n }\n\n reject(createError('Request aborted', config, 'ECONNABORTED', request));\n\n // Clean up request\n request = null;\n };\n\n // Handle low level network errors\n request.onerror = function handleError() {\n // Real errors are hidden from us by the browser\n // onerror should only fire if it's a network error\n reject(createError('Network Error', config, null, request));\n\n // Clean up request\n request = null;\n };\n\n // Handle timeout\n request.ontimeout = function handleTimeout() {\n reject(createError('timeout of ' + config.timeout + 'ms exceeded', config, 'ECONNABORTED',\n request));\n\n // Clean up request\n request = null;\n };\n\n // Add xsrf header\n // This is only done if running in a standard browser environment.\n // Specifically not if we're in a web worker, or react-native.\n if (utils.isStandardBrowserEnv()) {\n var cookies = require('./../helpers/cookies');\n\n // Add xsrf header\n var xsrfValue = (config.withCredentials || isURLSameOrigin(config.url)) && config.xsrfCookieName ?\n cookies.read(config.xsrfCookieName) :\n undefined;\n\n if (xsrfValue) {\n requestHeaders[config.xsrfHeaderName] = xsrfValue;\n }\n }\n\n // Add headers to the request\n if ('setRequestHeader' in request) {\n utils.forEach(requestHeaders, function setRequestHeader(val, key) {\n if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') {\n // Remove Content-Type if data is undefined\n delete requestHeaders[key];\n } else {\n // Otherwise add header to the request\n request.setRequestHeader(key, val);\n }\n });\n }\n\n // Add withCredentials to request if needed\n if (config.withCredentials) {\n request.withCredentials = true;\n }\n\n // Add responseType to request if needed\n if (config.responseType) {\n try {\n request.responseType = config.responseType;\n } catch (e) {\n // Expected DOMException thrown by browsers not compatible XMLHttpRequest Level 2.\n // But, this can be suppressed for 'json' type as it can be parsed by default 'transformResponse' function.\n if (config.responseType !== 'json') {\n throw e;\n }\n }\n }\n\n // Handle progress if needed\n if (typeof config.onDownloadProgress === 'function') {\n request.addEventListener('progress', config.onDownloadProgress);\n }\n\n // Not all browsers support upload events\n if (typeof config.onUploadProgress === 'function' && request.upload) {\n request.upload.addEventListener('progress', config.onUploadProgress);\n }\n\n if (config.cancelToken) {\n // Handle cancellation\n config.cancelToken.promise.then(function onCanceled(cancel) {\n if (!request) {\n return;\n }\n\n request.abort();\n reject(cancel);\n // Clean up request\n request = null;\n });\n }\n\n if (requestData === undefined) {\n requestData = null;\n }\n\n // Send the request\n request.send(requestData);\n });\n};\n","//! moment.js locale configuration\n\n;(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined'\n && typeof require === 'function' ? factory(require('../moment')) :\n typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\n var tzmLatn = moment.defineLocale('tzm-latn', {\n months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n longDateFormat : {\n LT : 'HH:mm',\n LTS : 'HH:mm:ss',\n L : 'DD/MM/YYYY',\n LL : 'D MMMM YYYY',\n LLL : 'D MMMM YYYY HH:mm',\n LLLL : 'dddd D MMMM YYYY HH:mm'\n },\n calendar : {\n sameDay: '[asdkh g] LT',\n nextDay: '[aska g] LT',\n nextWeek: 'dddd [g] LT',\n lastDay: '[assant g] LT',\n lastWeek: 'dddd [g] LT',\n sameElse: 'L'\n },\n relativeTime : {\n future : 'dadkh s yan %s',\n past : 'yan %s',\n s : 'imik',\n ss : '%d imik',\n m : 'minuḍ',\n mm : '%d minuḍ',\n h : 'saɛa',\n hh : '%d tassaɛin',\n d : 'ass',\n dd : '%d ossan',\n M : 'ayowr',\n MM : '%d iyyirn',\n y : 'asgas',\n yy : '%d isgasn'\n },\n week : {\n dow : 6, // Saturday is the first day of the week.\n doy : 12 // The week that contains Jan 12th is the first week of the year.\n }\n });\n\n return tzmLatn;\n\n})));\n","//! moment.js locale configuration\n\n;(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined'\n && typeof require === 'function' ? factory(require('../moment')) :\n typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\n var jv = moment.defineLocale('jv', {\n months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember'.split('_'),\n monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des'.split('_'),\n weekdays : 'Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu'.split('_'),\n weekdaysShort : 'Min_Sen_Sel_Reb_Kem_Jem_Sep'.split('_'),\n weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'),\n longDateFormat : {\n LT : 'HH.mm',\n LTS : 'HH.mm.ss',\n L : 'DD/MM/YYYY',\n LL : 'D MMMM YYYY',\n LLL : 'D MMMM YYYY [pukul] HH.mm',\n LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n },\n meridiemParse: /enjing|siyang|sonten|ndalu/,\n meridiemHour : function (hour, meridiem) {\n if (hour === 12) {\n hour = 0;\n }\n if (meridiem === 'enjing') {\n return hour;\n } else if (meridiem === 'siyang') {\n return hour >= 11 ? hour : hour + 12;\n } else if (meridiem === 'sonten' || meridiem === 'ndalu') {\n return hour + 12;\n }\n },\n meridiem : function (hours, minutes, isLower) {\n if (hours < 11) {\n return 'enjing';\n } else if (hours < 15) {\n return 'siyang';\n } else if (hours < 19) {\n return 'sonten';\n } else {\n return 'ndalu';\n }\n },\n calendar : {\n sameDay : '[Dinten puniko pukul] LT',\n nextDay : '[Mbenjang pukul] LT',\n nextWeek : 'dddd [pukul] LT',\n lastDay : '[Kala wingi pukul] LT',\n lastWeek : 'dddd [kepengker pukul] LT',\n sameElse : 'L'\n },\n relativeTime : {\n future : 'wonten ing %s',\n past : '%s ingkang kepengker',\n s : 'sawetawis detik',\n ss : '%d detik',\n m : 'setunggal menit',\n mm : '%d menit',\n h : 'setunggal jam',\n hh : '%d jam',\n d : 'sedinten',\n dd : '%d dinten',\n M : 'sewulan',\n MM : '%d wulan',\n y : 'setaun',\n yy : '%d taun'\n },\n week : {\n dow : 1, // Monday is the first day of the week.\n doy : 7 // The week that contains Jan 7th is the first week of the year.\n }\n });\n\n return jv;\n\n})));\n","//! moment.js locale configuration\n\n;(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined'\n && typeof require === 'function' ? factory(require('../moment')) :\n typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\n var nn = moment.defineLocale('nn', {\n months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'),\n weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'),\n weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'),\n longDateFormat : {\n LT : 'HH:mm',\n LTS : 'HH:mm:ss',\n L : 'DD.MM.YYYY',\n LL : 'D. MMMM YYYY',\n LLL : 'D. MMMM YYYY [kl.] H:mm',\n LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm'\n },\n calendar : {\n sameDay: '[I dag klokka] LT',\n nextDay: '[I morgon klokka] LT',\n nextWeek: 'dddd [klokka] LT',\n lastDay: '[I går klokka] LT',\n lastWeek: '[Føregåande] dddd [klokka] LT',\n sameElse: 'L'\n },\n relativeTime : {\n future : 'om %s',\n past : '%s sidan',\n s : 'nokre sekund',\n ss : '%d sekund',\n m : 'eit minutt',\n mm : '%d minutt',\n h : 'ein time',\n hh : '%d timar',\n d : 'ein dag',\n dd : '%d dagar',\n M : 'ein månad',\n MM : '%d månader',\n y : 'eit år',\n yy : '%d år'\n },\n dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n ordinal : '%d.',\n week : {\n dow : 1, // Monday is the first day of the week.\n doy : 4 // The week that contains Jan 4th is the first week of the year.\n }\n });\n\n return nn;\n\n})));\n","module.exports = true;\n","//! moment.js locale configuration\n\n;(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined'\n && typeof require === 'function' ? factory(require('../moment')) :\n typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\n var units = {\n 'ss': 'sekundes_sekundēm_sekunde_sekundes'.split('_'),\n 'm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),\n 'mm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),\n 'h': 'stundas_stundām_stunda_stundas'.split('_'),\n 'hh': 'stundas_stundām_stunda_stundas'.split('_'),\n 'd': 'dienas_dienām_diena_dienas'.split('_'),\n 'dd': 'dienas_dienām_diena_dienas'.split('_'),\n 'M': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),\n 'MM': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),\n 'y': 'gada_gadiem_gads_gadi'.split('_'),\n 'yy': 'gada_gadiem_gads_gadi'.split('_')\n };\n /**\n * @param withoutSuffix boolean true = a length of time; false = before/after a period of time.\n */\n function format(forms, number, withoutSuffix) {\n if (withoutSuffix) {\n // E.g. \"21 minūte\", \"3 minūtes\".\n return number % 10 === 1 && number % 100 !== 11 ? forms[2] : forms[3];\n } else {\n // E.g. \"21 minūtes\" as in \"pēc 21 minūtes\".\n // E.g. \"3 minūtēm\" as in \"pēc 3 minūtēm\".\n return number % 10 === 1 && number % 100 !== 11 ? forms[0] : forms[1];\n }\n }\n function relativeTimeWithPlural(number, withoutSuffix, key) {\n return number + ' ' + format(units[key], number, withoutSuffix);\n }\n function relativeTimeWithSingular(number, withoutSuffix, key) {\n return format(units[key], number, withoutSuffix);\n }\n function relativeSeconds(number, withoutSuffix) {\n return withoutSuffix ? 'dažas sekundes' : 'dažām sekundēm';\n }\n\n var lv = moment.defineLocale('lv', {\n months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'),\n monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'),\n weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'),\n weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'),\n weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'),\n weekdaysParseExact : true,\n longDateFormat : {\n LT : 'HH:mm',\n LTS : 'HH:mm:ss',\n L : 'DD.MM.YYYY.',\n LL : 'YYYY. [gada] D. MMMM',\n LLL : 'YYYY. [gada] D. MMMM, HH:mm',\n LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm'\n },\n calendar : {\n sameDay : '[Šodien pulksten] LT',\n nextDay : '[Rīt pulksten] LT',\n nextWeek : 'dddd [pulksten] LT',\n lastDay : '[Vakar pulksten] LT',\n lastWeek : '[Pagājušā] dddd [pulksten] LT',\n sameElse : 'L'\n },\n relativeTime : {\n future : 'pēc %s',\n past : 'pirms %s',\n s : relativeSeconds,\n ss : relativeTimeWithPlural,\n m : relativeTimeWithSingular,\n mm : relativeTimeWithPlural,\n h : relativeTimeWithSingular,\n hh : relativeTimeWithPlural,\n d : relativeTimeWithSingular,\n dd : relativeTimeWithPlural,\n M : relativeTimeWithSingular,\n MM : relativeTimeWithPlural,\n y : relativeTimeWithSingular,\n yy : relativeTimeWithPlural\n },\n dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n ordinal : '%d.',\n week : {\n dow : 1, // Monday is the first day of the week.\n doy : 4 // The week that contains Jan 4th is the first week of the year.\n }\n });\n\n return lv;\n\n})));\n","//! moment.js locale configuration\n\n;(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined'\n && typeof require === 'function' ? factory(require('../moment')) :\n typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\n function processRelativeTime(number, withoutSuffix, key, isFuture) {\n var format = {\n 'm': ['eine Minute', 'einer Minute'],\n 'h': ['eine Stunde', 'einer Stunde'],\n 'd': ['ein Tag', 'einem Tag'],\n 'dd': [number + ' Tage', number + ' Tagen'],\n 'M': ['ein Monat', 'einem Monat'],\n 'MM': [number + ' Monate', number + ' Monaten'],\n 'y': ['ein Jahr', 'einem Jahr'],\n 'yy': [number + ' Jahre', number + ' Jahren']\n };\n return withoutSuffix ? format[key][0] : format[key][1];\n }\n\n var deCh = moment.defineLocale('de-ch', {\n months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n monthsShort : 'Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split('_'),\n monthsParseExact : true,\n weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n weekdaysShort : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n weekdaysParseExact : true,\n longDateFormat : {\n LT: 'HH:mm',\n LTS: 'HH:mm:ss',\n L : 'DD.MM.YYYY',\n LL : 'D. MMMM YYYY',\n LLL : 'D. MMMM YYYY HH:mm',\n LLLL : 'dddd, D. MMMM YYYY HH:mm'\n },\n calendar : {\n sameDay: '[heute um] LT [Uhr]',\n sameElse: 'L',\n nextDay: '[morgen um] LT [Uhr]',\n nextWeek: 'dddd [um] LT [Uhr]',\n lastDay: '[gestern um] LT [Uhr]',\n lastWeek: '[letzten] dddd [um] LT [Uhr]'\n },\n relativeTime : {\n future : 'in %s',\n past : 'vor %s',\n s : 'ein paar Sekunden',\n ss : '%d Sekunden',\n m : processRelativeTime,\n mm : '%d Minuten',\n h : processRelativeTime,\n hh : '%d Stunden',\n d : processRelativeTime,\n dd : processRelativeTime,\n M : processRelativeTime,\n MM : processRelativeTime,\n y : processRelativeTime,\n yy : processRelativeTime\n },\n dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n ordinal : '%d.',\n week : {\n dow : 1, // Monday is the first day of the week.\n doy : 4 // The week that contains Jan 4th is the first week of the year.\n }\n });\n\n return deCh;\n\n})));\n","module.exports = require('./lib/axios');","var anObject = require('./_an-object');\nvar isObject = require('./_is-object');\nvar newPromiseCapability = require('./_new-promise-capability');\n\nmodule.exports = function (C, x) {\n anObject(C);\n if (isObject(x) && x.constructor === C) return x;\n var promiseCapability = newPromiseCapability.f(C);\n var resolve = promiseCapability.resolve;\n resolve(x);\n return promiseCapability.promise;\n};\n","import _Object$defineProperty from \"../../core-js/object/define-property\";\nexport default function _defineProperty(obj, key, value) {\n if (key in obj) {\n _Object$defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}","// 7.2.1 RequireObjectCoercible(argument)\nmodule.exports = function (it) {\n if (it == undefined) throw TypeError(\"Can't call method on \" + it);\n return it;\n};\n","/* global module */\n'use strict';\n\n/**\n * Class representing the API\n */\nvar SpotifyWebApi = (function() {\n var _baseUri = 'https://api.spotify.com/v1';\n var _accessToken = null;\n var _promiseImplementation = null;\n\n var WrapPromiseWithAbort = function(promise, onAbort) {\n promise.abort = onAbort;\n return promise;\n };\n\n var _promiseProvider = function(promiseFunction, onAbort) {\n var returnedPromise;\n if (_promiseImplementation !== null) {\n var deferred = _promiseImplementation.defer();\n promiseFunction(\n function(resolvedResult) {\n deferred.resolve(resolvedResult);\n },\n function(rejectedResult) {\n deferred.reject(rejectedResult);\n }\n );\n returnedPromise = deferred.promise;\n } else {\n if (window.Promise) {\n returnedPromise = new window.Promise(promiseFunction);\n }\n }\n\n if (returnedPromise) {\n return new WrapPromiseWithAbort(returnedPromise, onAbort);\n } else {\n return null;\n }\n };\n\n var _extend = function() {\n var args = Array.prototype.slice.call(arguments);\n var target = args[0];\n var objects = args.slice(1);\n target = target || {};\n objects.forEach(function(object) {\n for (var j in object) {\n if (object.hasOwnProperty(j)) {\n target[j] = object[j];\n }\n }\n });\n return target;\n };\n\n var _buildUrl = function(url, parameters) {\n var qs = '';\n for (var key in parameters) {\n if (parameters.hasOwnProperty(key)) {\n var value = parameters[key];\n qs += encodeURIComponent(key) + '=' + encodeURIComponent(value) + '&';\n }\n }\n if (qs.length > 0) {\n // chop off last '&'\n qs = qs.substring(0, qs.length - 1);\n url = url + '?' + qs;\n }\n return url;\n };\n\n var _performRequest = function(requestData, callback) {\n var req = new XMLHttpRequest();\n\n var promiseFunction = function(resolve, reject) {\n function success(data) {\n if (resolve) {\n resolve(data);\n }\n if (callback) {\n callback(null, data);\n }\n }\n\n function failure() {\n if (reject) {\n reject(req);\n }\n if (callback) {\n callback(req, null);\n }\n }\n\n var type = requestData.type || 'GET';\n req.open(type, _buildUrl(requestData.url, requestData.params));\n if (_accessToken) {\n req.setRequestHeader('Authorization', 'Bearer ' + _accessToken);\n }\n if (requestData.contentType) {\n req.setRequestHeader('Content-Type', requestData.contentType)\n }\n\n req.onreadystatechange = function() {\n if (req.readyState === 4) {\n var data = null;\n try {\n data = req.responseText ? JSON.parse(req.responseText) : '';\n } catch (e) {\n console.error(e);\n }\n\n if (req.status >= 200 && req.status < 300) {\n success(data);\n } else {\n failure();\n }\n }\n };\n\n if (type === 'GET') {\n req.send(null);\n } else {\n var postData = null\n if (requestData.postData) {\n postData = requestData.contentType === 'image/jpeg' ? requestData.postData : JSON.stringify(requestData.postData)\n }\n req.send(postData);\n }\n };\n\n if (callback) {\n promiseFunction();\n return null;\n } else {\n return _promiseProvider(promiseFunction, function() {\n req.abort();\n });\n }\n };\n\n var _checkParamsAndPerformRequest = function(requestData, options, callback, optionsAlwaysExtendParams) {\n var opt = {};\n var cb = null;\n\n if (typeof options === 'object') {\n opt = options;\n cb = callback;\n } else if (typeof options === 'function') {\n cb = options;\n }\n\n // options extend postData, if any. Otherwise they extend parameters sent in the url\n var type = requestData.type || 'GET';\n if (type !== 'GET' && requestData.postData && !optionsAlwaysExtendParams) {\n requestData.postData = _extend(requestData.postData, opt);\n } else {\n requestData.params = _extend(requestData.params, opt);\n }\n return _performRequest(requestData, cb);\n };\n\n /**\n * Creates an instance of the wrapper\n * @constructor\n */\n var Constr = function() {};\n\n Constr.prototype = {\n constructor: SpotifyWebApi\n };\n\n /**\n * Fetches a resource through a generic GET request.\n *\n * @param {string} url The URL to be fetched\n * @param {function(Object,Object)} callback An optional callback\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getGeneric = function(url, callback) {\n var requestData = {\n url: url\n };\n return _checkParamsAndPerformRequest(requestData, callback);\n };\n\n /**\n * Fetches information about the current user.\n * See [Get Current User's Profile](https://developer.spotify.com/web-api/get-current-users-profile/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getMe = function(options, callback) {\n var requestData = {\n url: _baseUri + '/me'\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Fetches current user's saved tracks.\n * See [Get Current User's Saved Tracks](https://developer.spotify.com/web-api/get-users-saved-tracks/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getMySavedTracks = function(options, callback) {\n var requestData = {\n url: _baseUri + '/me/tracks'\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Adds a list of tracks to the current user's saved tracks.\n * See [Save Tracks for Current User](https://developer.spotify.com/web-api/save-tracks-user/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Array} trackIds The ids of the tracks. If you know their Spotify URI it is easy\n * to find their track id (e.g. spotify:track:)\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.addToMySavedTracks = function(trackIds, options, callback) {\n var requestData = {\n url: _baseUri + '/me/tracks',\n type: 'PUT',\n postData: trackIds\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Remove a list of tracks from the current user's saved tracks.\n * See [Remove Tracks for Current User](https://developer.spotify.com/web-api/remove-tracks-user/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Array} trackIds The ids of the tracks. If you know their Spotify URI it is easy\n * to find their track id (e.g. spotify:track:)\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.removeFromMySavedTracks = function(trackIds, options, callback) {\n var requestData = {\n url: _baseUri + '/me/tracks',\n type: 'DELETE',\n postData: trackIds\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Checks if the current user's saved tracks contains a certain list of tracks.\n * See [Check Current User's Saved Tracks](https://developer.spotify.com/web-api/check-users-saved-tracks/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Array} trackIds The ids of the tracks. If you know their Spotify URI it is easy\n * to find their track id (e.g. spotify:track:)\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.containsMySavedTracks = function(trackIds, options, callback) {\n var requestData = {\n url: _baseUri + '/me/tracks/contains',\n params: { ids: trackIds.join(',') }\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Get a list of the albums saved in the current Spotify user's \"Your Music\" library.\n * See [Get Current User's Saved Albums](https://developer.spotify.com/web-api/get-users-saved-albums/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getMySavedAlbums = function(options, callback) {\n var requestData = {\n url: _baseUri + '/me/albums'\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Save one or more albums to the current user's \"Your Music\" library.\n * See [Save Albums for Current User](https://developer.spotify.com/web-api/save-albums-user/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Array} albumIds The ids of the albums. If you know their Spotify URI, it is easy\n * to find their album id (e.g. spotify:album:)\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.addToMySavedAlbums = function(albumIds, options, callback) {\n var requestData = {\n url: _baseUri + '/me/albums',\n type: 'PUT',\n postData: albumIds\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Remove one or more albums from the current user's \"Your Music\" library.\n * See [Remove Albums for Current User](https://developer.spotify.com/web-api/remove-albums-user/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Array} albumIds The ids of the albums. If you know their Spotify URI, it is easy\n * to find their album id (e.g. spotify:album:)\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.removeFromMySavedAlbums = function(albumIds, options, callback) {\n var requestData = {\n url: _baseUri + '/me/albums',\n type: 'DELETE',\n postData: albumIds\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Check if one or more albums is already saved in the current Spotify user's \"Your Music\" library.\n * See [Check User's Saved Albums](https://developer.spotify.com/web-api/check-users-saved-albums/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Array} albumIds The ids of the albums. If you know their Spotify URI, it is easy\n * to find their album id (e.g. spotify:album:)\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.containsMySavedAlbums = function(albumIds, options, callback) {\n var requestData = {\n url: _baseUri + '/me/albums/contains',\n params: { ids: albumIds.join(',') }\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Get the current user’s top artists based on calculated affinity.\n * See [Get a User’s Top Artists](https://developer.spotify.com/web-api/get-users-top-artists-and-tracks/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getMyTopArtists = function(options, callback) {\n var requestData = {\n url: _baseUri + '/me/top/artists'\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Get the current user’s top tracks based on calculated affinity.\n * See [Get a User’s Top Tracks](https://developer.spotify.com/web-api/get-users-top-artists-and-tracks/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getMyTopTracks = function(options, callback) {\n var requestData = {\n url: _baseUri + '/me/top/tracks'\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Get tracks from the current user’s recently played tracks.\n * See [Get Current User’s Recently Played Tracks](https://developer.spotify.com/web-api/web-api-personalization-endpoints/get-recently-played/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getMyRecentlyPlayedTracks = function(options, callback) {\n var requestData = {\n url: _baseUri + '/me/player/recently-played'\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Adds the current user as a follower of one or more other Spotify users.\n * See [Follow Artists or Users](https://developer.spotify.com/web-api/follow-artists-users/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Array} userIds The ids of the users. If you know their Spotify URI it is easy\n * to find their user id (e.g. spotify:user:)\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is an empty value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.followUsers = function(userIds, callback) {\n var requestData = {\n url: _baseUri + '/me/following/',\n type: 'PUT',\n params: {\n ids: userIds.join(','),\n type: 'user'\n }\n };\n return _checkParamsAndPerformRequest(requestData, callback);\n };\n\n /**\n * Adds the current user as a follower of one or more artists.\n * See [Follow Artists or Users](https://developer.spotify.com/web-api/follow-artists-users/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Array} artistIds The ids of the artists. If you know their Spotify URI it is easy\n * to find their artist id (e.g. spotify:artist:)\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is an empty value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.followArtists = function(artistIds, callback) {\n var requestData = {\n url: _baseUri + '/me/following/',\n type: 'PUT',\n params: {\n ids: artistIds.join(','),\n type: 'artist'\n }\n };\n return _checkParamsAndPerformRequest(requestData, callback);\n };\n\n /**\n * Add the current user as a follower of one playlist.\n * See [Follow a Playlist](https://developer.spotify.com/web-api/follow-playlist/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} playlistId The id of the playlist. If you know the Spotify URI it is easy\n * to find the playlist id (e.g. spotify:user:xxxx:playlist:)\n * @param {Object} options A JSON object with options that can be passed. For instance,\n * whether you want the playlist to be followed privately ({public: false})\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is an empty value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.followPlaylist = function(playlistId, options, callback) {\n var requestData = {\n url: _baseUri + '/playlists/' + playlistId + '/followers',\n type: 'PUT',\n postData: {}\n };\n\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Removes the current user as a follower of one or more other Spotify users.\n * See [Unfollow Artists or Users](https://developer.spotify.com/web-api/unfollow-artists-users/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Array} userIds The ids of the users. If you know their Spotify URI it is easy\n * to find their user id (e.g. spotify:user:)\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is an empty value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.unfollowUsers = function(userIds, callback) {\n var requestData = {\n url: _baseUri + '/me/following/',\n type: 'DELETE',\n params: {\n ids: userIds.join(','),\n type: 'user'\n }\n };\n return _checkParamsAndPerformRequest(requestData, callback);\n };\n\n /**\n * Removes the current user as a follower of one or more artists.\n * See [Unfollow Artists or Users](https://developer.spotify.com/web-api/unfollow-artists-users/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Array} artistIds The ids of the artists. If you know their Spotify URI it is easy\n * to find their artist id (e.g. spotify:artist:)\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is an empty value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.unfollowArtists = function(artistIds, callback) {\n var requestData = {\n url: _baseUri + '/me/following/',\n type: 'DELETE',\n params: {\n ids: artistIds.join(','),\n type: 'artist'\n }\n };\n return _checkParamsAndPerformRequest(requestData, callback);\n };\n\n /**\n * Remove the current user as a follower of one playlist.\n * See [Unfollow a Playlist](https://developer.spotify.com/web-api/unfollow-playlist/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} playlistId The id of the playlist. If you know the Spotify URI it is easy\n * to find the playlist id (e.g. spotify:user:xxxx:playlist:)\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is an empty value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.unfollowPlaylist = function(playlistId, callback) {\n var requestData = {\n url: _baseUri + '/playlists/' + playlistId + '/followers',\n type: 'DELETE'\n };\n return _checkParamsAndPerformRequest(requestData, callback);\n };\n\n /**\n * Checks to see if the current user is following one or more other Spotify users.\n * See [Check if Current User Follows Users or Artists](https://developer.spotify.com/web-api/check-current-user-follows/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Array} userIds The ids of the users. If you know their Spotify URI it is easy\n * to find their user id (e.g. spotify:user:)\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is an array of boolean values that indicate\n * whether the user is following the users sent in the request.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.isFollowingUsers = function(userIds, callback) {\n var requestData = {\n url: _baseUri + '/me/following/contains',\n type: 'GET',\n params: {\n ids: userIds.join(','),\n type: 'user'\n }\n };\n return _checkParamsAndPerformRequest(requestData, callback);\n };\n\n /**\n * Checks to see if the current user is following one or more artists.\n * See [Check if Current User Follows](https://developer.spotify.com/web-api/check-current-user-follows/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Array} artistIds The ids of the artists. If you know their Spotify URI it is easy\n * to find their artist id (e.g. spotify:artist:)\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is an array of boolean values that indicate\n * whether the user is following the artists sent in the request.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.isFollowingArtists = function(artistIds, callback) {\n var requestData = {\n url: _baseUri + '/me/following/contains',\n type: 'GET',\n params: {\n ids: artistIds.join(','),\n type: 'artist'\n }\n };\n return _checkParamsAndPerformRequest(requestData, callback);\n };\n\n /**\n * Check to see if one or more Spotify users are following a specified playlist.\n * See [Check if Users Follow a Playlist](https://developer.spotify.com/web-api/check-user-following-playlist/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} playlistId The id of the playlist. If you know the Spotify URI it is easy\n * to find the playlist id (e.g. spotify:user:xxxx:playlist:)\n * @param {Array} userIds The ids of the users. If you know their Spotify URI it is easy\n * to find their user id (e.g. spotify:user:)\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is an array of boolean values that indicate\n * whether the users are following the playlist sent in the request.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.areFollowingPlaylist = function(playlistId, userIds, callback) {\n var requestData = {\n url: _baseUri + '/playlists/' + playlistId + '/followers/contains',\n type: 'GET',\n params: {\n ids: userIds.join(',')\n }\n };\n return _checkParamsAndPerformRequest(requestData, callback);\n };\n\n /**\n * Get the current user's followed artists.\n * See [Get User's Followed Artists](https://developer.spotify.com/web-api/get-followed-artists/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Object} [options] Options, being after and limit.\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is an object with a paged object containing\n * artists.\n * @returns {Promise|undefined} A promise that if successful, resolves to an object containing a paging object which contains\n * artists objects. Not returned if a callback is given.\n */\n Constr.prototype.getFollowedArtists = function(options, callback) {\n var requestData = {\n url: _baseUri + '/me/following',\n type: 'GET',\n params: {\n type: 'artist'\n }\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Fetches information about a specific user.\n * See [Get a User's Profile](https://developer.spotify.com/web-api/get-users-profile/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} userId The id of the user. If you know the Spotify URI it is easy\n * to find the id (e.g. spotify:user:)\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getUser = function(userId, options, callback) {\n var requestData = {\n url: _baseUri + '/users/' + encodeURIComponent(userId)\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Fetches a list of the current user's playlists.\n * See [Get a List of a User's Playlists](https://developer.spotify.com/web-api/get-list-users-playlists/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} userId An optional id of the user. If you know the Spotify URI it is easy\n * to find the id (e.g. spotify:user:). If not provided, the id of the user that granted\n * the permissions will be used.\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getUserPlaylists = function(userId, options, callback) {\n var requestData;\n if (typeof userId === 'string') {\n requestData = {\n url: _baseUri + '/users/' + encodeURIComponent(userId) + '/playlists'\n };\n } else {\n requestData = {\n url: _baseUri + '/me/playlists'\n };\n callback = options;\n options = userId;\n }\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Fetches a specific playlist.\n * See [Get a Playlist](https://developer.spotify.com/web-api/get-playlist/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} playlistId The id of the playlist. If you know the Spotify URI it is easy\n * to find the playlist id (e.g. spotify:user:xxxx:playlist:)\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getPlaylist = function(playlistId, options, callback) {\n var requestData = {\n url: _baseUri + '/playlists/' + playlistId\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Fetches the tracks from a specific playlist.\n * See [Get a Playlist's Tracks](https://developer.spotify.com/web-api/get-playlists-tracks/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} playlistId The id of the playlist. If you know the Spotify URI it is easy\n * to find the playlist id (e.g. spotify:user:xxxx:playlist:)\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getPlaylistTracks = function(playlistId, options, callback) {\n var requestData = {\n url: _baseUri + '/playlists/' + playlistId + '/tracks'\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Creates a playlist and stores it in the current user's library.\n * See [Create a Playlist](https://developer.spotify.com/web-api/create-playlist/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} userId The id of the user. If you know the Spotify URI it is easy\n * to find the id (e.g. spotify:user:)\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.createPlaylist = function(userId, options, callback) {\n var requestData = {\n url: _baseUri + '/users/' + encodeURIComponent(userId) + '/playlists',\n type: 'POST',\n postData: options\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Change a playlist's name and public/private state\n * See [Change a Playlist's Details](https://developer.spotify.com/web-api/change-playlist-details/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} playlistId The id of the playlist. If you know the Spotify URI it is easy\n * to find the playlist id (e.g. spotify:user:xxxx:playlist:)\n * @param {Object} data A JSON object with the data to update. E.g. {name: 'A new name', public: true}\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.changePlaylistDetails = function(playlistId, data, callback) {\n var requestData = {\n url: _baseUri + '/playlists/' + playlistId,\n type: 'PUT',\n postData: data\n };\n return _checkParamsAndPerformRequest(requestData, data, callback);\n };\n\n /**\n * Add tracks to a playlist.\n * See [Add Tracks to a Playlist](https://developer.spotify.com/web-api/add-tracks-to-playlist/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} playlistId The id of the playlist. If you know the Spotify URI it is easy\n * to find the playlist id (e.g. spotify:user:xxxx:playlist:)\n * @param {Array} uris An array of Spotify URIs for the tracks\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.addTracksToPlaylist = function(playlistId, uris, options, callback) {\n var requestData = {\n url: _baseUri + '/playlists/' + playlistId + '/tracks',\n type: 'POST',\n postData: {\n uris: uris\n }\n };\n return _checkParamsAndPerformRequest(requestData, options, callback, true);\n };\n\n /**\n * Replace the tracks of a playlist\n * See [Replace a Playlist's Tracks](https://developer.spotify.com/web-api/replace-playlists-tracks/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} playlistId The id of the playlist. If you know the Spotify URI it is easy\n * to find the playlist id (e.g. spotify:user:xxxx:playlist:)\n * @param {Array} uris An array of Spotify URIs for the tracks\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.replaceTracksInPlaylist = function(playlistId, uris, callback) {\n var requestData = {\n url: _baseUri + '/playlists/' + playlistId + '/tracks',\n type: 'PUT',\n postData: { uris: uris }\n };\n return _checkParamsAndPerformRequest(requestData, {}, callback);\n };\n\n /**\n * Reorder tracks in a playlist\n * See [Reorder a Playlist’s Tracks](https://developer.spotify.com/web-api/reorder-playlists-tracks/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} playlistId The id of the playlist. If you know the Spotify URI it is easy\n * to find the playlist id (e.g. spotify:user:xxxx:playlist:)\n * @param {number} rangeStart The position of the first track to be reordered.\n * @param {number} insertBefore The position where the tracks should be inserted. To reorder the tracks to\n * the end of the playlist, simply set insert_before to the position after the last track.\n * @param {Object} options An object with optional parameters (range_length, snapshot_id)\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.reorderTracksInPlaylist = function(playlistId, rangeStart, insertBefore, options, callback) {\n /* eslint-disable camelcase */\n var requestData = {\n url: _baseUri + '/playlists/' + playlistId + '/tracks',\n type: 'PUT',\n postData: {\n range_start: rangeStart,\n insert_before: insertBefore\n }\n };\n /* eslint-enable camelcase */\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Remove tracks from a playlist\n * See [Remove Tracks from a Playlist](https://developer.spotify.com/web-api/remove-tracks-playlist/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} playlistId The id of the playlist. If you know the Spotify URI it is easy\n * to find the playlist id (e.g. spotify:user:xxxx:playlist:)\n * @param {Array} uris An array of tracks to be removed. Each element of the array can be either a\n * string, in which case it is treated as a URI, or an object containing the properties `uri` (which is a\n * string) and `positions` (which is an array of integers).\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.removeTracksFromPlaylist = function(playlistId, uris, callback) {\n var dataToBeSent = uris.map(function(uri) {\n if (typeof uri === 'string') {\n return { uri: uri };\n } else {\n return uri;\n }\n });\n\n var requestData = {\n url: _baseUri + '/playlists/' + playlistId + '/tracks',\n type: 'DELETE',\n postData: { tracks: dataToBeSent }\n };\n return _checkParamsAndPerformRequest(requestData, {}, callback);\n };\n\n /**\n * Remove tracks from a playlist, specifying a snapshot id.\n * See [Remove Tracks from a Playlist](https://developer.spotify.com/web-api/remove-tracks-playlist/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} playlistId The id of the playlist. If you know the Spotify URI it is easy\n * to find the playlist id (e.g. spotify:user:xxxx:playlist:)\n * @param {Array} uris An array of tracks to be removed. Each element of the array can be either a\n * string, in which case it is treated as a URI, or an object containing the properties `uri` (which is a\n * string) and `positions` (which is an array of integers).\n * @param {string} snapshotId The playlist's snapshot ID against which you want to make the changes\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.removeTracksFromPlaylistWithSnapshotId = function(playlistId, uris, snapshotId, callback) {\n var dataToBeSent = uris.map(function(uri) {\n if (typeof uri === 'string') {\n return { uri: uri };\n } else {\n return uri;\n }\n });\n /* eslint-disable camelcase */\n var requestData = {\n url: _baseUri + '/playlists/' + playlistId + '/tracks',\n type: 'DELETE',\n postData: {\n tracks: dataToBeSent,\n snapshot_id: snapshotId\n }\n };\n /* eslint-enable camelcase */\n return _checkParamsAndPerformRequest(requestData, {}, callback);\n };\n\n /**\n * Remove tracks from a playlist, specifying the positions of the tracks to be removed.\n * See [Remove Tracks from a Playlist](https://developer.spotify.com/web-api/remove-tracks-playlist/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} playlistId The id of the playlist. If you know the Spotify URI it is easy\n * to find the playlist id (e.g. spotify:user:xxxx:playlist:)\n * @param {Array} positions array of integers containing the positions of the tracks to remove\n * from the playlist.\n * @param {string} snapshotId The playlist's snapshot ID against which you want to make the changes\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.removeTracksFromPlaylistInPositions = function(playlistId, positions, snapshotId, callback) {\n /* eslint-disable camelcase */\n var requestData = {\n url: _baseUri + '/playlists/' + playlistId + '/tracks',\n type: 'DELETE',\n postData: {\n positions: positions,\n snapshot_id: snapshotId\n }\n };\n /* eslint-enable camelcase */\n return _checkParamsAndPerformRequest(requestData, {}, callback);\n };\n\n /**\n * Upload a custom playlist cover image.\n * See [Upload A Custom Playlist Cover Image](https://developer.spotify.com/web-api/upload-a-custom-playlist-cover-image/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} playlistId The id of the playlist. If you know the Spotify URI it is easy\n * to find the playlist id (e.g. spotify:user:xxxx:playlist:)\n * @param {string} imageData Base64 encoded JPEG image data, maximum payload size is 256 KB.\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.uploadCustomPlaylistCoverImage = function(playlistId, imageData, callback) {\n var requestData = {\n url: _baseUri + '/playlists/' + playlistId + '/images',\n type: 'PUT',\n postData: imageData.replace(/^data:image\\/jpeg;base64,/, ''),\n contentType: 'image/jpeg'\n };\n return _checkParamsAndPerformRequest(requestData, {}, callback);\n };\n\n /**\n * Fetches an album from the Spotify catalog.\n * See [Get an Album](https://developer.spotify.com/web-api/get-album/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} albumId The id of the album. If you know the Spotify URI it is easy\n * to find the album id (e.g. spotify:album:)\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getAlbum = function(albumId, options, callback) {\n var requestData = {\n url: _baseUri + '/albums/' + albumId\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Fetches the tracks of an album from the Spotify catalog.\n * See [Get an Album's Tracks](https://developer.spotify.com/web-api/get-albums-tracks/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} albumId The id of the album. If you know the Spotify URI it is easy\n * to find the album id (e.g. spotify:album:)\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getAlbumTracks = function(albumId, options, callback) {\n var requestData = {\n url: _baseUri + '/albums/' + albumId + '/tracks'\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Fetches multiple albums from the Spotify catalog.\n * See [Get Several Albums](https://developer.spotify.com/web-api/get-several-albums/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Array} albumIds The ids of the albums. If you know their Spotify URI it is easy\n * to find their album id (e.g. spotify:album:)\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getAlbums = function(albumIds, options, callback) {\n var requestData = {\n url: _baseUri + '/albums/',\n params: { ids: albumIds.join(',') }\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Fetches a track from the Spotify catalog.\n * See [Get a Track](https://developer.spotify.com/web-api/get-track/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} trackId The id of the track. If you know the Spotify URI it is easy\n * to find the track id (e.g. spotify:track:)\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getTrack = function(trackId, options, callback) {\n var requestData = {};\n requestData.url = _baseUri + '/tracks/' + trackId;\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Fetches multiple tracks from the Spotify catalog.\n * See [Get Several Tracks](https://developer.spotify.com/web-api/get-several-tracks/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Array} trackIds The ids of the tracks. If you know their Spotify URI it is easy\n * to find their track id (e.g. spotify:track:)\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getTracks = function(trackIds, options, callback) {\n var requestData = {\n url: _baseUri + '/tracks/',\n params: { ids: trackIds.join(',') }\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Fetches an artist from the Spotify catalog.\n * See [Get an Artist](https://developer.spotify.com/web-api/get-artist/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} artistId The id of the artist. If you know the Spotify URI it is easy\n * to find the artist id (e.g. spotify:artist:)\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getArtist = function(artistId, options, callback) {\n var requestData = {\n url: _baseUri + '/artists/' + artistId\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Fetches multiple artists from the Spotify catalog.\n * See [Get Several Artists](https://developer.spotify.com/web-api/get-several-artists/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Array} artistIds The ids of the artists. If you know their Spotify URI it is easy\n * to find their artist id (e.g. spotify:artist:)\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getArtists = function(artistIds, options, callback) {\n var requestData = {\n url: _baseUri + '/artists/',\n params: { ids: artistIds.join(',') }\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Fetches the albums of an artist from the Spotify catalog.\n * See [Get an Artist's Albums](https://developer.spotify.com/web-api/get-artists-albums/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} artistId The id of the artist. If you know the Spotify URI it is easy\n * to find the artist id (e.g. spotify:artist:)\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getArtistAlbums = function(artistId, options, callback) {\n var requestData = {\n url: _baseUri + '/artists/' + artistId + '/albums'\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Fetches a list of top tracks of an artist from the Spotify catalog, for a specific country.\n * See [Get an Artist's Top Tracks](https://developer.spotify.com/web-api/get-artists-top-tracks/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} artistId The id of the artist. If you know the Spotify URI it is easy\n * to find the artist id (e.g. spotify:artist:)\n * @param {string} countryId The id of the country (e.g. ES for Spain or US for United States)\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getArtistTopTracks = function(artistId, countryId, options, callback) {\n var requestData = {\n url: _baseUri + '/artists/' + artistId + '/top-tracks',\n params: { country: countryId }\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Fetches a list of artists related with a given one from the Spotify catalog.\n * See [Get an Artist's Related Artists](https://developer.spotify.com/web-api/get-related-artists/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} artistId The id of the artist. If you know the Spotify URI it is easy\n * to find the artist id (e.g. spotify:artist:)\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getArtistRelatedArtists = function(artistId, options, callback) {\n var requestData = {\n url: _baseUri + '/artists/' + artistId + '/related-artists'\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Fetches a list of Spotify featured playlists (shown, for example, on a Spotify player's \"Browse\" tab).\n * See [Get a List of Featured Playlists](https://developer.spotify.com/web-api/get-list-featured-playlists/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getFeaturedPlaylists = function(options, callback) {\n var requestData = {\n url: _baseUri + '/browse/featured-playlists'\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Fetches a list of new album releases featured in Spotify (shown, for example, on a Spotify player's \"Browse\" tab).\n * See [Get a List of New Releases](https://developer.spotify.com/web-api/get-list-new-releases/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getNewReleases = function(options, callback) {\n var requestData = {\n url: _baseUri + '/browse/new-releases'\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Get a list of categories used to tag items in Spotify (on, for example, the Spotify player's \"Browse\" tab).\n * See [Get a List of Categories](https://developer.spotify.com/web-api/get-list-categories/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getCategories = function(options, callback) {\n var requestData = {\n url: _baseUri + '/browse/categories'\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Get a single category used to tag items in Spotify (on, for example, the Spotify player's \"Browse\" tab).\n * See [Get a Category](https://developer.spotify.com/web-api/get-category/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} categoryId The id of the category. These can be found with the getCategories function\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getCategory = function(categoryId, options, callback) {\n var requestData = {\n url: _baseUri + '/browse/categories/' + categoryId\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Get a list of Spotify playlists tagged with a particular category.\n * See [Get a Category's Playlists](https://developer.spotify.com/web-api/get-categorys-playlists/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} categoryId The id of the category. These can be found with the getCategories function\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getCategoryPlaylists = function(categoryId, options, callback) {\n var requestData = {\n url: _baseUri + '/browse/categories/' + categoryId + '/playlists'\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Get Spotify catalog information about artists, albums, tracks or playlists that match a keyword string.\n * See [Search for an Item](https://developer.spotify.com/web-api/search-item/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} query The search query\n * @param {Array} types An array of item types to search across.\n * Valid types are: 'album', 'artist', 'playlist', and 'track'.\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.search = function(query, types, options, callback) {\n var requestData = {\n url: _baseUri + '/search/',\n params: {\n q: query,\n type: types.join(',')\n }\n };\n return _checkParamsAndPerformRequest(requestData, options, callback);\n };\n\n /**\n * Fetches albums from the Spotify catalog according to a query.\n * See [Search for an Item](https://developer.spotify.com/web-api/search-item/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} query The search query\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.searchAlbums = function(query, options, callback) {\n return this.search(query, ['album'], options, callback);\n };\n\n /**\n * Fetches artists from the Spotify catalog according to a query.\n * See [Search for an Item](https://developer.spotify.com/web-api/search-item/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} query The search query\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.searchArtists = function(query, options, callback) {\n return this.search(query, ['artist'], options, callback);\n };\n\n /**\n * Fetches tracks from the Spotify catalog according to a query.\n * See [Search for an Item](https://developer.spotify.com/web-api/search-item/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} query The search query\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.searchTracks = function(query, options, callback) {\n return this.search(query, ['track'], options, callback);\n };\n\n /**\n * Fetches playlists from the Spotify catalog according to a query.\n * See [Search for an Item](https://developer.spotify.com/web-api/search-item/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} query The search query\n * @param {Object} options A JSON object with options that can be passed\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.searchPlaylists = function(query, options, callback) {\n return this.search(query, ['playlist'], options, callback);\n };\n\n /**\n * Get audio features for a single track identified by its unique Spotify ID.\n * See [Get Audio Features for a Track](https://developer.spotify.com/web-api/get-audio-features/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} trackId The id of the track. If you know the Spotify URI it is easy\n * to find the track id (e.g. spotify:track:)\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getAudioFeaturesForTrack = function(trackId, callback) {\n var requestData = {};\n requestData.url = _baseUri + '/audio-features/' + trackId;\n return _checkParamsAndPerformRequest(requestData, {}, callback);\n };\n\n /**\n * Get audio features for multiple tracks based on their Spotify IDs.\n * See [Get Audio Features for Several Tracks](https://developer.spotify.com/web-api/get-several-audio-features/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {Array} trackIds The ids of the tracks. If you know their Spotify URI it is easy\n * to find their track id (e.g. spotify:track:)\n * @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first\n * one is the error object (null if no error), and the second is the value if the request succeeded.\n * @return {Object} Null if a callback is provided, a `Promise` object otherwise\n */\n Constr.prototype.getAudioFeaturesForTracks = function(trackIds, callback) {\n var requestData = {\n url: _baseUri + '/audio-features',\n params: { ids: trackIds }\n };\n return _checkParamsAndPerformRequest(requestData, {}, callback);\n };\n\n /**\n * Get audio analysis for a single track identified by its unique Spotify ID.\n * See [Get Audio Analysis for a Track](https://developer.spotify.com/web-api/get-audio-analysis/) on\n * the Spotify Developer site for more information about the endpoint.\n *\n * @param {string} trackId The id of the track. If you know the Spotify URI it is easy\n * to find the track id (e.g. spotify:track: