{"version":3,"sources":["webpack:///./node_modules/howler/dist/howler.js","webpack:///(webpack)/buildin/global.js"],"names":["_typeof","Symbol","iterator","obj","constructor","prototype","HowlerGlobal","this","init","self","Howler","_counter","_html5AudioPool","html5PoolSize","_codecs","_howls","_muted","_volume","_canPlayEvent","_navigator","window","navigator","masterGain","noAudio","usingWebAudio","autoSuspend","ctx","autoUnlock","_setup","volume","vol","parseFloat","setupAudioContext","gain","setValueAtTime","currentTime","i","length","_webAudio","ids","_getSoundIds","j","sound","_soundById","_node","mute","muted","stop","unload","close","codecs","ext","replace","state","_autoSuspend","Audio","oncanplaythrough","e","_setupCodecs","audioTest","err","canPlayType","mpegTest","checkOpera","userAgent","match","isOldOpera","parseInt","split","mp3","mpeg","opus","ogg","oga","wav","aac","caf","m4a","m4b","mp4","weba","webm","dolby","flac","_unlockAudio","_audioUnlocked","_mobileUnloaded","sampleRate","_scratchBuffer","createBuffer","unlock","audioNode","_unlocked","_releaseHtml5Audio","load","_autoResume","source","createBufferSource","buffer","connect","destination","start","noteOn","resume","onended","disconnect","document","removeEventListener","_emit","addEventListener","_obtainHtml5Audio","pop","testPlay","play","Promise","then","console","warn","audio","push","suspend","_sounds","_paused","_suspendTimer","clearTimeout","setTimeout","handleSuspension","_resumeAfterSuspend","Howl","o","src","error","_autoplay","autoplay","_format","format","_html5","html5","_loop","loop","_pool","pool","_preload","preload","_rate","rate","_sprite","sprite","_src","undefined","_xhr","method","xhr","headers","withCredentials","_duration","_state","_endTimers","_queue","_playLock","_onend","onend","fn","_onfade","onfade","_onload","onload","_onloaderror","onloaderror","_onplayerror","onplayerror","_onpause","onpause","_onplay","onplay","_onstop","onstop","_onmute","onmute","_onvolume","onvolume","_onrate","onrate","_onseek","onseek","_onunlock","onunlock","_onresume","event","action","url","str","exec","toLowerCase","location","protocol","slice","Sound","loadBuffer","internal","id","num","_ended","_id","_inactiveSound","soundId","_loadQueue","seek","Math","max","_seek","duration","timeout","abs","setParams","_start","_stop","node","playWebAudio","_refreshBuffer","_playStart","bufferSource","noteGrainOn","Infinity","bind","once","_clearTimer","playHtml5","playbackRate","paused","loadedNoReadyState","ejecta","readyState","isCocoonJS","listener","pause","_rateSeek","_stopFade","noteOff","_cleanBuffer","isNaN","arguments","_clearSound","_interval","args","index","indexOf","apply","fade","from","to","len","min","end","linearRampToValueAtTime","_startFadeInterval","isGroup","diff","steps","stepLen","lastTick","Date","now","_fadeTo","setInterval","tick","round","clearInterval","cancelScheduledValues","loopStart","loopEnd","playing","realTime","rateSeek","seekAndEmit","emitSeek","sounds","_errorFn","_loadFn","_endFn","splice","remCache","cache","on","events","off","isId","keys","Object","Array","isArray","msg","call","task","shift","ended","_drain","reset","limit","cnt","_panner","isIOS","vendor","test","howl","_parent","parent","create","createGain","createGainNode","_errorListener","_loadListener","_endListener","code","ceil","__default","loadSound","data","atob","dataView","Uint8Array","charCodeAt","decodeAudioData","XMLHttpRequest","open","responseType","forEach","key","setRequestHeader","status","response","onerror","safeXhrSend","send","arraybuffer","success","AudioContext","webkitAudioContext","iOS","platform","appVersion","version","safari","exports","global","_super","_pos","_orientation","stereo","pan","pos","x","y","z","positionX","setTargetAtTime","positionY","positionZ","setPosition","orientation","xUp","yUp","zUp","or","forwardX","forwardY","forwardZ","upX","upY","upZ","setOrientation","_stereo","_pannerAttr","coneInnerAngle","coneOuterAngle","coneOuterGain","distanceModel","maxDistance","panningModel","refDistance","rolloffFactor","_onstereo","onstereo","_onpos","onpos","_onorientation","onorientation","pannerType","createStereoPanner","setupPanner","orientationX","orientationY","orientationZ","pannerAttr","_coneInnerAngle","_coneOuterAngle","_coneOuterGain","_distanceModel","_maxDistance","_refDistance","_rolloffFactor","_panningModel","pa","panner","type","createPanner","g","Function","module"],"mappings":"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","file":"js/20-d5e6861df58b4b0c30cd.chunk.js","sourcesContent":["function _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n/*!\n * howler.js v2.2.1\n * howlerjs.com\n *\n * (c) 2013-2020, James Simpson of GoldFire Studios\n * goldfirestudios.com\n *\n * MIT License\n */\n(function () {\n 'use strict';\n /** Global Methods **/\n\n /***************************************************************************/\n\n /**\n * Create the global controller. All contained methods and properties apply\n * to all sounds that are currently playing or will be in the future.\n */\n\n var HowlerGlobal = function HowlerGlobal() {\n this.init();\n };\n\n HowlerGlobal.prototype = {\n /**\n * Initialize the global Howler object.\n * @return {Howler}\n */\n init: function init() {\n var self = this || Howler; // Create a global ID counter.\n\n self._counter = 1000; // Pool of unlocked HTML5 Audio objects.\n\n self._html5AudioPool = [];\n self.html5PoolSize = 10; // Internal properties.\n\n self._codecs = {};\n self._howls = [];\n self._muted = false;\n self._volume = 1;\n self._canPlayEvent = 'canplaythrough';\n self._navigator = typeof window !== 'undefined' && window.navigator ? window.navigator : null; // Public properties.\n\n self.masterGain = null;\n self.noAudio = false;\n self.usingWebAudio = true;\n self.autoSuspend = true;\n self.ctx = null; // Set to false to disable the auto audio unlocker.\n\n self.autoUnlock = true; // Setup the various state values for global tracking.\n\n self._setup();\n\n return self;\n },\n\n /**\n * Get/set the global volume for all sounds.\n * @param {Float} vol Volume from 0.0 to 1.0.\n * @return {Howler/Float} Returns self or current volume.\n */\n volume: function volume(vol) {\n var self = this || Howler;\n vol = parseFloat(vol); // If we don't have an AudioContext created yet, run the setup.\n\n if (!self.ctx) {\n setupAudioContext();\n }\n\n if (typeof vol !== 'undefined' && vol >= 0 && vol <= 1) {\n self._volume = vol; // Don't update any of the nodes if we are muted.\n\n if (self._muted) {\n return self;\n } // When using Web Audio, we just need to adjust the master gain.\n\n\n if (self.usingWebAudio) {\n self.masterGain.gain.setValueAtTime(vol, Howler.ctx.currentTime);\n } // Loop through and change volume for all HTML5 audio nodes.\n\n\n for (var i = 0; i < self._howls.length; i++) {\n if (!self._howls[i]._webAudio) {\n // Get all of the sounds in this Howl group.\n var ids = self._howls[i]._getSoundIds(); // Loop through all sounds and change the volumes.\n\n\n for (var j = 0; j < ids.length; j++) {\n var sound = self._howls[i]._soundById(ids[j]);\n\n if (sound && sound._node) {\n sound._node.volume = sound._volume * vol;\n }\n }\n }\n }\n\n return self;\n }\n\n return self._volume;\n },\n\n /**\n * Handle muting and unmuting globally.\n * @param {Boolean} muted Is muted or not.\n */\n mute: function mute(muted) {\n var self = this || Howler; // If we don't have an AudioContext created yet, run the setup.\n\n if (!self.ctx) {\n setupAudioContext();\n }\n\n self._muted = muted; // With Web Audio, we just need to mute the master gain.\n\n if (self.usingWebAudio) {\n self.masterGain.gain.setValueAtTime(muted ? 0 : self._volume, Howler.ctx.currentTime);\n } // Loop through and mute all HTML5 Audio nodes.\n\n\n for (var i = 0; i < self._howls.length; i++) {\n if (!self._howls[i]._webAudio) {\n // Get all of the sounds in this Howl group.\n var ids = self._howls[i]._getSoundIds(); // Loop through all sounds and mark the audio node as muted.\n\n\n for (var j = 0; j < ids.length; j++) {\n var sound = self._howls[i]._soundById(ids[j]);\n\n if (sound && sound._node) {\n sound._node.muted = muted ? true : sound._muted;\n }\n }\n }\n }\n\n return self;\n },\n\n /**\n * Handle stopping all sounds globally.\n */\n stop: function stop() {\n var self = this || Howler; // Loop through all Howls and stop them.\n\n for (var i = 0; i < self._howls.length; i++) {\n self._howls[i].stop();\n }\n\n return self;\n },\n\n /**\n * Unload and destroy all currently loaded Howl objects.\n * @return {Howler}\n */\n unload: function unload() {\n var self = this || Howler;\n\n for (var i = self._howls.length - 1; i >= 0; i--) {\n self._howls[i].unload();\n } // Create a new AudioContext to make sure it is fully reset.\n\n\n if (self.usingWebAudio && self.ctx && typeof self.ctx.close !== 'undefined') {\n self.ctx.close();\n self.ctx = null;\n setupAudioContext();\n }\n\n return self;\n },\n\n /**\n * Check for codec support of specific extension.\n * @param {String} ext Audio file extention.\n * @return {Boolean}\n */\n codecs: function codecs(ext) {\n return (this || Howler)._codecs[ext.replace(/^x-/, '')];\n },\n\n /**\n * Setup various state values for global tracking.\n * @return {Howler}\n */\n _setup: function _setup() {\n var self = this || Howler; // Keeps track of the suspend/resume state of the AudioContext.\n\n self.state = self.ctx ? self.ctx.state || 'suspended' : 'suspended'; // Automatically begin the 30-second suspend process\n\n self._autoSuspend(); // Check if audio is available.\n\n\n if (!self.usingWebAudio) {\n // No audio is available on this system if noAudio is set to true.\n if (typeof Audio !== 'undefined') {\n try {\n var test = new Audio(); // Check if the canplaythrough event is available.\n\n if (typeof test.oncanplaythrough === 'undefined') {\n self._canPlayEvent = 'canplay';\n }\n } catch (e) {\n self.noAudio = true;\n }\n } else {\n self.noAudio = true;\n }\n } // Test to make sure audio isn't disabled in Internet Explorer.\n\n\n try {\n var test = new Audio();\n\n if (test.muted) {\n self.noAudio = true;\n }\n } catch (e) {} // Check for supported codecs.\n\n\n if (!self.noAudio) {\n self._setupCodecs();\n }\n\n return self;\n },\n\n /**\n * Check for browser support for various codecs and cache the results.\n * @return {Howler}\n */\n _setupCodecs: function _setupCodecs() {\n var self = this || Howler;\n var audioTest = null; // Must wrap in a try/catch because IE11 in server mode throws an error.\n\n try {\n audioTest = typeof Audio !== 'undefined' ? new Audio() : null;\n } catch (err) {\n return self;\n }\n\n if (!audioTest || typeof audioTest.canPlayType !== 'function') {\n return self;\n }\n\n var mpegTest = audioTest.canPlayType('audio/mpeg;').replace(/^no$/, ''); // Opera version <33 has mixed MP3 support, so we need to check for and block it.\n\n var checkOpera = self._navigator && self._navigator.userAgent.match(/OPR\\/([0-6].)/g);\n\n var isOldOpera = checkOpera && parseInt(checkOpera[0].split('/')[1], 10) < 33;\n self._codecs = {\n mp3: !!(!isOldOpera && (mpegTest || audioTest.canPlayType('audio/mp3;').replace(/^no$/, ''))),\n mpeg: !!mpegTest,\n opus: !!audioTest.canPlayType('audio/ogg; codecs=\"opus\"').replace(/^no$/, ''),\n ogg: !!audioTest.canPlayType('audio/ogg; codecs=\"vorbis\"').replace(/^no$/, ''),\n oga: !!audioTest.canPlayType('audio/ogg; codecs=\"vorbis\"').replace(/^no$/, ''),\n wav: !!(audioTest.canPlayType('audio/wav; codecs=\"1\"') || audioTest.canPlayType('audio/wav')).replace(/^no$/, ''),\n aac: !!audioTest.canPlayType('audio/aac;').replace(/^no$/, ''),\n caf: !!audioTest.canPlayType('audio/x-caf;').replace(/^no$/, ''),\n m4a: !!(audioTest.canPlayType('audio/x-m4a;') || audioTest.canPlayType('audio/m4a;') || audioTest.canPlayType('audio/aac;')).replace(/^no$/, ''),\n m4b: !!(audioTest.canPlayType('audio/x-m4b;') || audioTest.canPlayType('audio/m4b;') || audioTest.canPlayType('audio/aac;')).replace(/^no$/, ''),\n mp4: !!(audioTest.canPlayType('audio/x-mp4;') || audioTest.canPlayType('audio/mp4;') || audioTest.canPlayType('audio/aac;')).replace(/^no$/, ''),\n weba: !!audioTest.canPlayType('audio/webm; codecs=\"vorbis\"').replace(/^no$/, ''),\n webm: !!audioTest.canPlayType('audio/webm; codecs=\"vorbis\"').replace(/^no$/, ''),\n dolby: !!audioTest.canPlayType('audio/mp4; codecs=\"ec-3\"').replace(/^no$/, ''),\n flac: !!(audioTest.canPlayType('audio/x-flac;') || audioTest.canPlayType('audio/flac;')).replace(/^no$/, '')\n };\n return self;\n },\n\n /**\n * Some browsers/devices will only allow audio to be played after a user interaction.\n * Attempt to automatically unlock audio on the first user interaction.\n * Concept from: http://paulbakaus.com/tutorials/html5/web-audio-on-ios/\n * @return {Howler}\n */\n _unlockAudio: function _unlockAudio() {\n var self = this || Howler; // Only run this if Web Audio is supported and it hasn't already been unlocked.\n\n if (self._audioUnlocked || !self.ctx) {\n return;\n }\n\n self._audioUnlocked = false;\n self.autoUnlock = false; // Some mobile devices/platforms have distortion issues when opening/closing tabs and/or web views.\n // Bugs in the browser (especially Mobile Safari) can cause the sampleRate to change from 44100 to 48000.\n // By calling Howler.unload(), we create a new AudioContext with the correct sampleRate.\n\n if (!self._mobileUnloaded && self.ctx.sampleRate !== 44100) {\n self._mobileUnloaded = true;\n self.unload();\n } // Scratch buffer for enabling iOS to dispose of web audio buffers correctly, as per:\n // http://stackoverflow.com/questions/24119684\n\n\n self._scratchBuffer = self.ctx.createBuffer(1, 1, 22050); // Call this method on touch start to create and play a buffer,\n // then check if the audio actually played to determine if\n // audio has now been unlocked on iOS, Android, etc.\n\n var unlock = function unlock(e) {\n // Create a pool of unlocked HTML5 Audio objects that can\n // be used for playing sounds without user interaction. HTML5\n // Audio objects must be individually unlocked, as opposed\n // to the WebAudio API which only needs a single activation.\n // This must occur before WebAudio setup or the source.onended\n // event will not fire.\n while (self._html5AudioPool.length < self.html5PoolSize) {\n try {\n var audioNode = new Audio(); // Mark this Audio object as unlocked to ensure it can get returned\n // to the unlocked pool when released.\n\n audioNode._unlocked = true; // Add the audio node to the pool.\n\n self._releaseHtml5Audio(audioNode);\n } catch (e) {\n self.noAudio = true;\n break;\n }\n } // Loop through any assigned audio nodes and unlock them.\n\n\n for (var i = 0; i < self._howls.length; i++) {\n if (!self._howls[i]._webAudio) {\n // Get all of the sounds in this Howl group.\n var ids = self._howls[i]._getSoundIds(); // Loop through all sounds and unlock the audio nodes.\n\n\n for (var j = 0; j < ids.length; j++) {\n var sound = self._howls[i]._soundById(ids[j]);\n\n if (sound && sound._node && !sound._node._unlocked) {\n sound._node._unlocked = true;\n\n sound._node.load();\n }\n }\n }\n } // Fix Android can not play in suspend state.\n\n\n self._autoResume(); // Create an empty buffer.\n\n\n var source = self.ctx.createBufferSource();\n source.buffer = self._scratchBuffer;\n source.connect(self.ctx.destination); // Play the empty buffer.\n\n if (typeof source.start === 'undefined') {\n source.noteOn(0);\n } else {\n source.start(0);\n } // Calling resume() on a stack initiated by user gesture is what actually unlocks the audio on Android Chrome >= 55.\n\n\n if (typeof self.ctx.resume === 'function') {\n self.ctx.resume();\n } // Setup a timeout to check that we are unlocked on the next event loop.\n\n\n source.onended = function () {\n source.disconnect(0); // Update the unlocked state and prevent this check from happening again.\n\n self._audioUnlocked = true; // Remove the touch start listener.\n\n document.removeEventListener('touchstart', unlock, true);\n document.removeEventListener('touchend', unlock, true);\n document.removeEventListener('click', unlock, true); // Let all sounds know that audio has been unlocked.\n\n for (var i = 0; i < self._howls.length; i++) {\n self._howls[i]._emit('unlock');\n }\n };\n }; // Setup a touch start listener to attempt an unlock in.\n\n\n document.addEventListener('touchstart', unlock, true);\n document.addEventListener('touchend', unlock, true);\n document.addEventListener('click', unlock, true);\n return self;\n },\n\n /**\n * Get an unlocked HTML5 Audio object from the pool. If none are left,\n * return a new Audio object and throw a warning.\n * @return {Audio} HTML5 Audio object.\n */\n _obtainHtml5Audio: function _obtainHtml5Audio() {\n var self = this || Howler; // Return the next object from the pool if one exists.\n\n if (self._html5AudioPool.length) {\n return self._html5AudioPool.pop();\n } //.Check if the audio is locked and throw a warning.\n\n\n var testPlay = new Audio().play();\n\n if (testPlay && typeof Promise !== 'undefined' && (testPlay instanceof Promise || typeof testPlay.then === 'function')) {\n testPlay[\"catch\"](function () {\n console.warn('HTML5 Audio pool exhausted, returning potentially locked audio object.');\n });\n }\n\n return new Audio();\n },\n\n /**\n * Return an activated HTML5 Audio object to the pool.\n * @return {Howler}\n */\n _releaseHtml5Audio: function _releaseHtml5Audio(audio) {\n var self = this || Howler; // Don't add audio to the pool if we don't know if it has been unlocked.\n\n if (audio._unlocked) {\n self._html5AudioPool.push(audio);\n }\n\n return self;\n },\n\n /**\n * Automatically suspend the Web Audio AudioContext after no sound has played for 30 seconds.\n * This saves processing/energy and fixes various browser-specific bugs with audio getting stuck.\n * @return {Howler}\n */\n _autoSuspend: function _autoSuspend() {\n var self = this;\n\n if (!self.autoSuspend || !self.ctx || typeof self.ctx.suspend === 'undefined' || !Howler.usingWebAudio) {\n return;\n } // Check if any sounds are playing.\n\n\n for (var i = 0; i < self._howls.length; i++) {\n if (self._howls[i]._webAudio) {\n for (var j = 0; j < self._howls[i]._sounds.length; j++) {\n if (!self._howls[i]._sounds[j]._paused) {\n return self;\n }\n }\n }\n }\n\n if (self._suspendTimer) {\n clearTimeout(self._suspendTimer);\n } // If no sound has played after 30 seconds, suspend the context.\n\n\n self._suspendTimer = setTimeout(function () {\n if (!self.autoSuspend) {\n return;\n }\n\n self._suspendTimer = null;\n self.state = 'suspending'; // Handle updating the state of the audio context after suspending.\n\n var handleSuspension = function handleSuspension() {\n self.state = 'suspended';\n\n if (self._resumeAfterSuspend) {\n delete self._resumeAfterSuspend;\n\n self._autoResume();\n }\n }; // Either the state gets suspended or it is interrupted.\n // Either way, we need to update the state to suspended.\n\n\n self.ctx.suspend().then(handleSuspension, handleSuspension);\n }, 30000);\n return self;\n },\n\n /**\n * Automatically resume the Web Audio AudioContext when a new sound is played.\n * @return {Howler}\n */\n _autoResume: function _autoResume() {\n var self = this;\n\n if (!self.ctx || typeof self.ctx.resume === 'undefined' || !Howler.usingWebAudio) {\n return;\n }\n\n if (self.state === 'running' && self.ctx.state !== 'interrupted' && self._suspendTimer) {\n clearTimeout(self._suspendTimer);\n self._suspendTimer = null;\n } else if (self.state === 'suspended' || self.state === 'running' && self.ctx.state === 'interrupted') {\n self.ctx.resume().then(function () {\n self.state = 'running'; // Emit to all Howls that the audio has resumed.\n\n for (var i = 0; i < self._howls.length; i++) {\n self._howls[i]._emit('resume');\n }\n });\n\n if (self._suspendTimer) {\n clearTimeout(self._suspendTimer);\n self._suspendTimer = null;\n }\n } else if (self.state === 'suspending') {\n self._resumeAfterSuspend = true;\n }\n\n return self;\n }\n }; // Setup the global audio controller.\n\n var Howler = new HowlerGlobal();\n /** Group Methods **/\n\n /***************************************************************************/\n\n /**\n * Create an audio group controller.\n * @param {Object} o Passed in properties for this group.\n */\n\n var Howl = function Howl(o) {\n var self = this; // Throw an error if no source is provided.\n\n if (!o.src || o.src.length === 0) {\n console.error('An array of source files must be passed with any new Howl.');\n return;\n }\n\n self.init(o);\n };\n\n Howl.prototype = {\n /**\n * Initialize a new Howl group object.\n * @param {Object} o Passed in properties for this group.\n * @return {Howl}\n */\n init: function init(o) {\n var self = this; // If we don't have an AudioContext created yet, run the setup.\n\n if (!Howler.ctx) {\n setupAudioContext();\n } // Setup user-defined default properties.\n\n\n self._autoplay = o.autoplay || false;\n self._format = typeof o.format !== 'string' ? o.format : [o.format];\n self._html5 = o.html5 || false;\n self._muted = o.mute || false;\n self._loop = o.loop || false;\n self._pool = o.pool || 5;\n self._preload = typeof o.preload === 'boolean' || o.preload === 'metadata' ? o.preload : true;\n self._rate = o.rate || 1;\n self._sprite = o.sprite || {};\n self._src = typeof o.src !== 'string' ? o.src : [o.src];\n self._volume = o.volume !== undefined ? o.volume : 1;\n self._xhr = {\n method: o.xhr && o.xhr.method ? o.xhr.method : 'GET',\n headers: o.xhr && o.xhr.headers ? o.xhr.headers : null,\n withCredentials: o.xhr && o.xhr.withCredentials ? o.xhr.withCredentials : false\n }; // Setup all other default properties.\n\n self._duration = 0;\n self._state = 'unloaded';\n self._sounds = [];\n self._endTimers = {};\n self._queue = [];\n self._playLock = false; // Setup event listeners.\n\n self._onend = o.onend ? [{\n fn: o.onend\n }] : [];\n self._onfade = o.onfade ? [{\n fn: o.onfade\n }] : [];\n self._onload = o.onload ? [{\n fn: o.onload\n }] : [];\n self._onloaderror = o.onloaderror ? [{\n fn: o.onloaderror\n }] : [];\n self._onplayerror = o.onplayerror ? [{\n fn: o.onplayerror\n }] : [];\n self._onpause = o.onpause ? [{\n fn: o.onpause\n }] : [];\n self._onplay = o.onplay ? [{\n fn: o.onplay\n }] : [];\n self._onstop = o.onstop ? [{\n fn: o.onstop\n }] : [];\n self._onmute = o.onmute ? [{\n fn: o.onmute\n }] : [];\n self._onvolume = o.onvolume ? [{\n fn: o.onvolume\n }] : [];\n self._onrate = o.onrate ? [{\n fn: o.onrate\n }] : [];\n self._onseek = o.onseek ? [{\n fn: o.onseek\n }] : [];\n self._onunlock = o.onunlock ? [{\n fn: o.onunlock\n }] : [];\n self._onresume = []; // Web Audio or HTML5 Audio?\n\n self._webAudio = Howler.usingWebAudio && !self._html5; // Automatically try to enable audio.\n\n if (typeof Howler.ctx !== 'undefined' && Howler.ctx && Howler.autoUnlock) {\n Howler._unlockAudio();\n } // Keep track of this Howl group in the global controller.\n\n\n Howler._howls.push(self); // If they selected autoplay, add a play event to the load queue.\n\n\n if (self._autoplay) {\n self._queue.push({\n event: 'play',\n action: function action() {\n self.play();\n }\n });\n } // Load the source file unless otherwise specified.\n\n\n if (self._preload && self._preload !== 'none') {\n self.load();\n }\n\n return self;\n },\n\n /**\n * Load the audio file.\n * @return {Howler}\n */\n load: function load() {\n var self = this;\n var url = null; // If no audio is available, quit immediately.\n\n if (Howler.noAudio) {\n self._emit('loaderror', null, 'No audio support.');\n\n return;\n } // Make sure our source is in an array.\n\n\n if (typeof self._src === 'string') {\n self._src = [self._src];\n } // Loop through the sources and pick the first one that is compatible.\n\n\n for (var i = 0; i < self._src.length; i++) {\n var ext, str;\n\n if (self._format && self._format[i]) {\n // If an extension was specified, use that instead.\n ext = self._format[i];\n } else {\n // Make sure the source is a string.\n str = self._src[i];\n\n if (typeof str !== 'string') {\n self._emit('loaderror', null, 'Non-string found in selected audio sources - ignoring.');\n\n continue;\n } // Extract the file extension from the URL or base64 data URI.\n\n\n ext = /^data:audio\\/([^;,]+);/i.exec(str);\n\n if (!ext) {\n ext = /\\.([^.]+)$/.exec(str.split('?', 1)[0]);\n }\n\n if (ext) {\n ext = ext[1].toLowerCase();\n }\n } // Log a warning if no extension was found.\n\n\n if (!ext) {\n console.warn('No file extension was found. Consider using the \"format\" property or specify an extension.');\n } // Check if this extension is available.\n\n\n if (ext && Howler.codecs(ext)) {\n url = self._src[i];\n break;\n }\n }\n\n if (!url) {\n self._emit('loaderror', null, 'No codec support for selected audio sources.');\n\n return;\n }\n\n self._src = url;\n self._state = 'loading'; // If the hosting page is HTTPS and the source isn't,\n // drop down to HTML5 Audio to avoid Mixed Content errors.\n\n if (window.location.protocol === 'https:' && url.slice(0, 5) === 'http:') {\n self._html5 = true;\n self._webAudio = false;\n } // Create a new sound object and add it to the pool.\n\n\n new Sound(self); // Load and decode the audio data for playback.\n\n if (self._webAudio) {\n loadBuffer(self);\n }\n\n return self;\n },\n\n /**\n * Play a sound or resume previous playback.\n * @param {String/Number} sprite Sprite name for sprite playback or sound id to continue previous.\n * @param {Boolean} internal Internal Use: true prevents event firing.\n * @return {Number} Sound ID.\n */\n play: function play(sprite, internal) {\n var self = this;\n var id = null; // Determine if a sprite, sound id or nothing was passed\n\n if (typeof sprite === 'number') {\n id = sprite;\n sprite = null;\n } else if (typeof sprite === 'string' && self._state === 'loaded' && !self._sprite[sprite]) {\n // If the passed sprite doesn't exist, do nothing.\n return null;\n } else if (typeof sprite === 'undefined') {\n // Use the default sound sprite (plays the full audio length).\n sprite = '__default'; // Check if there is a single paused sound that isn't ended.\n // If there is, play that sound. If not, continue as usual.\n\n if (!self._playLock) {\n var num = 0;\n\n for (var i = 0; i < self._sounds.length; i++) {\n if (self._sounds[i]._paused && !self._sounds[i]._ended) {\n num++;\n id = self._sounds[i]._id;\n }\n }\n\n if (num === 1) {\n sprite = null;\n } else {\n id = null;\n }\n }\n } // Get the selected node, or get one from the pool.\n\n\n var sound = id ? self._soundById(id) : self._inactiveSound(); // If the sound doesn't exist, do nothing.\n\n if (!sound) {\n return null;\n } // Select the sprite definition.\n\n\n if (id && !sprite) {\n sprite = sound._sprite || '__default';\n } // If the sound hasn't loaded, we must wait to get the audio's duration.\n // We also need to wait to make sure we don't run into race conditions with\n // the order of function calls.\n\n\n if (self._state !== 'loaded') {\n // Set the sprite value on this sound.\n sound._sprite = sprite; // Mark this sound as not ended in case another sound is played before this one loads.\n\n sound._ended = false; // Add the sound to the queue to be played on load.\n\n var soundId = sound._id;\n\n self._queue.push({\n event: 'play',\n action: function action() {\n self.play(soundId);\n }\n });\n\n return soundId;\n } // Don't play the sound if an id was passed and it is already playing.\n\n\n if (id && !sound._paused) {\n // Trigger the play event, in order to keep iterating through queue.\n if (!internal) {\n self._loadQueue('play');\n }\n\n return sound._id;\n } // Make sure the AudioContext isn't suspended, and resume it if it is.\n\n\n if (self._webAudio) {\n Howler._autoResume();\n } // Determine how long to play for and where to start playing.\n\n\n var seek = Math.max(0, sound._seek > 0 ? sound._seek : self._sprite[sprite][0] / 1000);\n var duration = Math.max(0, (self._sprite[sprite][0] + self._sprite[sprite][1]) / 1000 - seek);\n var timeout = duration * 1000 / Math.abs(sound._rate);\n var start = self._sprite[sprite][0] / 1000;\n var stop = (self._sprite[sprite][0] + self._sprite[sprite][1]) / 1000;\n sound._sprite = sprite; // Mark the sound as ended instantly so that this async playback\n // doesn't get grabbed by another call to play while this one waits to start.\n\n sound._ended = false; // Update the parameters of the sound.\n\n var setParams = function setParams() {\n sound._paused = false;\n sound._seek = seek;\n sound._start = start;\n sound._stop = stop;\n sound._loop = !!(sound._loop || self._sprite[sprite][2]);\n }; // End the sound instantly if seek is at the end.\n\n\n if (seek >= stop) {\n self._ended(sound);\n\n return;\n } // Begin the actual playback.\n\n\n var node = sound._node;\n\n if (self._webAudio) {\n // Fire this when the sound is ready to play to begin Web Audio playback.\n var playWebAudio = function playWebAudio() {\n self._playLock = false;\n setParams();\n\n self._refreshBuffer(sound); // Setup the playback params.\n\n\n var vol = sound._muted || self._muted ? 0 : sound._volume;\n node.gain.setValueAtTime(vol, Howler.ctx.currentTime);\n sound._playStart = Howler.ctx.currentTime; // Play the sound using the supported method.\n\n if (typeof node.bufferSource.start === 'undefined') {\n sound._loop ? node.bufferSource.noteGrainOn(0, seek, 86400) : node.bufferSource.noteGrainOn(0, seek, duration);\n } else {\n sound._loop ? node.bufferSource.start(0, seek, 86400) : node.bufferSource.start(0, seek, duration);\n } // Start a new timer if none is present.\n\n\n if (timeout !== Infinity) {\n self._endTimers[sound._id] = setTimeout(self._ended.bind(self, sound), timeout);\n }\n\n if (!internal) {\n setTimeout(function () {\n self._emit('play', sound._id);\n\n self._loadQueue();\n }, 0);\n }\n };\n\n if (Howler.state === 'running' && Howler.ctx.state !== 'interrupted') {\n playWebAudio();\n } else {\n self._playLock = true; // Wait for the audio context to resume before playing.\n\n self.once('resume', playWebAudio); // Cancel the end timer.\n\n self._clearTimer(sound._id);\n }\n } else {\n // Fire this when the sound is ready to play to begin HTML5 Audio playback.\n var playHtml5 = function playHtml5() {\n node.currentTime = seek;\n node.muted = sound._muted || self._muted || Howler._muted || node.muted;\n node.volume = sound._volume * Howler.volume();\n node.playbackRate = sound._rate; // Some browsers will throw an error if this is called without user interaction.\n\n try {\n var play = node.play(); // Support older browsers that don't support promises, and thus don't have this issue.\n\n if (play && typeof Promise !== 'undefined' && (play instanceof Promise || typeof play.then === 'function')) {\n // Implements a lock to prevent DOMException: The play() request was interrupted by a call to pause().\n self._playLock = true; // Set param values immediately.\n\n setParams(); // Releases the lock and executes queued actions.\n\n play.then(function () {\n self._playLock = false;\n node._unlocked = true;\n\n if (!internal) {\n self._emit('play', sound._id);\n\n self._loadQueue();\n }\n })[\"catch\"](function () {\n self._playLock = false;\n\n self._emit('playerror', sound._id, 'Playback was unable to start. This is most commonly an issue ' + 'on mobile devices and Chrome where playback was not within a user interaction.'); // Reset the ended and paused values.\n\n\n sound._ended = true;\n sound._paused = true;\n });\n } else if (!internal) {\n self._playLock = false;\n setParams();\n\n self._emit('play', sound._id);\n\n self._loadQueue();\n } // Setting rate before playing won't work in IE, so we set it again here.\n\n\n node.playbackRate = sound._rate; // If the node is still paused, then we can assume there was a playback issue.\n\n if (node.paused) {\n self._emit('playerror', sound._id, 'Playback was unable to start. This is most commonly an issue ' + 'on mobile devices and Chrome where playback was not within a user interaction.');\n\n return;\n } // Setup the end timer on sprites or listen for the ended event.\n\n\n if (sprite !== '__default' || sound._loop) {\n self._endTimers[sound._id] = setTimeout(self._ended.bind(self, sound), timeout);\n } else {\n self._endTimers[sound._id] = function () {\n // Fire ended on this audio node.\n self._ended(sound); // Clear this listener.\n\n\n node.removeEventListener('ended', self._endTimers[sound._id], false);\n };\n\n node.addEventListener('ended', self._endTimers[sound._id], false);\n }\n } catch (err) {\n self._emit('playerror', sound._id, err);\n }\n }; // If this is streaming audio, make sure the src is set and load again.\n\n\n if (node.src === 'data:audio/wav;base64,UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA') {\n node.src = self._src;\n node.load();\n } // Play immediately if ready, or wait for the 'canplaythrough'e vent.\n\n\n var loadedNoReadyState = window && window.ejecta || !node.readyState && Howler._navigator.isCocoonJS;\n\n if (node.readyState >= 3 || loadedNoReadyState) {\n playHtml5();\n } else {\n self._playLock = true;\n\n var listener = function listener() {\n // Begin playback.\n playHtml5(); // Clear this listener.\n\n node.removeEventListener(Howler._canPlayEvent, listener, false);\n };\n\n node.addEventListener(Howler._canPlayEvent, listener, false); // Cancel the end timer.\n\n self._clearTimer(sound._id);\n }\n }\n\n return sound._id;\n },\n\n /**\n * Pause playback and save current position.\n * @param {Number} id The sound ID (empty to pause all in group).\n * @return {Howl}\n */\n pause: function pause(id) {\n var self = this; // If the sound hasn't loaded or a play() promise is pending, add it to the load queue to pause when capable.\n\n if (self._state !== 'loaded' || self._playLock) {\n self._queue.push({\n event: 'pause',\n action: function action() {\n self.pause(id);\n }\n });\n\n return self;\n } // If no id is passed, get all ID's to be paused.\n\n\n var ids = self._getSoundIds(id);\n\n for (var i = 0; i < ids.length; i++) {\n // Clear the end timer.\n self._clearTimer(ids[i]); // Get the sound.\n\n\n var sound = self._soundById(ids[i]);\n\n if (sound && !sound._paused) {\n // Reset the seek position.\n sound._seek = self.seek(ids[i]);\n sound._rateSeek = 0;\n sound._paused = true; // Stop currently running fades.\n\n self._stopFade(ids[i]);\n\n if (sound._node) {\n if (self._webAudio) {\n // Make sure the sound has been created.\n if (!sound._node.bufferSource) {\n continue;\n }\n\n if (typeof sound._node.bufferSource.stop === 'undefined') {\n sound._node.bufferSource.noteOff(0);\n } else {\n sound._node.bufferSource.stop(0);\n } // Clean up the buffer source.\n\n\n self._cleanBuffer(sound._node);\n } else if (!isNaN(sound._node.duration) || sound._node.duration === Infinity) {\n sound._node.pause();\n }\n }\n } // Fire the pause event, unless `true` is passed as the 2nd argument.\n\n\n if (!arguments[1]) {\n self._emit('pause', sound ? sound._id : null);\n }\n }\n\n return self;\n },\n\n /**\n * Stop playback and reset to start.\n * @param {Number} id The sound ID (empty to stop all in group).\n * @param {Boolean} internal Internal Use: true prevents event firing.\n * @return {Howl}\n */\n stop: function stop(id, internal) {\n var self = this; // If the sound hasn't loaded, add it to the load queue to stop when capable.\n\n if (self._state !== 'loaded' || self._playLock) {\n self._queue.push({\n event: 'stop',\n action: function action() {\n self.stop(id);\n }\n });\n\n return self;\n } // If no id is passed, get all ID's to be stopped.\n\n\n var ids = self._getSoundIds(id);\n\n for (var i = 0; i < ids.length; i++) {\n // Clear the end timer.\n self._clearTimer(ids[i]); // Get the sound.\n\n\n var sound = self._soundById(ids[i]);\n\n if (sound) {\n // Reset the seek position.\n sound._seek = sound._start || 0;\n sound._rateSeek = 0;\n sound._paused = true;\n sound._ended = true; // Stop currently running fades.\n\n self._stopFade(ids[i]);\n\n if (sound._node) {\n if (self._webAudio) {\n // Make sure the sound's AudioBufferSourceNode has been created.\n if (sound._node.bufferSource) {\n if (typeof sound._node.bufferSource.stop === 'undefined') {\n sound._node.bufferSource.noteOff(0);\n } else {\n sound._node.bufferSource.stop(0);\n } // Clean up the buffer source.\n\n\n self._cleanBuffer(sound._node);\n }\n } else if (!isNaN(sound._node.duration) || sound._node.duration === Infinity) {\n sound._node.currentTime = sound._start || 0;\n\n sound._node.pause(); // If this is a live stream, stop download once the audio is stopped.\n\n\n if (sound._node.duration === Infinity) {\n self._clearSound(sound._node);\n }\n }\n }\n\n if (!internal) {\n self._emit('stop', sound._id);\n }\n }\n }\n\n return self;\n },\n\n /**\n * Mute/unmute a single sound or all sounds in this Howl group.\n * @param {Boolean} muted Set to true to mute and false to unmute.\n * @param {Number} id The sound ID to update (omit to mute/unmute all).\n * @return {Howl}\n */\n mute: function mute(muted, id) {\n var self = this; // If the sound hasn't loaded, add it to the load queue to mute when capable.\n\n if (self._state !== 'loaded' || self._playLock) {\n self._queue.push({\n event: 'mute',\n action: function action() {\n self.mute(muted, id);\n }\n });\n\n return self;\n } // If applying mute/unmute to all sounds, update the group's value.\n\n\n if (typeof id === 'undefined') {\n if (typeof muted === 'boolean') {\n self._muted = muted;\n } else {\n return self._muted;\n }\n } // If no id is passed, get all ID's to be muted.\n\n\n var ids = self._getSoundIds(id);\n\n for (var i = 0; i < ids.length; i++) {\n // Get the sound.\n var sound = self._soundById(ids[i]);\n\n if (sound) {\n sound._muted = muted; // Cancel active fade and set the volume to the end value.\n\n if (sound._interval) {\n self._stopFade(sound._id);\n }\n\n if (self._webAudio && sound._node) {\n sound._node.gain.setValueAtTime(muted ? 0 : sound._volume, Howler.ctx.currentTime);\n } else if (sound._node) {\n sound._node.muted = Howler._muted ? true : muted;\n }\n\n self._emit('mute', sound._id);\n }\n }\n\n return self;\n },\n\n /**\n * Get/set the volume of this sound or of the Howl group. This method can optionally take 0, 1 or 2 arguments.\n * volume() -> Returns the group's volume value.\n * volume(id) -> Returns the sound id's current volume.\n * volume(vol) -> Sets the volume of all sounds in this Howl group.\n * volume(vol, id) -> Sets the volume of passed sound id.\n * @return {Howl/Number} Returns self or current volume.\n */\n volume: function volume() {\n var self = this;\n var args = arguments;\n var vol, id; // Determine the values based on arguments.\n\n if (args.length === 0) {\n // Return the value of the groups' volume.\n return self._volume;\n } else if (args.length === 1 || args.length === 2 && typeof args[1] === 'undefined') {\n // First check if this is an ID, and if not, assume it is a new volume.\n var ids = self._getSoundIds();\n\n var index = ids.indexOf(args[0]);\n\n if (index >= 0) {\n id = parseInt(args[0], 10);\n } else {\n vol = parseFloat(args[0]);\n }\n } else if (args.length >= 2) {\n vol = parseFloat(args[0]);\n id = parseInt(args[1], 10);\n } // Update the volume or return the current volume.\n\n\n var sound;\n\n if (typeof vol !== 'undefined' && vol >= 0 && vol <= 1) {\n // If the sound hasn't loaded, add it to the load queue to change volume when capable.\n if (self._state !== 'loaded' || self._playLock) {\n self._queue.push({\n event: 'volume',\n action: function action() {\n self.volume.apply(self, args);\n }\n });\n\n return self;\n } // Set the group volume.\n\n\n if (typeof id === 'undefined') {\n self._volume = vol;\n } // Update one or all volumes.\n\n\n id = self._getSoundIds(id);\n\n for (var i = 0; i < id.length; i++) {\n // Get the sound.\n sound = self._soundById(id[i]);\n\n if (sound) {\n sound._volume = vol; // Stop currently running fades.\n\n if (!args[2]) {\n self._stopFade(id[i]);\n }\n\n if (self._webAudio && sound._node && !sound._muted) {\n sound._node.gain.setValueAtTime(vol, Howler.ctx.currentTime);\n } else if (sound._node && !sound._muted) {\n sound._node.volume = vol * Howler.volume();\n }\n\n self._emit('volume', sound._id);\n }\n }\n } else {\n sound = id ? self._soundById(id) : self._sounds[0];\n return sound ? sound._volume : 0;\n }\n\n return self;\n },\n\n /**\n * Fade a currently playing sound between two volumes (if no id is passed, all sounds will fade).\n * @param {Number} from The value to fade from (0.0 to 1.0).\n * @param {Number} to The volume to fade to (0.0 to 1.0).\n * @param {Number} len Time in milliseconds to fade.\n * @param {Number} id The sound id (omit to fade all sounds).\n * @return {Howl}\n */\n fade: function fade(from, to, len, id) {\n var self = this; // If the sound hasn't loaded, add it to the load queue to fade when capable.\n\n if (self._state !== 'loaded' || self._playLock) {\n self._queue.push({\n event: 'fade',\n action: function action() {\n self.fade(from, to, len, id);\n }\n });\n\n return self;\n } // Make sure the to/from/len values are numbers.\n\n\n from = Math.min(Math.max(0, parseFloat(from)), 1);\n to = Math.min(Math.max(0, parseFloat(to)), 1);\n len = parseFloat(len); // Set the volume to the start position.\n\n self.volume(from, id); // Fade the volume of one or all sounds.\n\n var ids = self._getSoundIds(id);\n\n for (var i = 0; i < ids.length; i++) {\n // Get the sound.\n var sound = self._soundById(ids[i]); // Create a linear fade or fall back to timeouts with HTML5 Audio.\n\n\n if (sound) {\n // Stop the previous fade if no sprite is being used (otherwise, volume handles this).\n if (!id) {\n self._stopFade(ids[i]);\n } // If we are using Web Audio, let the native methods do the actual fade.\n\n\n if (self._webAudio && !sound._muted) {\n var currentTime = Howler.ctx.currentTime;\n var end = currentTime + len / 1000;\n sound._volume = from;\n\n sound._node.gain.setValueAtTime(from, currentTime);\n\n sound._node.gain.linearRampToValueAtTime(to, end);\n }\n\n self._startFadeInterval(sound, from, to, len, ids[i], typeof id === 'undefined');\n }\n }\n\n return self;\n },\n\n /**\n * Starts the internal interval to fade a sound.\n * @param {Object} sound Reference to sound to fade.\n * @param {Number} from The value to fade from (0.0 to 1.0).\n * @param {Number} to The volume to fade to (0.0 to 1.0).\n * @param {Number} len Time in milliseconds to fade.\n * @param {Number} id The sound id to fade.\n * @param {Boolean} isGroup If true, set the volume on the group.\n */\n _startFadeInterval: function _startFadeInterval(sound, from, to, len, id, isGroup) {\n var self = this;\n var vol = from;\n var diff = to - from;\n var steps = Math.abs(diff / 0.01);\n var stepLen = Math.max(4, steps > 0 ? len / steps : len);\n var lastTick = Date.now(); // Store the value being faded to.\n\n sound._fadeTo = to; // Update the volume value on each interval tick.\n\n sound._interval = setInterval(function () {\n // Update the volume based on the time since the last tick.\n var tick = (Date.now() - lastTick) / len;\n lastTick = Date.now();\n vol += diff * tick; // Round to within 2 decimal points.\n\n vol = Math.round(vol * 100) / 100; // Make sure the volume is in the right bounds.\n\n if (diff < 0) {\n vol = Math.max(to, vol);\n } else {\n vol = Math.min(to, vol);\n } // Change the volume.\n\n\n if (self._webAudio) {\n sound._volume = vol;\n } else {\n self.volume(vol, sound._id, true);\n } // Set the group's volume.\n\n\n if (isGroup) {\n self._volume = vol;\n } // When the fade is complete, stop it and fire event.\n\n\n if (to < from && vol <= to || to > from && vol >= to) {\n clearInterval(sound._interval);\n sound._interval = null;\n sound._fadeTo = null;\n self.volume(to, sound._id);\n\n self._emit('fade', sound._id);\n }\n }, stepLen);\n },\n\n /**\n * Internal method that stops the currently playing fade when\n * a new fade starts, volume is changed or the sound is stopped.\n * @param {Number} id The sound id.\n * @return {Howl}\n */\n _stopFade: function _stopFade(id) {\n var self = this;\n\n var sound = self._soundById(id);\n\n if (sound && sound._interval) {\n if (self._webAudio) {\n sound._node.gain.cancelScheduledValues(Howler.ctx.currentTime);\n }\n\n clearInterval(sound._interval);\n sound._interval = null;\n self.volume(sound._fadeTo, id);\n sound._fadeTo = null;\n\n self._emit('fade', id);\n }\n\n return self;\n },\n\n /**\n * Get/set the loop parameter on a sound. This method can optionally take 0, 1 or 2 arguments.\n * loop() -> Returns the group's loop value.\n * loop(id) -> Returns the sound id's loop value.\n * loop(loop) -> Sets the loop value for all sounds in this Howl group.\n * loop(loop, id) -> Sets the loop value of passed sound id.\n * @return {Howl/Boolean} Returns self or current loop value.\n */\n loop: function loop() {\n var self = this;\n var args = arguments;\n var loop, id, sound; // Determine the values for loop and id.\n\n if (args.length === 0) {\n // Return the grou's loop value.\n return self._loop;\n } else if (args.length === 1) {\n if (typeof args[0] === 'boolean') {\n loop = args[0];\n self._loop = loop;\n } else {\n // Return this sound's loop value.\n sound = self._soundById(parseInt(args[0], 10));\n return sound ? sound._loop : false;\n }\n } else if (args.length === 2) {\n loop = args[0];\n id = parseInt(args[1], 10);\n } // If no id is passed, get all ID's to be looped.\n\n\n var ids = self._getSoundIds(id);\n\n for (var i = 0; i < ids.length; i++) {\n sound = self._soundById(ids[i]);\n\n if (sound) {\n sound._loop = loop;\n\n if (self._webAudio && sound._node && sound._node.bufferSource) {\n sound._node.bufferSource.loop = loop;\n\n if (loop) {\n sound._node.bufferSource.loopStart = sound._start || 0;\n sound._node.bufferSource.loopEnd = sound._stop;\n }\n }\n }\n }\n\n return self;\n },\n\n /**\n * Get/set the playback rate of a sound. This method can optionally take 0, 1 or 2 arguments.\n * rate() -> Returns the first sound node's current playback rate.\n * rate(id) -> Returns the sound id's current playback rate.\n * rate(rate) -> Sets the playback rate of all sounds in this Howl group.\n * rate(rate, id) -> Sets the playback rate of passed sound id.\n * @return {Howl/Number} Returns self or the current playback rate.\n */\n rate: function rate() {\n var self = this;\n var args = arguments;\n var rate, id; // Determine the values based on arguments.\n\n if (args.length === 0) {\n // We will simply return the current rate of the first node.\n id = self._sounds[0]._id;\n } else if (args.length === 1) {\n // First check if this is an ID, and if not, assume it is a new rate value.\n var ids = self._getSoundIds();\n\n var index = ids.indexOf(args[0]);\n\n if (index >= 0) {\n id = parseInt(args[0], 10);\n } else {\n rate = parseFloat(args[0]);\n }\n } else if (args.length === 2) {\n rate = parseFloat(args[0]);\n id = parseInt(args[1], 10);\n } // Update the playback rate or return the current value.\n\n\n var sound;\n\n if (typeof rate === 'number') {\n // If the sound hasn't loaded, add it to the load queue to change playback rate when capable.\n if (self._state !== 'loaded' || self._playLock) {\n self._queue.push({\n event: 'rate',\n action: function action() {\n self.rate.apply(self, args);\n }\n });\n\n return self;\n } // Set the group rate.\n\n\n if (typeof id === 'undefined') {\n self._rate = rate;\n } // Update one or all volumes.\n\n\n id = self._getSoundIds(id);\n\n for (var i = 0; i < id.length; i++) {\n // Get the sound.\n sound = self._soundById(id[i]);\n\n if (sound) {\n // Keep track of our position when the rate changed and update the playback\n // start position so we can properly adjust the seek position for time elapsed.\n if (self.playing(id[i])) {\n sound._rateSeek = self.seek(id[i]);\n sound._playStart = self._webAudio ? Howler.ctx.currentTime : sound._playStart;\n }\n\n sound._rate = rate; // Change the playback rate.\n\n if (self._webAudio && sound._node && sound._node.bufferSource) {\n sound._node.bufferSource.playbackRate.setValueAtTime(rate, Howler.ctx.currentTime);\n } else if (sound._node) {\n sound._node.playbackRate = rate;\n } // Reset the timers.\n\n\n var seek = self.seek(id[i]);\n var duration = (self._sprite[sound._sprite][0] + self._sprite[sound._sprite][1]) / 1000 - seek;\n var timeout = duration * 1000 / Math.abs(sound._rate); // Start a new end timer if sound is already playing.\n\n if (self._endTimers[id[i]] || !sound._paused) {\n self._clearTimer(id[i]);\n\n self._endTimers[id[i]] = setTimeout(self._ended.bind(self, sound), timeout);\n }\n\n self._emit('rate', sound._id);\n }\n }\n } else {\n sound = self._soundById(id);\n return sound ? sound._rate : self._rate;\n }\n\n return self;\n },\n\n /**\n * Get/set the seek position of a sound. This method can optionally take 0, 1 or 2 arguments.\n * seek() -> Returns the first sound node's current seek position.\n * seek(id) -> Returns the sound id's current seek position.\n * seek(seek) -> Sets the seek position of the first sound node.\n * seek(seek, id) -> Sets the seek position of passed sound id.\n * @return {Howl/Number} Returns self or the current seek position.\n */\n seek: function seek() {\n var self = this;\n var args = arguments;\n var seek, id; // Determine the values based on arguments.\n\n if (args.length === 0) {\n // We will simply return the current position of the first node.\n id = self._sounds[0]._id;\n } else if (args.length === 1) {\n // First check if this is an ID, and if not, assume it is a new seek position.\n var ids = self._getSoundIds();\n\n var index = ids.indexOf(args[0]);\n\n if (index >= 0) {\n id = parseInt(args[0], 10);\n } else if (self._sounds.length) {\n id = self._sounds[0]._id;\n seek = parseFloat(args[0]);\n }\n } else if (args.length === 2) {\n seek = parseFloat(args[0]);\n id = parseInt(args[1], 10);\n } // If there is no ID, bail out.\n\n\n if (typeof id === 'undefined') {\n return self;\n } // If the sound hasn't loaded, add it to the load queue to seek when capable.\n\n\n if (typeof seek === 'number' && (self._state !== 'loaded' || self._playLock)) {\n self._queue.push({\n event: 'seek',\n action: function action() {\n self.seek.apply(self, args);\n }\n });\n\n return self;\n } // Get the sound.\n\n\n var sound = self._soundById(id);\n\n if (sound) {\n if (typeof seek === 'number' && seek >= 0) {\n // Pause the sound and update position for restarting playback.\n var playing = self.playing(id);\n\n if (playing) {\n self.pause(id, true);\n } // Move the position of the track and cancel timer.\n\n\n sound._seek = seek;\n sound._ended = false;\n\n self._clearTimer(id); // Update the seek position for HTML5 Audio.\n\n\n if (!self._webAudio && sound._node && !isNaN(sound._node.duration)) {\n sound._node.currentTime = seek;\n } // Seek and emit when ready.\n\n\n var seekAndEmit = function seekAndEmit() {\n self._emit('seek', id); // Restart the playback if the sound was playing.\n\n\n if (playing) {\n self.play(id, true);\n }\n }; // Wait for the play lock to be unset before emitting (HTML5 Audio).\n\n\n if (playing && !self._webAudio) {\n var emitSeek = function emitSeek() {\n if (!self._playLock) {\n seekAndEmit();\n } else {\n setTimeout(emitSeek, 0);\n }\n };\n\n setTimeout(emitSeek, 0);\n } else {\n seekAndEmit();\n }\n } else {\n if (self._webAudio) {\n var realTime = self.playing(id) ? Howler.ctx.currentTime - sound._playStart : 0;\n var rateSeek = sound._rateSeek ? sound._rateSeek - sound._seek : 0;\n return sound._seek + (rateSeek + realTime * Math.abs(sound._rate));\n } else {\n return sound._node.currentTime;\n }\n }\n }\n\n return self;\n },\n\n /**\n * Check if a specific sound is currently playing or not (if id is provided), or check if at least one of the sounds in the group is playing or not.\n * @param {Number} id The sound id to check. If none is passed, the whole sound group is checked.\n * @return {Boolean} True if playing and false if not.\n */\n playing: function playing(id) {\n var self = this; // Check the passed sound ID (if any).\n\n if (typeof id === 'number') {\n var sound = self._soundById(id);\n\n return sound ? !sound._paused : false;\n } // Otherwise, loop through all sounds and check if any are playing.\n\n\n for (var i = 0; i < self._sounds.length; i++) {\n if (!self._sounds[i]._paused) {\n return true;\n }\n }\n\n return false;\n },\n\n /**\n * Get the duration of this sound. Passing a sound id will return the sprite duration.\n * @param {Number} id The sound id to check. If none is passed, return full source duration.\n * @return {Number} Audio duration in seconds.\n */\n duration: function duration(id) {\n var self = this;\n var duration = self._duration; // If we pass an ID, get the sound and return the sprite length.\n\n var sound = self._soundById(id);\n\n if (sound) {\n duration = self._sprite[sound._sprite][1] / 1000;\n }\n\n return duration;\n },\n\n /**\n * Returns the current loaded state of this Howl.\n * @return {String} 'unloaded', 'loading', 'loaded'\n */\n state: function state() {\n return this._state;\n },\n\n /**\n * Unload and destroy the current Howl object.\n * This will immediately stop all sound instances attached to this group.\n */\n unload: function unload() {\n var self = this; // Stop playing any active sounds.\n\n var sounds = self._sounds;\n\n for (var i = 0; i < sounds.length; i++) {\n // Stop the sound if it is currently playing.\n if (!sounds[i]._paused) {\n self.stop(sounds[i]._id);\n } // Remove the source or disconnect.\n\n\n if (!self._webAudio) {\n // Set the source to 0-second silence to stop any downloading (except in IE).\n self._clearSound(sounds[i]._node); // Remove any event listeners.\n\n\n sounds[i]._node.removeEventListener('error', sounds[i]._errorFn, false);\n\n sounds[i]._node.removeEventListener(Howler._canPlayEvent, sounds[i]._loadFn, false);\n\n sounds[i]._node.removeEventListener('ended', sounds[i]._endFn, false); // Release the Audio object back to the pool.\n\n\n Howler._releaseHtml5Audio(sounds[i]._node);\n } // Empty out all of the nodes.\n\n\n delete sounds[i]._node; // Make sure all timers are cleared out.\n\n self._clearTimer(sounds[i]._id);\n } // Remove the references in the global Howler object.\n\n\n var index = Howler._howls.indexOf(self);\n\n if (index >= 0) {\n Howler._howls.splice(index, 1);\n } // Delete this sound from the cache (if no other Howl is using it).\n\n\n var remCache = true;\n\n for (i = 0; i < Howler._howls.length; i++) {\n if (Howler._howls[i]._src === self._src || self._src.indexOf(Howler._howls[i]._src) >= 0) {\n remCache = false;\n break;\n }\n }\n\n if (cache && remCache) {\n delete cache[self._src];\n } // Clear global errors.\n\n\n Howler.noAudio = false; // Clear out `self`.\n\n self._state = 'unloaded';\n self._sounds = [];\n self = null;\n return null;\n },\n\n /**\n * Listen to a custom event.\n * @param {String} event Event name.\n * @param {Function} fn Listener to call.\n * @param {Number} id (optional) Only listen to events for this sound.\n * @param {Number} once (INTERNAL) Marks event to fire only once.\n * @return {Howl}\n */\n on: function on(event, fn, id, once) {\n var self = this;\n var events = self['_on' + event];\n\n if (typeof fn === 'function') {\n events.push(once ? {\n id: id,\n fn: fn,\n once: once\n } : {\n id: id,\n fn: fn\n });\n }\n\n return self;\n },\n\n /**\n * Remove a custom event. Call without parameters to remove all events.\n * @param {String} event Event name.\n * @param {Function} fn Listener to remove. Leave empty to remove all.\n * @param {Number} id (optional) Only remove events for this sound.\n * @return {Howl}\n */\n off: function off(event, fn, id) {\n var self = this;\n var events = self['_on' + event];\n var i = 0; // Allow passing just an event and ID.\n\n if (typeof fn === 'number') {\n id = fn;\n fn = null;\n }\n\n if (fn || id) {\n // Loop through event store and remove the passed function.\n for (i = 0; i < events.length; i++) {\n var isId = id === events[i].id;\n\n if (fn === events[i].fn && isId || !fn && isId) {\n events.splice(i, 1);\n break;\n }\n }\n } else if (event) {\n // Clear out all events of this type.\n self['_on' + event] = [];\n } else {\n // Clear out all events of every type.\n var keys = Object.keys(self);\n\n for (i = 0; i < keys.length; i++) {\n if (keys[i].indexOf('_on') === 0 && Array.isArray(self[keys[i]])) {\n self[keys[i]] = [];\n }\n }\n }\n\n return self;\n },\n\n /**\n * Listen to a custom event and remove it once fired.\n * @param {String} event Event name.\n * @param {Function} fn Listener to call.\n * @param {Number} id (optional) Only listen to events for this sound.\n * @return {Howl}\n */\n once: function once(event, fn, id) {\n var self = this; // Setup the event listener.\n\n self.on(event, fn, id, 1);\n return self;\n },\n\n /**\n * Emit all events of a specific type and pass the sound id.\n * @param {String} event Event name.\n * @param {Number} id Sound ID.\n * @param {Number} msg Message to go with event.\n * @return {Howl}\n */\n _emit: function _emit(event, id, msg) {\n var self = this;\n var events = self['_on' + event]; // Loop through event store and fire all functions.\n\n for (var i = events.length - 1; i >= 0; i--) {\n // Only fire the listener if the correct ID is used.\n if (!events[i].id || events[i].id === id || event === 'load') {\n setTimeout(function (fn) {\n fn.call(this, id, msg);\n }.bind(self, events[i].fn), 0); // If this event was setup with `once`, remove it.\n\n if (events[i].once) {\n self.off(event, events[i].fn, events[i].id);\n }\n }\n } // Pass the event type into load queue so that it can continue stepping.\n\n\n self._loadQueue(event);\n\n return self;\n },\n\n /**\n * Queue of actions initiated before the sound has loaded.\n * These will be called in sequence, with the next only firing\n * after the previous has finished executing (even if async like play).\n * @return {Howl}\n */\n _loadQueue: function _loadQueue(event) {\n var self = this;\n\n if (self._queue.length > 0) {\n var task = self._queue[0]; // Remove this task if a matching event was passed.\n\n if (task.event === event) {\n self._queue.shift();\n\n self._loadQueue();\n } // Run the task if no event type is passed.\n\n\n if (!event) {\n task.action();\n }\n }\n\n return self;\n },\n\n /**\n * Fired when playback ends at the end of the duration.\n * @param {Sound} sound The sound object to work with.\n * @return {Howl}\n */\n _ended: function _ended(sound) {\n var self = this;\n var sprite = sound._sprite; // If we are using IE and there was network latency we may be clipping\n // audio before it completes playing. Lets check the node to make sure it\n // believes it has completed, before ending the playback.\n\n if (!self._webAudio && sound._node && !sound._node.paused && !sound._node.ended && sound._node.currentTime < sound._stop) {\n setTimeout(self._ended.bind(self, sound), 100);\n return self;\n } // Should this sound loop?\n\n\n var loop = !!(sound._loop || self._sprite[sprite][2]); // Fire the ended event.\n\n self._emit('end', sound._id); // Restart the playback for HTML5 Audio loop.\n\n\n if (!self._webAudio && loop) {\n self.stop(sound._id, true).play(sound._id);\n } // Restart this timer if on a Web Audio loop.\n\n\n if (self._webAudio && loop) {\n self._emit('play', sound._id);\n\n sound._seek = sound._start || 0;\n sound._rateSeek = 0;\n sound._playStart = Howler.ctx.currentTime;\n var timeout = (sound._stop - sound._start) * 1000 / Math.abs(sound._rate);\n self._endTimers[sound._id] = setTimeout(self._ended.bind(self, sound), timeout);\n } // Mark the node as paused.\n\n\n if (self._webAudio && !loop) {\n sound._paused = true;\n sound._ended = true;\n sound._seek = sound._start || 0;\n sound._rateSeek = 0;\n\n self._clearTimer(sound._id); // Clean up the buffer source.\n\n\n self._cleanBuffer(sound._node); // Attempt to auto-suspend AudioContext if no sounds are still playing.\n\n\n Howler._autoSuspend();\n } // When using a sprite, end the track.\n\n\n if (!self._webAudio && !loop) {\n self.stop(sound._id, true);\n }\n\n return self;\n },\n\n /**\n * Clear the end timer for a sound playback.\n * @param {Number} id The sound ID.\n * @return {Howl}\n */\n _clearTimer: function _clearTimer(id) {\n var self = this;\n\n if (self._endTimers[id]) {\n // Clear the timeout or remove the ended listener.\n if (typeof self._endTimers[id] !== 'function') {\n clearTimeout(self._endTimers[id]);\n } else {\n var sound = self._soundById(id);\n\n if (sound && sound._node) {\n sound._node.removeEventListener('ended', self._endTimers[id], false);\n }\n }\n\n delete self._endTimers[id];\n }\n\n return self;\n },\n\n /**\n * Return the sound identified by this ID, or return null.\n * @param {Number} id Sound ID\n * @return {Object} Sound object or null.\n */\n _soundById: function _soundById(id) {\n var self = this; // Loop through all sounds and find the one with this ID.\n\n for (var i = 0; i < self._sounds.length; i++) {\n if (id === self._sounds[i]._id) {\n return self._sounds[i];\n }\n }\n\n return null;\n },\n\n /**\n * Return an inactive sound from the pool or create a new one.\n * @return {Sound} Sound playback object.\n */\n _inactiveSound: function _inactiveSound() {\n var self = this;\n\n self._drain(); // Find the first inactive node to recycle.\n\n\n for (var i = 0; i < self._sounds.length; i++) {\n if (self._sounds[i]._ended) {\n return self._sounds[i].reset();\n }\n } // If no inactive node was found, create a new one.\n\n\n return new Sound(self);\n },\n\n /**\n * Drain excess inactive sounds from the pool.\n */\n _drain: function _drain() {\n var self = this;\n var limit = self._pool;\n var cnt = 0;\n var i = 0; // If there are less sounds than the max pool size, we are done.\n\n if (self._sounds.length < limit) {\n return;\n } // Count the number of inactive sounds.\n\n\n for (i = 0; i < self._sounds.length; i++) {\n if (self._sounds[i]._ended) {\n cnt++;\n }\n } // Remove excess inactive sounds, going in reverse order.\n\n\n for (i = self._sounds.length - 1; i >= 0; i--) {\n if (cnt <= limit) {\n return;\n }\n\n if (self._sounds[i]._ended) {\n // Disconnect the audio source when using Web Audio.\n if (self._webAudio && self._sounds[i]._node) {\n self._sounds[i]._node.disconnect(0);\n } // Remove sounds until we have the pool size.\n\n\n self._sounds.splice(i, 1);\n\n cnt--;\n }\n }\n },\n\n /**\n * Get all ID's from the sounds pool.\n * @param {Number} id Only return one ID if one is passed.\n * @return {Array} Array of IDs.\n */\n _getSoundIds: function _getSoundIds(id) {\n var self = this;\n\n if (typeof id === 'undefined') {\n var ids = [];\n\n for (var i = 0; i < self._sounds.length; i++) {\n ids.push(self._sounds[i]._id);\n }\n\n return ids;\n } else {\n return [id];\n }\n },\n\n /**\n * Load the sound back into the buffer source.\n * @param {Sound} sound The sound object to work with.\n * @return {Howl}\n */\n _refreshBuffer: function _refreshBuffer(sound) {\n var self = this; // Setup the buffer source for playback.\n\n sound._node.bufferSource = Howler.ctx.createBufferSource();\n sound._node.bufferSource.buffer = cache[self._src]; // Connect to the correct node.\n\n if (sound._panner) {\n sound._node.bufferSource.connect(sound._panner);\n } else {\n sound._node.bufferSource.connect(sound._node);\n } // Setup looping and playback rate.\n\n\n sound._node.bufferSource.loop = sound._loop;\n\n if (sound._loop) {\n sound._node.bufferSource.loopStart = sound._start || 0;\n sound._node.bufferSource.loopEnd = sound._stop || 0;\n }\n\n sound._node.bufferSource.playbackRate.setValueAtTime(sound._rate, Howler.ctx.currentTime);\n\n return self;\n },\n\n /**\n * Prevent memory leaks by cleaning up the buffer source after playback.\n * @param {Object} node Sound's audio node containing the buffer source.\n * @return {Howl}\n */\n _cleanBuffer: function _cleanBuffer(node) {\n var self = this;\n var isIOS = Howler._navigator && Howler._navigator.vendor.indexOf('Apple') >= 0;\n\n if (Howler._scratchBuffer && node.bufferSource) {\n node.bufferSource.onended = null;\n node.bufferSource.disconnect(0);\n\n if (isIOS) {\n try {\n node.bufferSource.buffer = Howler._scratchBuffer;\n } catch (e) {}\n }\n }\n\n node.bufferSource = null;\n return self;\n },\n\n /**\n * Set the source to a 0-second silence to stop any downloading (except in IE).\n * @param {Object} node Audio node to clear.\n */\n _clearSound: function _clearSound(node) {\n var checkIE = /MSIE |Trident\\//.test(Howler._navigator && Howler._navigator.userAgent);\n\n if (!checkIE) {\n node.src = 'data:audio/wav;base64,UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA';\n }\n }\n };\n /** Single Sound Methods **/\n\n /***************************************************************************/\n\n /**\n * Setup the sound object, which each node attached to a Howl group is contained in.\n * @param {Object} howl The Howl parent group.\n */\n\n var Sound = function Sound(howl) {\n this._parent = howl;\n this.init();\n };\n\n Sound.prototype = {\n /**\n * Initialize a new Sound object.\n * @return {Sound}\n */\n init: function init() {\n var self = this;\n var parent = self._parent; // Setup the default parameters.\n\n self._muted = parent._muted;\n self._loop = parent._loop;\n self._volume = parent._volume;\n self._rate = parent._rate;\n self._seek = 0;\n self._paused = true;\n self._ended = true;\n self._sprite = '__default'; // Generate a unique ID for this sound.\n\n self._id = ++Howler._counter; // Add itself to the parent's pool.\n\n parent._sounds.push(self); // Create the new node.\n\n\n self.create();\n return self;\n },\n\n /**\n * Create and setup a new sound object, whether HTML5 Audio or Web Audio.\n * @return {Sound}\n */\n create: function create() {\n var self = this;\n var parent = self._parent;\n var volume = Howler._muted || self._muted || self._parent._muted ? 0 : self._volume;\n\n if (parent._webAudio) {\n // Create the gain node for controlling volume (the source will connect to this).\n self._node = typeof Howler.ctx.createGain === 'undefined' ? Howler.ctx.createGainNode() : Howler.ctx.createGain();\n\n self._node.gain.setValueAtTime(volume, Howler.ctx.currentTime);\n\n self._node.paused = true;\n\n self._node.connect(Howler.masterGain);\n } else if (!Howler.noAudio) {\n // Get an unlocked Audio object from the pool.\n self._node = Howler._obtainHtml5Audio(); // Listen for errors (http://dev.w3.org/html5/spec-author-view/spec.html#mediaerror).\n\n self._errorFn = self._errorListener.bind(self);\n\n self._node.addEventListener('error', self._errorFn, false); // Listen for 'canplaythrough' event to let us know the sound is ready.\n\n\n self._loadFn = self._loadListener.bind(self);\n\n self._node.addEventListener(Howler._canPlayEvent, self._loadFn, false); // Listen for the 'ended' event on the sound to account for edge-case where\n // a finite sound has a duration of Infinity.\n\n\n self._endFn = self._endListener.bind(self);\n\n self._node.addEventListener('ended', self._endFn, false); // Setup the new audio node.\n\n\n self._node.src = parent._src;\n self._node.preload = parent._preload === true ? 'auto' : parent._preload;\n self._node.volume = volume * Howler.volume(); // Begin loading the source.\n\n self._node.load();\n }\n\n return self;\n },\n\n /**\n * Reset the parameters of this sound to the original state (for recycle).\n * @return {Sound}\n */\n reset: function reset() {\n var self = this;\n var parent = self._parent; // Reset all of the parameters of this sound.\n\n self._muted = parent._muted;\n self._loop = parent._loop;\n self._volume = parent._volume;\n self._rate = parent._rate;\n self._seek = 0;\n self._rateSeek = 0;\n self._paused = true;\n self._ended = true;\n self._sprite = '__default'; // Generate a new ID so that it isn't confused with the previous sound.\n\n self._id = ++Howler._counter;\n return self;\n },\n\n /**\n * HTML5 Audio error listener callback.\n */\n _errorListener: function _errorListener() {\n var self = this; // Fire an error event and pass back the code.\n\n self._parent._emit('loaderror', self._id, self._node.error ? self._node.error.code : 0); // Clear the event listener.\n\n\n self._node.removeEventListener('error', self._errorFn, false);\n },\n\n /**\n * HTML5 Audio canplaythrough listener callback.\n */\n _loadListener: function _loadListener() {\n var self = this;\n var parent = self._parent; // Round up the duration to account for the lower precision in HTML5 Audio.\n\n parent._duration = Math.ceil(self._node.duration * 10) / 10; // Setup a sprite if none is defined.\n\n if (Object.keys(parent._sprite).length === 0) {\n parent._sprite = {\n __default: [0, parent._duration * 1000]\n };\n }\n\n if (parent._state !== 'loaded') {\n parent._state = 'loaded';\n\n parent._emit('load');\n\n parent._loadQueue();\n } // Clear the event listener.\n\n\n self._node.removeEventListener(Howler._canPlayEvent, self._loadFn, false);\n },\n\n /**\n * HTML5 Audio ended listener callback.\n */\n _endListener: function _endListener() {\n var self = this;\n var parent = self._parent; // Only handle the `ended`` event if the duration is Infinity.\n\n if (parent._duration === Infinity) {\n // Update the parent duration to match the real audio duration.\n // Round up the duration to account for the lower precision in HTML5 Audio.\n parent._duration = Math.ceil(self._node.duration * 10) / 10; // Update the sprite that corresponds to the real duration.\n\n if (parent._sprite.__default[1] === Infinity) {\n parent._sprite.__default[1] = parent._duration * 1000;\n } // Run the regular ended method.\n\n\n parent._ended(self);\n } // Clear the event listener since the duration is now correct.\n\n\n self._node.removeEventListener('ended', self._endFn, false);\n }\n };\n /** Helper Methods **/\n\n /***************************************************************************/\n\n var cache = {};\n /**\n * Buffer a sound from URL, Data URI or cache and decode to audio source (Web Audio API).\n * @param {Howl} self\n */\n\n var loadBuffer = function loadBuffer(self) {\n var url = self._src; // Check if the buffer has already been cached and use it instead.\n\n if (cache[url]) {\n // Set the duration from the cache.\n self._duration = cache[url].duration; // Load the sound into this Howl.\n\n loadSound(self);\n return;\n }\n\n if (/^data:[^;]+;base64,/.test(url)) {\n // Decode the base64 data URI without XHR, since some browsers don't support it.\n var data = atob(url.split(',')[1]);\n var dataView = new Uint8Array(data.length);\n\n for (var i = 0; i < data.length; ++i) {\n dataView[i] = data.charCodeAt(i);\n }\n\n decodeAudioData(dataView.buffer, self);\n } else {\n // Load the buffer from the URL.\n var xhr = new XMLHttpRequest();\n xhr.open(self._xhr.method, url, true);\n xhr.withCredentials = self._xhr.withCredentials;\n xhr.responseType = 'arraybuffer'; // Apply any custom headers to the request.\n\n if (self._xhr.headers) {\n Object.keys(self._xhr.headers).forEach(function (key) {\n xhr.setRequestHeader(key, self._xhr.headers[key]);\n });\n }\n\n xhr.onload = function () {\n // Make sure we get a successful response back.\n var code = (xhr.status + '')[0];\n\n if (code !== '0' && code !== '2' && code !== '3') {\n self._emit('loaderror', null, 'Failed loading audio file with status: ' + xhr.status + '.');\n\n return;\n }\n\n decodeAudioData(xhr.response, self);\n };\n\n xhr.onerror = function () {\n // If there is an error, switch to HTML5 Audio.\n if (self._webAudio) {\n self._html5 = true;\n self._webAudio = false;\n self._sounds = [];\n delete cache[url];\n self.load();\n }\n };\n\n safeXhrSend(xhr);\n }\n };\n /**\n * Send the XHR request wrapped in a try/catch.\n * @param {Object} xhr XHR to send.\n */\n\n\n var safeXhrSend = function safeXhrSend(xhr) {\n try {\n xhr.send();\n } catch (e) {\n xhr.onerror();\n }\n };\n /**\n * Decode audio data from an array buffer.\n * @param {ArrayBuffer} arraybuffer The audio data.\n * @param {Howl} self\n */\n\n\n var decodeAudioData = function decodeAudioData(arraybuffer, self) {\n // Fire a load error if something broke.\n var error = function error() {\n self._emit('loaderror', null, 'Decoding audio data failed.');\n }; // Load the sound on success.\n\n\n var success = function success(buffer) {\n if (buffer && self._sounds.length > 0) {\n cache[self._src] = buffer;\n loadSound(self, buffer);\n } else {\n error();\n }\n }; // Decode the buffer into an audio source.\n\n\n if (typeof Promise !== 'undefined' && Howler.ctx.decodeAudioData.length === 1) {\n Howler.ctx.decodeAudioData(arraybuffer).then(success)[\"catch\"](error);\n } else {\n Howler.ctx.decodeAudioData(arraybuffer, success, error);\n }\n };\n /**\n * Sound is now loaded, so finish setting everything up and fire the loaded event.\n * @param {Howl} self\n * @param {Object} buffer The decoded buffer sound source.\n */\n\n\n var loadSound = function loadSound(self, buffer) {\n // Set the duration.\n if (buffer && !self._duration) {\n self._duration = buffer.duration;\n } // Setup a sprite if none is defined.\n\n\n if (Object.keys(self._sprite).length === 0) {\n self._sprite = {\n __default: [0, self._duration * 1000]\n };\n } // Fire the loaded event.\n\n\n if (self._state !== 'loaded') {\n self._state = 'loaded';\n\n self._emit('load');\n\n self._loadQueue();\n }\n };\n /**\n * Setup the audio context when available, or switch to HTML5 Audio mode.\n */\n\n\n var setupAudioContext = function setupAudioContext() {\n // If we have already detected that Web Audio isn't supported, don't run this step again.\n if (!Howler.usingWebAudio) {\n return;\n } // Check if we are using Web Audio and setup the AudioContext if we are.\n\n\n try {\n if (typeof AudioContext !== 'undefined') {\n Howler.ctx = new AudioContext();\n } else if (typeof webkitAudioContext !== 'undefined') {\n Howler.ctx = new webkitAudioContext();\n } else {\n Howler.usingWebAudio = false;\n }\n } catch (e) {\n Howler.usingWebAudio = false;\n } // If the audio context creation still failed, set using web audio to false.\n\n\n if (!Howler.ctx) {\n Howler.usingWebAudio = false;\n } // Check if a webview is being used on iOS8 or earlier (rather than the browser).\n // If it is, disable Web Audio as it causes crashing.\n\n\n var iOS = /iP(hone|od|ad)/.test(Howler._navigator && Howler._navigator.platform);\n\n var appVersion = Howler._navigator && Howler._navigator.appVersion.match(/OS (\\d+)_(\\d+)_?(\\d+)?/);\n\n var version = appVersion ? parseInt(appVersion[1], 10) : null;\n\n if (iOS && version && version < 9) {\n var safari = /safari/.test(Howler._navigator && Howler._navigator.userAgent.toLowerCase());\n\n if (Howler._navigator && !safari) {\n Howler.usingWebAudio = false;\n }\n } // Create and expose the master GainNode when using Web Audio (useful for plugins or advanced usage).\n\n\n if (Howler.usingWebAudio) {\n Howler.masterGain = typeof Howler.ctx.createGain === 'undefined' ? Howler.ctx.createGainNode() : Howler.ctx.createGain();\n Howler.masterGain.gain.setValueAtTime(Howler._muted ? 0 : Howler._volume, Howler.ctx.currentTime);\n Howler.masterGain.connect(Howler.ctx.destination);\n } // Re-run the setup on Howler.\n\n\n Howler._setup();\n }; // Add support for AMD (Asynchronous Module Definition) libraries such as require.js.\n\n\n if (typeof define === 'function' && define.amd) {\n define([], function () {\n return {\n Howler: Howler,\n Howl: Howl\n };\n });\n } // Add support for CommonJS libraries such as browserify.\n\n\n if (typeof exports !== 'undefined') {\n exports.Howler = Howler;\n exports.Howl = Howl;\n } // Add to global in Node.js (for testing, etc).\n\n\n if (typeof global !== 'undefined') {\n global.HowlerGlobal = HowlerGlobal;\n global.Howler = Howler;\n global.Howl = Howl;\n global.Sound = Sound;\n } else if (typeof window !== 'undefined') {\n // Define globally in case AMD is not available or unused.\n window.HowlerGlobal = HowlerGlobal;\n window.Howler = Howler;\n window.Howl = Howl;\n window.Sound = Sound;\n }\n})();\n/*!\n * Spatial Plugin - Adds support for stereo and 3D audio where Web Audio is supported.\n * \n * howler.js v2.2.1\n * howlerjs.com\n *\n * (c) 2013-2020, James Simpson of GoldFire Studios\n * goldfirestudios.com\n *\n * MIT License\n */\n\n\n(function () {\n 'use strict'; // Setup default properties.\n\n HowlerGlobal.prototype._pos = [0, 0, 0];\n HowlerGlobal.prototype._orientation = [0, 0, -1, 0, 1, 0];\n /** Global Methods **/\n\n /***************************************************************************/\n\n /**\n * Helper method to update the stereo panning position of all current Howls.\n * Future Howls will not use this value unless explicitly set.\n * @param {Number} pan A value of -1.0 is all the way left and 1.0 is all the way right.\n * @return {Howler/Number} Self or current stereo panning value.\n */\n\n HowlerGlobal.prototype.stereo = function (pan) {\n var self = this; // Stop right here if not using Web Audio.\n\n if (!self.ctx || !self.ctx.listener) {\n return self;\n } // Loop through all Howls and update their stereo panning.\n\n\n for (var i = self._howls.length - 1; i >= 0; i--) {\n self._howls[i].stereo(pan);\n }\n\n return self;\n };\n /**\n * Get/set the position of the listener in 3D cartesian space. Sounds using\n * 3D position will be relative to the listener's position.\n * @param {Number} x The x-position of the listener.\n * @param {Number} y The y-position of the listener.\n * @param {Number} z The z-position of the listener.\n * @return {Howler/Array} Self or current listener position.\n */\n\n\n HowlerGlobal.prototype.pos = function (x, y, z) {\n var self = this; // Stop right here if not using Web Audio.\n\n if (!self.ctx || !self.ctx.listener) {\n return self;\n } // Set the defaults for optional 'y' & 'z'.\n\n\n y = typeof y !== 'number' ? self._pos[1] : y;\n z = typeof z !== 'number' ? self._pos[2] : z;\n\n if (typeof x === 'number') {\n self._pos = [x, y, z];\n\n if (typeof self.ctx.listener.positionX !== 'undefined') {\n self.ctx.listener.positionX.setTargetAtTime(self._pos[0], Howler.ctx.currentTime, 0.1);\n self.ctx.listener.positionY.setTargetAtTime(self._pos[1], Howler.ctx.currentTime, 0.1);\n self.ctx.listener.positionZ.setTargetAtTime(self._pos[2], Howler.ctx.currentTime, 0.1);\n } else {\n self.ctx.listener.setPosition(self._pos[0], self._pos[1], self._pos[2]);\n }\n } else {\n return self._pos;\n }\n\n return self;\n };\n /**\n * Get/set the direction the listener is pointing in the 3D cartesian space.\n * A front and up vector must be provided. The front is the direction the\n * face of the listener is pointing, and up is the direction the top of the\n * listener is pointing. Thus, these values are expected to be at right angles\n * from each other.\n * @param {Number} x The x-orientation of the listener.\n * @param {Number} y The y-orientation of the listener.\n * @param {Number} z The z-orientation of the listener.\n * @param {Number} xUp The x-orientation of the top of the listener.\n * @param {Number} yUp The y-orientation of the top of the listener.\n * @param {Number} zUp The z-orientation of the top of the listener.\n * @return {Howler/Array} Returns self or the current orientation vectors.\n */\n\n\n HowlerGlobal.prototype.orientation = function (x, y, z, xUp, yUp, zUp) {\n var self = this; // Stop right here if not using Web Audio.\n\n if (!self.ctx || !self.ctx.listener) {\n return self;\n } // Set the defaults for optional 'y' & 'z'.\n\n\n var or = self._orientation;\n y = typeof y !== 'number' ? or[1] : y;\n z = typeof z !== 'number' ? or[2] : z;\n xUp = typeof xUp !== 'number' ? or[3] : xUp;\n yUp = typeof yUp !== 'number' ? or[4] : yUp;\n zUp = typeof zUp !== 'number' ? or[5] : zUp;\n\n if (typeof x === 'number') {\n self._orientation = [x, y, z, xUp, yUp, zUp];\n\n if (typeof self.ctx.listener.forwardX !== 'undefined') {\n self.ctx.listener.forwardX.setTargetAtTime(x, Howler.ctx.currentTime, 0.1);\n self.ctx.listener.forwardY.setTargetAtTime(y, Howler.ctx.currentTime, 0.1);\n self.ctx.listener.forwardZ.setTargetAtTime(z, Howler.ctx.currentTime, 0.1);\n self.ctx.listener.upX.setTargetAtTime(xUp, Howler.ctx.currentTime, 0.1);\n self.ctx.listener.upY.setTargetAtTime(yUp, Howler.ctx.currentTime, 0.1);\n self.ctx.listener.upZ.setTargetAtTime(zUp, Howler.ctx.currentTime, 0.1);\n } else {\n self.ctx.listener.setOrientation(x, y, z, xUp, yUp, zUp);\n }\n } else {\n return or;\n }\n\n return self;\n };\n /** Group Methods **/\n\n /***************************************************************************/\n\n /**\n * Add new properties to the core init.\n * @param {Function} _super Core init method.\n * @return {Howl}\n */\n\n\n Howl.prototype.init = function (_super) {\n return function (o) {\n var self = this; // Setup user-defined default properties.\n\n self._orientation = o.orientation || [1, 0, 0];\n self._stereo = o.stereo || null;\n self._pos = o.pos || null;\n self._pannerAttr = {\n coneInnerAngle: typeof o.coneInnerAngle !== 'undefined' ? o.coneInnerAngle : 360,\n coneOuterAngle: typeof o.coneOuterAngle !== 'undefined' ? o.coneOuterAngle : 360,\n coneOuterGain: typeof o.coneOuterGain !== 'undefined' ? o.coneOuterGain : 0,\n distanceModel: typeof o.distanceModel !== 'undefined' ? o.distanceModel : 'inverse',\n maxDistance: typeof o.maxDistance !== 'undefined' ? o.maxDistance : 10000,\n panningModel: typeof o.panningModel !== 'undefined' ? o.panningModel : 'HRTF',\n refDistance: typeof o.refDistance !== 'undefined' ? o.refDistance : 1,\n rolloffFactor: typeof o.rolloffFactor !== 'undefined' ? o.rolloffFactor : 1\n }; // Setup event listeners.\n\n self._onstereo = o.onstereo ? [{\n fn: o.onstereo\n }] : [];\n self._onpos = o.onpos ? [{\n fn: o.onpos\n }] : [];\n self._onorientation = o.onorientation ? [{\n fn: o.onorientation\n }] : []; // Complete initilization with howler.js core's init function.\n\n return _super.call(this, o);\n };\n }(Howl.prototype.init);\n /**\n * Get/set the stereo panning of the audio source for this sound or all in the group.\n * @param {Number} pan A value of -1.0 is all the way left and 1.0 is all the way right.\n * @param {Number} id (optional) The sound ID. If none is passed, all in group will be updated.\n * @return {Howl/Number} Returns self or the current stereo panning value.\n */\n\n\n Howl.prototype.stereo = function (pan, id) {\n var self = this; // Stop right here if not using Web Audio.\n\n if (!self._webAudio) {\n return self;\n } // If the sound hasn't loaded, add it to the load queue to change stereo pan when capable.\n\n\n if (self._state !== 'loaded') {\n self._queue.push({\n event: 'stereo',\n action: function action() {\n self.stereo(pan, id);\n }\n });\n\n return self;\n } // Check for PannerStereoNode support and fallback to PannerNode if it doesn't exist.\n\n\n var pannerType = typeof Howler.ctx.createStereoPanner === 'undefined' ? 'spatial' : 'stereo'; // Setup the group's stereo panning if no ID is passed.\n\n if (typeof id === 'undefined') {\n // Return the group's stereo panning if no parameters are passed.\n if (typeof pan === 'number') {\n self._stereo = pan;\n self._pos = [pan, 0, 0];\n } else {\n return self._stereo;\n }\n } // Change the streo panning of one or all sounds in group.\n\n\n var ids = self._getSoundIds(id);\n\n for (var i = 0; i < ids.length; i++) {\n // Get the sound.\n var sound = self._soundById(ids[i]);\n\n if (sound) {\n if (typeof pan === 'number') {\n sound._stereo = pan;\n sound._pos = [pan, 0, 0];\n\n if (sound._node) {\n // If we are falling back, make sure the panningModel is equalpower.\n sound._pannerAttr.panningModel = 'equalpower'; // Check if there is a panner setup and create a new one if not.\n\n if (!sound._panner || !sound._panner.pan) {\n setupPanner(sound, pannerType);\n }\n\n if (pannerType === 'spatial') {\n if (typeof sound._panner.positionX !== 'undefined') {\n sound._panner.positionX.setValueAtTime(pan, Howler.ctx.currentTime);\n\n sound._panner.positionY.setValueAtTime(0, Howler.ctx.currentTime);\n\n sound._panner.positionZ.setValueAtTime(0, Howler.ctx.currentTime);\n } else {\n sound._panner.setPosition(pan, 0, 0);\n }\n } else {\n sound._panner.pan.setValueAtTime(pan, Howler.ctx.currentTime);\n }\n }\n\n self._emit('stereo', sound._id);\n } else {\n return sound._stereo;\n }\n }\n }\n\n return self;\n };\n /**\n * Get/set the 3D spatial position of the audio source for this sound or group relative to the global listener.\n * @param {Number} x The x-position of the audio source.\n * @param {Number} y The y-position of the audio source.\n * @param {Number} z The z-position of the audio source.\n * @param {Number} id (optional) The sound ID. If none is passed, all in group will be updated.\n * @return {Howl/Array} Returns self or the current 3D spatial position: [x, y, z].\n */\n\n\n Howl.prototype.pos = function (x, y, z, id) {\n var self = this; // Stop right here if not using Web Audio.\n\n if (!self._webAudio) {\n return self;\n } // If the sound hasn't loaded, add it to the load queue to change position when capable.\n\n\n if (self._state !== 'loaded') {\n self._queue.push({\n event: 'pos',\n action: function action() {\n self.pos(x, y, z, id);\n }\n });\n\n return self;\n } // Set the defaults for optional 'y' & 'z'.\n\n\n y = typeof y !== 'number' ? 0 : y;\n z = typeof z !== 'number' ? -0.5 : z; // Setup the group's spatial position if no ID is passed.\n\n if (typeof id === 'undefined') {\n // Return the group's spatial position if no parameters are passed.\n if (typeof x === 'number') {\n self._pos = [x, y, z];\n } else {\n return self._pos;\n }\n } // Change the spatial position of one or all sounds in group.\n\n\n var ids = self._getSoundIds(id);\n\n for (var i = 0; i < ids.length; i++) {\n // Get the sound.\n var sound = self._soundById(ids[i]);\n\n if (sound) {\n if (typeof x === 'number') {\n sound._pos = [x, y, z];\n\n if (sound._node) {\n // Check if there is a panner setup and create a new one if not.\n if (!sound._panner || sound._panner.pan) {\n setupPanner(sound, 'spatial');\n }\n\n if (typeof sound._panner.positionX !== 'undefined') {\n sound._panner.positionX.setValueAtTime(x, Howler.ctx.currentTime);\n\n sound._panner.positionY.setValueAtTime(y, Howler.ctx.currentTime);\n\n sound._panner.positionZ.setValueAtTime(z, Howler.ctx.currentTime);\n } else {\n sound._panner.setPosition(x, y, z);\n }\n }\n\n self._emit('pos', sound._id);\n } else {\n return sound._pos;\n }\n }\n }\n\n return self;\n };\n /**\n * Get/set the direction the audio source is pointing in the 3D cartesian coordinate\n * space. Depending on how direction the sound is, based on the `cone` attributes,\n * a sound pointing away from the listener can be quiet or silent.\n * @param {Number} x The x-orientation of the source.\n * @param {Number} y The y-orientation of the source.\n * @param {Number} z The z-orientation of the source.\n * @param {Number} id (optional) The sound ID. If none is passed, all in group will be updated.\n * @return {Howl/Array} Returns self or the current 3D spatial orientation: [x, y, z].\n */\n\n\n Howl.prototype.orientation = function (x, y, z, id) {\n var self = this; // Stop right here if not using Web Audio.\n\n if (!self._webAudio) {\n return self;\n } // If the sound hasn't loaded, add it to the load queue to change orientation when capable.\n\n\n if (self._state !== 'loaded') {\n self._queue.push({\n event: 'orientation',\n action: function action() {\n self.orientation(x, y, z, id);\n }\n });\n\n return self;\n } // Set the defaults for optional 'y' & 'z'.\n\n\n y = typeof y !== 'number' ? self._orientation[1] : y;\n z = typeof z !== 'number' ? self._orientation[2] : z; // Setup the group's spatial orientation if no ID is passed.\n\n if (typeof id === 'undefined') {\n // Return the group's spatial orientation if no parameters are passed.\n if (typeof x === 'number') {\n self._orientation = [x, y, z];\n } else {\n return self._orientation;\n }\n } // Change the spatial orientation of one or all sounds in group.\n\n\n var ids = self._getSoundIds(id);\n\n for (var i = 0; i < ids.length; i++) {\n // Get the sound.\n var sound = self._soundById(ids[i]);\n\n if (sound) {\n if (typeof x === 'number') {\n sound._orientation = [x, y, z];\n\n if (sound._node) {\n // Check if there is a panner setup and create a new one if not.\n if (!sound._panner) {\n // Make sure we have a position to setup the node with.\n if (!sound._pos) {\n sound._pos = self._pos || [0, 0, -0.5];\n }\n\n setupPanner(sound, 'spatial');\n }\n\n if (typeof sound._panner.orientationX !== 'undefined') {\n sound._panner.orientationX.setValueAtTime(x, Howler.ctx.currentTime);\n\n sound._panner.orientationY.setValueAtTime(y, Howler.ctx.currentTime);\n\n sound._panner.orientationZ.setValueAtTime(z, Howler.ctx.currentTime);\n } else {\n sound._panner.setOrientation(x, y, z);\n }\n }\n\n self._emit('orientation', sound._id);\n } else {\n return sound._orientation;\n }\n }\n }\n\n return self;\n };\n /**\n * Get/set the panner node's attributes for a sound or group of sounds.\n * This method can optionall take 0, 1 or 2 arguments.\n * pannerAttr() -> Returns the group's values.\n * pannerAttr(id) -> Returns the sound id's values.\n * pannerAttr(o) -> Set's the values of all sounds in this Howl group.\n * pannerAttr(o, id) -> Set's the values of passed sound id.\n *\n * Attributes:\n * coneInnerAngle - (360 by default) A parameter for directional audio sources, this is an angle, in degrees,\n * inside of which there will be no volume reduction.\n * coneOuterAngle - (360 by default) A parameter for directional audio sources, this is an angle, in degrees,\n * outside of which the volume will be reduced to a constant value of `coneOuterGain`.\n * coneOuterGain - (0 by default) A parameter for directional audio sources, this is the gain outside of the\n * `coneOuterAngle`. It is a linear value in the range `[0, 1]`.\n * distanceModel - ('inverse' by default) Determines algorithm used to reduce volume as audio moves away from\n * listener. Can be `linear`, `inverse` or `exponential.\n * maxDistance - (10000 by default) The maximum distance between source and listener, after which the volume\n * will not be reduced any further.\n * refDistance - (1 by default) A reference distance for reducing volume as source moves further from the listener.\n * This is simply a variable of the distance model and has a different effect depending on which model\n * is used and the scale of your coordinates. Generally, volume will be equal to 1 at this distance.\n * rolloffFactor - (1 by default) How quickly the volume reduces as source moves from listener. This is simply a\n * variable of the distance model and can be in the range of `[0, 1]` with `linear` and `[0, ∞]`\n * with `inverse` and `exponential`.\n * panningModel - ('HRTF' by default) Determines which spatialization algorithm is used to position audio.\n * Can be `HRTF` or `equalpower`.\n *\n * @return {Howl/Object} Returns self or current panner attributes.\n */\n\n\n Howl.prototype.pannerAttr = function () {\n var self = this;\n var args = arguments;\n var o, id, sound; // Stop right here if not using Web Audio.\n\n if (!self._webAudio) {\n return self;\n } // Determine the values based on arguments.\n\n\n if (args.length === 0) {\n // Return the group's panner attribute values.\n return self._pannerAttr;\n } else if (args.length === 1) {\n if (_typeof(args[0]) === 'object') {\n o = args[0]; // Set the grou's panner attribute values.\n\n if (typeof id === 'undefined') {\n if (!o.pannerAttr) {\n o.pannerAttr = {\n coneInnerAngle: o.coneInnerAngle,\n coneOuterAngle: o.coneOuterAngle,\n coneOuterGain: o.coneOuterGain,\n distanceModel: o.distanceModel,\n maxDistance: o.maxDistance,\n refDistance: o.refDistance,\n rolloffFactor: o.rolloffFactor,\n panningModel: o.panningModel\n };\n }\n\n self._pannerAttr = {\n coneInnerAngle: typeof o.pannerAttr.coneInnerAngle !== 'undefined' ? o.pannerAttr.coneInnerAngle : self._coneInnerAngle,\n coneOuterAngle: typeof o.pannerAttr.coneOuterAngle !== 'undefined' ? o.pannerAttr.coneOuterAngle : self._coneOuterAngle,\n coneOuterGain: typeof o.pannerAttr.coneOuterGain !== 'undefined' ? o.pannerAttr.coneOuterGain : self._coneOuterGain,\n distanceModel: typeof o.pannerAttr.distanceModel !== 'undefined' ? o.pannerAttr.distanceModel : self._distanceModel,\n maxDistance: typeof o.pannerAttr.maxDistance !== 'undefined' ? o.pannerAttr.maxDistance : self._maxDistance,\n refDistance: typeof o.pannerAttr.refDistance !== 'undefined' ? o.pannerAttr.refDistance : self._refDistance,\n rolloffFactor: typeof o.pannerAttr.rolloffFactor !== 'undefined' ? o.pannerAttr.rolloffFactor : self._rolloffFactor,\n panningModel: typeof o.pannerAttr.panningModel !== 'undefined' ? o.pannerAttr.panningModel : self._panningModel\n };\n }\n } else {\n // Return this sound's panner attribute values.\n sound = self._soundById(parseInt(args[0], 10));\n return sound ? sound._pannerAttr : self._pannerAttr;\n }\n } else if (args.length === 2) {\n o = args[0];\n id = parseInt(args[1], 10);\n } // Update the values of the specified sounds.\n\n\n var ids = self._getSoundIds(id);\n\n for (var i = 0; i < ids.length; i++) {\n sound = self._soundById(ids[i]);\n\n if (sound) {\n // Merge the new values into the sound.\n var pa = sound._pannerAttr;\n pa = {\n coneInnerAngle: typeof o.coneInnerAngle !== 'undefined' ? o.coneInnerAngle : pa.coneInnerAngle,\n coneOuterAngle: typeof o.coneOuterAngle !== 'undefined' ? o.coneOuterAngle : pa.coneOuterAngle,\n coneOuterGain: typeof o.coneOuterGain !== 'undefined' ? o.coneOuterGain : pa.coneOuterGain,\n distanceModel: typeof o.distanceModel !== 'undefined' ? o.distanceModel : pa.distanceModel,\n maxDistance: typeof o.maxDistance !== 'undefined' ? o.maxDistance : pa.maxDistance,\n refDistance: typeof o.refDistance !== 'undefined' ? o.refDistance : pa.refDistance,\n rolloffFactor: typeof o.rolloffFactor !== 'undefined' ? o.rolloffFactor : pa.rolloffFactor,\n panningModel: typeof o.panningModel !== 'undefined' ? o.panningModel : pa.panningModel\n }; // Update the panner values or create a new panner if none exists.\n\n var panner = sound._panner;\n\n if (panner) {\n panner.coneInnerAngle = pa.coneInnerAngle;\n panner.coneOuterAngle = pa.coneOuterAngle;\n panner.coneOuterGain = pa.coneOuterGain;\n panner.distanceModel = pa.distanceModel;\n panner.maxDistance = pa.maxDistance;\n panner.refDistance = pa.refDistance;\n panner.rolloffFactor = pa.rolloffFactor;\n panner.panningModel = pa.panningModel;\n } else {\n // Make sure we have a position to setup the node with.\n if (!sound._pos) {\n sound._pos = self._pos || [0, 0, -0.5];\n } // Create a new panner node.\n\n\n setupPanner(sound, 'spatial');\n }\n }\n }\n\n return self;\n };\n /** Single Sound Methods **/\n\n /***************************************************************************/\n\n /**\n * Add new properties to the core Sound init.\n * @param {Function} _super Core Sound init method.\n * @return {Sound}\n */\n\n\n Sound.prototype.init = function (_super) {\n return function () {\n var self = this;\n var parent = self._parent; // Setup user-defined default properties.\n\n self._orientation = parent._orientation;\n self._stereo = parent._stereo;\n self._pos = parent._pos;\n self._pannerAttr = parent._pannerAttr; // Complete initilization with howler.js core Sound's init function.\n\n _super.call(this); // If a stereo or position was specified, set it up.\n\n\n if (self._stereo) {\n parent.stereo(self._stereo);\n } else if (self._pos) {\n parent.pos(self._pos[0], self._pos[1], self._pos[2], self._id);\n }\n };\n }(Sound.prototype.init);\n /**\n * Override the Sound.reset method to clean up properties from the spatial plugin.\n * @param {Function} _super Sound reset method.\n * @return {Sound}\n */\n\n\n Sound.prototype.reset = function (_super) {\n return function () {\n var self = this;\n var parent = self._parent; // Reset all spatial plugin properties on this sound.\n\n self._orientation = parent._orientation;\n self._stereo = parent._stereo;\n self._pos = parent._pos;\n self._pannerAttr = parent._pannerAttr; // If a stereo or position was specified, set it up.\n\n if (self._stereo) {\n parent.stereo(self._stereo);\n } else if (self._pos) {\n parent.pos(self._pos[0], self._pos[1], self._pos[2], self._id);\n } else if (self._panner) {\n // Disconnect the panner.\n self._panner.disconnect(0);\n\n self._panner = undefined;\n\n parent._refreshBuffer(self);\n } // Complete resetting of the sound.\n\n\n return _super.call(this);\n };\n }(Sound.prototype.reset);\n /** Helper Methods **/\n\n /***************************************************************************/\n\n /**\n * Create a new panner node and save it on the sound.\n * @param {Sound} sound Specific sound to setup panning on.\n * @param {String} type Type of panner to create: 'stereo' or 'spatial'.\n */\n\n\n var setupPanner = function setupPanner(sound, type) {\n type = type || 'spatial'; // Create the new panner node.\n\n if (type === 'spatial') {\n sound._panner = Howler.ctx.createPanner();\n sound._panner.coneInnerAngle = sound._pannerAttr.coneInnerAngle;\n sound._panner.coneOuterAngle = sound._pannerAttr.coneOuterAngle;\n sound._panner.coneOuterGain = sound._pannerAttr.coneOuterGain;\n sound._panner.distanceModel = sound._pannerAttr.distanceModel;\n sound._panner.maxDistance = sound._pannerAttr.maxDistance;\n sound._panner.refDistance = sound._pannerAttr.refDistance;\n sound._panner.rolloffFactor = sound._pannerAttr.rolloffFactor;\n sound._panner.panningModel = sound._pannerAttr.panningModel;\n\n if (typeof sound._panner.positionX !== 'undefined') {\n sound._panner.positionX.setValueAtTime(sound._pos[0], Howler.ctx.currentTime);\n\n sound._panner.positionY.setValueAtTime(sound._pos[1], Howler.ctx.currentTime);\n\n sound._panner.positionZ.setValueAtTime(sound._pos[2], Howler.ctx.currentTime);\n } else {\n sound._panner.setPosition(sound._pos[0], sound._pos[1], sound._pos[2]);\n }\n\n if (typeof sound._panner.orientationX !== 'undefined') {\n sound._panner.orientationX.setValueAtTime(sound._orientation[0], Howler.ctx.currentTime);\n\n sound._panner.orientationY.setValueAtTime(sound._orientation[1], Howler.ctx.currentTime);\n\n sound._panner.orientationZ.setValueAtTime(sound._orientation[2], Howler.ctx.currentTime);\n } else {\n sound._panner.setOrientation(sound._orientation[0], sound._orientation[1], sound._orientation[2]);\n }\n } else {\n sound._panner = Howler.ctx.createStereoPanner();\n\n sound._panner.pan.setValueAtTime(sound._stereo, Howler.ctx.currentTime);\n }\n\n sound._panner.connect(sound._node); // Update the connections.\n\n\n if (!sound._paused) {\n sound._parent.pause(sound._id, true).play(sound._id, true);\n }\n };\n})();","function _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nvar g; // This works in non-strict mode\n\ng = function () {\n return this;\n}();\n\ntry {\n // This works if eval is allowed (see CSP)\n g = g || new Function(\"return this\")();\n} catch (e) {\n // This works if the window reference is available\n if ((typeof window === \"undefined\" ? \"undefined\" : _typeof(window)) === \"object\") g = window;\n} // g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\n\nmodule.exports = g;"],"sourceRoot":""}