Files
doneit-web/.angular/cache/14.2.12/babel-webpack/259714cba0aa33a21bd29ede1b6ac303.json
T
Eudes Inácio 53b71ea16f its working
2023-06-30 09:54:21 +01:00

1 line
309 KiB
JSON

{"ast":null,"code":"/*!\n * howler.js v2.2.3\n * howlerjs.com\n *\n * (c) 2013-2020, James Simpson of GoldFire Studios\n * goldfirestudios.com\n *\n * MIT License\n */\n\n(function () {\n 'use strict';\n\n /** Global Methods **/\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 var HowlerGlobal = function () {\n this.init();\n };\n HowlerGlobal.prototype = {\n /**\n * Initialize the global Howler object.\n * @return {Howler}\n */\n init: function () {\n var self = this || Howler;\n\n // Create a global ID counter.\n self._counter = 1000;\n\n // Pool of unlocked HTML5 Audio objects.\n self._html5AudioPool = [];\n self.html5PoolSize = 10;\n\n // Internal properties.\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;\n\n // Public properties.\n self.masterGain = null;\n self.noAudio = false;\n self.usingWebAudio = true;\n self.autoSuspend = true;\n self.ctx = null;\n\n // Set to false to disable the auto audio unlocker.\n self.autoUnlock = true;\n\n // Setup the various state values for global tracking.\n self._setup();\n return self;\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 (vol) {\n var self = this || Howler;\n vol = parseFloat(vol);\n\n // If we don't have an AudioContext created yet, run the setup.\n if (!self.ctx) {\n setupAudioContext();\n }\n if (typeof vol !== 'undefined' && vol >= 0 && vol <= 1) {\n self._volume = vol;\n\n // Don't update any of the nodes if we are muted.\n if (self._muted) {\n return self;\n }\n\n // When using Web Audio, we just need to adjust the master gain.\n if (self.usingWebAudio) {\n self.masterGain.gain.setValueAtTime(vol, Howler.ctx.currentTime);\n }\n\n // Loop through and change volume for all HTML5 audio nodes.\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();\n\n // Loop through all sounds and change the volumes.\n for (var j = 0; j < ids.length; j++) {\n var sound = self._howls[i]._soundById(ids[j]);\n if (sound && sound._node) {\n sound._node.volume = sound._volume * vol;\n }\n }\n }\n }\n return self;\n }\n return self._volume;\n },\n /**\n * Handle muting and unmuting globally.\n * @param {Boolean} muted Is muted or not.\n */\n mute: function (muted) {\n var self = this || Howler;\n\n // If we don't have an AudioContext created yet, run the setup.\n if (!self.ctx) {\n setupAudioContext();\n }\n self._muted = muted;\n\n // With Web Audio, we just need to mute the master gain.\n if (self.usingWebAudio) {\n self.masterGain.gain.setValueAtTime(muted ? 0 : self._volume, Howler.ctx.currentTime);\n }\n\n // Loop through and mute all HTML5 Audio nodes.\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();\n\n // Loop through all sounds and mark the audio node as muted.\n for (var j = 0; j < ids.length; j++) {\n var sound = self._howls[i]._soundById(ids[j]);\n if (sound && sound._node) {\n sound._node.muted = muted ? true : sound._muted;\n }\n }\n }\n }\n return self;\n },\n /**\n * Handle stopping all sounds globally.\n */\n stop: function () {\n var self = this || Howler;\n\n // Loop through all Howls and stop them.\n for (var i = 0; i < self._howls.length; i++) {\n self._howls[i].stop();\n }\n return self;\n },\n /**\n * Unload and destroy all currently loaded Howl objects.\n * @return {Howler}\n */\n unload: function () {\n var self = this || Howler;\n for (var i = self._howls.length - 1; i >= 0; i--) {\n self._howls[i].unload();\n }\n\n // Create a new AudioContext to make sure it is fully reset.\n if (self.usingWebAudio && self.ctx && typeof self.ctx.close !== 'undefined') {\n self.ctx.close();\n self.ctx = null;\n setupAudioContext();\n }\n return self;\n },\n /**\n * Check for codec support of specific extension.\n * @param {String} ext Audio file extention.\n * @return {Boolean}\n */\n codecs: function (ext) {\n return (this || Howler)._codecs[ext.replace(/^x-/, '')];\n },\n /**\n * Setup various state values for global tracking.\n * @return {Howler}\n */\n _setup: function () {\n var self = this || Howler;\n\n // Keeps track of the suspend/resume state of the AudioContext.\n self.state = self.ctx ? self.ctx.state || 'suspended' : 'suspended';\n\n // Automatically begin the 30-second suspend process\n self._autoSuspend();\n\n // Check if audio is available.\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();\n\n // Check if the canplaythrough event is available.\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 }\n\n // Test to make sure audio isn't disabled in Internet Explorer.\n try {\n var test = new Audio();\n if (test.muted) {\n self.noAudio = true;\n }\n } catch (e) {}\n\n // Check for supported codecs.\n if (!self.noAudio) {\n self._setupCodecs();\n }\n return self;\n },\n /**\n * Check for browser support for various codecs and cache the results.\n * @return {Howler}\n */\n _setupCodecs: function () {\n var self = this || Howler;\n var audioTest = null;\n\n // Must wrap in a try/catch because IE11 in server mode throws an error.\n try {\n audioTest = typeof Audio !== 'undefined' ? new Audio() : null;\n } catch (err) {\n return self;\n }\n if (!audioTest || typeof audioTest.canPlayType !== 'function') {\n return self;\n }\n var mpegTest = audioTest.canPlayType('audio/mpeg;').replace(/^no$/, '');\n\n // Opera version <33 has mixed MP3 support, so we need to check for and block it.\n var ua = self._navigator ? self._navigator.userAgent : '';\n var checkOpera = ua.match(/OPR\\/([0-6].)/g);\n var isOldOpera = checkOpera && parseInt(checkOpera[0].split('/')[1], 10) < 33;\n var checkSafari = ua.indexOf('Safari') !== -1 && ua.indexOf('Chrome') === -1;\n var safariVersion = ua.match(/Version\\/(.*?) /);\n var isOldSafari = checkSafari && safariVersion && parseInt(safariVersion[1], 10) < 15;\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: !!(!isOldSafari && audioTest.canPlayType('audio/webm; codecs=\"vorbis\"').replace(/^no$/, '')),\n webm: !!(!isOldSafari && 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 * 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 () {\n var self = this || Howler;\n\n // Only run this if Web Audio is supported and it hasn't already been unlocked.\n if (self._audioUnlocked || !self.ctx) {\n return;\n }\n self._audioUnlocked = false;\n self.autoUnlock = false;\n\n // 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 if (!self._mobileUnloaded && self.ctx.sampleRate !== 44100) {\n self._mobileUnloaded = true;\n self.unload();\n }\n\n // Scratch buffer for enabling iOS to dispose of web audio buffers correctly, as per:\n // http://stackoverflow.com/questions/24119684\n self._scratchBuffer = self.ctx.createBuffer(1, 1, 22050);\n\n // 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 var unlock = function (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();\n\n // Mark this Audio object as unlocked to ensure it can get returned\n // to the unlocked pool when released.\n audioNode._unlocked = true;\n\n // Add the audio node to the pool.\n self._releaseHtml5Audio(audioNode);\n } catch (e) {\n self.noAudio = true;\n break;\n }\n }\n\n // Loop through any assigned audio nodes and unlock them.\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();\n\n // Loop through all sounds and unlock the audio nodes.\n for (var j = 0; j < ids.length; j++) {\n var sound = self._howls[i]._soundById(ids[j]);\n if (sound && sound._node && !sound._node._unlocked) {\n sound._node._unlocked = true;\n sound._node.load();\n }\n }\n }\n }\n\n // Fix Android can not play in suspend state.\n self._autoResume();\n\n // Create an empty buffer.\n var source = self.ctx.createBufferSource();\n source.buffer = self._scratchBuffer;\n source.connect(self.ctx.destination);\n\n // Play the empty buffer.\n if (typeof source.start === 'undefined') {\n source.noteOn(0);\n } else {\n source.start(0);\n }\n\n // Calling resume() on a stack initiated by user gesture is what actually unlocks the audio on Android Chrome >= 55.\n if (typeof self.ctx.resume === 'function') {\n self.ctx.resume();\n }\n\n // Setup a timeout to check that we are unlocked on the next event loop.\n source.onended = function () {\n source.disconnect(0);\n\n // Update the unlocked state and prevent this check from happening again.\n self._audioUnlocked = true;\n\n // Remove the touch start listener.\n document.removeEventListener('touchstart', unlock, true);\n document.removeEventListener('touchend', unlock, true);\n document.removeEventListener('click', unlock, true);\n document.removeEventListener('keydown', unlock, true);\n\n // Let all sounds know that audio has been unlocked.\n for (var i = 0; i < self._howls.length; i++) {\n self._howls[i]._emit('unlock');\n }\n };\n };\n\n // Setup a touch start listener to attempt an unlock in.\n document.addEventListener('touchstart', unlock, true);\n document.addEventListener('touchend', unlock, true);\n document.addEventListener('click', unlock, true);\n document.addEventListener('keydown', unlock, true);\n return self;\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 () {\n var self = this || Howler;\n\n // Return the next object from the pool if one exists.\n if (self._html5AudioPool.length) {\n return self._html5AudioPool.pop();\n }\n\n //.Check if the audio is locked and throw a warning.\n var testPlay = new Audio().play();\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 return new Audio();\n },\n /**\n * Return an activated HTML5 Audio object to the pool.\n * @return {Howler}\n */\n _releaseHtml5Audio: function (audio) {\n var self = this || Howler;\n\n // Don't add audio to the pool if we don't know if it has been unlocked.\n if (audio._unlocked) {\n self._html5AudioPool.push(audio);\n }\n return self;\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 () {\n var self = this;\n if (!self.autoSuspend || !self.ctx || typeof self.ctx.suspend === 'undefined' || !Howler.usingWebAudio) {\n return;\n }\n\n // Check if any sounds are playing.\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 if (self._suspendTimer) {\n clearTimeout(self._suspendTimer);\n }\n\n // If no sound has played after 30 seconds, suspend the context.\n self._suspendTimer = setTimeout(function () {\n if (!self.autoSuspend) {\n return;\n }\n self._suspendTimer = null;\n self.state = 'suspending';\n\n // Handle updating the state of the audio context after suspending.\n var handleSuspension = function () {\n self.state = 'suspended';\n if (self._resumeAfterSuspend) {\n delete self._resumeAfterSuspend;\n self._autoResume();\n }\n };\n\n // Either the state gets suspended or it is interrupted.\n // Either way, we need to update the state to suspended.\n self.ctx.suspend().then(handleSuspension, handleSuspension);\n }, 30000);\n return self;\n },\n /**\n * Automatically resume the Web Audio AudioContext when a new sound is played.\n * @return {Howler}\n */\n _autoResume: function () {\n var self = this;\n if (!self.ctx || typeof self.ctx.resume === 'undefined' || !Howler.usingWebAudio) {\n return;\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';\n\n // Emit to all Howls that the audio has resumed.\n for (var i = 0; i < self._howls.length; i++) {\n self._howls[i]._emit('resume');\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 return self;\n }\n };\n\n // Setup the global audio controller.\n var Howler = new HowlerGlobal();\n\n /** Group Methods **/\n /***************************************************************************/\n\n /**\n * Create an audio group controller.\n * @param {Object} o Passed in properties for this group.\n */\n var Howl = function (o) {\n var self = this;\n\n // Throw an error if no source is provided.\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 self.init(o);\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 (o) {\n var self = this;\n\n // If we don't have an AudioContext created yet, run the setup.\n if (!Howler.ctx) {\n setupAudioContext();\n }\n\n // Setup user-defined default properties.\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 };\n\n // Setup all other default properties.\n self._duration = 0;\n self._state = 'unloaded';\n self._sounds = [];\n self._endTimers = {};\n self._queue = [];\n self._playLock = false;\n\n // Setup event listeners.\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 = [];\n\n // Web Audio or HTML5 Audio?\n self._webAudio = Howler.usingWebAudio && !self._html5;\n\n // Automatically try to enable audio.\n if (typeof Howler.ctx !== 'undefined' && Howler.ctx && Howler.autoUnlock) {\n Howler._unlockAudio();\n }\n\n // Keep track of this Howl group in the global controller.\n Howler._howls.push(self);\n\n // If they selected autoplay, add a play event to the load queue.\n if (self._autoplay) {\n self._queue.push({\n event: 'play',\n action: function () {\n self.play();\n }\n });\n }\n\n // Load the source file unless otherwise specified.\n if (self._preload && self._preload !== 'none') {\n self.load();\n }\n return self;\n },\n /**\n * Load the audio file.\n * @return {Howler}\n */\n load: function () {\n var self = this;\n var url = null;\n\n // If no audio is available, quit immediately.\n if (Howler.noAudio) {\n self._emit('loaderror', null, 'No audio support.');\n return;\n }\n\n // Make sure our source is in an array.\n if (typeof self._src === 'string') {\n self._src = [self._src];\n }\n\n // Loop through the sources and pick the first one that is compatible.\n for (var i = 0; i < self._src.length; i++) {\n var ext, str;\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 if (typeof str !== 'string') {\n self._emit('loaderror', null, 'Non-string found in selected audio sources - ignoring.');\n continue;\n }\n\n // Extract the file extension from the URL or base64 data URI.\n ext = /^data:audio\\/([^;,]+);/i.exec(str);\n if (!ext) {\n ext = /\\.([^.]+)$/.exec(str.split('?', 1)[0]);\n }\n if (ext) {\n ext = ext[1].toLowerCase();\n }\n }\n\n // Log a warning if no extension was found.\n if (!ext) {\n console.warn('No file extension was found. Consider using the \"format\" property or specify an extension.');\n }\n\n // Check if this extension is available.\n if (ext && Howler.codecs(ext)) {\n url = self._src[i];\n break;\n }\n }\n if (!url) {\n self._emit('loaderror', null, 'No codec support for selected audio sources.');\n return;\n }\n self._src = url;\n self._state = 'loading';\n\n // If the hosting page is HTTPS and the source isn't,\n // drop down to HTML5 Audio to avoid Mixed Content errors.\n if (window.location.protocol === 'https:' && url.slice(0, 5) === 'http:') {\n self._html5 = true;\n self._webAudio = false;\n }\n\n // Create a new sound object and add it to the pool.\n new Sound(self);\n\n // Load and decode the audio data for playback.\n if (self._webAudio) {\n loadBuffer(self);\n }\n return self;\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 (sprite, internal) {\n var self = this;\n var id = null;\n\n // Determine if a sprite, sound id or nothing was passed\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';\n\n // 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 if (!self._playLock) {\n var num = 0;\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 if (num === 1) {\n sprite = null;\n } else {\n id = null;\n }\n }\n }\n\n // Get the selected node, or get one from the pool.\n var sound = id ? self._soundById(id) : self._inactiveSound();\n\n // If the sound doesn't exist, do nothing.\n if (!sound) {\n return null;\n }\n\n // Select the sprite definition.\n if (id && !sprite) {\n sprite = sound._sprite || '__default';\n }\n\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 if (self._state !== 'loaded') {\n // Set the sprite value on this sound.\n sound._sprite = sprite;\n\n // Mark this sound as not ended in case another sound is played before this one loads.\n sound._ended = false;\n\n // Add the sound to the queue to be played on load.\n var soundId = sound._id;\n self._queue.push({\n event: 'play',\n action: function () {\n self.play(soundId);\n }\n });\n return soundId;\n }\n\n // Don't play the sound if an id was passed and it is already playing.\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 return sound._id;\n }\n\n // Make sure the AudioContext isn't suspended, and resume it if it is.\n if (self._webAudio) {\n Howler._autoResume();\n }\n\n // Determine how long to play for and where to start playing.\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;\n\n // 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 sound._ended = false;\n\n // Update the parameters of the sound.\n var setParams = function () {\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 };\n\n // End the sound instantly if seek is at the end.\n if (seek >= stop) {\n self._ended(sound);\n return;\n }\n\n // Begin the actual playback.\n var node = sound._node;\n if (self._webAudio) {\n // Fire this when the sound is ready to play to begin Web Audio playback.\n var playWebAudio = function () {\n self._playLock = false;\n setParams();\n self._refreshBuffer(sound);\n\n // Setup the playback params.\n var vol = sound._muted || self._muted ? 0 : sound._volume;\n node.gain.setValueAtTime(vol, Howler.ctx.currentTime);\n sound._playStart = Howler.ctx.currentTime;\n\n // Play the sound using the supported method.\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 }\n\n // Start a new timer if none is present.\n if (timeout !== Infinity) {\n self._endTimers[sound._id] = setTimeout(self._ended.bind(self, sound), timeout);\n }\n if (!internal) {\n setTimeout(function () {\n self._emit('play', sound._id);\n self._loadQueue();\n }, 0);\n }\n };\n if (Howler.state === 'running' && Howler.ctx.state !== 'interrupted') {\n playWebAudio();\n } else {\n self._playLock = true;\n\n // Wait for the audio context to resume before playing.\n self.once('resume', playWebAudio);\n\n // Cancel the end timer.\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 () {\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;\n\n // Some browsers will throw an error if this is called without user interaction.\n try {\n var play = node.play();\n\n // Support older browsers that don't support promises, and thus don't have this issue.\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;\n\n // Set param values immediately.\n setParams();\n\n // Releases the lock and executes queued actions.\n play.then(function () {\n self._playLock = false;\n node._unlocked = true;\n if (!internal) {\n self._emit('play', sound._id);\n } else {\n self._loadQueue();\n }\n }).catch(function () {\n self._playLock = false;\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 // Reset the ended and paused values.\n sound._ended = true;\n sound._paused = true;\n });\n } else if (!internal) {\n self._playLock = false;\n setParams();\n self._emit('play', sound._id);\n }\n\n // Setting rate before playing won't work in IE, so we set it again here.\n node.playbackRate = sound._rate;\n\n // If the node is still paused, then we can assume there was a playback issue.\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 return;\n }\n\n // Setup the end timer on sprites or listen for the ended event.\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);\n\n // Clear this listener.\n node.removeEventListener('ended', self._endTimers[sound._id], false);\n };\n node.addEventListener('ended', self._endTimers[sound._id], false);\n }\n } catch (err) {\n self._emit('playerror', sound._id, err);\n }\n };\n\n // If this is streaming audio, make sure the src is set and load again.\n if (node.src === 'data:audio/wav;base64,UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA') {\n node.src = self._src;\n node.load();\n }\n\n // Play immediately if ready, or wait for the 'canplaythrough'e vent.\n var loadedNoReadyState = window && window.ejecta || !node.readyState && Howler._navigator.isCocoonJS;\n if (node.readyState >= 3 || loadedNoReadyState) {\n playHtml5();\n } else {\n self._playLock = true;\n self._state = 'loading';\n var listener = function () {\n self._state = 'loaded';\n\n // Begin playback.\n playHtml5();\n\n // Clear this listener.\n node.removeEventListener(Howler._canPlayEvent, listener, false);\n };\n node.addEventListener(Howler._canPlayEvent, listener, false);\n\n // Cancel the end timer.\n self._clearTimer(sound._id);\n }\n }\n return sound._id;\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 (id) {\n var self = this;\n\n // If the sound hasn't loaded or a play() promise is pending, add it to the load queue to pause when capable.\n if (self._state !== 'loaded' || self._playLock) {\n self._queue.push({\n event: 'pause',\n action: function () {\n self.pause(id);\n }\n });\n return self;\n }\n\n // If no id is passed, get all ID's to be paused.\n var ids = self._getSoundIds(id);\n for (var i = 0; i < ids.length; i++) {\n // Clear the end timer.\n self._clearTimer(ids[i]);\n\n // Get the sound.\n var sound = self._soundById(ids[i]);\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;\n\n // Stop currently running fades.\n self._stopFade(ids[i]);\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 if (typeof sound._node.bufferSource.stop === 'undefined') {\n sound._node.bufferSource.noteOff(0);\n } else {\n sound._node.bufferSource.stop(0);\n }\n\n // Clean up the buffer source.\n self._cleanBuffer(sound._node);\n } else if (!isNaN(sound._node.duration) || sound._node.duration === Infinity) {\n sound._node.pause();\n }\n }\n }\n\n // Fire the pause event, unless `true` is passed as the 2nd argument.\n if (!arguments[1]) {\n self._emit('pause', sound ? sound._id : null);\n }\n }\n return self;\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 (id, internal) {\n var self = this;\n\n // If the sound hasn't loaded, add it to the load queue to stop when capable.\n if (self._state !== 'loaded' || self._playLock) {\n self._queue.push({\n event: 'stop',\n action: function () {\n self.stop(id);\n }\n });\n return self;\n }\n\n // If no id is passed, get all ID's to be stopped.\n var ids = self._getSoundIds(id);\n for (var i = 0; i < ids.length; i++) {\n // Clear the end timer.\n self._clearTimer(ids[i]);\n\n // Get the sound.\n var sound = self._soundById(ids[i]);\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;\n\n // Stop currently running fades.\n self._stopFade(ids[i]);\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 }\n\n // Clean up the buffer source.\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 sound._node.pause();\n\n // If this is a live stream, stop download once the audio is stopped.\n if (sound._node.duration === Infinity) {\n self._clearSound(sound._node);\n }\n }\n }\n if (!internal) {\n self._emit('stop', sound._id);\n }\n }\n }\n return self;\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 (muted, id) {\n var self = this;\n\n // If the sound hasn't loaded, add it to the load queue to mute when capable.\n if (self._state !== 'loaded' || self._playLock) {\n self._queue.push({\n event: 'mute',\n action: function () {\n self.mute(muted, id);\n }\n });\n return self;\n }\n\n // If applying mute/unmute to all sounds, update the group's value.\n if (typeof id === 'undefined') {\n if (typeof muted === 'boolean') {\n self._muted = muted;\n } else {\n return self._muted;\n }\n }\n\n // If no id is passed, get all ID's to be muted.\n var ids = self._getSoundIds(id);\n for (var i = 0; i < ids.length; i++) {\n // Get the sound.\n var sound = self._soundById(ids[i]);\n if (sound) {\n sound._muted = muted;\n\n // Cancel active fade and set the volume to the end value.\n if (sound._interval) {\n self._stopFade(sound._id);\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 self._emit('mute', sound._id);\n }\n }\n return self;\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 () {\n var self = this;\n var args = arguments;\n var vol, id;\n\n // Determine the values based on arguments.\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 var index = ids.indexOf(args[0]);\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 }\n\n // Update the volume or return the current volume.\n var sound;\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 () {\n self.volume.apply(self, args);\n }\n });\n return self;\n }\n\n // Set the group volume.\n if (typeof id === 'undefined') {\n self._volume = vol;\n }\n\n // Update one or all volumes.\n id = self._getSoundIds(id);\n for (var i = 0; i < id.length; i++) {\n // Get the sound.\n sound = self._soundById(id[i]);\n if (sound) {\n sound._volume = vol;\n\n // Stop currently running fades.\n if (!args[2]) {\n self._stopFade(id[i]);\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 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 return self;\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 (from, to, len, id) {\n var self = this;\n\n // If the sound hasn't loaded, add it to the load queue to fade when capable.\n if (self._state !== 'loaded' || self._playLock) {\n self._queue.push({\n event: 'fade',\n action: function () {\n self.fade(from, to, len, id);\n }\n });\n return self;\n }\n\n // Make sure the to/from/len values are numbers.\n from = Math.min(Math.max(0, parseFloat(from)), 1);\n to = Math.min(Math.max(0, parseFloat(to)), 1);\n len = parseFloat(len);\n\n // Set the volume to the start position.\n self.volume(from, id);\n\n // Fade the volume of one or all sounds.\n var ids = self._getSoundIds(id);\n for (var i = 0; i < ids.length; i++) {\n // Get the sound.\n var sound = self._soundById(ids[i]);\n\n // Create a linear fade or fall back to timeouts with HTML5 Audio.\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 }\n\n // If we are using Web Audio, let the native methods do the actual fade.\n if (self._webAudio && !sound._muted) {\n var currentTime = Howler.ctx.currentTime;\n var end = currentTime + len / 1000;\n sound._volume = from;\n sound._node.gain.setValueAtTime(from, currentTime);\n sound._node.gain.linearRampToValueAtTime(to, end);\n }\n self._startFadeInterval(sound, from, to, len, ids[i], typeof id === 'undefined');\n }\n }\n return self;\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 (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();\n\n // Store the value being faded to.\n sound._fadeTo = to;\n\n // Update the volume value on each interval tick.\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;\n\n // Round to within 2 decimal points.\n vol = Math.round(vol * 100) / 100;\n\n // Make sure the volume is in the right bounds.\n if (diff < 0) {\n vol = Math.max(to, vol);\n } else {\n vol = Math.min(to, vol);\n }\n\n // Change the volume.\n if (self._webAudio) {\n sound._volume = vol;\n } else {\n self.volume(vol, sound._id, true);\n }\n\n // Set the group's volume.\n if (isGroup) {\n self._volume = vol;\n }\n\n // When the fade is complete, stop it and fire event.\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 self._emit('fade', sound._id);\n }\n }, stepLen);\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 (id) {\n var self = this;\n var sound = self._soundById(id);\n if (sound && sound._interval) {\n if (self._webAudio) {\n sound._node.gain.cancelScheduledValues(Howler.ctx.currentTime);\n }\n clearInterval(sound._interval);\n sound._interval = null;\n self.volume(sound._fadeTo, id);\n sound._fadeTo = null;\n self._emit('fade', id);\n }\n return self;\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 () {\n var self = this;\n var args = arguments;\n var loop, id, sound;\n\n // Determine the values for loop and id.\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 }\n\n // If no id is passed, get all ID's to be looped.\n var ids = self._getSoundIds(id);\n for (var i = 0; i < ids.length; i++) {\n sound = self._soundById(ids[i]);\n if (sound) {\n sound._loop = loop;\n if (self._webAudio && sound._node && sound._node.bufferSource) {\n sound._node.bufferSource.loop = loop;\n if (loop) {\n sound._node.bufferSource.loopStart = sound._start || 0;\n sound._node.bufferSource.loopEnd = sound._stop;\n\n // If playing, restart playback to ensure looping updates.\n if (self.playing(ids[i])) {\n self.pause(ids[i], true);\n self.play(ids[i], true);\n }\n }\n }\n }\n }\n return self;\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 () {\n var self = this;\n var args = arguments;\n var rate, id;\n\n // Determine the values based on arguments.\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 var index = ids.indexOf(args[0]);\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 }\n\n // Update the playback rate or return the current value.\n var sound;\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 () {\n self.rate.apply(self, args);\n }\n });\n return self;\n }\n\n // Set the group rate.\n if (typeof id === 'undefined') {\n self._rate = rate;\n }\n\n // Update one or all volumes.\n id = self._getSoundIds(id);\n for (var i = 0; i < id.length; i++) {\n // Get the sound.\n sound = self._soundById(id[i]);\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 sound._rate = rate;\n\n // Change the playback rate.\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 }\n\n // Reset the timers.\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);\n\n // Start a new end timer if sound is already playing.\n if (self._endTimers[id[i]] || !sound._paused) {\n self._clearTimer(id[i]);\n self._endTimers[id[i]] = setTimeout(self._ended.bind(self, sound), timeout);\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 return self;\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 () {\n var self = this;\n var args = arguments;\n var seek, id;\n\n // Determine the values based on arguments.\n if (args.length === 0) {\n // We will simply return the current position of the first node.\n if (self._sounds.length) {\n id = self._sounds[0]._id;\n }\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 var index = ids.indexOf(args[0]);\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 }\n\n // If there is no ID, bail out.\n if (typeof id === 'undefined') {\n return 0;\n }\n\n // If the sound hasn't loaded, add it to the load queue to seek when capable.\n if (typeof seek === 'number' && (self._state !== 'loaded' || self._playLock)) {\n self._queue.push({\n event: 'seek',\n action: function () {\n self.seek.apply(self, args);\n }\n });\n return self;\n }\n\n // Get the sound.\n var sound = self._soundById(id);\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 if (playing) {\n self.pause(id, true);\n }\n\n // Move the position of the track and cancel timer.\n sound._seek = seek;\n sound._ended = false;\n self._clearTimer(id);\n\n // Update the seek position for HTML5 Audio.\n if (!self._webAudio && sound._node && !isNaN(sound._node.duration)) {\n sound._node.currentTime = seek;\n }\n\n // Seek and emit when ready.\n var seekAndEmit = function () {\n // Restart the playback if the sound was playing.\n if (playing) {\n self.play(id, true);\n }\n self._emit('seek', id);\n };\n\n // Wait for the play lock to be unset before emitting (HTML5 Audio).\n if (playing && !self._webAudio) {\n var emitSeek = function () {\n if (!self._playLock) {\n seekAndEmit();\n } else {\n setTimeout(emitSeek, 0);\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 return self;\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 (id) {\n var self = this;\n\n // Check the passed sound ID (if any).\n if (typeof id === 'number') {\n var sound = self._soundById(id);\n return sound ? !sound._paused : false;\n }\n\n // Otherwise, loop through all sounds and check if any are playing.\n for (var i = 0; i < self._sounds.length; i++) {\n if (!self._sounds[i]._paused) {\n return true;\n }\n }\n return false;\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 (id) {\n var self = this;\n var duration = self._duration;\n\n // If we pass an ID, get the sound and return the sprite length.\n var sound = self._soundById(id);\n if (sound) {\n duration = self._sprite[sound._sprite][1] / 1000;\n }\n return duration;\n },\n /**\n * Returns the current loaded state of this Howl.\n * @return {String} 'unloaded', 'loading', 'loaded'\n */\n state: function () {\n return this._state;\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 () {\n var self = this;\n\n // Stop playing any active sounds.\n var sounds = self._sounds;\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 }\n\n // Remove the source or disconnect.\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);\n\n // Remove any event listeners.\n sounds[i]._node.removeEventListener('error', sounds[i]._errorFn, false);\n sounds[i]._node.removeEventListener(Howler._canPlayEvent, sounds[i]._loadFn, false);\n sounds[i]._node.removeEventListener('ended', sounds[i]._endFn, false);\n\n // Release the Audio object back to the pool.\n Howler._releaseHtml5Audio(sounds[i]._node);\n }\n\n // Empty out all of the nodes.\n delete sounds[i]._node;\n\n // Make sure all timers are cleared out.\n self._clearTimer(sounds[i]._id);\n }\n\n // Remove the references in the global Howler object.\n var index = Howler._howls.indexOf(self);\n if (index >= 0) {\n Howler._howls.splice(index, 1);\n }\n\n // Delete this sound from the cache (if no other Howl is using it).\n var remCache = true;\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 if (cache && remCache) {\n delete cache[self._src];\n }\n\n // Clear global errors.\n Howler.noAudio = false;\n\n // Clear out `self`.\n self._state = 'unloaded';\n self._sounds = [];\n self = null;\n return null;\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 (event, fn, id, once) {\n var self = this;\n var events = self['_on' + event];\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 return self;\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 (event, fn, id) {\n var self = this;\n var events = self['_on' + event];\n var i = 0;\n\n // Allow passing just an event and ID.\n if (typeof fn === 'number') {\n id = fn;\n fn = null;\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 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 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 return self;\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 (event, fn, id) {\n var self = this;\n\n // Setup the event listener.\n self.on(event, fn, id, 1);\n return self;\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 (event, id, msg) {\n var self = this;\n var events = self['_on' + event];\n\n // Loop through event store and fire all functions.\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);\n\n // If this event was setup with `once`, remove it.\n if (events[i].once) {\n self.off(event, events[i].fn, events[i].id);\n }\n }\n }\n\n // Pass the event type into load queue so that it can continue stepping.\n self._loadQueue(event);\n return self;\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 (event) {\n var self = this;\n if (self._queue.length > 0) {\n var task = self._queue[0];\n\n // Remove this task if a matching event was passed.\n if (task.event === event) {\n self._queue.shift();\n self._loadQueue();\n }\n\n // Run the task if no event type is passed.\n if (!event) {\n task.action();\n }\n }\n return self;\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 (sound) {\n var self = this;\n var sprite = sound._sprite;\n\n // 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 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 }\n\n // Should this sound loop?\n var loop = !!(sound._loop || self._sprite[sprite][2]);\n\n // Fire the ended event.\n self._emit('end', sound._id);\n\n // Restart the playback for HTML5 Audio loop.\n if (!self._webAudio && loop) {\n self.stop(sound._id, true).play(sound._id);\n }\n\n // Restart this timer if on a Web Audio loop.\n if (self._webAudio && loop) {\n self._emit('play', sound._id);\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 }\n\n // Mark the node as paused.\n if (self._webAudio && !loop) {\n sound._paused = true;\n sound._ended = true;\n sound._seek = sound._start || 0;\n sound._rateSeek = 0;\n self._clearTimer(sound._id);\n\n // Clean up the buffer source.\n self._cleanBuffer(sound._node);\n\n // Attempt to auto-suspend AudioContext if no sounds are still playing.\n Howler._autoSuspend();\n }\n\n // When using a sprite, end the track.\n if (!self._webAudio && !loop) {\n self.stop(sound._id, true);\n }\n return self;\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 (id) {\n var self = this;\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 if (sound && sound._node) {\n sound._node.removeEventListener('ended', self._endTimers[id], false);\n }\n }\n delete self._endTimers[id];\n }\n return self;\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 (id) {\n var self = this;\n\n // Loop through all sounds and find the one with this ID.\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 return null;\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 () {\n var self = this;\n self._drain();\n\n // Find the first inactive node to recycle.\n for (var i = 0; i < self._sounds.length; i++) {\n if (self._sounds[i]._ended) {\n return self._sounds[i].reset();\n }\n }\n\n // If no inactive node was found, create a new one.\n return new Sound(self);\n },\n /**\n * Drain excess inactive sounds from the pool.\n */\n _drain: function () {\n var self = this;\n var limit = self._pool;\n var cnt = 0;\n var i = 0;\n\n // If there are less sounds than the max pool size, we are done.\n if (self._sounds.length < limit) {\n return;\n }\n\n // Count the number of inactive sounds.\n for (i = 0; i < self._sounds.length; i++) {\n if (self._sounds[i]._ended) {\n cnt++;\n }\n }\n\n // Remove excess inactive sounds, going in reverse order.\n for (i = self._sounds.length - 1; i >= 0; i--) {\n if (cnt <= limit) {\n return;\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 }\n\n // Remove sounds until we have the pool size.\n self._sounds.splice(i, 1);\n cnt--;\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 (id) {\n var self = this;\n if (typeof id === 'undefined') {\n var ids = [];\n for (var i = 0; i < self._sounds.length; i++) {\n ids.push(self._sounds[i]._id);\n }\n return ids;\n } else {\n return [id];\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 (sound) {\n var self = this;\n\n // Setup the buffer source for playback.\n sound._node.bufferSource = Howler.ctx.createBufferSource();\n sound._node.bufferSource.buffer = cache[self._src];\n\n // Connect to the correct node.\n if (sound._panner) {\n sound._node.bufferSource.connect(sound._panner);\n } else {\n sound._node.bufferSource.connect(sound._node);\n }\n\n // Setup looping and playback rate.\n sound._node.bufferSource.loop = sound._loop;\n if (sound._loop) {\n sound._node.bufferSource.loopStart = sound._start || 0;\n sound._node.bufferSource.loopEnd = sound._stop || 0;\n }\n sound._node.bufferSource.playbackRate.setValueAtTime(sound._rate, Howler.ctx.currentTime);\n return self;\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 (node) {\n var self = this;\n var isIOS = Howler._navigator && Howler._navigator.vendor.indexOf('Apple') >= 0;\n if (Howler._scratchBuffer && node.bufferSource) {\n node.bufferSource.onended = null;\n node.bufferSource.disconnect(0);\n if (isIOS) {\n try {\n node.bufferSource.buffer = Howler._scratchBuffer;\n } catch (e) {}\n }\n }\n node.bufferSource = null;\n return self;\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 (node) {\n var checkIE = /MSIE |Trident\\//.test(Howler._navigator && Howler._navigator.userAgent);\n if (!checkIE) {\n node.src = 'data:audio/wav;base64,UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA';\n }\n }\n };\n\n /** Single Sound Methods **/\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 var Sound = function (howl) {\n this._parent = howl;\n this.init();\n };\n Sound.prototype = {\n /**\n * Initialize a new Sound object.\n * @return {Sound}\n */\n init: function () {\n var self = this;\n var parent = self._parent;\n\n // Setup the default parameters.\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';\n\n // Generate a unique ID for this sound.\n self._id = ++Howler._counter;\n\n // Add itself to the parent's pool.\n parent._sounds.push(self);\n\n // Create the new node.\n self.create();\n return self;\n },\n /**\n * Create and setup a new sound object, whether HTML5 Audio or Web Audio.\n * @return {Sound}\n */\n create: function () {\n var self = this;\n var parent = self._parent;\n var volume = Howler._muted || self._muted || self._parent._muted ? 0 : self._volume;\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 self._node.gain.setValueAtTime(volume, Howler.ctx.currentTime);\n self._node.paused = true;\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();\n\n // Listen for errors (http://dev.w3.org/html5/spec-author-view/spec.html#mediaerror).\n self._errorFn = self._errorListener.bind(self);\n self._node.addEventListener('error', self._errorFn, false);\n\n // Listen for 'canplaythrough' event to let us know the sound is ready.\n self._loadFn = self._loadListener.bind(self);\n self._node.addEventListener(Howler._canPlayEvent, self._loadFn, false);\n\n // Listen for the 'ended' event on the sound to account for edge-case where\n // a finite sound has a duration of Infinity.\n self._endFn = self._endListener.bind(self);\n self._node.addEventListener('ended', self._endFn, false);\n\n // Setup the new audio node.\n self._node.src = parent._src;\n self._node.preload = parent._preload === true ? 'auto' : parent._preload;\n self._node.volume = volume * Howler.volume();\n\n // Begin loading the source.\n self._node.load();\n }\n return self;\n },\n /**\n * Reset the parameters of this sound to the original state (for recycle).\n * @return {Sound}\n */\n reset: function () {\n var self = this;\n var parent = self._parent;\n\n // Reset all of the parameters of this sound.\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';\n\n // Generate a new ID so that it isn't confused with the previous sound.\n self._id = ++Howler._counter;\n return self;\n },\n /**\n * HTML5 Audio error listener callback.\n */\n _errorListener: function () {\n var self = this;\n\n // Fire an error event and pass back the code.\n self._parent._emit('loaderror', self._id, self._node.error ? self._node.error.code : 0);\n\n // Clear the event listener.\n self._node.removeEventListener('error', self._errorFn, false);\n },\n /**\n * HTML5 Audio canplaythrough listener callback.\n */\n _loadListener: function () {\n var self = this;\n var parent = self._parent;\n\n // Round up the duration to account for the lower precision in HTML5 Audio.\n parent._duration = Math.ceil(self._node.duration * 10) / 10;\n\n // Setup a sprite if none is defined.\n if (Object.keys(parent._sprite).length === 0) {\n parent._sprite = {\n __default: [0, parent._duration * 1000]\n };\n }\n if (parent._state !== 'loaded') {\n parent._state = 'loaded';\n parent._emit('load');\n parent._loadQueue();\n }\n\n // Clear the event listener.\n self._node.removeEventListener(Howler._canPlayEvent, self._loadFn, false);\n },\n /**\n * HTML5 Audio ended listener callback.\n */\n _endListener: function () {\n var self = this;\n var parent = self._parent;\n\n // Only handle the `ended`` event if the duration is Infinity.\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;\n\n // Update the sprite that corresponds to the real duration.\n if (parent._sprite.__default[1] === Infinity) {\n parent._sprite.__default[1] = parent._duration * 1000;\n }\n\n // Run the regular ended method.\n parent._ended(self);\n }\n\n // Clear the event listener since the duration is now correct.\n self._node.removeEventListener('ended', self._endFn, false);\n }\n };\n\n /** Helper Methods **/\n /***************************************************************************/\n\n var cache = {};\n\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 var loadBuffer = function (self) {\n var url = self._src;\n\n // Check if the buffer has already been cached and use it instead.\n if (cache[url]) {\n // Set the duration from the cache.\n self._duration = cache[url].duration;\n\n // Load the sound into this Howl.\n loadSound(self);\n return;\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 for (var i = 0; i < data.length; ++i) {\n dataView[i] = data.charCodeAt(i);\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';\n\n // Apply any custom headers to the request.\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 xhr.onload = function () {\n // Make sure we get a successful response back.\n var code = (xhr.status + '')[0];\n if (code !== '0' && code !== '2' && code !== '3') {\n self._emit('loaderror', null, 'Failed loading audio file with status: ' + xhr.status + '.');\n return;\n }\n decodeAudioData(xhr.response, self);\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 safeXhrSend(xhr);\n }\n };\n\n /**\n * Send the XHR request wrapped in a try/catch.\n * @param {Object} xhr XHR to send.\n */\n var safeXhrSend = function (xhr) {\n try {\n xhr.send();\n } catch (e) {\n xhr.onerror();\n }\n };\n\n /**\n * Decode audio data from an array buffer.\n * @param {ArrayBuffer} arraybuffer The audio data.\n * @param {Howl} self\n */\n var decodeAudioData = function (arraybuffer, self) {\n // Fire a load error if something broke.\n var error = function () {\n self._emit('loaderror', null, 'Decoding audio data failed.');\n };\n\n // Load the sound on success.\n var success = function (buffer) {\n if (buffer && self._sounds.length > 0) {\n cache[self._src] = buffer;\n loadSound(self, buffer);\n } else {\n error();\n }\n };\n\n // Decode the buffer into an audio source.\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 /**\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 var loadSound = function (self, buffer) {\n // Set the duration.\n if (buffer && !self._duration) {\n self._duration = buffer.duration;\n }\n\n // Setup a sprite if none is defined.\n if (Object.keys(self._sprite).length === 0) {\n self._sprite = {\n __default: [0, self._duration * 1000]\n };\n }\n\n // Fire the loaded event.\n if (self._state !== 'loaded') {\n self._state = 'loaded';\n self._emit('load');\n self._loadQueue();\n }\n };\n\n /**\n * Setup the audio context when available, or switch to HTML5 Audio mode.\n */\n var setupAudioContext = function () {\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 }\n\n // Check if we are using Web Audio and setup the AudioContext if we are.\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 }\n\n // If the audio context creation still failed, set using web audio to false.\n if (!Howler.ctx) {\n Howler.usingWebAudio = false;\n }\n\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 var iOS = /iP(hone|od|ad)/.test(Howler._navigator && Howler._navigator.platform);\n var appVersion = Howler._navigator && Howler._navigator.appVersion.match(/OS (\\d+)_(\\d+)_?(\\d+)?/);\n var version = appVersion ? parseInt(appVersion[1], 10) : null;\n if (iOS && version && version < 9) {\n var safari = /safari/.test(Howler._navigator && Howler._navigator.userAgent.toLowerCase());\n if (Howler._navigator && !safari) {\n Howler.usingWebAudio = false;\n }\n }\n\n // Create and expose the master GainNode when using Web Audio (useful for plugins or advanced usage).\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 }\n\n // Re-run the setup on Howler.\n Howler._setup();\n };\n\n // Add support for AMD (Asynchronous Module Definition) libraries such as require.js.\n if (typeof define === 'function' && define.amd) {\n define([], function () {\n return {\n Howler: Howler,\n Howl: Howl\n };\n });\n }\n\n // Add support for CommonJS libraries such as browserify.\n if (typeof exports !== 'undefined') {\n exports.Howler = Howler;\n exports.Howl = Howl;\n }\n\n // Add to global in Node.js (for testing, etc).\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/*!\n * Spatial Plugin - Adds support for stereo and 3D audio where Web Audio is supported.\n * \n * howler.js v2.2.3\n * howlerjs.com\n *\n * (c) 2013-2020, James Simpson of GoldFire Studios\n * goldfirestudios.com\n *\n * MIT License\n */\n\n(function () {\n 'use strict';\n\n // Setup default properties.\n HowlerGlobal.prototype._pos = [0, 0, 0];\n HowlerGlobal.prototype._orientation = [0, 0, -1, 0, 1, 0];\n\n /** Global Methods **/\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 HowlerGlobal.prototype.stereo = function (pan) {\n var self = this;\n\n // Stop right here if not using Web Audio.\n if (!self.ctx || !self.ctx.listener) {\n return self;\n }\n\n // Loop through all Howls and update their stereo panning.\n for (var i = self._howls.length - 1; i >= 0; i--) {\n self._howls[i].stereo(pan);\n }\n return self;\n };\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 HowlerGlobal.prototype.pos = function (x, y, z) {\n var self = this;\n\n // Stop right here if not using Web Audio.\n if (!self.ctx || !self.ctx.listener) {\n return self;\n }\n\n // Set the defaults for optional 'y' & 'z'.\n y = typeof y !== 'number' ? self._pos[1] : y;\n z = typeof z !== 'number' ? self._pos[2] : z;\n if (typeof x === 'number') {\n self._pos = [x, y, z];\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 return self;\n };\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 HowlerGlobal.prototype.orientation = function (x, y, z, xUp, yUp, zUp) {\n var self = this;\n\n // Stop right here if not using Web Audio.\n if (!self.ctx || !self.ctx.listener) {\n return self;\n }\n\n // Set the defaults for optional 'y' & 'z'.\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 if (typeof x === 'number') {\n self._orientation = [x, y, z, xUp, yUp, zUp];\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 return self;\n };\n\n /** Group Methods **/\n /***************************************************************************/\n\n /**\n * Add new properties to the core init.\n * @param {Function} _super Core init method.\n * @return {Howl}\n */\n Howl.prototype.init = function (_super) {\n return function (o) {\n var self = this;\n\n // Setup user-defined default properties.\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 };\n\n // Setup event listeners.\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 }] : [];\n\n // Complete initilization with howler.js core's init function.\n return _super.call(this, o);\n };\n }(Howl.prototype.init);\n\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 Howl.prototype.stereo = function (pan, id) {\n var self = this;\n\n // Stop right here if not using Web Audio.\n if (!self._webAudio) {\n return self;\n }\n\n // If the sound hasn't loaded, add it to the load queue to change stereo pan when capable.\n if (self._state !== 'loaded') {\n self._queue.push({\n event: 'stereo',\n action: function () {\n self.stereo(pan, id);\n }\n });\n return self;\n }\n\n // Check for PannerStereoNode support and fallback to PannerNode if it doesn't exist.\n var pannerType = typeof Howler.ctx.createStereoPanner === 'undefined' ? 'spatial' : 'stereo';\n\n // Setup the group's stereo panning if no ID is passed.\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 }\n\n // Change the streo panning of one or all sounds in group.\n var ids = self._getSoundIds(id);\n for (var i = 0; i < ids.length; i++) {\n // Get the sound.\n var sound = self._soundById(ids[i]);\n if (sound) {\n if (typeof pan === 'number') {\n sound._stereo = pan;\n sound._pos = [pan, 0, 0];\n if (sound._node) {\n // If we are falling back, make sure the panningModel is equalpower.\n sound._pannerAttr.panningModel = 'equalpower';\n\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, pannerType);\n }\n if (pannerType === 'spatial') {\n if (typeof sound._panner.positionX !== 'undefined') {\n sound._panner.positionX.setValueAtTime(pan, Howler.ctx.currentTime);\n sound._panner.positionY.setValueAtTime(0, Howler.ctx.currentTime);\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 self._emit('stereo', sound._id);\n } else {\n return sound._stereo;\n }\n }\n }\n return self;\n };\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 Howl.prototype.pos = function (x, y, z, id) {\n var self = this;\n\n // Stop right here if not using Web Audio.\n if (!self._webAudio) {\n return self;\n }\n\n // If the sound hasn't loaded, add it to the load queue to change position when capable.\n if (self._state !== 'loaded') {\n self._queue.push({\n event: 'pos',\n action: function () {\n self.pos(x, y, z, id);\n }\n });\n return self;\n }\n\n // Set the defaults for optional 'y' & 'z'.\n y = typeof y !== 'number' ? 0 : y;\n z = typeof z !== 'number' ? -0.5 : z;\n\n // Setup the group's spatial position if no ID is passed.\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 }\n\n // Change the spatial position of one or all sounds in group.\n var ids = self._getSoundIds(id);\n for (var i = 0; i < ids.length; i++) {\n // Get the sound.\n var sound = self._soundById(ids[i]);\n if (sound) {\n if (typeof x === 'number') {\n sound._pos = [x, y, z];\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 if (typeof sound._panner.positionX !== 'undefined') {\n sound._panner.positionX.setValueAtTime(x, Howler.ctx.currentTime);\n sound._panner.positionY.setValueAtTime(y, Howler.ctx.currentTime);\n sound._panner.positionZ.setValueAtTime(z, Howler.ctx.currentTime);\n } else {\n sound._panner.setPosition(x, y, z);\n }\n }\n self._emit('pos', sound._id);\n } else {\n return sound._pos;\n }\n }\n }\n return self;\n };\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 Howl.prototype.orientation = function (x, y, z, id) {\n var self = this;\n\n // Stop right here if not using Web Audio.\n if (!self._webAudio) {\n return self;\n }\n\n // If the sound hasn't loaded, add it to the load queue to change orientation when capable.\n if (self._state !== 'loaded') {\n self._queue.push({\n event: 'orientation',\n action: function () {\n self.orientation(x, y, z, id);\n }\n });\n return self;\n }\n\n // Set the defaults for optional 'y' & 'z'.\n y = typeof y !== 'number' ? self._orientation[1] : y;\n z = typeof z !== 'number' ? self._orientation[2] : z;\n\n // Setup the group's spatial orientation if no ID is passed.\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 }\n\n // Change the spatial orientation of one or all sounds in group.\n var ids = self._getSoundIds(id);\n for (var i = 0; i < ids.length; i++) {\n // Get the sound.\n var sound = self._soundById(ids[i]);\n if (sound) {\n if (typeof x === 'number') {\n sound._orientation = [x, y, z];\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 setupPanner(sound, 'spatial');\n }\n if (typeof sound._panner.orientationX !== 'undefined') {\n sound._panner.orientationX.setValueAtTime(x, Howler.ctx.currentTime);\n sound._panner.orientationY.setValueAtTime(y, Howler.ctx.currentTime);\n sound._panner.orientationZ.setValueAtTime(z, Howler.ctx.currentTime);\n } else {\n sound._panner.setOrientation(x, y, z);\n }\n }\n self._emit('orientation', sound._id);\n } else {\n return sound._orientation;\n }\n }\n }\n return self;\n };\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 Howl.prototype.pannerAttr = function () {\n var self = this;\n var args = arguments;\n var o, id, sound;\n\n // Stop right here if not using Web Audio.\n if (!self._webAudio) {\n return self;\n }\n\n // Determine the values based on arguments.\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];\n\n // Set the grou's panner attribute values.\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 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 }\n\n // Update the values of the specified sounds.\n var ids = self._getSoundIds(id);\n for (var i = 0; i < ids.length; i++) {\n sound = self._soundById(ids[i]);\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 };\n\n // Update the panner values or create a new panner if none exists.\n var panner = sound._panner;\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 }\n\n // Create a new panner node.\n setupPanner(sound, 'spatial');\n }\n }\n }\n return self;\n };\n\n /** Single Sound Methods **/\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 Sound.prototype.init = function (_super) {\n return function () {\n var self = this;\n var parent = self._parent;\n\n // Setup user-defined default properties.\n self._orientation = parent._orientation;\n self._stereo = parent._stereo;\n self._pos = parent._pos;\n self._pannerAttr = parent._pannerAttr;\n\n // Complete initilization with howler.js core Sound's init function.\n _super.call(this);\n\n // If a stereo or position was specified, set it up.\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 /**\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 Sound.prototype.reset = function (_super) {\n return function () {\n var self = this;\n var parent = self._parent;\n\n // Reset all spatial plugin properties on this sound.\n self._orientation = parent._orientation;\n self._stereo = parent._stereo;\n self._pos = parent._pos;\n self._pannerAttr = parent._pannerAttr;\n\n // If a stereo or position was specified, set it up.\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 self._panner = undefined;\n parent._refreshBuffer(self);\n }\n\n // Complete resetting of the sound.\n return _super.call(this);\n };\n }(Sound.prototype.reset);\n\n /** Helper Methods **/\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 var setupPanner = function (sound, type) {\n type = type || 'spatial';\n\n // Create the new panner node.\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 if (typeof sound._panner.positionX !== 'undefined') {\n sound._panner.positionX.setValueAtTime(sound._pos[0], Howler.ctx.currentTime);\n sound._panner.positionY.setValueAtTime(sound._pos[1], Howler.ctx.currentTime);\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 if (typeof sound._panner.orientationX !== 'undefined') {\n sound._panner.orientationX.setValueAtTime(sound._orientation[0], Howler.ctx.currentTime);\n sound._panner.orientationY.setValueAtTime(sound._orientation[1], Howler.ctx.currentTime);\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 sound._panner.pan.setValueAtTime(sound._stereo, Howler.ctx.currentTime);\n }\n sound._panner.connect(sound._node);\n\n // Update the connections.\n if (!sound._paused) {\n sound._parent.pause(sound._id, true).play(sound._id, true);\n }\n };\n})();","map":{"version":3,"names":["HowlerGlobal","init","prototype","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","test","oncanplaythrough","e","_setupCodecs","audioTest","err","canPlayType","mpegTest","ua","userAgent","checkOpera","match","isOldOpera","parseInt","split","checkSafari","indexOf","safariVersion","isOldSafari","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","catch","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","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","seekAndEmit","emitSeek","realTime","rateSeek","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","checkIE","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","define","amd","exports","global","_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","_super","_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"],"sources":["C:/Users/eudes.inacio/GabineteDigital/gabinete-digital-fo/node_modules/howler/dist/howler.js"],"sourcesContent":["/*!\n * howler.js v2.2.3\n * howlerjs.com\n *\n * (c) 2013-2020, James Simpson of GoldFire Studios\n * goldfirestudios.com\n *\n * MIT License\n */\n\n(function() {\n\n 'use strict';\n\n /** Global Methods **/\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 var HowlerGlobal = function() {\n this.init();\n };\n HowlerGlobal.prototype = {\n /**\n * Initialize the global Howler object.\n * @return {Howler}\n */\n init: function() {\n var self = this || Howler;\n\n // Create a global ID counter.\n self._counter = 1000;\n\n // Pool of unlocked HTML5 Audio objects.\n self._html5AudioPool = [];\n self.html5PoolSize = 10;\n\n // Internal properties.\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;\n\n // Public properties.\n self.masterGain = null;\n self.noAudio = false;\n self.usingWebAudio = true;\n self.autoSuspend = true;\n self.ctx = null;\n\n // Set to false to disable the auto audio unlocker.\n self.autoUnlock = true;\n\n // Setup the various state values for global tracking.\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(vol) {\n var self = this || Howler;\n vol = parseFloat(vol);\n\n // If we don't have an AudioContext created yet, run the setup.\n if (!self.ctx) {\n setupAudioContext();\n }\n\n if (typeof vol !== 'undefined' && vol >= 0 && vol <= 1) {\n self._volume = vol;\n\n // Don't update any of the nodes if we are muted.\n if (self._muted) {\n return self;\n }\n\n // When using Web Audio, we just need to adjust the master gain.\n if (self.usingWebAudio) {\n self.masterGain.gain.setValueAtTime(vol, Howler.ctx.currentTime);\n }\n\n // Loop through and change volume for all HTML5 audio nodes.\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();\n\n // Loop through all sounds and change the volumes.\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(muted) {\n var self = this || Howler;\n\n // If we don't have an AudioContext created yet, run the setup.\n if (!self.ctx) {\n setupAudioContext();\n }\n\n self._muted = muted;\n\n // With Web Audio, we just need to mute the master gain.\n if (self.usingWebAudio) {\n self.masterGain.gain.setValueAtTime(muted ? 0 : self._volume, Howler.ctx.currentTime);\n }\n\n // Loop through and mute all HTML5 Audio nodes.\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();\n\n // Loop through all sounds and mark the audio node as muted.\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() {\n var self = this || Howler;\n\n // Loop through all Howls and stop them.\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() {\n var self = this || Howler;\n\n for (var i=self._howls.length-1; i>=0; i--) {\n self._howls[i].unload();\n }\n\n // Create a new AudioContext to make sure it is fully reset.\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(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() {\n var self = this || Howler;\n\n // Keeps track of the suspend/resume state of the AudioContext.\n self.state = self.ctx ? self.ctx.state || 'suspended' : 'suspended';\n\n // Automatically begin the 30-second suspend process\n self._autoSuspend();\n\n // Check if audio is available.\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();\n\n // Check if the canplaythrough event is available.\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 }\n\n // Test to make sure audio isn't disabled in Internet Explorer.\n try {\n var test = new Audio();\n if (test.muted) {\n self.noAudio = true;\n }\n } catch (e) {}\n\n // Check for supported codecs.\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() {\n var self = this || Howler;\n var audioTest = null;\n\n // Must wrap in a try/catch because IE11 in server mode throws an error.\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$/, '');\n\n // Opera version <33 has mixed MP3 support, so we need to check for and block it.\n var ua = self._navigator ? self._navigator.userAgent : '';\n var checkOpera = ua.match(/OPR\\/([0-6].)/g);\n var isOldOpera = (checkOpera && parseInt(checkOpera[0].split('/')[1], 10) < 33);\n var checkSafari = ua.indexOf('Safari') !== -1 && ua.indexOf('Chrome') === -1;\n var safariVersion = ua.match(/Version\\/(.*?) /);\n var isOldSafari = (checkSafari && safariVersion && parseInt(safariVersion[1], 10) < 15);\n\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: !!(!isOldSafari && audioTest.canPlayType('audio/webm; codecs=\"vorbis\"').replace(/^no$/, '')),\n webm: !!(!isOldSafari && 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\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() {\n var self = this || Howler;\n\n // Only run this if Web Audio is supported and it hasn't already been unlocked.\n if (self._audioUnlocked || !self.ctx) {\n return;\n }\n\n self._audioUnlocked = false;\n self.autoUnlock = false;\n\n // 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 if (!self._mobileUnloaded && self.ctx.sampleRate !== 44100) {\n self._mobileUnloaded = true;\n self.unload();\n }\n\n // Scratch buffer for enabling iOS to dispose of web audio buffers correctly, as per:\n // http://stackoverflow.com/questions/24119684\n self._scratchBuffer = self.ctx.createBuffer(1, 1, 22050);\n\n // 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 var unlock = function(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();\n\n // Mark this Audio object as unlocked to ensure it can get returned\n // to the unlocked pool when released.\n audioNode._unlocked = true;\n\n // Add the audio node to the pool.\n self._releaseHtml5Audio(audioNode);\n } catch (e) {\n self.noAudio = true;\n break;\n }\n }\n\n // Loop through any assigned audio nodes and unlock them.\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();\n\n // Loop through all sounds and unlock the audio nodes.\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 sound._node.load();\n }\n }\n }\n }\n\n // Fix Android can not play in suspend state.\n self._autoResume();\n\n // Create an empty buffer.\n var source = self.ctx.createBufferSource();\n source.buffer = self._scratchBuffer;\n source.connect(self.ctx.destination);\n\n // Play the empty buffer.\n if (typeof source.start === 'undefined') {\n source.noteOn(0);\n } else {\n source.start(0);\n }\n\n // Calling resume() on a stack initiated by user gesture is what actually unlocks the audio on Android Chrome >= 55.\n if (typeof self.ctx.resume === 'function') {\n self.ctx.resume();\n }\n\n // Setup a timeout to check that we are unlocked on the next event loop.\n source.onended = function() {\n source.disconnect(0);\n\n // Update the unlocked state and prevent this check from happening again.\n self._audioUnlocked = true;\n\n // Remove the touch start listener.\n document.removeEventListener('touchstart', unlock, true);\n document.removeEventListener('touchend', unlock, true);\n document.removeEventListener('click', unlock, true);\n document.removeEventListener('keydown', unlock, true);\n\n // Let all sounds know that audio has been unlocked.\n for (var i=0; i<self._howls.length; i++) {\n self._howls[i]._emit('unlock');\n }\n };\n };\n\n // Setup a touch start listener to attempt an unlock in.\n document.addEventListener('touchstart', unlock, true);\n document.addEventListener('touchend', unlock, true);\n document.addEventListener('click', unlock, true);\n document.addEventListener('keydown', unlock, true);\n\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() {\n var self = this || Howler;\n\n // Return the next object from the pool if one exists.\n if (self._html5AudioPool.length) {\n return self._html5AudioPool.pop();\n }\n\n //.Check if the audio is locked and throw a warning.\n var testPlay = new Audio().play();\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(audio) {\n var self = this || Howler;\n\n // Don't add audio to the pool if we don't know if it has been unlocked.\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() {\n var self = this;\n\n if (!self.autoSuspend || !self.ctx || typeof self.ctx.suspend === 'undefined' || !Howler.usingWebAudio) {\n return;\n }\n\n // Check if any sounds are playing.\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 }\n\n // If no sound has played after 30 seconds, suspend the context.\n self._suspendTimer = setTimeout(function() {\n if (!self.autoSuspend) {\n return;\n }\n\n self._suspendTimer = null;\n self.state = 'suspending';\n\n // Handle updating the state of the audio context after suspending.\n var handleSuspension = function() {\n self.state = 'suspended';\n\n if (self._resumeAfterSuspend) {\n delete self._resumeAfterSuspend;\n self._autoResume();\n }\n };\n\n // Either the state gets suspended or it is interrupted.\n // Either way, we need to update the state to suspended.\n self.ctx.suspend().then(handleSuspension, handleSuspension);\n }, 30000);\n\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() {\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';\n\n // Emit to all Howls that the audio has resumed.\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 };\n\n // Setup the global audio controller.\n var Howler = new HowlerGlobal();\n\n /** Group Methods **/\n /***************************************************************************/\n\n /**\n * Create an audio group controller.\n * @param {Object} o Passed in properties for this group.\n */\n var Howl = function(o) {\n var self = this;\n\n // Throw an error if no source is provided.\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 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(o) {\n var self = this;\n\n // If we don't have an AudioContext created yet, run the setup.\n if (!Howler.ctx) {\n setupAudioContext();\n }\n\n // Setup user-defined default properties.\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 };\n\n // Setup all other default properties.\n self._duration = 0;\n self._state = 'unloaded';\n self._sounds = [];\n self._endTimers = {};\n self._queue = [];\n self._playLock = false;\n\n // Setup event listeners.\n self._onend = o.onend ? [{fn: o.onend}] : [];\n self._onfade = o.onfade ? [{fn: o.onfade}] : [];\n self._onload = o.onload ? [{fn: o.onload}] : [];\n self._onloaderror = o.onloaderror ? [{fn: o.onloaderror}] : [];\n self._onplayerror = o.onplayerror ? [{fn: o.onplayerror}] : [];\n self._onpause = o.onpause ? [{fn: o.onpause}] : [];\n self._onplay = o.onplay ? [{fn: o.onplay}] : [];\n self._onstop = o.onstop ? [{fn: o.onstop}] : [];\n self._onmute = o.onmute ? [{fn: o.onmute}] : [];\n self._onvolume = o.onvolume ? [{fn: o.onvolume}] : [];\n self._onrate = o.onrate ? [{fn: o.onrate}] : [];\n self._onseek = o.onseek ? [{fn: o.onseek}] : [];\n self._onunlock = o.onunlock ? [{fn: o.onunlock}] : [];\n self._onresume = [];\n\n // Web Audio or HTML5 Audio?\n self._webAudio = Howler.usingWebAudio && !self._html5;\n\n // Automatically try to enable audio.\n if (typeof Howler.ctx !== 'undefined' && Howler.ctx && Howler.autoUnlock) {\n Howler._unlockAudio();\n }\n\n // Keep track of this Howl group in the global controller.\n Howler._howls.push(self);\n\n // If they selected autoplay, add a play event to the load queue.\n if (self._autoplay) {\n self._queue.push({\n event: 'play',\n action: function() {\n self.play();\n }\n });\n }\n\n // Load the source file unless otherwise specified.\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() {\n var self = this;\n var url = null;\n\n // If no audio is available, quit immediately.\n if (Howler.noAudio) {\n self._emit('loaderror', null, 'No audio support.');\n return;\n }\n\n // Make sure our source is in an array.\n if (typeof self._src === 'string') {\n self._src = [self._src];\n }\n\n // Loop through the sources and pick the first one that is compatible.\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 if (typeof str !== 'string') {\n self._emit('loaderror', null, 'Non-string found in selected audio sources - ignoring.');\n continue;\n }\n\n // Extract the file extension from the URL or base64 data URI.\n ext = /^data:audio\\/([^;,]+);/i.exec(str);\n if (!ext) {\n ext = /\\.([^.]+)$/.exec(str.split('?', 1)[0]);\n }\n\n if (ext) {\n ext = ext[1].toLowerCase();\n }\n }\n\n // Log a warning if no extension was found.\n if (!ext) {\n console.warn('No file extension was found. Consider using the \"format\" property or specify an extension.');\n }\n\n // Check if this extension is available.\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 return;\n }\n\n self._src = url;\n self._state = 'loading';\n\n // If the hosting page is HTTPS and the source isn't,\n // drop down to HTML5 Audio to avoid Mixed Content errors.\n if (window.location.protocol === 'https:' && url.slice(0, 5) === 'http:') {\n self._html5 = true;\n self._webAudio = false;\n }\n\n // Create a new sound object and add it to the pool.\n new Sound(self);\n\n // Load and decode the audio data for playback.\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(sprite, internal) {\n var self = this;\n var id = null;\n\n // Determine if a sprite, sound id or nothing was passed\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';\n\n // 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 if (!self._playLock) {\n var num = 0;\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 }\n\n // Get the selected node, or get one from the pool.\n var sound = id ? self._soundById(id) : self._inactiveSound();\n\n // If the sound doesn't exist, do nothing.\n if (!sound) {\n return null;\n }\n\n // Select the sprite definition.\n if (id && !sprite) {\n sprite = sound._sprite || '__default';\n }\n\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 if (self._state !== 'loaded') {\n // Set the sprite value on this sound.\n sound._sprite = sprite;\n\n // Mark this sound as not ended in case another sound is played before this one loads.\n sound._ended = false;\n\n // Add the sound to the queue to be played on load.\n var soundId = sound._id;\n self._queue.push({\n event: 'play',\n action: function() {\n self.play(soundId);\n }\n });\n\n return soundId;\n }\n\n // Don't play the sound if an id was passed and it is already playing.\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 }\n\n // Make sure the AudioContext isn't suspended, and resume it if it is.\n if (self._webAudio) {\n Howler._autoResume();\n }\n\n // Determine how long to play for and where to start playing.\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;\n\n // 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 sound._ended = false;\n\n // Update the parameters of the sound.\n var setParams = function() {\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 };\n\n // End the sound instantly if seek is at the end.\n if (seek >= stop) {\n self._ended(sound);\n return;\n }\n\n // Begin the actual playback.\n var node = sound._node;\n if (self._webAudio) {\n // Fire this when the sound is ready to play to begin Web Audio playback.\n var playWebAudio = function() {\n self._playLock = false;\n setParams();\n self._refreshBuffer(sound);\n\n // Setup the playback params.\n var vol = (sound._muted || self._muted) ? 0 : sound._volume;\n node.gain.setValueAtTime(vol, Howler.ctx.currentTime);\n sound._playStart = Howler.ctx.currentTime;\n\n // Play the sound using the supported method.\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 }\n\n // Start a new timer if none is present.\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 self._loadQueue();\n }, 0);\n }\n };\n\n if (Howler.state === 'running' && Howler.ctx.state !== 'interrupted') {\n playWebAudio();\n } else {\n self._playLock = true;\n\n // Wait for the audio context to resume before playing.\n self.once('resume', playWebAudio);\n\n // Cancel the end timer.\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() {\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;\n\n // Some browsers will throw an error if this is called without user interaction.\n try {\n var play = node.play();\n\n // Support older browsers that don't support promises, and thus don't have this issue.\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;\n\n // Set param values immediately.\n setParams();\n\n // Releases the lock and executes queued actions.\n play\n .then(function() {\n self._playLock = false;\n node._unlocked = true;\n if (!internal) {\n self._emit('play', sound._id);\n } else {\n self._loadQueue();\n }\n })\n .catch(function() {\n self._playLock = false;\n self._emit('playerror', sound._id, 'Playback was unable to start. This is most commonly an issue ' +\n 'on mobile devices and Chrome where playback was not within a user interaction.');\n\n // Reset the ended and paused values.\n sound._ended = true;\n sound._paused = true;\n });\n } else if (!internal) {\n self._playLock = false;\n setParams();\n self._emit('play', sound._id);\n }\n\n // Setting rate before playing won't work in IE, so we set it again here.\n node.playbackRate = sound._rate;\n\n // If the node is still paused, then we can assume there was a playback issue.\n if (node.paused) {\n self._emit('playerror', sound._id, 'Playback was unable to start. This is most commonly an issue ' +\n 'on mobile devices and Chrome where playback was not within a user interaction.');\n return;\n }\n\n // Setup the end timer on sprites or listen for the ended event.\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);\n\n // Clear this listener.\n node.removeEventListener('ended', self._endTimers[sound._id], false);\n };\n node.addEventListener('ended', self._endTimers[sound._id], false);\n }\n } catch (err) {\n self._emit('playerror', sound._id, err);\n }\n };\n\n // If this is streaming audio, make sure the src is set and load again.\n if (node.src === 'data:audio/wav;base64,UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA') {\n node.src = self._src;\n node.load();\n }\n\n // Play immediately if ready, or wait for the 'canplaythrough'e vent.\n var loadedNoReadyState = (window && window.ejecta) || (!node.readyState && Howler._navigator.isCocoonJS);\n if (node.readyState >= 3 || loadedNoReadyState) {\n playHtml5();\n } else {\n self._playLock = true;\n self._state = 'loading';\n\n var listener = function() {\n self._state = 'loaded';\n \n // Begin playback.\n playHtml5();\n\n // Clear this listener.\n node.removeEventListener(Howler._canPlayEvent, listener, false);\n };\n node.addEventListener(Howler._canPlayEvent, listener, false);\n\n // Cancel the end timer.\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(id) {\n var self = this;\n\n // If the sound hasn't loaded or a play() promise is pending, add it to the load queue to pause when capable.\n if (self._state !== 'loaded' || self._playLock) {\n self._queue.push({\n event: 'pause',\n action: function() {\n self.pause(id);\n }\n });\n\n return self;\n }\n\n // If no id is passed, get all ID's to be paused.\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]);\n\n // Get the sound.\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;\n\n // Stop currently running fades.\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 }\n\n // Clean up the buffer source.\n self._cleanBuffer(sound._node);\n } else if (!isNaN(sound._node.duration) || sound._node.duration === Infinity) {\n sound._node.pause();\n }\n }\n }\n\n // Fire the pause event, unless `true` is passed as the 2nd argument.\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(id, internal) {\n var self = this;\n\n // If the sound hasn't loaded, add it to the load queue to stop when capable.\n if (self._state !== 'loaded' || self._playLock) {\n self._queue.push({\n event: 'stop',\n action: function() {\n self.stop(id);\n }\n });\n\n return self;\n }\n\n // If no id is passed, get all ID's to be stopped.\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]);\n\n // Get the sound.\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;\n\n // Stop currently running fades.\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 }\n\n // Clean up the buffer source.\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 sound._node.pause();\n\n // If this is a live stream, stop download once the audio is stopped.\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(muted, id) {\n var self = this;\n\n // If the sound hasn't loaded, add it to the load queue to mute when capable.\n if (self._state !== 'loaded'|| self._playLock) {\n self._queue.push({\n event: 'mute',\n action: function() {\n self.mute(muted, id);\n }\n });\n\n return self;\n }\n\n // If applying mute/unmute to all sounds, update the group's value.\n if (typeof id === 'undefined') {\n if (typeof muted === 'boolean') {\n self._muted = muted;\n } else {\n return self._muted;\n }\n }\n\n // If no id is passed, get all ID's to be muted.\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;\n\n // Cancel active fade and set the volume to the end value.\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() {\n var self = this;\n var args = arguments;\n var vol, id;\n\n // Determine the values based on arguments.\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 var index = ids.indexOf(args[0]);\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 }\n\n // Update the volume or return the current volume.\n var sound;\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() {\n self.volume.apply(self, args);\n }\n });\n\n return self;\n }\n\n // Set the group volume.\n if (typeof id === 'undefined') {\n self._volume = vol;\n }\n\n // Update one or all volumes.\n id = self._getSoundIds(id);\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;\n\n // Stop currently running fades.\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(from, to, len, id) {\n var self = this;\n\n // If the sound hasn't loaded, add it to the load queue to fade when capable.\n if (self._state !== 'loaded' || self._playLock) {\n self._queue.push({\n event: 'fade',\n action: function() {\n self.fade(from, to, len, id);\n }\n });\n\n return self;\n }\n\n // Make sure the to/from/len values are numbers.\n from = Math.min(Math.max(0, parseFloat(from)), 1);\n to = Math.min(Math.max(0, parseFloat(to)), 1);\n len = parseFloat(len);\n\n // Set the volume to the start position.\n self.volume(from, id);\n\n // Fade the volume of one or all sounds.\n var ids = self._getSoundIds(id);\n for (var i=0; i<ids.length; i++) {\n // Get the sound.\n var sound = self._soundById(ids[i]);\n\n // Create a linear fade or fall back to timeouts with HTML5 Audio.\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 }\n\n // If we are using Web Audio, let the native methods do the actual fade.\n if (self._webAudio && !sound._muted) {\n var currentTime = Howler.ctx.currentTime;\n var end = currentTime + (len / 1000);\n sound._volume = from;\n sound._node.gain.setValueAtTime(from, currentTime);\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(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();\n\n // Store the value being faded to.\n sound._fadeTo = to;\n\n // Update the volume value on each interval tick.\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;\n\n // Round to within 2 decimal points.\n vol = Math.round(vol * 100) / 100;\n\n // Make sure the volume is in the right bounds.\n if (diff < 0) {\n vol = Math.max(to, vol);\n } else {\n vol = Math.min(to, vol);\n }\n\n // Change the volume.\n if (self._webAudio) {\n sound._volume = vol;\n } else {\n self.volume(vol, sound._id, true);\n }\n\n // Set the group's volume.\n if (isGroup) {\n self._volume = vol;\n }\n\n // When the fade is complete, stop it and fire event.\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 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(id) {\n var self = this;\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 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() {\n var self = this;\n var args = arguments;\n var loop, id, sound;\n\n // Determine the values for loop and id.\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 }\n\n // If no id is passed, get all ID's to be looped.\n var ids = self._getSoundIds(id);\n for (var i=0; i<ids.length; i++) {\n sound = self._soundById(ids[i]);\n\n if (sound) {\n sound._loop = loop;\n if (self._webAudio && sound._node && sound._node.bufferSource) {\n sound._node.bufferSource.loop = loop;\n if (loop) {\n sound._node.bufferSource.loopStart = sound._start || 0;\n sound._node.bufferSource.loopEnd = sound._stop;\n\n // If playing, restart playback to ensure looping updates.\n if (self.playing(ids[i])) {\n self.pause(ids[i], true);\n self.play(ids[i], true);\n }\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() {\n var self = this;\n var args = arguments;\n var rate, id;\n\n // Determine the values based on arguments.\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 var index = ids.indexOf(args[0]);\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 }\n\n // Update the playback rate or return the current value.\n var sound;\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() {\n self.rate.apply(self, args);\n }\n });\n\n return self;\n }\n\n // Set the group rate.\n if (typeof id === 'undefined') {\n self._rate = rate;\n }\n\n // Update one or all volumes.\n id = self._getSoundIds(id);\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 sound._rate = rate;\n\n // Change the playback rate.\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 }\n\n // Reset the timers.\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);\n\n // Start a new end timer if sound is already playing.\n if (self._endTimers[id[i]] || !sound._paused) {\n self._clearTimer(id[i]);\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() {\n var self = this;\n var args = arguments;\n var seek, id;\n\n // Determine the values based on arguments.\n if (args.length === 0) {\n // We will simply return the current position of the first node.\n if (self._sounds.length) {\n id = self._sounds[0]._id;\n }\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 var index = ids.indexOf(args[0]);\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 }\n\n // If there is no ID, bail out.\n if (typeof id === 'undefined') {\n return 0;\n }\n\n // If the sound hasn't loaded, add it to the load queue to seek when capable.\n if (typeof seek === 'number' && (self._state !== 'loaded' || self._playLock)) {\n self._queue.push({\n event: 'seek',\n action: function() {\n self.seek.apply(self, args);\n }\n });\n\n return self;\n }\n\n // Get the sound.\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 if (playing) {\n self.pause(id, true);\n }\n\n // Move the position of the track and cancel timer.\n sound._seek = seek;\n sound._ended = false;\n self._clearTimer(id);\n\n // Update the seek position for HTML5 Audio.\n if (!self._webAudio && sound._node && !isNaN(sound._node.duration)) {\n sound._node.currentTime = seek;\n }\n\n // Seek and emit when ready.\n var seekAndEmit = function() {\n // Restart the playback if the sound was playing.\n if (playing) {\n self.play(id, true);\n }\n\n self._emit('seek', id);\n };\n\n // Wait for the play lock to be unset before emitting (HTML5 Audio).\n if (playing && !self._webAudio) {\n var emitSeek = function() {\n if (!self._playLock) {\n seekAndEmit();\n } else {\n setTimeout(emitSeek, 0);\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(id) {\n var self = this;\n\n // Check the passed sound ID (if any).\n if (typeof id === 'number') {\n var sound = self._soundById(id);\n return sound ? !sound._paused : false;\n }\n\n // Otherwise, loop through all sounds and check if any are playing.\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(id) {\n var self = this;\n var duration = self._duration;\n\n // If we pass an ID, get the sound and return the sprite length.\n var sound = self._soundById(id);\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() {\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() {\n var self = this;\n\n // Stop playing any active sounds.\n var sounds = self._sounds;\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 }\n\n // Remove the source or disconnect.\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);\n\n // Remove any event listeners.\n sounds[i]._node.removeEventListener('error', sounds[i]._errorFn, false);\n sounds[i]._node.removeEventListener(Howler._canPlayEvent, sounds[i]._loadFn, false);\n sounds[i]._node.removeEventListener('ended', sounds[i]._endFn, false);\n\n // Release the Audio object back to the pool.\n Howler._releaseHtml5Audio(sounds[i]._node);\n }\n\n // Empty out all of the nodes.\n delete sounds[i]._node;\n\n // Make sure all timers are cleared out.\n self._clearTimer(sounds[i]._id);\n }\n\n // Remove the references in the global Howler object.\n var index = Howler._howls.indexOf(self);\n if (index >= 0) {\n Howler._howls.splice(index, 1);\n }\n\n // Delete this sound from the cache (if no other Howl is using it).\n var remCache = true;\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 }\n\n // Clear global errors.\n Howler.noAudio = false;\n\n // Clear out `self`.\n self._state = 'unloaded';\n self._sounds = [];\n self = null;\n\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(event, fn, id, once) {\n var self = this;\n var events = self['_on' + event];\n\n if (typeof fn === 'function') {\n events.push(once ? {id: id, fn: fn, once: once} : {id: id, fn: fn});\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(event, fn, id) {\n var self = this;\n var events = self['_on' + event];\n var i = 0;\n\n // Allow passing just an event and ID.\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 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 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(event, fn, id) {\n var self = this;\n\n // Setup the event listener.\n self.on(event, fn, id, 1);\n\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(event, id, msg) {\n var self = this;\n var events = self['_on' + event];\n\n // Loop through event store and fire all functions.\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);\n\n // If this event was setup with `once`, remove it.\n if (events[i].once) {\n self.off(event, events[i].fn, events[i].id);\n }\n }\n }\n\n // Pass the event type into load queue so that it can continue stepping.\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(event) {\n var self = this;\n\n if (self._queue.length > 0) {\n var task = self._queue[0];\n\n // Remove this task if a matching event was passed.\n if (task.event === event) {\n self._queue.shift();\n self._loadQueue();\n }\n\n // Run the task if no event type is passed.\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(sound) {\n var self = this;\n var sprite = sound._sprite;\n\n // 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 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 }\n\n // Should this sound loop?\n var loop = !!(sound._loop || self._sprite[sprite][2]);\n\n // Fire the ended event.\n self._emit('end', sound._id);\n\n // Restart the playback for HTML5 Audio loop.\n if (!self._webAudio && loop) {\n self.stop(sound._id, true).play(sound._id);\n }\n\n // Restart this timer if on a Web Audio loop.\n if (self._webAudio && loop) {\n self._emit('play', sound._id);\n sound._seek = sound._start || 0;\n sound._rateSeek = 0;\n sound._playStart = Howler.ctx.currentTime;\n\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 }\n\n // Mark the node as paused.\n if (self._webAudio && !loop) {\n sound._paused = true;\n sound._ended = true;\n sound._seek = sound._start || 0;\n sound._rateSeek = 0;\n self._clearTimer(sound._id);\n\n // Clean up the buffer source.\n self._cleanBuffer(sound._node);\n\n // Attempt to auto-suspend AudioContext if no sounds are still playing.\n Howler._autoSuspend();\n }\n\n // When using a sprite, end the track.\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(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 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(id) {\n var self = this;\n\n // Loop through all sounds and find the one with this ID.\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() {\n var self = this;\n\n self._drain();\n\n // Find the first inactive node to recycle.\n for (var i=0; i<self._sounds.length; i++) {\n if (self._sounds[i]._ended) {\n return self._sounds[i].reset();\n }\n }\n\n // If no inactive node was found, create a new one.\n return new Sound(self);\n },\n\n /**\n * Drain excess inactive sounds from the pool.\n */\n _drain: function() {\n var self = this;\n var limit = self._pool;\n var cnt = 0;\n var i = 0;\n\n // If there are less sounds than the max pool size, we are done.\n if (self._sounds.length < limit) {\n return;\n }\n\n // Count the number of inactive sounds.\n for (i=0; i<self._sounds.length; i++) {\n if (self._sounds[i]._ended) {\n cnt++;\n }\n }\n\n // Remove excess inactive sounds, going in reverse order.\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 }\n\n // Remove sounds until we have the pool size.\n self._sounds.splice(i, 1);\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(id) {\n var self = this;\n\n if (typeof id === 'undefined') {\n var ids = [];\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(sound) {\n var self = this;\n\n // Setup the buffer source for playback.\n sound._node.bufferSource = Howler.ctx.createBufferSource();\n sound._node.bufferSource.buffer = cache[self._src];\n\n // Connect to the correct node.\n if (sound._panner) {\n sound._node.bufferSource.connect(sound._panner);\n } else {\n sound._node.bufferSource.connect(sound._node);\n }\n\n // Setup looping and playback rate.\n sound._node.bufferSource.loop = sound._loop;\n if (sound._loop) {\n sound._node.bufferSource.loopStart = sound._start || 0;\n sound._node.bufferSource.loopEnd = sound._stop || 0;\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(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 if (isIOS) {\n try { node.bufferSource.buffer = Howler._scratchBuffer; } catch(e) {}\n }\n }\n node.bufferSource = null;\n\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(node) {\n var checkIE = /MSIE |Trident\\//.test(Howler._navigator && Howler._navigator.userAgent);\n if (!checkIE) {\n node.src = 'data:audio/wav;base64,UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA';\n }\n }\n };\n\n /** Single Sound Methods **/\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 var Sound = function(howl) {\n this._parent = howl;\n this.init();\n };\n Sound.prototype = {\n /**\n * Initialize a new Sound object.\n * @return {Sound}\n */\n init: function() {\n var self = this;\n var parent = self._parent;\n\n // Setup the default parameters.\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';\n\n // Generate a unique ID for this sound.\n self._id = ++Howler._counter;\n\n // Add itself to the parent's pool.\n parent._sounds.push(self);\n\n // Create the new node.\n self.create();\n\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() {\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 self._node.gain.setValueAtTime(volume, Howler.ctx.currentTime);\n self._node.paused = true;\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();\n\n // Listen for errors (http://dev.w3.org/html5/spec-author-view/spec.html#mediaerror).\n self._errorFn = self._errorListener.bind(self);\n self._node.addEventListener('error', self._errorFn, false);\n\n // Listen for 'canplaythrough' event to let us know the sound is ready.\n self._loadFn = self._loadListener.bind(self);\n self._node.addEventListener(Howler._canPlayEvent, self._loadFn, false);\n\n // Listen for the 'ended' event on the sound to account for edge-case where\n // a finite sound has a duration of Infinity.\n self._endFn = self._endListener.bind(self);\n self._node.addEventListener('ended', self._endFn, false);\n\n // Setup the new audio node.\n self._node.src = parent._src;\n self._node.preload = parent._preload === true ? 'auto' : parent._preload;\n self._node.volume = volume * Howler.volume();\n\n // Begin loading the source.\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() {\n var self = this;\n var parent = self._parent;\n\n // Reset all of the parameters of this sound.\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';\n\n // Generate a new ID so that it isn't confused with the previous sound.\n self._id = ++Howler._counter;\n\n return self;\n },\n\n /**\n * HTML5 Audio error listener callback.\n */\n _errorListener: function() {\n var self = this;\n\n // Fire an error event and pass back the code.\n self._parent._emit('loaderror', self._id, self._node.error ? self._node.error.code : 0);\n\n // Clear the event listener.\n self._node.removeEventListener('error', self._errorFn, false);\n },\n\n /**\n * HTML5 Audio canplaythrough listener callback.\n */\n _loadListener: function() {\n var self = this;\n var parent = self._parent;\n\n // Round up the duration to account for the lower precision in HTML5 Audio.\n parent._duration = Math.ceil(self._node.duration * 10) / 10;\n\n // Setup a sprite if none is defined.\n if (Object.keys(parent._sprite).length === 0) {\n parent._sprite = {__default: [0, parent._duration * 1000]};\n }\n\n if (parent._state !== 'loaded') {\n parent._state = 'loaded';\n parent._emit('load');\n parent._loadQueue();\n }\n\n // Clear the event listener.\n self._node.removeEventListener(Howler._canPlayEvent, self._loadFn, false);\n },\n\n /**\n * HTML5 Audio ended listener callback.\n */\n _endListener: function() {\n var self = this;\n var parent = self._parent;\n\n // Only handle the `ended`` event if the duration is Infinity.\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;\n\n // Update the sprite that corresponds to the real duration.\n if (parent._sprite.__default[1] === Infinity) {\n parent._sprite.__default[1] = parent._duration * 1000;\n }\n\n // Run the regular ended method.\n parent._ended(self);\n }\n\n // Clear the event listener since the duration is now correct.\n self._node.removeEventListener('ended', self._endFn, false);\n }\n };\n\n /** Helper Methods **/\n /***************************************************************************/\n\n var cache = {};\n\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 var loadBuffer = function(self) {\n var url = self._src;\n\n // Check if the buffer has already been cached and use it instead.\n if (cache[url]) {\n // Set the duration from the cache.\n self._duration = cache[url].duration;\n\n // Load the sound into this Howl.\n loadSound(self);\n\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 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';\n\n // Apply any custom headers to the request.\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 if (code !== '0' && code !== '2' && code !== '3') {\n self._emit('loaderror', null, 'Failed loading audio file with status: ' + xhr.status + '.');\n return;\n }\n\n decodeAudioData(xhr.response, self);\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 safeXhrSend(xhr);\n }\n };\n\n /**\n * Send the XHR request wrapped in a try/catch.\n * @param {Object} xhr XHR to send.\n */\n var safeXhrSend = function(xhr) {\n try {\n xhr.send();\n } catch (e) {\n xhr.onerror();\n }\n };\n\n /**\n * Decode audio data from an array buffer.\n * @param {ArrayBuffer} arraybuffer The audio data.\n * @param {Howl} self\n */\n var decodeAudioData = function(arraybuffer, self) {\n // Fire a load error if something broke.\n var error = function() {\n self._emit('loaderror', null, 'Decoding audio data failed.');\n };\n\n // Load the sound on success.\n var success = function(buffer) {\n if (buffer && self._sounds.length > 0) {\n cache[self._src] = buffer;\n loadSound(self, buffer);\n } else {\n error();\n }\n };\n\n // Decode the buffer into an audio source.\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 /**\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 var loadSound = function(self, buffer) {\n // Set the duration.\n if (buffer && !self._duration) {\n self._duration = buffer.duration;\n }\n\n // Setup a sprite if none is defined.\n if (Object.keys(self._sprite).length === 0) {\n self._sprite = {__default: [0, self._duration * 1000]};\n }\n\n // Fire the loaded event.\n if (self._state !== 'loaded') {\n self._state = 'loaded';\n self._emit('load');\n self._loadQueue();\n }\n };\n\n /**\n * Setup the audio context when available, or switch to HTML5 Audio mode.\n */\n var setupAudioContext = function() {\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 }\n\n // Check if we are using Web Audio and setup the AudioContext if we are.\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 }\n\n // If the audio context creation still failed, set using web audio to false.\n if (!Howler.ctx) {\n Howler.usingWebAudio = false;\n }\n\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 var iOS = (/iP(hone|od|ad)/.test(Howler._navigator && Howler._navigator.platform));\n var appVersion = Howler._navigator && Howler._navigator.appVersion.match(/OS (\\d+)_(\\d+)_?(\\d+)?/);\n var version = appVersion ? parseInt(appVersion[1], 10) : null;\n if (iOS && version && version < 9) {\n var safari = /safari/.test(Howler._navigator && Howler._navigator.userAgent.toLowerCase());\n if (Howler._navigator && !safari) {\n Howler.usingWebAudio = false;\n }\n }\n\n // Create and expose the master GainNode when using Web Audio (useful for plugins or advanced usage).\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 }\n\n // Re-run the setup on Howler.\n Howler._setup();\n };\n\n // Add support for AMD (Asynchronous Module Definition) libraries such as require.js.\n if (typeof define === 'function' && define.amd) {\n define([], function() {\n return {\n Howler: Howler,\n Howl: Howl\n };\n });\n }\n\n // Add support for CommonJS libraries such as browserify.\n if (typeof exports !== 'undefined') {\n exports.Howler = Howler;\n exports.Howl = Howl;\n }\n\n // Add to global in Node.js (for testing, etc).\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') { // 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\n/*!\n * Spatial Plugin - Adds support for stereo and 3D audio where Web Audio is supported.\n * \n * howler.js v2.2.3\n * howlerjs.com\n *\n * (c) 2013-2020, James Simpson of GoldFire Studios\n * goldfirestudios.com\n *\n * MIT License\n */\n\n(function() {\n\n 'use strict';\n\n // Setup default properties.\n HowlerGlobal.prototype._pos = [0, 0, 0];\n HowlerGlobal.prototype._orientation = [0, 0, -1, 0, 1, 0];\n\n /** Global Methods **/\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 HowlerGlobal.prototype.stereo = function(pan) {\n var self = this;\n\n // Stop right here if not using Web Audio.\n if (!self.ctx || !self.ctx.listener) {\n return self;\n }\n\n // Loop through all Howls and update their stereo panning.\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 /**\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 HowlerGlobal.prototype.pos = function(x, y, z) {\n var self = this;\n\n // Stop right here if not using Web Audio.\n if (!self.ctx || !self.ctx.listener) {\n return self;\n }\n\n // Set the defaults for optional 'y' & 'z'.\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 /**\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 HowlerGlobal.prototype.orientation = function(x, y, z, xUp, yUp, zUp) {\n var self = this;\n\n // Stop right here if not using Web Audio.\n if (!self.ctx || !self.ctx.listener) {\n return self;\n }\n\n // Set the defaults for optional 'y' & 'z'.\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\n /** Group Methods **/\n /***************************************************************************/\n\n /**\n * Add new properties to the core init.\n * @param {Function} _super Core init method.\n * @return {Howl}\n */\n Howl.prototype.init = (function(_super) {\n return function(o) {\n var self = this;\n\n // Setup user-defined default properties.\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 };\n\n // Setup event listeners.\n self._onstereo = o.onstereo ? [{fn: o.onstereo}] : [];\n self._onpos = o.onpos ? [{fn: o.onpos}] : [];\n self._onorientation = o.onorientation ? [{fn: o.onorientation}] : [];\n\n // Complete initilization with howler.js core's init function.\n return _super.call(this, o);\n };\n })(Howl.prototype.init);\n\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 Howl.prototype.stereo = function(pan, id) {\n var self = this;\n\n // Stop right here if not using Web Audio.\n if (!self._webAudio) {\n return self;\n }\n\n // If the sound hasn't loaded, add it to the load queue to change stereo pan when capable.\n if (self._state !== 'loaded') {\n self._queue.push({\n event: 'stereo',\n action: function() {\n self.stereo(pan, id);\n }\n });\n\n return self;\n }\n\n // Check for PannerStereoNode support and fallback to PannerNode if it doesn't exist.\n var pannerType = (typeof Howler.ctx.createStereoPanner === 'undefined') ? 'spatial' : 'stereo';\n\n // Setup the group's stereo panning if no ID is passed.\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 }\n\n // Change the streo panning of one or all sounds in group.\n var ids = self._getSoundIds(id);\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';\n\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, pannerType);\n }\n\n if (pannerType === 'spatial') {\n if (typeof sound._panner.positionX !== 'undefined') {\n sound._panner.positionX.setValueAtTime(pan, Howler.ctx.currentTime);\n sound._panner.positionY.setValueAtTime(0, Howler.ctx.currentTime);\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 /**\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 Howl.prototype.pos = function(x, y, z, id) {\n var self = this;\n\n // Stop right here if not using Web Audio.\n if (!self._webAudio) {\n return self;\n }\n\n // If the sound hasn't loaded, add it to the load queue to change position when capable.\n if (self._state !== 'loaded') {\n self._queue.push({\n event: 'pos',\n action: function() {\n self.pos(x, y, z, id);\n }\n });\n\n return self;\n }\n\n // Set the defaults for optional 'y' & 'z'.\n y = (typeof y !== 'number') ? 0 : y;\n z = (typeof z !== 'number') ? -0.5 : z;\n\n // Setup the group's spatial position if no ID is passed.\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 }\n\n // Change the spatial position of one or all sounds in group.\n var ids = self._getSoundIds(id);\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 sound._panner.positionY.setValueAtTime(y, Howler.ctx.currentTime);\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 /**\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 Howl.prototype.orientation = function(x, y, z, id) {\n var self = this;\n\n // Stop right here if not using Web Audio.\n if (!self._webAudio) {\n return self;\n }\n\n // If the sound hasn't loaded, add it to the load queue to change orientation when capable.\n if (self._state !== 'loaded') {\n self._queue.push({\n event: 'orientation',\n action: function() {\n self.orientation(x, y, z, id);\n }\n });\n\n return self;\n }\n\n // Set the defaults for optional 'y' & 'z'.\n y = (typeof y !== 'number') ? self._orientation[1] : y;\n z = (typeof z !== 'number') ? self._orientation[2] : z;\n\n // Setup the group's spatial orientation if no ID is passed.\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 }\n\n // Change the spatial orientation of one or all sounds in group.\n var ids = self._getSoundIds(id);\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 sound._panner.orientationY.setValueAtTime(y, Howler.ctx.currentTime);\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 /**\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 Howl.prototype.pannerAttr = function() {\n var self = this;\n var args = arguments;\n var o, id, sound;\n\n // Stop right here if not using Web Audio.\n if (!self._webAudio) {\n return self;\n }\n\n // Determine the values based on arguments.\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];\n\n // Set the grou's panner attribute values.\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 }\n\n // Update the values of the specified sounds.\n var ids = self._getSoundIds(id);\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 };\n\n // Update the panner values or create a new panner if none exists.\n var panner = sound._panner;\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 }\n\n // Create a new panner node.\n setupPanner(sound, 'spatial');\n }\n }\n }\n\n return self;\n };\n\n /** Single Sound Methods **/\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 Sound.prototype.init = (function(_super) {\n return function() {\n var self = this;\n var parent = self._parent;\n\n // Setup user-defined default properties.\n self._orientation = parent._orientation;\n self._stereo = parent._stereo;\n self._pos = parent._pos;\n self._pannerAttr = parent._pannerAttr;\n\n // Complete initilization with howler.js core Sound's init function.\n _super.call(this);\n\n // If a stereo or position was specified, set it up.\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 /**\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 Sound.prototype.reset = (function(_super) {\n return function() {\n var self = this;\n var parent = self._parent;\n\n // Reset all spatial plugin properties on this sound.\n self._orientation = parent._orientation;\n self._stereo = parent._stereo;\n self._pos = parent._pos;\n self._pannerAttr = parent._pannerAttr;\n\n // If a stereo or position was specified, set it up.\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 self._panner = undefined;\n parent._refreshBuffer(self);\n }\n\n // Complete resetting of the sound.\n return _super.call(this);\n };\n })(Sound.prototype.reset);\n\n /** Helper Methods **/\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 var setupPanner = function(sound, type) {\n type = type || 'spatial';\n\n // Create the new panner node.\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 sound._panner.positionY.setValueAtTime(sound._pos[1], Howler.ctx.currentTime);\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 sound._panner.orientationY.setValueAtTime(sound._orientation[1], Howler.ctx.currentTime);\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 sound._panner.pan.setValueAtTime(sound._stereo, Howler.ctx.currentTime);\n }\n\n sound._panner.connect(sound._node);\n\n // Update the connections.\n if (!sound._paused) {\n sound._parent.pause(sound._id, true).play(sound._id, true);\n }\n };\n})();\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,CAAC,YAAW;EAEV,YAAY;;EAEZ;EACA;;EAEA;AACF;AACA;AACA;EACE,IAAIA,YAAY,GAAG,SAAAA,CAAA,EAAW;IAC5B,IAAI,CAACC,IAAI,CAAC,CAAC;EACb,CAAC;EACDD,YAAY,CAACE,SAAS,GAAG;IACvB;AACJ;AACA;AACA;IACID,IAAI,EAAE,SAAAA,CAAA,EAAW;MACf,IAAIE,IAAI,GAAG,IAAI,IAAIC,MAAM;;MAEzB;MACAD,IAAI,CAACE,QAAQ,GAAG,IAAI;;MAEpB;MACAF,IAAI,CAACG,eAAe,GAAG,EAAE;MACzBH,IAAI,CAACI,aAAa,GAAG,EAAE;;MAEvB;MACAJ,IAAI,CAACK,OAAO,GAAG,CAAC,CAAC;MACjBL,IAAI,CAACM,MAAM,GAAG,EAAE;MAChBN,IAAI,CAACO,MAAM,GAAG,KAAK;MACnBP,IAAI,CAACQ,OAAO,GAAG,CAAC;MAChBR,IAAI,CAACS,aAAa,GAAG,gBAAgB;MACrCT,IAAI,CAACU,UAAU,GAAI,OAAOC,MAAM,KAAK,WAAW,IAAIA,MAAM,CAACC,SAAS,GAAID,MAAM,CAACC,SAAS,GAAG,IAAI;;MAE/F;MACAZ,IAAI,CAACa,UAAU,GAAG,IAAI;MACtBb,IAAI,CAACc,OAAO,GAAG,KAAK;MACpBd,IAAI,CAACe,aAAa,GAAG,IAAI;MACzBf,IAAI,CAACgB,WAAW,GAAG,IAAI;MACvBhB,IAAI,CAACiB,GAAG,GAAG,IAAI;;MAEf;MACAjB,IAAI,CAACkB,UAAU,GAAG,IAAI;;MAEtB;MACAlB,IAAI,CAACmB,MAAM,CAAC,CAAC;MAEb,OAAOnB,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;IACIoB,MAAM,EAAE,SAAAA,CAASC,GAAG,EAAE;MACpB,IAAIrB,IAAI,GAAG,IAAI,IAAIC,MAAM;MACzBoB,GAAG,GAAGC,UAAU,CAACD,GAAG,CAAC;;MAErB;MACA,IAAI,CAACrB,IAAI,CAACiB,GAAG,EAAE;QACbM,iBAAiB,CAAC,CAAC;MACrB;MAEA,IAAI,OAAOF,GAAG,KAAK,WAAW,IAAIA,GAAG,IAAI,CAAC,IAAIA,GAAG,IAAI,CAAC,EAAE;QACtDrB,IAAI,CAACQ,OAAO,GAAGa,GAAG;;QAElB;QACA,IAAIrB,IAAI,CAACO,MAAM,EAAE;UACf,OAAOP,IAAI;QACb;;QAEA;QACA,IAAIA,IAAI,CAACe,aAAa,EAAE;UACtBf,IAAI,CAACa,UAAU,CAACW,IAAI,CAACC,cAAc,CAACJ,GAAG,EAAEpB,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;QAClE;;QAEA;QACA,KAAK,IAAIC,CAAC,GAAC,CAAC,EAAEA,CAAC,GAAC3B,IAAI,CAACM,MAAM,CAACsB,MAAM,EAAED,CAAC,EAAE,EAAE;UACvC,IAAI,CAAC3B,IAAI,CAACM,MAAM,CAACqB,CAAC,CAAC,CAACE,SAAS,EAAE;YAC7B;YACA,IAAIC,GAAG,GAAG9B,IAAI,CAACM,MAAM,CAACqB,CAAC,CAAC,CAACI,YAAY,CAAC,CAAC;;YAEvC;YACA,KAAK,IAAIC,CAAC,GAAC,CAAC,EAAEA,CAAC,GAACF,GAAG,CAACF,MAAM,EAAEI,CAAC,EAAE,EAAE;cAC/B,IAAIC,KAAK,GAAGjC,IAAI,CAACM,MAAM,CAACqB,CAAC,CAAC,CAACO,UAAU,CAACJ,GAAG,CAACE,CAAC,CAAC,CAAC;cAE7C,IAAIC,KAAK,IAAIA,KAAK,CAACE,KAAK,EAAE;gBACxBF,KAAK,CAACE,KAAK,CAACf,MAAM,GAAGa,KAAK,CAACzB,OAAO,GAAGa,GAAG;cAC1C;YACF;UACF;QACF;QAEA,OAAOrB,IAAI;MACb;MAEA,OAAOA,IAAI,CAACQ,OAAO;IACrB,CAAC;IAED;AACJ;AACA;AACA;IACI4B,IAAI,EAAE,SAAAA,CAASC,KAAK,EAAE;MACpB,IAAIrC,IAAI,GAAG,IAAI,IAAIC,MAAM;;MAEzB;MACA,IAAI,CAACD,IAAI,CAACiB,GAAG,EAAE;QACbM,iBAAiB,CAAC,CAAC;MACrB;MAEAvB,IAAI,CAACO,MAAM,GAAG8B,KAAK;;MAEnB;MACA,IAAIrC,IAAI,CAACe,aAAa,EAAE;QACtBf,IAAI,CAACa,UAAU,CAACW,IAAI,CAACC,cAAc,CAACY,KAAK,GAAG,CAAC,GAAGrC,IAAI,CAACQ,OAAO,EAAEP,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;MACvF;;MAEA;MACA,KAAK,IAAIC,CAAC,GAAC,CAAC,EAAEA,CAAC,GAAC3B,IAAI,CAACM,MAAM,CAACsB,MAAM,EAAED,CAAC,EAAE,EAAE;QACvC,IAAI,CAAC3B,IAAI,CAACM,MAAM,CAACqB,CAAC,CAAC,CAACE,SAAS,EAAE;UAC7B;UACA,IAAIC,GAAG,GAAG9B,IAAI,CAACM,MAAM,CAACqB,CAAC,CAAC,CAACI,YAAY,CAAC,CAAC;;UAEvC;UACA,KAAK,IAAIC,CAAC,GAAC,CAAC,EAAEA,CAAC,GAACF,GAAG,CAACF,MAAM,EAAEI,CAAC,EAAE,EAAE;YAC/B,IAAIC,KAAK,GAAGjC,IAAI,CAACM,MAAM,CAACqB,CAAC,CAAC,CAACO,UAAU,CAACJ,GAAG,CAACE,CAAC,CAAC,CAAC;YAE7C,IAAIC,KAAK,IAAIA,KAAK,CAACE,KAAK,EAAE;cACxBF,KAAK,CAACE,KAAK,CAACE,KAAK,GAAIA,KAAK,GAAI,IAAI,GAAGJ,KAAK,CAAC1B,MAAM;YACnD;UACF;QACF;MACF;MAEA,OAAOP,IAAI;IACb,CAAC;IAED;AACJ;AACA;IACIsC,IAAI,EAAE,SAAAA,CAAA,EAAW;MACf,IAAItC,IAAI,GAAG,IAAI,IAAIC,MAAM;;MAEzB;MACA,KAAK,IAAI0B,CAAC,GAAC,CAAC,EAAEA,CAAC,GAAC3B,IAAI,CAACM,MAAM,CAACsB,MAAM,EAAED,CAAC,EAAE,EAAE;QACvC3B,IAAI,CAACM,MAAM,CAACqB,CAAC,CAAC,CAACW,IAAI,CAAC,CAAC;MACvB;MAEA,OAAOtC,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;IACIuC,MAAM,EAAE,SAAAA,CAAA,EAAW;MACjB,IAAIvC,IAAI,GAAG,IAAI,IAAIC,MAAM;MAEzB,KAAK,IAAI0B,CAAC,GAAC3B,IAAI,CAACM,MAAM,CAACsB,MAAM,GAAC,CAAC,EAAED,CAAC,IAAE,CAAC,EAAEA,CAAC,EAAE,EAAE;QAC1C3B,IAAI,CAACM,MAAM,CAACqB,CAAC,CAAC,CAACY,MAAM,CAAC,CAAC;MACzB;;MAEA;MACA,IAAIvC,IAAI,CAACe,aAAa,IAAIf,IAAI,CAACiB,GAAG,IAAI,OAAOjB,IAAI,CAACiB,GAAG,CAACuB,KAAK,KAAK,WAAW,EAAE;QAC3ExC,IAAI,CAACiB,GAAG,CAACuB,KAAK,CAAC,CAAC;QAChBxC,IAAI,CAACiB,GAAG,GAAG,IAAI;QACfM,iBAAiB,CAAC,CAAC;MACrB;MAEA,OAAOvB,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;IACIyC,MAAM,EAAE,SAAAA,CAASC,GAAG,EAAE;MACpB,OAAO,CAAC,IAAI,IAAIzC,MAAM,EAAEI,OAAO,CAACqC,GAAG,CAACC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACzD,CAAC;IAED;AACJ;AACA;AACA;IACIxB,MAAM,EAAE,SAAAA,CAAA,EAAW;MACjB,IAAInB,IAAI,GAAG,IAAI,IAAIC,MAAM;;MAEzB;MACAD,IAAI,CAAC4C,KAAK,GAAG5C,IAAI,CAACiB,GAAG,GAAGjB,IAAI,CAACiB,GAAG,CAAC2B,KAAK,IAAI,WAAW,GAAG,WAAW;;MAEnE;MACA5C,IAAI,CAAC6C,YAAY,CAAC,CAAC;;MAEnB;MACA,IAAI,CAAC7C,IAAI,CAACe,aAAa,EAAE;QACvB;QACA,IAAI,OAAO+B,KAAK,KAAK,WAAW,EAAE;UAChC,IAAI;YACF,IAAIC,IAAI,GAAG,IAAID,KAAK,CAAC,CAAC;;YAEtB;YACA,IAAI,OAAOC,IAAI,CAACC,gBAAgB,KAAK,WAAW,EAAE;cAChDhD,IAAI,CAACS,aAAa,GAAG,SAAS;YAChC;UACF,CAAC,CAAC,OAAMwC,CAAC,EAAE;YACTjD,IAAI,CAACc,OAAO,GAAG,IAAI;UACrB;QACF,CAAC,MAAM;UACLd,IAAI,CAACc,OAAO,GAAG,IAAI;QACrB;MACF;;MAEA;MACA,IAAI;QACF,IAAIiC,IAAI,GAAG,IAAID,KAAK,CAAC,CAAC;QACtB,IAAIC,IAAI,CAACV,KAAK,EAAE;UACdrC,IAAI,CAACc,OAAO,GAAG,IAAI;QACrB;MACF,CAAC,CAAC,OAAOmC,CAAC,EAAE,CAAC;;MAEb;MACA,IAAI,CAACjD,IAAI,CAACc,OAAO,EAAE;QACjBd,IAAI,CAACkD,YAAY,CAAC,CAAC;MACrB;MAEA,OAAOlD,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;IACIkD,YAAY,EAAE,SAAAA,CAAA,EAAW;MACvB,IAAIlD,IAAI,GAAG,IAAI,IAAIC,MAAM;MACzB,IAAIkD,SAAS,GAAG,IAAI;;MAEpB;MACA,IAAI;QACFA,SAAS,GAAI,OAAOL,KAAK,KAAK,WAAW,GAAI,IAAIA,KAAK,CAAC,CAAC,GAAG,IAAI;MACjE,CAAC,CAAC,OAAOM,GAAG,EAAE;QACZ,OAAOpD,IAAI;MACb;MAEA,IAAI,CAACmD,SAAS,IAAI,OAAOA,SAAS,CAACE,WAAW,KAAK,UAAU,EAAE;QAC7D,OAAOrD,IAAI;MACb;MAEA,IAAIsD,QAAQ,GAAGH,SAAS,CAACE,WAAW,CAAC,aAAa,CAAC,CAACV,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;;MAEvE;MACA,IAAIY,EAAE,GAAGvD,IAAI,CAACU,UAAU,GAAGV,IAAI,CAACU,UAAU,CAAC8C,SAAS,GAAG,EAAE;MACzD,IAAIC,UAAU,GAAGF,EAAE,CAACG,KAAK,CAAC,gBAAgB,CAAC;MAC3C,IAAIC,UAAU,GAAIF,UAAU,IAAIG,QAAQ,CAACH,UAAU,CAAC,CAAC,CAAC,CAACI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,EAAG;MAC/E,IAAIC,WAAW,GAAGP,EAAE,CAACQ,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAIR,EAAE,CAACQ,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;MAC5E,IAAIC,aAAa,GAAGT,EAAE,CAACG,KAAK,CAAC,iBAAiB,CAAC;MAC/C,IAAIO,WAAW,GAAIH,WAAW,IAAIE,aAAa,IAAIJ,QAAQ,CAACI,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,EAAG;MAEvFhE,IAAI,CAACK,OAAO,GAAG;QACb6D,GAAG,EAAE,CAAC,EAAE,CAACP,UAAU,KAAKL,QAAQ,IAAIH,SAAS,CAACE,WAAW,CAAC,YAAY,CAAC,CAACV,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;QAC7FwB,IAAI,EAAE,CAAC,CAACb,QAAQ;QAChBc,IAAI,EAAE,CAAC,CAACjB,SAAS,CAACE,WAAW,CAAC,0BAA0B,CAAC,CAACV,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QAC7E0B,GAAG,EAAE,CAAC,CAAClB,SAAS,CAACE,WAAW,CAAC,4BAA4B,CAAC,CAACV,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QAC9E2B,GAAG,EAAE,CAAC,CAACnB,SAAS,CAACE,WAAW,CAAC,4BAA4B,CAAC,CAACV,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QAC9E4B,GAAG,EAAE,CAAC,CAAC,CAACpB,SAAS,CAACE,WAAW,CAAC,uBAAuB,CAAC,IAAIF,SAAS,CAACE,WAAW,CAAC,WAAW,CAAC,EAAEV,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QACjH6B,GAAG,EAAE,CAAC,CAACrB,SAAS,CAACE,WAAW,CAAC,YAAY,CAAC,CAACV,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QAC9D8B,GAAG,EAAE,CAAC,CAACtB,SAAS,CAACE,WAAW,CAAC,cAAc,CAAC,CAACV,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QAChE+B,GAAG,EAAE,CAAC,CAAC,CAACvB,SAAS,CAACE,WAAW,CAAC,cAAc,CAAC,IAAIF,SAAS,CAACE,WAAW,CAAC,YAAY,CAAC,IAAIF,SAAS,CAACE,WAAW,CAAC,YAAY,CAAC,EAAEV,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QAChJgC,GAAG,EAAE,CAAC,CAAC,CAACxB,SAAS,CAACE,WAAW,CAAC,cAAc,CAAC,IAAIF,SAAS,CAACE,WAAW,CAAC,YAAY,CAAC,IAAIF,SAAS,CAACE,WAAW,CAAC,YAAY,CAAC,EAAEV,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QAChJiC,GAAG,EAAE,CAAC,CAAC,CAACzB,SAAS,CAACE,WAAW,CAAC,cAAc,CAAC,IAAIF,SAAS,CAACE,WAAW,CAAC,YAAY,CAAC,IAAIF,SAAS,CAACE,WAAW,CAAC,YAAY,CAAC,EAAEV,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QAChJkC,IAAI,EAAE,CAAC,EAAE,CAACZ,WAAW,IAAId,SAAS,CAACE,WAAW,CAAC,6BAA6B,CAAC,CAACV,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAClGmC,IAAI,EAAE,CAAC,EAAE,CAACb,WAAW,IAAId,SAAS,CAACE,WAAW,CAAC,6BAA6B,CAAC,CAACV,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAClGoC,KAAK,EAAE,CAAC,CAAC5B,SAAS,CAACE,WAAW,CAAC,0BAA0B,CAAC,CAACV,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QAC9EqC,IAAI,EAAE,CAAC,CAAC,CAAC7B,SAAS,CAACE,WAAW,CAAC,eAAe,CAAC,IAAIF,SAAS,CAACE,WAAW,CAAC,aAAa,CAAC,EAAEV,OAAO,CAAC,MAAM,EAAE,EAAE;MAC7G,CAAC;MAED,OAAO3C,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;AACA;IACIiF,YAAY,EAAE,SAAAA,CAAA,EAAW;MACvB,IAAIjF,IAAI,GAAG,IAAI,IAAIC,MAAM;;MAEzB;MACA,IAAID,IAAI,CAACkF,cAAc,IAAI,CAAClF,IAAI,CAACiB,GAAG,EAAE;QACpC;MACF;MAEAjB,IAAI,CAACkF,cAAc,GAAG,KAAK;MAC3BlF,IAAI,CAACkB,UAAU,GAAG,KAAK;;MAEvB;MACA;MACA;MACA,IAAI,CAAClB,IAAI,CAACmF,eAAe,IAAInF,IAAI,CAACiB,GAAG,CAACmE,UAAU,KAAK,KAAK,EAAE;QAC1DpF,IAAI,CAACmF,eAAe,GAAG,IAAI;QAC3BnF,IAAI,CAACuC,MAAM,CAAC,CAAC;MACf;;MAEA;MACA;MACAvC,IAAI,CAACqF,cAAc,GAAGrF,IAAI,CAACiB,GAAG,CAACqE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC;;MAExD;MACA;MACA;MACA,IAAIC,MAAM,GAAG,SAAAA,CAAStC,CAAC,EAAE;QACvB;QACA;QACA;QACA;QACA;QACA;QACA,OAAOjD,IAAI,CAACG,eAAe,CAACyB,MAAM,GAAG5B,IAAI,CAACI,aAAa,EAAE;UACvD,IAAI;YACF,IAAIoF,SAAS,GAAG,IAAI1C,KAAK,CAAC,CAAC;;YAE3B;YACA;YACA0C,SAAS,CAACC,SAAS,GAAG,IAAI;;YAE1B;YACAzF,IAAI,CAAC0F,kBAAkB,CAACF,SAAS,CAAC;UACpC,CAAC,CAAC,OAAOvC,CAAC,EAAE;YACVjD,IAAI,CAACc,OAAO,GAAG,IAAI;YACnB;UACF;QACF;;QAEA;QACA,KAAK,IAAIa,CAAC,GAAC,CAAC,EAAEA,CAAC,GAAC3B,IAAI,CAACM,MAAM,CAACsB,MAAM,EAAED,CAAC,EAAE,EAAE;UACvC,IAAI,CAAC3B,IAAI,CAACM,MAAM,CAACqB,CAAC,CAAC,CAACE,SAAS,EAAE;YAC7B;YACA,IAAIC,GAAG,GAAG9B,IAAI,CAACM,MAAM,CAACqB,CAAC,CAAC,CAACI,YAAY,CAAC,CAAC;;YAEvC;YACA,KAAK,IAAIC,CAAC,GAAC,CAAC,EAAEA,CAAC,GAACF,GAAG,CAACF,MAAM,EAAEI,CAAC,EAAE,EAAE;cAC/B,IAAIC,KAAK,GAAGjC,IAAI,CAACM,MAAM,CAACqB,CAAC,CAAC,CAACO,UAAU,CAACJ,GAAG,CAACE,CAAC,CAAC,CAAC;cAE7C,IAAIC,KAAK,IAAIA,KAAK,CAACE,KAAK,IAAI,CAACF,KAAK,CAACE,KAAK,CAACsD,SAAS,EAAE;gBAClDxD,KAAK,CAACE,KAAK,CAACsD,SAAS,GAAG,IAAI;gBAC5BxD,KAAK,CAACE,KAAK,CAACwD,IAAI,CAAC,CAAC;cACpB;YACF;UACF;QACF;;QAEA;QACA3F,IAAI,CAAC4F,WAAW,CAAC,CAAC;;QAElB;QACA,IAAIC,MAAM,GAAG7F,IAAI,CAACiB,GAAG,CAAC6E,kBAAkB,CAAC,CAAC;QAC1CD,MAAM,CAACE,MAAM,GAAG/F,IAAI,CAACqF,cAAc;QACnCQ,MAAM,CAACG,OAAO,CAAChG,IAAI,CAACiB,GAAG,CAACgF,WAAW,CAAC;;QAEpC;QACA,IAAI,OAAOJ,MAAM,CAACK,KAAK,KAAK,WAAW,EAAE;UACvCL,MAAM,CAACM,MAAM,CAAC,CAAC,CAAC;QAClB,CAAC,MAAM;UACLN,MAAM,CAACK,KAAK,CAAC,CAAC,CAAC;QACjB;;QAEA;QACA,IAAI,OAAOlG,IAAI,CAACiB,GAAG,CAACmF,MAAM,KAAK,UAAU,EAAE;UACzCpG,IAAI,CAACiB,GAAG,CAACmF,MAAM,CAAC,CAAC;QACnB;;QAEA;QACAP,MAAM,CAACQ,OAAO,GAAG,YAAW;UAC1BR,MAAM,CAACS,UAAU,CAAC,CAAC,CAAC;;UAEpB;UACAtG,IAAI,CAACkF,cAAc,GAAG,IAAI;;UAE1B;UACAqB,QAAQ,CAACC,mBAAmB,CAAC,YAAY,EAAEjB,MAAM,EAAE,IAAI,CAAC;UACxDgB,QAAQ,CAACC,mBAAmB,CAAC,UAAU,EAAEjB,MAAM,EAAE,IAAI,CAAC;UACtDgB,QAAQ,CAACC,mBAAmB,CAAC,OAAO,EAAEjB,MAAM,EAAE,IAAI,CAAC;UACnDgB,QAAQ,CAACC,mBAAmB,CAAC,SAAS,EAAEjB,MAAM,EAAE,IAAI,CAAC;;UAErD;UACA,KAAK,IAAI5D,CAAC,GAAC,CAAC,EAAEA,CAAC,GAAC3B,IAAI,CAACM,MAAM,CAACsB,MAAM,EAAED,CAAC,EAAE,EAAE;YACvC3B,IAAI,CAACM,MAAM,CAACqB,CAAC,CAAC,CAAC8E,KAAK,CAAC,QAAQ,CAAC;UAChC;QACF,CAAC;MACH,CAAC;;MAED;MACAF,QAAQ,CAACG,gBAAgB,CAAC,YAAY,EAAEnB,MAAM,EAAE,IAAI,CAAC;MACrDgB,QAAQ,CAACG,gBAAgB,CAAC,UAAU,EAAEnB,MAAM,EAAE,IAAI,CAAC;MACnDgB,QAAQ,CAACG,gBAAgB,CAAC,OAAO,EAAEnB,MAAM,EAAE,IAAI,CAAC;MAChDgB,QAAQ,CAACG,gBAAgB,CAAC,SAAS,EAAEnB,MAAM,EAAE,IAAI,CAAC;MAElD,OAAOvF,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;IACI2G,iBAAiB,EAAE,SAAAA,CAAA,EAAW;MAC5B,IAAI3G,IAAI,GAAG,IAAI,IAAIC,MAAM;;MAEzB;MACA,IAAID,IAAI,CAACG,eAAe,CAACyB,MAAM,EAAE;QAC/B,OAAO5B,IAAI,CAACG,eAAe,CAACyG,GAAG,CAAC,CAAC;MACnC;;MAEA;MACA,IAAIC,QAAQ,GAAG,IAAI/D,KAAK,CAAC,CAAC,CAACgE,IAAI,CAAC,CAAC;MACjC,IAAID,QAAQ,IAAI,OAAOE,OAAO,KAAK,WAAW,KAAKF,QAAQ,YAAYE,OAAO,IAAI,OAAOF,QAAQ,CAACG,IAAI,KAAK,UAAU,CAAC,EAAE;QACtHH,QAAQ,CAACI,KAAK,CAAC,YAAW;UACxBC,OAAO,CAACC,IAAI,CAAC,wEAAwE,CAAC;QACxF,CAAC,CAAC;MACJ;MAEA,OAAO,IAAIrE,KAAK,CAAC,CAAC;IACpB,CAAC;IAED;AACJ;AACA;AACA;IACI4C,kBAAkB,EAAE,SAAAA,CAAS0B,KAAK,EAAE;MAClC,IAAIpH,IAAI,GAAG,IAAI,IAAIC,MAAM;;MAEzB;MACA,IAAImH,KAAK,CAAC3B,SAAS,EAAE;QACnBzF,IAAI,CAACG,eAAe,CAACkH,IAAI,CAACD,KAAK,CAAC;MAClC;MAEA,OAAOpH,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;IACI6C,YAAY,EAAE,SAAAA,CAAA,EAAW;MACvB,IAAI7C,IAAI,GAAG,IAAI;MAEf,IAAI,CAACA,IAAI,CAACgB,WAAW,IAAI,CAAChB,IAAI,CAACiB,GAAG,IAAI,OAAOjB,IAAI,CAACiB,GAAG,CAACqG,OAAO,KAAK,WAAW,IAAI,CAACrH,MAAM,CAACc,aAAa,EAAE;QACtG;MACF;;MAEA;MACA,KAAK,IAAIY,CAAC,GAAC,CAAC,EAAEA,CAAC,GAAC3B,IAAI,CAACM,MAAM,CAACsB,MAAM,EAAED,CAAC,EAAE,EAAE;QACvC,IAAI3B,IAAI,CAACM,MAAM,CAACqB,CAAC,CAAC,CAACE,SAAS,EAAE;UAC5B,KAAK,IAAIG,CAAC,GAAC,CAAC,EAAEA,CAAC,GAAChC,IAAI,CAACM,MAAM,CAACqB,CAAC,CAAC,CAAC4F,OAAO,CAAC3F,MAAM,EAAEI,CAAC,EAAE,EAAE;YAClD,IAAI,CAAChC,IAAI,CAACM,MAAM,CAACqB,CAAC,CAAC,CAAC4F,OAAO,CAACvF,CAAC,CAAC,CAACwF,OAAO,EAAE;cACtC,OAAOxH,IAAI;YACb;UACF;QACF;MACF;MAEA,IAAIA,IAAI,CAACyH,aAAa,EAAE;QACtBC,YAAY,CAAC1H,IAAI,CAACyH,aAAa,CAAC;MAClC;;MAEA;MACAzH,IAAI,CAACyH,aAAa,GAAGE,UAAU,CAAC,YAAW;QACzC,IAAI,CAAC3H,IAAI,CAACgB,WAAW,EAAE;UACrB;QACF;QAEAhB,IAAI,CAACyH,aAAa,GAAG,IAAI;QACzBzH,IAAI,CAAC4C,KAAK,GAAG,YAAY;;QAEzB;QACA,IAAIgF,gBAAgB,GAAG,SAAAA,CAAA,EAAW;UAChC5H,IAAI,CAAC4C,KAAK,GAAG,WAAW;UAExB,IAAI5C,IAAI,CAAC6H,mBAAmB,EAAE;YAC5B,OAAO7H,IAAI,CAAC6H,mBAAmB;YAC/B7H,IAAI,CAAC4F,WAAW,CAAC,CAAC;UACpB;QACF,CAAC;;QAED;QACA;QACA5F,IAAI,CAACiB,GAAG,CAACqG,OAAO,CAAC,CAAC,CAACN,IAAI,CAACY,gBAAgB,EAAEA,gBAAgB,CAAC;MAC7D,CAAC,EAAE,KAAK,CAAC;MAET,OAAO5H,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;IACI4F,WAAW,EAAE,SAAAA,CAAA,EAAW;MACtB,IAAI5F,IAAI,GAAG,IAAI;MAEf,IAAI,CAACA,IAAI,CAACiB,GAAG,IAAI,OAAOjB,IAAI,CAACiB,GAAG,CAACmF,MAAM,KAAK,WAAW,IAAI,CAACnG,MAAM,CAACc,aAAa,EAAE;QAChF;MACF;MAEA,IAAIf,IAAI,CAAC4C,KAAK,KAAK,SAAS,IAAI5C,IAAI,CAACiB,GAAG,CAAC2B,KAAK,KAAK,aAAa,IAAI5C,IAAI,CAACyH,aAAa,EAAE;QACtFC,YAAY,CAAC1H,IAAI,CAACyH,aAAa,CAAC;QAChCzH,IAAI,CAACyH,aAAa,GAAG,IAAI;MAC3B,CAAC,MAAM,IAAIzH,IAAI,CAAC4C,KAAK,KAAK,WAAW,IAAI5C,IAAI,CAAC4C,KAAK,KAAK,SAAS,IAAI5C,IAAI,CAACiB,GAAG,CAAC2B,KAAK,KAAK,aAAa,EAAE;QACrG5C,IAAI,CAACiB,GAAG,CAACmF,MAAM,CAAC,CAAC,CAACY,IAAI,CAAC,YAAW;UAChChH,IAAI,CAAC4C,KAAK,GAAG,SAAS;;UAEtB;UACA,KAAK,IAAIjB,CAAC,GAAC,CAAC,EAAEA,CAAC,GAAC3B,IAAI,CAACM,MAAM,CAACsB,MAAM,EAAED,CAAC,EAAE,EAAE;YACvC3B,IAAI,CAACM,MAAM,CAACqB,CAAC,CAAC,CAAC8E,KAAK,CAAC,QAAQ,CAAC;UAChC;QACF,CAAC,CAAC;QAEF,IAAIzG,IAAI,CAACyH,aAAa,EAAE;UACtBC,YAAY,CAAC1H,IAAI,CAACyH,aAAa,CAAC;UAChCzH,IAAI,CAACyH,aAAa,GAAG,IAAI;QAC3B;MACF,CAAC,MAAM,IAAIzH,IAAI,CAAC4C,KAAK,KAAK,YAAY,EAAE;QACtC5C,IAAI,CAAC6H,mBAAmB,GAAG,IAAI;MACjC;MAEA,OAAO7H,IAAI;IACb;EACF,CAAC;;EAED;EACA,IAAIC,MAAM,GAAG,IAAIJ,YAAY,CAAC,CAAC;;EAE/B;EACA;;EAEA;AACF;AACA;AACA;EACE,IAAIiI,IAAI,GAAG,SAAAA,CAASC,CAAC,EAAE;IACrB,IAAI/H,IAAI,GAAG,IAAI;;IAEf;IACA,IAAI,CAAC+H,CAAC,CAACC,GAAG,IAAID,CAAC,CAACC,GAAG,CAACpG,MAAM,KAAK,CAAC,EAAE;MAChCsF,OAAO,CAACe,KAAK,CAAC,4DAA4D,CAAC;MAC3E;IACF;IAEAjI,IAAI,CAACF,IAAI,CAACiI,CAAC,CAAC;EACd,CAAC;EACDD,IAAI,CAAC/H,SAAS,GAAG;IACf;AACJ;AACA;AACA;AACA;IACID,IAAI,EAAE,SAAAA,CAASiI,CAAC,EAAE;MAChB,IAAI/H,IAAI,GAAG,IAAI;;MAEf;MACA,IAAI,CAACC,MAAM,CAACgB,GAAG,EAAE;QACfM,iBAAiB,CAAC,CAAC;MACrB;;MAEA;MACAvB,IAAI,CAACkI,SAAS,GAAGH,CAAC,CAACI,QAAQ,IAAI,KAAK;MACpCnI,IAAI,CAACoI,OAAO,GAAI,OAAOL,CAAC,CAACM,MAAM,KAAK,QAAQ,GAAIN,CAAC,CAACM,MAAM,GAAG,CAACN,CAAC,CAACM,MAAM,CAAC;MACrErI,IAAI,CAACsI,MAAM,GAAGP,CAAC,CAACQ,KAAK,IAAI,KAAK;MAC9BvI,IAAI,CAACO,MAAM,GAAGwH,CAAC,CAAC3F,IAAI,IAAI,KAAK;MAC7BpC,IAAI,CAACwI,KAAK,GAAGT,CAAC,CAACU,IAAI,IAAI,KAAK;MAC5BzI,IAAI,CAAC0I,KAAK,GAAGX,CAAC,CAACY,IAAI,IAAI,CAAC;MACxB3I,IAAI,CAAC4I,QAAQ,GAAI,OAAOb,CAAC,CAACc,OAAO,KAAK,SAAS,IAAId,CAAC,CAACc,OAAO,KAAK,UAAU,GAAId,CAAC,CAACc,OAAO,GAAG,IAAI;MAC/F7I,IAAI,CAAC8I,KAAK,GAAGf,CAAC,CAACgB,IAAI,IAAI,CAAC;MACxB/I,IAAI,CAACgJ,OAAO,GAAGjB,CAAC,CAACkB,MAAM,IAAI,CAAC,CAAC;MAC7BjJ,IAAI,CAACkJ,IAAI,GAAI,OAAOnB,CAAC,CAACC,GAAG,KAAK,QAAQ,GAAID,CAAC,CAACC,GAAG,GAAG,CAACD,CAAC,CAACC,GAAG,CAAC;MACzDhI,IAAI,CAACQ,OAAO,GAAGuH,CAAC,CAAC3G,MAAM,KAAK+H,SAAS,GAAGpB,CAAC,CAAC3G,MAAM,GAAG,CAAC;MACpDpB,IAAI,CAACoJ,IAAI,GAAG;QACVC,MAAM,EAAEtB,CAAC,CAACuB,GAAG,IAAIvB,CAAC,CAACuB,GAAG,CAACD,MAAM,GAAGtB,CAAC,CAACuB,GAAG,CAACD,MAAM,GAAG,KAAK;QACpDE,OAAO,EAAExB,CAAC,CAACuB,GAAG,IAAIvB,CAAC,CAACuB,GAAG,CAACC,OAAO,GAAGxB,CAAC,CAACuB,GAAG,CAACC,OAAO,GAAG,IAAI;QACtDC,eAAe,EAAEzB,CAAC,CAACuB,GAAG,IAAIvB,CAAC,CAACuB,GAAG,CAACE,eAAe,GAAGzB,CAAC,CAACuB,GAAG,CAACE,eAAe,GAAG;MAC5E,CAAC;;MAED;MACAxJ,IAAI,CAACyJ,SAAS,GAAG,CAAC;MAClBzJ,IAAI,CAAC0J,MAAM,GAAG,UAAU;MACxB1J,IAAI,CAACuH,OAAO,GAAG,EAAE;MACjBvH,IAAI,CAAC2J,UAAU,GAAG,CAAC,CAAC;MACpB3J,IAAI,CAAC4J,MAAM,GAAG,EAAE;MAChB5J,IAAI,CAAC6J,SAAS,GAAG,KAAK;;MAEtB;MACA7J,IAAI,CAAC8J,MAAM,GAAG/B,CAAC,CAACgC,KAAK,GAAG,CAAC;QAACC,EAAE,EAAEjC,CAAC,CAACgC;MAAK,CAAC,CAAC,GAAG,EAAE;MAC5C/J,IAAI,CAACiK,OAAO,GAAGlC,CAAC,CAACmC,MAAM,GAAG,CAAC;QAACF,EAAE,EAAEjC,CAAC,CAACmC;MAAM,CAAC,CAAC,GAAG,EAAE;MAC/ClK,IAAI,CAACmK,OAAO,GAAGpC,CAAC,CAACqC,MAAM,GAAG,CAAC;QAACJ,EAAE,EAAEjC,CAAC,CAACqC;MAAM,CAAC,CAAC,GAAG,EAAE;MAC/CpK,IAAI,CAACqK,YAAY,GAAGtC,CAAC,CAACuC,WAAW,GAAG,CAAC;QAACN,EAAE,EAAEjC,CAAC,CAACuC;MAAW,CAAC,CAAC,GAAG,EAAE;MAC9DtK,IAAI,CAACuK,YAAY,GAAGxC,CAAC,CAACyC,WAAW,GAAG,CAAC;QAACR,EAAE,EAAEjC,CAAC,CAACyC;MAAW,CAAC,CAAC,GAAG,EAAE;MAC9DxK,IAAI,CAACyK,QAAQ,GAAG1C,CAAC,CAAC2C,OAAO,GAAG,CAAC;QAACV,EAAE,EAAEjC,CAAC,CAAC2C;MAAO,CAAC,CAAC,GAAG,EAAE;MAClD1K,IAAI,CAAC2K,OAAO,GAAG5C,CAAC,CAAC6C,MAAM,GAAG,CAAC;QAACZ,EAAE,EAAEjC,CAAC,CAAC6C;MAAM,CAAC,CAAC,GAAG,EAAE;MAC/C5K,IAAI,CAAC6K,OAAO,GAAG9C,CAAC,CAAC+C,MAAM,GAAG,CAAC;QAACd,EAAE,EAAEjC,CAAC,CAAC+C;MAAM,CAAC,CAAC,GAAG,EAAE;MAC/C9K,IAAI,CAAC+K,OAAO,GAAGhD,CAAC,CAACiD,MAAM,GAAG,CAAC;QAAChB,EAAE,EAAEjC,CAAC,CAACiD;MAAM,CAAC,CAAC,GAAG,EAAE;MAC/ChL,IAAI,CAACiL,SAAS,GAAGlD,CAAC,CAACmD,QAAQ,GAAG,CAAC;QAAClB,EAAE,EAAEjC,CAAC,CAACmD;MAAQ,CAAC,CAAC,GAAG,EAAE;MACrDlL,IAAI,CAACmL,OAAO,GAAGpD,CAAC,CAACqD,MAAM,GAAG,CAAC;QAACpB,EAAE,EAAEjC,CAAC,CAACqD;MAAM,CAAC,CAAC,GAAG,EAAE;MAC/CpL,IAAI,CAACqL,OAAO,GAAGtD,CAAC,CAACuD,MAAM,GAAG,CAAC;QAACtB,EAAE,EAAEjC,CAAC,CAACuD;MAAM,CAAC,CAAC,GAAG,EAAE;MAC/CtL,IAAI,CAACuL,SAAS,GAAGxD,CAAC,CAACyD,QAAQ,GAAG,CAAC;QAACxB,EAAE,EAAEjC,CAAC,CAACyD;MAAQ,CAAC,CAAC,GAAG,EAAE;MACrDxL,IAAI,CAACyL,SAAS,GAAG,EAAE;;MAEnB;MACAzL,IAAI,CAAC6B,SAAS,GAAG5B,MAAM,CAACc,aAAa,IAAI,CAACf,IAAI,CAACsI,MAAM;;MAErD;MACA,IAAI,OAAOrI,MAAM,CAACgB,GAAG,KAAK,WAAW,IAAIhB,MAAM,CAACgB,GAAG,IAAIhB,MAAM,CAACiB,UAAU,EAAE;QACxEjB,MAAM,CAACgF,YAAY,CAAC,CAAC;MACvB;;MAEA;MACAhF,MAAM,CAACK,MAAM,CAAC+G,IAAI,CAACrH,IAAI,CAAC;;MAExB;MACA,IAAIA,IAAI,CAACkI,SAAS,EAAE;QAClBlI,IAAI,CAAC4J,MAAM,CAACvC,IAAI,CAAC;UACfqE,KAAK,EAAE,MAAM;UACbC,MAAM,EAAE,SAAAA,CAAA,EAAW;YACjB3L,IAAI,CAAC8G,IAAI,CAAC,CAAC;UACb;QACF,CAAC,CAAC;MACJ;;MAEA;MACA,IAAI9G,IAAI,CAAC4I,QAAQ,IAAI5I,IAAI,CAAC4I,QAAQ,KAAK,MAAM,EAAE;QAC7C5I,IAAI,CAAC2F,IAAI,CAAC,CAAC;MACb;MAEA,OAAO3F,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;IACI2F,IAAI,EAAE,SAAAA,CAAA,EAAW;MACf,IAAI3F,IAAI,GAAG,IAAI;MACf,IAAI4L,GAAG,GAAG,IAAI;;MAEd;MACA,IAAI3L,MAAM,CAACa,OAAO,EAAE;QAClBd,IAAI,CAACyG,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,mBAAmB,CAAC;QAClD;MACF;;MAEA;MACA,IAAI,OAAOzG,IAAI,CAACkJ,IAAI,KAAK,QAAQ,EAAE;QACjClJ,IAAI,CAACkJ,IAAI,GAAG,CAAClJ,IAAI,CAACkJ,IAAI,CAAC;MACzB;;MAEA;MACA,KAAK,IAAIvH,CAAC,GAAC,CAAC,EAAEA,CAAC,GAAC3B,IAAI,CAACkJ,IAAI,CAACtH,MAAM,EAAED,CAAC,EAAE,EAAE;QACrC,IAAIe,GAAG,EAAEmJ,GAAG;QAEZ,IAAI7L,IAAI,CAACoI,OAAO,IAAIpI,IAAI,CAACoI,OAAO,CAACzG,CAAC,CAAC,EAAE;UACnC;UACAe,GAAG,GAAG1C,IAAI,CAACoI,OAAO,CAACzG,CAAC,CAAC;QACvB,CAAC,MAAM;UACL;UACAkK,GAAG,GAAG7L,IAAI,CAACkJ,IAAI,CAACvH,CAAC,CAAC;UAClB,IAAI,OAAOkK,GAAG,KAAK,QAAQ,EAAE;YAC3B7L,IAAI,CAACyG,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,wDAAwD,CAAC;YACvF;UACF;;UAEA;UACA/D,GAAG,GAAG,yBAAyB,CAACoJ,IAAI,CAACD,GAAG,CAAC;UACzC,IAAI,CAACnJ,GAAG,EAAE;YACRA,GAAG,GAAG,YAAY,CAACoJ,IAAI,CAACD,GAAG,CAAChI,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;UAC/C;UAEA,IAAInB,GAAG,EAAE;YACPA,GAAG,GAAGA,GAAG,CAAC,CAAC,CAAC,CAACqJ,WAAW,CAAC,CAAC;UAC5B;QACF;;QAEA;QACA,IAAI,CAACrJ,GAAG,EAAE;UACRwE,OAAO,CAACC,IAAI,CAAC,4FAA4F,CAAC;QAC5G;;QAEA;QACA,IAAIzE,GAAG,IAAIzC,MAAM,CAACwC,MAAM,CAACC,GAAG,CAAC,EAAE;UAC7BkJ,GAAG,GAAG5L,IAAI,CAACkJ,IAAI,CAACvH,CAAC,CAAC;UAClB;QACF;MACF;MAEA,IAAI,CAACiK,GAAG,EAAE;QACR5L,IAAI,CAACyG,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,8CAA8C,CAAC;QAC7E;MACF;MAEAzG,IAAI,CAACkJ,IAAI,GAAG0C,GAAG;MACf5L,IAAI,CAAC0J,MAAM,GAAG,SAAS;;MAEvB;MACA;MACA,IAAI/I,MAAM,CAACqL,QAAQ,CAACC,QAAQ,KAAK,QAAQ,IAAIL,GAAG,CAACM,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,OAAO,EAAE;QACxElM,IAAI,CAACsI,MAAM,GAAG,IAAI;QAClBtI,IAAI,CAAC6B,SAAS,GAAG,KAAK;MACxB;;MAEA;MACA,IAAIsK,KAAK,CAACnM,IAAI,CAAC;;MAEf;MACA,IAAIA,IAAI,CAAC6B,SAAS,EAAE;QAClBuK,UAAU,CAACpM,IAAI,CAAC;MAClB;MAEA,OAAOA,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;AACA;IACI8G,IAAI,EAAE,SAAAA,CAASmC,MAAM,EAAEoD,QAAQ,EAAE;MAC/B,IAAIrM,IAAI,GAAG,IAAI;MACf,IAAIsM,EAAE,GAAG,IAAI;;MAEb;MACA,IAAI,OAAOrD,MAAM,KAAK,QAAQ,EAAE;QAC9BqD,EAAE,GAAGrD,MAAM;QACXA,MAAM,GAAG,IAAI;MACf,CAAC,MAAM,IAAI,OAAOA,MAAM,KAAK,QAAQ,IAAIjJ,IAAI,CAAC0J,MAAM,KAAK,QAAQ,IAAI,CAAC1J,IAAI,CAACgJ,OAAO,CAACC,MAAM,CAAC,EAAE;QAC1F;QACA,OAAO,IAAI;MACb,CAAC,MAAM,IAAI,OAAOA,MAAM,KAAK,WAAW,EAAE;QACxC;QACAA,MAAM,GAAG,WAAW;;QAEpB;QACA;QACA,IAAI,CAACjJ,IAAI,CAAC6J,SAAS,EAAE;UACnB,IAAI0C,GAAG,GAAG,CAAC;UACX,KAAK,IAAI5K,CAAC,GAAC,CAAC,EAAEA,CAAC,GAAC3B,IAAI,CAACuH,OAAO,CAAC3F,MAAM,EAAED,CAAC,EAAE,EAAE;YACxC,IAAI3B,IAAI,CAACuH,OAAO,CAAC5F,CAAC,CAAC,CAAC6F,OAAO,IAAI,CAACxH,IAAI,CAACuH,OAAO,CAAC5F,CAAC,CAAC,CAAC6K,MAAM,EAAE;cACtDD,GAAG,EAAE;cACLD,EAAE,GAAGtM,IAAI,CAACuH,OAAO,CAAC5F,CAAC,CAAC,CAAC8K,GAAG;YAC1B;UACF;UAEA,IAAIF,GAAG,KAAK,CAAC,EAAE;YACbtD,MAAM,GAAG,IAAI;UACf,CAAC,MAAM;YACLqD,EAAE,GAAG,IAAI;UACX;QACF;MACF;;MAEA;MACA,IAAIrK,KAAK,GAAGqK,EAAE,GAAGtM,IAAI,CAACkC,UAAU,CAACoK,EAAE,CAAC,GAAGtM,IAAI,CAAC0M,cAAc,CAAC,CAAC;;MAE5D;MACA,IAAI,CAACzK,KAAK,EAAE;QACV,OAAO,IAAI;MACb;;MAEA;MACA,IAAIqK,EAAE,IAAI,CAACrD,MAAM,EAAE;QACjBA,MAAM,GAAGhH,KAAK,CAAC+G,OAAO,IAAI,WAAW;MACvC;;MAEA;MACA;MACA;MACA,IAAIhJ,IAAI,CAAC0J,MAAM,KAAK,QAAQ,EAAE;QAC5B;QACAzH,KAAK,CAAC+G,OAAO,GAAGC,MAAM;;QAEtB;QACAhH,KAAK,CAACuK,MAAM,GAAG,KAAK;;QAEpB;QACA,IAAIG,OAAO,GAAG1K,KAAK,CAACwK,GAAG;QACvBzM,IAAI,CAAC4J,MAAM,CAACvC,IAAI,CAAC;UACfqE,KAAK,EAAE,MAAM;UACbC,MAAM,EAAE,SAAAA,CAAA,EAAW;YACjB3L,IAAI,CAAC8G,IAAI,CAAC6F,OAAO,CAAC;UACpB;QACF,CAAC,CAAC;QAEF,OAAOA,OAAO;MAChB;;MAEA;MACA,IAAIL,EAAE,IAAI,CAACrK,KAAK,CAACuF,OAAO,EAAE;QACxB;QACA,IAAI,CAAC6E,QAAQ,EAAE;UACbrM,IAAI,CAAC4M,UAAU,CAAC,MAAM,CAAC;QACzB;QAEA,OAAO3K,KAAK,CAACwK,GAAG;MAClB;;MAEA;MACA,IAAIzM,IAAI,CAAC6B,SAAS,EAAE;QAClB5B,MAAM,CAAC2F,WAAW,CAAC,CAAC;MACtB;;MAEA;MACA,IAAIiH,IAAI,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC,EAAE9K,KAAK,CAAC+K,KAAK,GAAG,CAAC,GAAG/K,KAAK,CAAC+K,KAAK,GAAGhN,IAAI,CAACgJ,OAAO,CAACC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;MACtF,IAAIgE,QAAQ,GAAGH,IAAI,CAACC,GAAG,CAAC,CAAC,EAAG,CAAC/M,IAAI,CAACgJ,OAAO,CAACC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAGjJ,IAAI,CAACgJ,OAAO,CAACC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,GAAI4D,IAAI,CAAC;MAC/F,IAAIK,OAAO,GAAID,QAAQ,GAAG,IAAI,GAAIH,IAAI,CAACK,GAAG,CAAClL,KAAK,CAAC6G,KAAK,CAAC;MACvD,IAAI5C,KAAK,GAAGlG,IAAI,CAACgJ,OAAO,CAACC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;MAC1C,IAAI3G,IAAI,GAAG,CAACtC,IAAI,CAACgJ,OAAO,CAACC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAGjJ,IAAI,CAACgJ,OAAO,CAACC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI;MACrEhH,KAAK,CAAC+G,OAAO,GAAGC,MAAM;;MAEtB;MACA;MACAhH,KAAK,CAACuK,MAAM,GAAG,KAAK;;MAEpB;MACA,IAAIY,SAAS,GAAG,SAAAA,CAAA,EAAW;QACzBnL,KAAK,CAACuF,OAAO,GAAG,KAAK;QACrBvF,KAAK,CAAC+K,KAAK,GAAGH,IAAI;QAClB5K,KAAK,CAACoL,MAAM,GAAGnH,KAAK;QACpBjE,KAAK,CAACqL,KAAK,GAAGhL,IAAI;QAClBL,KAAK,CAACuG,KAAK,GAAG,CAAC,EAAEvG,KAAK,CAACuG,KAAK,IAAIxI,IAAI,CAACgJ,OAAO,CAACC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;MAC1D,CAAC;;MAED;MACA,IAAI4D,IAAI,IAAIvK,IAAI,EAAE;QAChBtC,IAAI,CAACwM,MAAM,CAACvK,KAAK,CAAC;QAClB;MACF;;MAEA;MACA,IAAIsL,IAAI,GAAGtL,KAAK,CAACE,KAAK;MACtB,IAAInC,IAAI,CAAC6B,SAAS,EAAE;QAClB;QACA,IAAI2L,YAAY,GAAG,SAAAA,CAAA,EAAW;UAC5BxN,IAAI,CAAC6J,SAAS,GAAG,KAAK;UACtBuD,SAAS,CAAC,CAAC;UACXpN,IAAI,CAACyN,cAAc,CAACxL,KAAK,CAAC;;UAE1B;UACA,IAAIZ,GAAG,GAAIY,KAAK,CAAC1B,MAAM,IAAIP,IAAI,CAACO,MAAM,GAAI,CAAC,GAAG0B,KAAK,CAACzB,OAAO;UAC3D+M,IAAI,CAAC/L,IAAI,CAACC,cAAc,CAACJ,GAAG,EAAEpB,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;UACrDO,KAAK,CAACyL,UAAU,GAAGzN,MAAM,CAACgB,GAAG,CAACS,WAAW;;UAEzC;UACA,IAAI,OAAO6L,IAAI,CAACI,YAAY,CAACzH,KAAK,KAAK,WAAW,EAAE;YAClDjE,KAAK,CAACuG,KAAK,GAAG+E,IAAI,CAACI,YAAY,CAACC,WAAW,CAAC,CAAC,EAAEf,IAAI,EAAE,KAAK,CAAC,GAAGU,IAAI,CAACI,YAAY,CAACC,WAAW,CAAC,CAAC,EAAEf,IAAI,EAAEI,QAAQ,CAAC;UAChH,CAAC,MAAM;YACLhL,KAAK,CAACuG,KAAK,GAAG+E,IAAI,CAACI,YAAY,CAACzH,KAAK,CAAC,CAAC,EAAE2G,IAAI,EAAE,KAAK,CAAC,GAAGU,IAAI,CAACI,YAAY,CAACzH,KAAK,CAAC,CAAC,EAAE2G,IAAI,EAAEI,QAAQ,CAAC;UACpG;;UAEA;UACA,IAAIC,OAAO,KAAKW,QAAQ,EAAE;YACxB7N,IAAI,CAAC2J,UAAU,CAAC1H,KAAK,CAACwK,GAAG,CAAC,GAAG9E,UAAU,CAAC3H,IAAI,CAACwM,MAAM,CAACsB,IAAI,CAAC9N,IAAI,EAAEiC,KAAK,CAAC,EAAEiL,OAAO,CAAC;UACjF;UAEA,IAAI,CAACb,QAAQ,EAAE;YACb1E,UAAU,CAAC,YAAW;cACpB3H,IAAI,CAACyG,KAAK,CAAC,MAAM,EAAExE,KAAK,CAACwK,GAAG,CAAC;cAC7BzM,IAAI,CAAC4M,UAAU,CAAC,CAAC;YACnB,CAAC,EAAE,CAAC,CAAC;UACP;QACF,CAAC;QAED,IAAI3M,MAAM,CAAC2C,KAAK,KAAK,SAAS,IAAI3C,MAAM,CAACgB,GAAG,CAAC2B,KAAK,KAAK,aAAa,EAAE;UACpE4K,YAAY,CAAC,CAAC;QAChB,CAAC,MAAM;UACLxN,IAAI,CAAC6J,SAAS,GAAG,IAAI;;UAErB;UACA7J,IAAI,CAAC+N,IAAI,CAAC,QAAQ,EAAEP,YAAY,CAAC;;UAEjC;UACAxN,IAAI,CAACgO,WAAW,CAAC/L,KAAK,CAACwK,GAAG,CAAC;QAC7B;MACF,CAAC,MAAM;QACL;QACA,IAAIwB,SAAS,GAAG,SAAAA,CAAA,EAAW;UACzBV,IAAI,CAAC7L,WAAW,GAAGmL,IAAI;UACvBU,IAAI,CAAClL,KAAK,GAAGJ,KAAK,CAAC1B,MAAM,IAAIP,IAAI,CAACO,MAAM,IAAIN,MAAM,CAACM,MAAM,IAAIgN,IAAI,CAAClL,KAAK;UACvEkL,IAAI,CAACnM,MAAM,GAAGa,KAAK,CAACzB,OAAO,GAAGP,MAAM,CAACmB,MAAM,CAAC,CAAC;UAC7CmM,IAAI,CAACW,YAAY,GAAGjM,KAAK,CAAC6G,KAAK;;UAE/B;UACA,IAAI;YACF,IAAIhC,IAAI,GAAGyG,IAAI,CAACzG,IAAI,CAAC,CAAC;;YAEtB;YACA,IAAIA,IAAI,IAAI,OAAOC,OAAO,KAAK,WAAW,KAAKD,IAAI,YAAYC,OAAO,IAAI,OAAOD,IAAI,CAACE,IAAI,KAAK,UAAU,CAAC,EAAE;cAC1G;cACAhH,IAAI,CAAC6J,SAAS,GAAG,IAAI;;cAErB;cACAuD,SAAS,CAAC,CAAC;;cAEX;cACAtG,IAAI,CACDE,IAAI,CAAC,YAAW;gBACfhH,IAAI,CAAC6J,SAAS,GAAG,KAAK;gBACtB0D,IAAI,CAAC9H,SAAS,GAAG,IAAI;gBACrB,IAAI,CAAC4G,QAAQ,EAAE;kBACbrM,IAAI,CAACyG,KAAK,CAAC,MAAM,EAAExE,KAAK,CAACwK,GAAG,CAAC;gBAC/B,CAAC,MAAM;kBACLzM,IAAI,CAAC4M,UAAU,CAAC,CAAC;gBACnB;cACF,CAAC,CAAC,CACD3F,KAAK,CAAC,YAAW;gBAChBjH,IAAI,CAAC6J,SAAS,GAAG,KAAK;gBACtB7J,IAAI,CAACyG,KAAK,CAAC,WAAW,EAAExE,KAAK,CAACwK,GAAG,EAAE,+DAA+D,GAChG,gFAAgF,CAAC;;gBAEnF;gBACAxK,KAAK,CAACuK,MAAM,GAAG,IAAI;gBACnBvK,KAAK,CAACuF,OAAO,GAAG,IAAI;cACtB,CAAC,CAAC;YACN,CAAC,MAAM,IAAI,CAAC6E,QAAQ,EAAE;cACpBrM,IAAI,CAAC6J,SAAS,GAAG,KAAK;cACtBuD,SAAS,CAAC,CAAC;cACXpN,IAAI,CAACyG,KAAK,CAAC,MAAM,EAAExE,KAAK,CAACwK,GAAG,CAAC;YAC/B;;YAEA;YACAc,IAAI,CAACW,YAAY,GAAGjM,KAAK,CAAC6G,KAAK;;YAE/B;YACA,IAAIyE,IAAI,CAACY,MAAM,EAAE;cACfnO,IAAI,CAACyG,KAAK,CAAC,WAAW,EAAExE,KAAK,CAACwK,GAAG,EAAE,+DAA+D,GAChG,gFAAgF,CAAC;cACnF;YACF;;YAEA;YACA,IAAIxD,MAAM,KAAK,WAAW,IAAIhH,KAAK,CAACuG,KAAK,EAAE;cACzCxI,IAAI,CAAC2J,UAAU,CAAC1H,KAAK,CAACwK,GAAG,CAAC,GAAG9E,UAAU,CAAC3H,IAAI,CAACwM,MAAM,CAACsB,IAAI,CAAC9N,IAAI,EAAEiC,KAAK,CAAC,EAAEiL,OAAO,CAAC;YACjF,CAAC,MAAM;cACLlN,IAAI,CAAC2J,UAAU,CAAC1H,KAAK,CAACwK,GAAG,CAAC,GAAG,YAAW;gBACtC;gBACAzM,IAAI,CAACwM,MAAM,CAACvK,KAAK,CAAC;;gBAElB;gBACAsL,IAAI,CAAC/G,mBAAmB,CAAC,OAAO,EAAExG,IAAI,CAAC2J,UAAU,CAAC1H,KAAK,CAACwK,GAAG,CAAC,EAAE,KAAK,CAAC;cACtE,CAAC;cACDc,IAAI,CAAC7G,gBAAgB,CAAC,OAAO,EAAE1G,IAAI,CAAC2J,UAAU,CAAC1H,KAAK,CAACwK,GAAG,CAAC,EAAE,KAAK,CAAC;YACnE;UACF,CAAC,CAAC,OAAOrJ,GAAG,EAAE;YACZpD,IAAI,CAACyG,KAAK,CAAC,WAAW,EAAExE,KAAK,CAACwK,GAAG,EAAErJ,GAAG,CAAC;UACzC;QACF,CAAC;;QAED;QACA,IAAImK,IAAI,CAACvF,GAAG,KAAK,wFAAwF,EAAE;UACzGuF,IAAI,CAACvF,GAAG,GAAGhI,IAAI,CAACkJ,IAAI;UACpBqE,IAAI,CAAC5H,IAAI,CAAC,CAAC;QACb;;QAEA;QACA,IAAIyI,kBAAkB,GAAIzN,MAAM,IAAIA,MAAM,CAAC0N,MAAM,IAAM,CAACd,IAAI,CAACe,UAAU,IAAIrO,MAAM,CAACS,UAAU,CAAC6N,UAAW;QACxG,IAAIhB,IAAI,CAACe,UAAU,IAAI,CAAC,IAAIF,kBAAkB,EAAE;UAC9CH,SAAS,CAAC,CAAC;QACb,CAAC,MAAM;UACLjO,IAAI,CAAC6J,SAAS,GAAG,IAAI;UACrB7J,IAAI,CAAC0J,MAAM,GAAG,SAAS;UAEvB,IAAI8E,QAAQ,GAAG,SAAAA,CAAA,EAAW;YACxBxO,IAAI,CAAC0J,MAAM,GAAG,QAAQ;;YAEtB;YACAuE,SAAS,CAAC,CAAC;;YAEX;YACAV,IAAI,CAAC/G,mBAAmB,CAACvG,MAAM,CAACQ,aAAa,EAAE+N,QAAQ,EAAE,KAAK,CAAC;UACjE,CAAC;UACDjB,IAAI,CAAC7G,gBAAgB,CAACzG,MAAM,CAACQ,aAAa,EAAE+N,QAAQ,EAAE,KAAK,CAAC;;UAE5D;UACAxO,IAAI,CAACgO,WAAW,CAAC/L,KAAK,CAACwK,GAAG,CAAC;QAC7B;MACF;MAEA,OAAOxK,KAAK,CAACwK,GAAG;IAClB,CAAC;IAED;AACJ;AACA;AACA;AACA;IACIgC,KAAK,EAAE,SAAAA,CAASnC,EAAE,EAAE;MAClB,IAAItM,IAAI,GAAG,IAAI;;MAEf;MACA,IAAIA,IAAI,CAAC0J,MAAM,KAAK,QAAQ,IAAI1J,IAAI,CAAC6J,SAAS,EAAE;QAC9C7J,IAAI,CAAC4J,MAAM,CAACvC,IAAI,CAAC;UACfqE,KAAK,EAAE,OAAO;UACdC,MAAM,EAAE,SAAAA,CAAA,EAAW;YACjB3L,IAAI,CAACyO,KAAK,CAACnC,EAAE,CAAC;UAChB;QACF,CAAC,CAAC;QAEF,OAAOtM,IAAI;MACb;;MAEA;MACA,IAAI8B,GAAG,GAAG9B,IAAI,CAAC+B,YAAY,CAACuK,EAAE,CAAC;MAE/B,KAAK,IAAI3K,CAAC,GAAC,CAAC,EAAEA,CAAC,GAACG,GAAG,CAACF,MAAM,EAAED,CAAC,EAAE,EAAE;QAC/B;QACA3B,IAAI,CAACgO,WAAW,CAAClM,GAAG,CAACH,CAAC,CAAC,CAAC;;QAExB;QACA,IAAIM,KAAK,GAAGjC,IAAI,CAACkC,UAAU,CAACJ,GAAG,CAACH,CAAC,CAAC,CAAC;QAEnC,IAAIM,KAAK,IAAI,CAACA,KAAK,CAACuF,OAAO,EAAE;UAC3B;UACAvF,KAAK,CAAC+K,KAAK,GAAGhN,IAAI,CAAC6M,IAAI,CAAC/K,GAAG,CAACH,CAAC,CAAC,CAAC;UAC/BM,KAAK,CAACyM,SAAS,GAAG,CAAC;UACnBzM,KAAK,CAACuF,OAAO,GAAG,IAAI;;UAEpB;UACAxH,IAAI,CAAC2O,SAAS,CAAC7M,GAAG,CAACH,CAAC,CAAC,CAAC;UAEtB,IAAIM,KAAK,CAACE,KAAK,EAAE;YACf,IAAInC,IAAI,CAAC6B,SAAS,EAAE;cAClB;cACA,IAAI,CAACI,KAAK,CAACE,KAAK,CAACwL,YAAY,EAAE;gBAC7B;cACF;cAEA,IAAI,OAAO1L,KAAK,CAACE,KAAK,CAACwL,YAAY,CAACrL,IAAI,KAAK,WAAW,EAAE;gBACxDL,KAAK,CAACE,KAAK,CAACwL,YAAY,CAACiB,OAAO,CAAC,CAAC,CAAC;cACrC,CAAC,MAAM;gBACL3M,KAAK,CAACE,KAAK,CAACwL,YAAY,CAACrL,IAAI,CAAC,CAAC,CAAC;cAClC;;cAEA;cACAtC,IAAI,CAAC6O,YAAY,CAAC5M,KAAK,CAACE,KAAK,CAAC;YAChC,CAAC,MAAM,IAAI,CAAC2M,KAAK,CAAC7M,KAAK,CAACE,KAAK,CAAC8K,QAAQ,CAAC,IAAIhL,KAAK,CAACE,KAAK,CAAC8K,QAAQ,KAAKY,QAAQ,EAAE;cAC5E5L,KAAK,CAACE,KAAK,CAACsM,KAAK,CAAC,CAAC;YACrB;UACF;QACF;;QAEA;QACA,IAAI,CAACM,SAAS,CAAC,CAAC,CAAC,EAAE;UACjB/O,IAAI,CAACyG,KAAK,CAAC,OAAO,EAAExE,KAAK,GAAGA,KAAK,CAACwK,GAAG,GAAG,IAAI,CAAC;QAC/C;MACF;MAEA,OAAOzM,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;AACA;IACIsC,IAAI,EAAE,SAAAA,CAASgK,EAAE,EAAED,QAAQ,EAAE;MAC3B,IAAIrM,IAAI,GAAG,IAAI;;MAEf;MACA,IAAIA,IAAI,CAAC0J,MAAM,KAAK,QAAQ,IAAI1J,IAAI,CAAC6J,SAAS,EAAE;QAC9C7J,IAAI,CAAC4J,MAAM,CAACvC,IAAI,CAAC;UACfqE,KAAK,EAAE,MAAM;UACbC,MAAM,EAAE,SAAAA,CAAA,EAAW;YACjB3L,IAAI,CAACsC,IAAI,CAACgK,EAAE,CAAC;UACf;QACF,CAAC,CAAC;QAEF,OAAOtM,IAAI;MACb;;MAEA;MACA,IAAI8B,GAAG,GAAG9B,IAAI,CAAC+B,YAAY,CAACuK,EAAE,CAAC;MAE/B,KAAK,IAAI3K,CAAC,GAAC,CAAC,EAAEA,CAAC,GAACG,GAAG,CAACF,MAAM,EAAED,CAAC,EAAE,EAAE;QAC/B;QACA3B,IAAI,CAACgO,WAAW,CAAClM,GAAG,CAACH,CAAC,CAAC,CAAC;;QAExB;QACA,IAAIM,KAAK,GAAGjC,IAAI,CAACkC,UAAU,CAACJ,GAAG,CAACH,CAAC,CAAC,CAAC;QAEnC,IAAIM,KAAK,EAAE;UACT;UACAA,KAAK,CAAC+K,KAAK,GAAG/K,KAAK,CAACoL,MAAM,IAAI,CAAC;UAC/BpL,KAAK,CAACyM,SAAS,GAAG,CAAC;UACnBzM,KAAK,CAACuF,OAAO,GAAG,IAAI;UACpBvF,KAAK,CAACuK,MAAM,GAAG,IAAI;;UAEnB;UACAxM,IAAI,CAAC2O,SAAS,CAAC7M,GAAG,CAACH,CAAC,CAAC,CAAC;UAEtB,IAAIM,KAAK,CAACE,KAAK,EAAE;YACf,IAAInC,IAAI,CAAC6B,SAAS,EAAE;cAClB;cACA,IAAII,KAAK,CAACE,KAAK,CAACwL,YAAY,EAAE;gBAC5B,IAAI,OAAO1L,KAAK,CAACE,KAAK,CAACwL,YAAY,CAACrL,IAAI,KAAK,WAAW,EAAE;kBACxDL,KAAK,CAACE,KAAK,CAACwL,YAAY,CAACiB,OAAO,CAAC,CAAC,CAAC;gBACrC,CAAC,MAAM;kBACL3M,KAAK,CAACE,KAAK,CAACwL,YAAY,CAACrL,IAAI,CAAC,CAAC,CAAC;gBAClC;;gBAEA;gBACAtC,IAAI,CAAC6O,YAAY,CAAC5M,KAAK,CAACE,KAAK,CAAC;cAChC;YACF,CAAC,MAAM,IAAI,CAAC2M,KAAK,CAAC7M,KAAK,CAACE,KAAK,CAAC8K,QAAQ,CAAC,IAAIhL,KAAK,CAACE,KAAK,CAAC8K,QAAQ,KAAKY,QAAQ,EAAE;cAC5E5L,KAAK,CAACE,KAAK,CAACT,WAAW,GAAGO,KAAK,CAACoL,MAAM,IAAI,CAAC;cAC3CpL,KAAK,CAACE,KAAK,CAACsM,KAAK,CAAC,CAAC;;cAEnB;cACA,IAAIxM,KAAK,CAACE,KAAK,CAAC8K,QAAQ,KAAKY,QAAQ,EAAE;gBACrC7N,IAAI,CAACgP,WAAW,CAAC/M,KAAK,CAACE,KAAK,CAAC;cAC/B;YACF;UACF;UAEA,IAAI,CAACkK,QAAQ,EAAE;YACbrM,IAAI,CAACyG,KAAK,CAAC,MAAM,EAAExE,KAAK,CAACwK,GAAG,CAAC;UAC/B;QACF;MACF;MAEA,OAAOzM,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;AACA;IACIoC,IAAI,EAAE,SAAAA,CAASC,KAAK,EAAEiK,EAAE,EAAE;MACxB,IAAItM,IAAI,GAAG,IAAI;;MAEf;MACA,IAAIA,IAAI,CAAC0J,MAAM,KAAK,QAAQ,IAAG1J,IAAI,CAAC6J,SAAS,EAAE;QAC7C7J,IAAI,CAAC4J,MAAM,CAACvC,IAAI,CAAC;UACfqE,KAAK,EAAE,MAAM;UACbC,MAAM,EAAE,SAAAA,CAAA,EAAW;YACjB3L,IAAI,CAACoC,IAAI,CAACC,KAAK,EAAEiK,EAAE,CAAC;UACtB;QACF,CAAC,CAAC;QAEF,OAAOtM,IAAI;MACb;;MAEA;MACA,IAAI,OAAOsM,EAAE,KAAK,WAAW,EAAE;QAC7B,IAAI,OAAOjK,KAAK,KAAK,SAAS,EAAE;UAC9BrC,IAAI,CAACO,MAAM,GAAG8B,KAAK;QACrB,CAAC,MAAM;UACL,OAAOrC,IAAI,CAACO,MAAM;QACpB;MACF;;MAEA;MACA,IAAIuB,GAAG,GAAG9B,IAAI,CAAC+B,YAAY,CAACuK,EAAE,CAAC;MAE/B,KAAK,IAAI3K,CAAC,GAAC,CAAC,EAAEA,CAAC,GAACG,GAAG,CAACF,MAAM,EAAED,CAAC,EAAE,EAAE;QAC/B;QACA,IAAIM,KAAK,GAAGjC,IAAI,CAACkC,UAAU,CAACJ,GAAG,CAACH,CAAC,CAAC,CAAC;QAEnC,IAAIM,KAAK,EAAE;UACTA,KAAK,CAAC1B,MAAM,GAAG8B,KAAK;;UAEpB;UACA,IAAIJ,KAAK,CAACgN,SAAS,EAAE;YACnBjP,IAAI,CAAC2O,SAAS,CAAC1M,KAAK,CAACwK,GAAG,CAAC;UAC3B;UAEA,IAAIzM,IAAI,CAAC6B,SAAS,IAAII,KAAK,CAACE,KAAK,EAAE;YACjCF,KAAK,CAACE,KAAK,CAACX,IAAI,CAACC,cAAc,CAACY,KAAK,GAAG,CAAC,GAAGJ,KAAK,CAACzB,OAAO,EAAEP,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;UACpF,CAAC,MAAM,IAAIO,KAAK,CAACE,KAAK,EAAE;YACtBF,KAAK,CAACE,KAAK,CAACE,KAAK,GAAGpC,MAAM,CAACM,MAAM,GAAG,IAAI,GAAG8B,KAAK;UAClD;UAEArC,IAAI,CAACyG,KAAK,CAAC,MAAM,EAAExE,KAAK,CAACwK,GAAG,CAAC;QAC/B;MACF;MAEA,OAAOzM,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;IACIoB,MAAM,EAAE,SAAAA,CAAA,EAAW;MACjB,IAAIpB,IAAI,GAAG,IAAI;MACf,IAAIkP,IAAI,GAAGH,SAAS;MACpB,IAAI1N,GAAG,EAAEiL,EAAE;;MAEX;MACA,IAAI4C,IAAI,CAACtN,MAAM,KAAK,CAAC,EAAE;QACrB;QACA,OAAO5B,IAAI,CAACQ,OAAO;MACrB,CAAC,MAAM,IAAI0O,IAAI,CAACtN,MAAM,KAAK,CAAC,IAAIsN,IAAI,CAACtN,MAAM,KAAK,CAAC,IAAI,OAAOsN,IAAI,CAAC,CAAC,CAAC,KAAK,WAAW,EAAE;QACnF;QACA,IAAIpN,GAAG,GAAG9B,IAAI,CAAC+B,YAAY,CAAC,CAAC;QAC7B,IAAIoN,KAAK,GAAGrN,GAAG,CAACiC,OAAO,CAACmL,IAAI,CAAC,CAAC,CAAC,CAAC;QAChC,IAAIC,KAAK,IAAI,CAAC,EAAE;UACd7C,EAAE,GAAG1I,QAAQ,CAACsL,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAC5B,CAAC,MAAM;UACL7N,GAAG,GAAGC,UAAU,CAAC4N,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3B;MACF,CAAC,MAAM,IAAIA,IAAI,CAACtN,MAAM,IAAI,CAAC,EAAE;QAC3BP,GAAG,GAAGC,UAAU,CAAC4N,IAAI,CAAC,CAAC,CAAC,CAAC;QACzB5C,EAAE,GAAG1I,QAAQ,CAACsL,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;MAC5B;;MAEA;MACA,IAAIjN,KAAK;MACT,IAAI,OAAOZ,GAAG,KAAK,WAAW,IAAIA,GAAG,IAAI,CAAC,IAAIA,GAAG,IAAI,CAAC,EAAE;QACtD;QACA,IAAIrB,IAAI,CAAC0J,MAAM,KAAK,QAAQ,IAAG1J,IAAI,CAAC6J,SAAS,EAAE;UAC7C7J,IAAI,CAAC4J,MAAM,CAACvC,IAAI,CAAC;YACfqE,KAAK,EAAE,QAAQ;YACfC,MAAM,EAAE,SAAAA,CAAA,EAAW;cACjB3L,IAAI,CAACoB,MAAM,CAACgO,KAAK,CAACpP,IAAI,EAAEkP,IAAI,CAAC;YAC/B;UACF,CAAC,CAAC;UAEF,OAAOlP,IAAI;QACb;;QAEA;QACA,IAAI,OAAOsM,EAAE,KAAK,WAAW,EAAE;UAC7BtM,IAAI,CAACQ,OAAO,GAAGa,GAAG;QACpB;;QAEA;QACAiL,EAAE,GAAGtM,IAAI,CAAC+B,YAAY,CAACuK,EAAE,CAAC;QAC1B,KAAK,IAAI3K,CAAC,GAAC,CAAC,EAAEA,CAAC,GAAC2K,EAAE,CAAC1K,MAAM,EAAED,CAAC,EAAE,EAAE;UAC9B;UACAM,KAAK,GAAGjC,IAAI,CAACkC,UAAU,CAACoK,EAAE,CAAC3K,CAAC,CAAC,CAAC;UAE9B,IAAIM,KAAK,EAAE;YACTA,KAAK,CAACzB,OAAO,GAAGa,GAAG;;YAEnB;YACA,IAAI,CAAC6N,IAAI,CAAC,CAAC,CAAC,EAAE;cACZlP,IAAI,CAAC2O,SAAS,CAACrC,EAAE,CAAC3K,CAAC,CAAC,CAAC;YACvB;YAEA,IAAI3B,IAAI,CAAC6B,SAAS,IAAII,KAAK,CAACE,KAAK,IAAI,CAACF,KAAK,CAAC1B,MAAM,EAAE;cAClD0B,KAAK,CAACE,KAAK,CAACX,IAAI,CAACC,cAAc,CAACJ,GAAG,EAAEpB,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;YAC9D,CAAC,MAAM,IAAIO,KAAK,CAACE,KAAK,IAAI,CAACF,KAAK,CAAC1B,MAAM,EAAE;cACvC0B,KAAK,CAACE,KAAK,CAACf,MAAM,GAAGC,GAAG,GAAGpB,MAAM,CAACmB,MAAM,CAAC,CAAC;YAC5C;YAEApB,IAAI,CAACyG,KAAK,CAAC,QAAQ,EAAExE,KAAK,CAACwK,GAAG,CAAC;UACjC;QACF;MACF,CAAC,MAAM;QACLxK,KAAK,GAAGqK,EAAE,GAAGtM,IAAI,CAACkC,UAAU,CAACoK,EAAE,CAAC,GAAGtM,IAAI,CAACuH,OAAO,CAAC,CAAC,CAAC;QAClD,OAAOtF,KAAK,GAAGA,KAAK,CAACzB,OAAO,GAAG,CAAC;MAClC;MAEA,OAAOR,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;IACIqP,IAAI,EAAE,SAAAA,CAASC,IAAI,EAAEC,EAAE,EAAEC,GAAG,EAAElD,EAAE,EAAE;MAChC,IAAItM,IAAI,GAAG,IAAI;;MAEf;MACA,IAAIA,IAAI,CAAC0J,MAAM,KAAK,QAAQ,IAAI1J,IAAI,CAAC6J,SAAS,EAAE;QAC9C7J,IAAI,CAAC4J,MAAM,CAACvC,IAAI,CAAC;UACfqE,KAAK,EAAE,MAAM;UACbC,MAAM,EAAE,SAAAA,CAAA,EAAW;YACjB3L,IAAI,CAACqP,IAAI,CAACC,IAAI,EAAEC,EAAE,EAAEC,GAAG,EAAElD,EAAE,CAAC;UAC9B;QACF,CAAC,CAAC;QAEF,OAAOtM,IAAI;MACb;;MAEA;MACAsP,IAAI,GAAGxC,IAAI,CAAC2C,GAAG,CAAC3C,IAAI,CAACC,GAAG,CAAC,CAAC,EAAEzL,UAAU,CAACgO,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;MACjDC,EAAE,GAAGzC,IAAI,CAAC2C,GAAG,CAAC3C,IAAI,CAACC,GAAG,CAAC,CAAC,EAAEzL,UAAU,CAACiO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;MAC7CC,GAAG,GAAGlO,UAAU,CAACkO,GAAG,CAAC;;MAErB;MACAxP,IAAI,CAACoB,MAAM,CAACkO,IAAI,EAAEhD,EAAE,CAAC;;MAErB;MACA,IAAIxK,GAAG,GAAG9B,IAAI,CAAC+B,YAAY,CAACuK,EAAE,CAAC;MAC/B,KAAK,IAAI3K,CAAC,GAAC,CAAC,EAAEA,CAAC,GAACG,GAAG,CAACF,MAAM,EAAED,CAAC,EAAE,EAAE;QAC/B;QACA,IAAIM,KAAK,GAAGjC,IAAI,CAACkC,UAAU,CAACJ,GAAG,CAACH,CAAC,CAAC,CAAC;;QAEnC;QACA,IAAIM,KAAK,EAAE;UACT;UACA,IAAI,CAACqK,EAAE,EAAE;YACPtM,IAAI,CAAC2O,SAAS,CAAC7M,GAAG,CAACH,CAAC,CAAC,CAAC;UACxB;;UAEA;UACA,IAAI3B,IAAI,CAAC6B,SAAS,IAAI,CAACI,KAAK,CAAC1B,MAAM,EAAE;YACnC,IAAImB,WAAW,GAAGzB,MAAM,CAACgB,GAAG,CAACS,WAAW;YACxC,IAAIgO,GAAG,GAAGhO,WAAW,GAAI8N,GAAG,GAAG,IAAK;YACpCvN,KAAK,CAACzB,OAAO,GAAG8O,IAAI;YACpBrN,KAAK,CAACE,KAAK,CAACX,IAAI,CAACC,cAAc,CAAC6N,IAAI,EAAE5N,WAAW,CAAC;YAClDO,KAAK,CAACE,KAAK,CAACX,IAAI,CAACmO,uBAAuB,CAACJ,EAAE,EAAEG,GAAG,CAAC;UACnD;UAEA1P,IAAI,CAAC4P,kBAAkB,CAAC3N,KAAK,EAAEqN,IAAI,EAAEC,EAAE,EAAEC,GAAG,EAAE1N,GAAG,CAACH,CAAC,CAAC,EAAE,OAAO2K,EAAE,KAAK,WAAW,CAAC;QAClF;MACF;MAEA,OAAOtM,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;IACI4P,kBAAkB,EAAE,SAAAA,CAAS3N,KAAK,EAAEqN,IAAI,EAAEC,EAAE,EAAEC,GAAG,EAAElD,EAAE,EAAEuD,OAAO,EAAE;MAC9D,IAAI7P,IAAI,GAAG,IAAI;MACf,IAAIqB,GAAG,GAAGiO,IAAI;MACd,IAAIQ,IAAI,GAAGP,EAAE,GAAGD,IAAI;MACpB,IAAIS,KAAK,GAAGjD,IAAI,CAACK,GAAG,CAAC2C,IAAI,GAAG,IAAI,CAAC;MACjC,IAAIE,OAAO,GAAGlD,IAAI,CAACC,GAAG,CAAC,CAAC,EAAGgD,KAAK,GAAG,CAAC,GAAIP,GAAG,GAAGO,KAAK,GAAGP,GAAG,CAAC;MAC1D,IAAIS,QAAQ,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC;;MAEzB;MACAlO,KAAK,CAACmO,OAAO,GAAGb,EAAE;;MAElB;MACAtN,KAAK,CAACgN,SAAS,GAAGoB,WAAW,CAAC,YAAW;QACvC;QACA,IAAIC,IAAI,GAAG,CAACJ,IAAI,CAACC,GAAG,CAAC,CAAC,GAAGF,QAAQ,IAAIT,GAAG;QACxCS,QAAQ,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC;QACrB9O,GAAG,IAAIyO,IAAI,GAAGQ,IAAI;;QAElB;QACAjP,GAAG,GAAGyL,IAAI,CAACyD,KAAK,CAAClP,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG;;QAEjC;QACA,IAAIyO,IAAI,GAAG,CAAC,EAAE;UACZzO,GAAG,GAAGyL,IAAI,CAACC,GAAG,CAACwC,EAAE,EAAElO,GAAG,CAAC;QACzB,CAAC,MAAM;UACLA,GAAG,GAAGyL,IAAI,CAAC2C,GAAG,CAACF,EAAE,EAAElO,GAAG,CAAC;QACzB;;QAEA;QACA,IAAIrB,IAAI,CAAC6B,SAAS,EAAE;UAClBI,KAAK,CAACzB,OAAO,GAAGa,GAAG;QACrB,CAAC,MAAM;UACLrB,IAAI,CAACoB,MAAM,CAACC,GAAG,EAAEY,KAAK,CAACwK,GAAG,EAAE,IAAI,CAAC;QACnC;;QAEA;QACA,IAAIoD,OAAO,EAAE;UACX7P,IAAI,CAACQ,OAAO,GAAGa,GAAG;QACpB;;QAEA;QACA,IAAKkO,EAAE,GAAGD,IAAI,IAAIjO,GAAG,IAAIkO,EAAE,IAAMA,EAAE,GAAGD,IAAI,IAAIjO,GAAG,IAAIkO,EAAG,EAAE;UACxDiB,aAAa,CAACvO,KAAK,CAACgN,SAAS,CAAC;UAC9BhN,KAAK,CAACgN,SAAS,GAAG,IAAI;UACtBhN,KAAK,CAACmO,OAAO,GAAG,IAAI;UACpBpQ,IAAI,CAACoB,MAAM,CAACmO,EAAE,EAAEtN,KAAK,CAACwK,GAAG,CAAC;UAC1BzM,IAAI,CAACyG,KAAK,CAAC,MAAM,EAAExE,KAAK,CAACwK,GAAG,CAAC;QAC/B;MACF,CAAC,EAAEuD,OAAO,CAAC;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;AACA;IACIrB,SAAS,EAAE,SAAAA,CAASrC,EAAE,EAAE;MACtB,IAAItM,IAAI,GAAG,IAAI;MACf,IAAIiC,KAAK,GAAGjC,IAAI,CAACkC,UAAU,CAACoK,EAAE,CAAC;MAE/B,IAAIrK,KAAK,IAAIA,KAAK,CAACgN,SAAS,EAAE;QAC5B,IAAIjP,IAAI,CAAC6B,SAAS,EAAE;UAClBI,KAAK,CAACE,KAAK,CAACX,IAAI,CAACiP,qBAAqB,CAACxQ,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;QAChE;QAEA8O,aAAa,CAACvO,KAAK,CAACgN,SAAS,CAAC;QAC9BhN,KAAK,CAACgN,SAAS,GAAG,IAAI;QACtBjP,IAAI,CAACoB,MAAM,CAACa,KAAK,CAACmO,OAAO,EAAE9D,EAAE,CAAC;QAC9BrK,KAAK,CAACmO,OAAO,GAAG,IAAI;QACpBpQ,IAAI,CAACyG,KAAK,CAAC,MAAM,EAAE6F,EAAE,CAAC;MACxB;MAEA,OAAOtM,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;IACIyI,IAAI,EAAE,SAAAA,CAAA,EAAW;MACf,IAAIzI,IAAI,GAAG,IAAI;MACf,IAAIkP,IAAI,GAAGH,SAAS;MACpB,IAAItG,IAAI,EAAE6D,EAAE,EAAErK,KAAK;;MAEnB;MACA,IAAIiN,IAAI,CAACtN,MAAM,KAAK,CAAC,EAAE;QACrB;QACA,OAAO5B,IAAI,CAACwI,KAAK;MACnB,CAAC,MAAM,IAAI0G,IAAI,CAACtN,MAAM,KAAK,CAAC,EAAE;QAC5B,IAAI,OAAOsN,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE;UAChCzG,IAAI,GAAGyG,IAAI,CAAC,CAAC,CAAC;UACdlP,IAAI,CAACwI,KAAK,GAAGC,IAAI;QACnB,CAAC,MAAM;UACL;UACAxG,KAAK,GAAGjC,IAAI,CAACkC,UAAU,CAAC0B,QAAQ,CAACsL,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;UAC9C,OAAOjN,KAAK,GAAGA,KAAK,CAACuG,KAAK,GAAG,KAAK;QACpC;MACF,CAAC,MAAM,IAAI0G,IAAI,CAACtN,MAAM,KAAK,CAAC,EAAE;QAC5B6G,IAAI,GAAGyG,IAAI,CAAC,CAAC,CAAC;QACd5C,EAAE,GAAG1I,QAAQ,CAACsL,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;MAC5B;;MAEA;MACA,IAAIpN,GAAG,GAAG9B,IAAI,CAAC+B,YAAY,CAACuK,EAAE,CAAC;MAC/B,KAAK,IAAI3K,CAAC,GAAC,CAAC,EAAEA,CAAC,GAACG,GAAG,CAACF,MAAM,EAAED,CAAC,EAAE,EAAE;QAC/BM,KAAK,GAAGjC,IAAI,CAACkC,UAAU,CAACJ,GAAG,CAACH,CAAC,CAAC,CAAC;QAE/B,IAAIM,KAAK,EAAE;UACTA,KAAK,CAACuG,KAAK,GAAGC,IAAI;UAClB,IAAIzI,IAAI,CAAC6B,SAAS,IAAII,KAAK,CAACE,KAAK,IAAIF,KAAK,CAACE,KAAK,CAACwL,YAAY,EAAE;YAC7D1L,KAAK,CAACE,KAAK,CAACwL,YAAY,CAAClF,IAAI,GAAGA,IAAI;YACpC,IAAIA,IAAI,EAAE;cACRxG,KAAK,CAACE,KAAK,CAACwL,YAAY,CAAC+C,SAAS,GAAGzO,KAAK,CAACoL,MAAM,IAAI,CAAC;cACtDpL,KAAK,CAACE,KAAK,CAACwL,YAAY,CAACgD,OAAO,GAAG1O,KAAK,CAACqL,KAAK;;cAE9C;cACA,IAAItN,IAAI,CAAC4Q,OAAO,CAAC9O,GAAG,CAACH,CAAC,CAAC,CAAC,EAAE;gBACxB3B,IAAI,CAACyO,KAAK,CAAC3M,GAAG,CAACH,CAAC,CAAC,EAAE,IAAI,CAAC;gBACxB3B,IAAI,CAAC8G,IAAI,CAAChF,GAAG,CAACH,CAAC,CAAC,EAAE,IAAI,CAAC;cACzB;YACF;UACF;QACF;MACF;MAEA,OAAO3B,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;IACI+I,IAAI,EAAE,SAAAA,CAAA,EAAW;MACf,IAAI/I,IAAI,GAAG,IAAI;MACf,IAAIkP,IAAI,GAAGH,SAAS;MACpB,IAAIhG,IAAI,EAAEuD,EAAE;;MAEZ;MACA,IAAI4C,IAAI,CAACtN,MAAM,KAAK,CAAC,EAAE;QACrB;QACA0K,EAAE,GAAGtM,IAAI,CAACuH,OAAO,CAAC,CAAC,CAAC,CAACkF,GAAG;MAC1B,CAAC,MAAM,IAAIyC,IAAI,CAACtN,MAAM,KAAK,CAAC,EAAE;QAC5B;QACA,IAAIE,GAAG,GAAG9B,IAAI,CAAC+B,YAAY,CAAC,CAAC;QAC7B,IAAIoN,KAAK,GAAGrN,GAAG,CAACiC,OAAO,CAACmL,IAAI,CAAC,CAAC,CAAC,CAAC;QAChC,IAAIC,KAAK,IAAI,CAAC,EAAE;UACd7C,EAAE,GAAG1I,QAAQ,CAACsL,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAC5B,CAAC,MAAM;UACLnG,IAAI,GAAGzH,UAAU,CAAC4N,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5B;MACF,CAAC,MAAM,IAAIA,IAAI,CAACtN,MAAM,KAAK,CAAC,EAAE;QAC5BmH,IAAI,GAAGzH,UAAU,CAAC4N,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1B5C,EAAE,GAAG1I,QAAQ,CAACsL,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;MAC5B;;MAEA;MACA,IAAIjN,KAAK;MACT,IAAI,OAAO8G,IAAI,KAAK,QAAQ,EAAE;QAC5B;QACA,IAAI/I,IAAI,CAAC0J,MAAM,KAAK,QAAQ,IAAI1J,IAAI,CAAC6J,SAAS,EAAE;UAC9C7J,IAAI,CAAC4J,MAAM,CAACvC,IAAI,CAAC;YACfqE,KAAK,EAAE,MAAM;YACbC,MAAM,EAAE,SAAAA,CAAA,EAAW;cACjB3L,IAAI,CAAC+I,IAAI,CAACqG,KAAK,CAACpP,IAAI,EAAEkP,IAAI,CAAC;YAC7B;UACF,CAAC,CAAC;UAEF,OAAOlP,IAAI;QACb;;QAEA;QACA,IAAI,OAAOsM,EAAE,KAAK,WAAW,EAAE;UAC7BtM,IAAI,CAAC8I,KAAK,GAAGC,IAAI;QACnB;;QAEA;QACAuD,EAAE,GAAGtM,IAAI,CAAC+B,YAAY,CAACuK,EAAE,CAAC;QAC1B,KAAK,IAAI3K,CAAC,GAAC,CAAC,EAAEA,CAAC,GAAC2K,EAAE,CAAC1K,MAAM,EAAED,CAAC,EAAE,EAAE;UAC9B;UACAM,KAAK,GAAGjC,IAAI,CAACkC,UAAU,CAACoK,EAAE,CAAC3K,CAAC,CAAC,CAAC;UAE9B,IAAIM,KAAK,EAAE;YACT;YACA;YACA,IAAIjC,IAAI,CAAC4Q,OAAO,CAACtE,EAAE,CAAC3K,CAAC,CAAC,CAAC,EAAE;cACvBM,KAAK,CAACyM,SAAS,GAAG1O,IAAI,CAAC6M,IAAI,CAACP,EAAE,CAAC3K,CAAC,CAAC,CAAC;cAClCM,KAAK,CAACyL,UAAU,GAAG1N,IAAI,CAAC6B,SAAS,GAAG5B,MAAM,CAACgB,GAAG,CAACS,WAAW,GAAGO,KAAK,CAACyL,UAAU;YAC/E;YACAzL,KAAK,CAAC6G,KAAK,GAAGC,IAAI;;YAElB;YACA,IAAI/I,IAAI,CAAC6B,SAAS,IAAII,KAAK,CAACE,KAAK,IAAIF,KAAK,CAACE,KAAK,CAACwL,YAAY,EAAE;cAC7D1L,KAAK,CAACE,KAAK,CAACwL,YAAY,CAACO,YAAY,CAACzM,cAAc,CAACsH,IAAI,EAAE9I,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;YACpF,CAAC,MAAM,IAAIO,KAAK,CAACE,KAAK,EAAE;cACtBF,KAAK,CAACE,KAAK,CAAC+L,YAAY,GAAGnF,IAAI;YACjC;;YAEA;YACA,IAAI8D,IAAI,GAAG7M,IAAI,CAAC6M,IAAI,CAACP,EAAE,CAAC3K,CAAC,CAAC,CAAC;YAC3B,IAAIsL,QAAQ,GAAI,CAACjN,IAAI,CAACgJ,OAAO,CAAC/G,KAAK,CAAC+G,OAAO,CAAC,CAAC,CAAC,CAAC,GAAGhJ,IAAI,CAACgJ,OAAO,CAAC/G,KAAK,CAAC+G,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,GAAI6D,IAAI;YAChG,IAAIK,OAAO,GAAID,QAAQ,GAAG,IAAI,GAAIH,IAAI,CAACK,GAAG,CAAClL,KAAK,CAAC6G,KAAK,CAAC;;YAEvD;YACA,IAAI9I,IAAI,CAAC2J,UAAU,CAAC2C,EAAE,CAAC3K,CAAC,CAAC,CAAC,IAAI,CAACM,KAAK,CAACuF,OAAO,EAAE;cAC5CxH,IAAI,CAACgO,WAAW,CAAC1B,EAAE,CAAC3K,CAAC,CAAC,CAAC;cACvB3B,IAAI,CAAC2J,UAAU,CAAC2C,EAAE,CAAC3K,CAAC,CAAC,CAAC,GAAGgG,UAAU,CAAC3H,IAAI,CAACwM,MAAM,CAACsB,IAAI,CAAC9N,IAAI,EAAEiC,KAAK,CAAC,EAAEiL,OAAO,CAAC;YAC7E;YAEAlN,IAAI,CAACyG,KAAK,CAAC,MAAM,EAAExE,KAAK,CAACwK,GAAG,CAAC;UAC/B;QACF;MACF,CAAC,MAAM;QACLxK,KAAK,GAAGjC,IAAI,CAACkC,UAAU,CAACoK,EAAE,CAAC;QAC3B,OAAOrK,KAAK,GAAGA,KAAK,CAAC6G,KAAK,GAAG9I,IAAI,CAAC8I,KAAK;MACzC;MAEA,OAAO9I,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;IACI6M,IAAI,EAAE,SAAAA,CAAA,EAAW;MACf,IAAI7M,IAAI,GAAG,IAAI;MACf,IAAIkP,IAAI,GAAGH,SAAS;MACpB,IAAIlC,IAAI,EAAEP,EAAE;;MAEZ;MACA,IAAI4C,IAAI,CAACtN,MAAM,KAAK,CAAC,EAAE;QACrB;QACA,IAAI5B,IAAI,CAACuH,OAAO,CAAC3F,MAAM,EAAE;UACvB0K,EAAE,GAAGtM,IAAI,CAACuH,OAAO,CAAC,CAAC,CAAC,CAACkF,GAAG;QAC1B;MACF,CAAC,MAAM,IAAIyC,IAAI,CAACtN,MAAM,KAAK,CAAC,EAAE;QAC5B;QACA,IAAIE,GAAG,GAAG9B,IAAI,CAAC+B,YAAY,CAAC,CAAC;QAC7B,IAAIoN,KAAK,GAAGrN,GAAG,CAACiC,OAAO,CAACmL,IAAI,CAAC,CAAC,CAAC,CAAC;QAChC,IAAIC,KAAK,IAAI,CAAC,EAAE;UACd7C,EAAE,GAAG1I,QAAQ,CAACsL,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAC5B,CAAC,MAAM,IAAIlP,IAAI,CAACuH,OAAO,CAAC3F,MAAM,EAAE;UAC9B0K,EAAE,GAAGtM,IAAI,CAACuH,OAAO,CAAC,CAAC,CAAC,CAACkF,GAAG;UACxBI,IAAI,GAAGvL,UAAU,CAAC4N,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5B;MACF,CAAC,MAAM,IAAIA,IAAI,CAACtN,MAAM,KAAK,CAAC,EAAE;QAC5BiL,IAAI,GAAGvL,UAAU,CAAC4N,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1B5C,EAAE,GAAG1I,QAAQ,CAACsL,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;MAC5B;;MAEA;MACA,IAAI,OAAO5C,EAAE,KAAK,WAAW,EAAE;QAC7B,OAAO,CAAC;MACV;;MAEA;MACA,IAAI,OAAOO,IAAI,KAAK,QAAQ,KAAK7M,IAAI,CAAC0J,MAAM,KAAK,QAAQ,IAAI1J,IAAI,CAAC6J,SAAS,CAAC,EAAE;QAC5E7J,IAAI,CAAC4J,MAAM,CAACvC,IAAI,CAAC;UACfqE,KAAK,EAAE,MAAM;UACbC,MAAM,EAAE,SAAAA,CAAA,EAAW;YACjB3L,IAAI,CAAC6M,IAAI,CAACuC,KAAK,CAACpP,IAAI,EAAEkP,IAAI,CAAC;UAC7B;QACF,CAAC,CAAC;QAEF,OAAOlP,IAAI;MACb;;MAEA;MACA,IAAIiC,KAAK,GAAGjC,IAAI,CAACkC,UAAU,CAACoK,EAAE,CAAC;MAE/B,IAAIrK,KAAK,EAAE;QACT,IAAI,OAAO4K,IAAI,KAAK,QAAQ,IAAIA,IAAI,IAAI,CAAC,EAAE;UACzC;UACA,IAAI+D,OAAO,GAAG5Q,IAAI,CAAC4Q,OAAO,CAACtE,EAAE,CAAC;UAC9B,IAAIsE,OAAO,EAAE;YACX5Q,IAAI,CAACyO,KAAK,CAACnC,EAAE,EAAE,IAAI,CAAC;UACtB;;UAEA;UACArK,KAAK,CAAC+K,KAAK,GAAGH,IAAI;UAClB5K,KAAK,CAACuK,MAAM,GAAG,KAAK;UACpBxM,IAAI,CAACgO,WAAW,CAAC1B,EAAE,CAAC;;UAEpB;UACA,IAAI,CAACtM,IAAI,CAAC6B,SAAS,IAAII,KAAK,CAACE,KAAK,IAAI,CAAC2M,KAAK,CAAC7M,KAAK,CAACE,KAAK,CAAC8K,QAAQ,CAAC,EAAE;YAClEhL,KAAK,CAACE,KAAK,CAACT,WAAW,GAAGmL,IAAI;UAChC;;UAEA;UACA,IAAIgE,WAAW,GAAG,SAAAA,CAAA,EAAW;YAC3B;YACA,IAAID,OAAO,EAAE;cACX5Q,IAAI,CAAC8G,IAAI,CAACwF,EAAE,EAAE,IAAI,CAAC;YACrB;YAEAtM,IAAI,CAACyG,KAAK,CAAC,MAAM,EAAE6F,EAAE,CAAC;UACxB,CAAC;;UAED;UACA,IAAIsE,OAAO,IAAI,CAAC5Q,IAAI,CAAC6B,SAAS,EAAE;YAC9B,IAAIiP,QAAQ,GAAG,SAAAA,CAAA,EAAW;cACxB,IAAI,CAAC9Q,IAAI,CAAC6J,SAAS,EAAE;gBACnBgH,WAAW,CAAC,CAAC;cACf,CAAC,MAAM;gBACLlJ,UAAU,CAACmJ,QAAQ,EAAE,CAAC,CAAC;cACzB;YACF,CAAC;YACDnJ,UAAU,CAACmJ,QAAQ,EAAE,CAAC,CAAC;UACzB,CAAC,MAAM;YACLD,WAAW,CAAC,CAAC;UACf;QACF,CAAC,MAAM;UACL,IAAI7Q,IAAI,CAAC6B,SAAS,EAAE;YAClB,IAAIkP,QAAQ,GAAG/Q,IAAI,CAAC4Q,OAAO,CAACtE,EAAE,CAAC,GAAGrM,MAAM,CAACgB,GAAG,CAACS,WAAW,GAAGO,KAAK,CAACyL,UAAU,GAAG,CAAC;YAC/E,IAAIsD,QAAQ,GAAG/O,KAAK,CAACyM,SAAS,GAAGzM,KAAK,CAACyM,SAAS,GAAGzM,KAAK,CAAC+K,KAAK,GAAG,CAAC;YAClE,OAAO/K,KAAK,CAAC+K,KAAK,IAAIgE,QAAQ,GAAGD,QAAQ,GAAGjE,IAAI,CAACK,GAAG,CAAClL,KAAK,CAAC6G,KAAK,CAAC,CAAC;UACpE,CAAC,MAAM;YACL,OAAO7G,KAAK,CAACE,KAAK,CAACT,WAAW;UAChC;QACF;MACF;MAEA,OAAO1B,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;IACI4Q,OAAO,EAAE,SAAAA,CAAStE,EAAE,EAAE;MACpB,IAAItM,IAAI,GAAG,IAAI;;MAEf;MACA,IAAI,OAAOsM,EAAE,KAAK,QAAQ,EAAE;QAC1B,IAAIrK,KAAK,GAAGjC,IAAI,CAACkC,UAAU,CAACoK,EAAE,CAAC;QAC/B,OAAOrK,KAAK,GAAG,CAACA,KAAK,CAACuF,OAAO,GAAG,KAAK;MACvC;;MAEA;MACA,KAAK,IAAI7F,CAAC,GAAC,CAAC,EAAEA,CAAC,GAAC3B,IAAI,CAACuH,OAAO,CAAC3F,MAAM,EAAED,CAAC,EAAE,EAAE;QACxC,IAAI,CAAC3B,IAAI,CAACuH,OAAO,CAAC5F,CAAC,CAAC,CAAC6F,OAAO,EAAE;UAC5B,OAAO,IAAI;QACb;MACF;MAEA,OAAO,KAAK;IACd,CAAC;IAED;AACJ;AACA;AACA;AACA;IACIyF,QAAQ,EAAE,SAAAA,CAASX,EAAE,EAAE;MACrB,IAAItM,IAAI,GAAG,IAAI;MACf,IAAIiN,QAAQ,GAAGjN,IAAI,CAACyJ,SAAS;;MAE7B;MACA,IAAIxH,KAAK,GAAGjC,IAAI,CAACkC,UAAU,CAACoK,EAAE,CAAC;MAC/B,IAAIrK,KAAK,EAAE;QACTgL,QAAQ,GAAGjN,IAAI,CAACgJ,OAAO,CAAC/G,KAAK,CAAC+G,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;MAClD;MAEA,OAAOiE,QAAQ;IACjB,CAAC;IAED;AACJ;AACA;AACA;IACIrK,KAAK,EAAE,SAAAA,CAAA,EAAW;MAChB,OAAO,IAAI,CAAC8G,MAAM;IACpB,CAAC;IAED;AACJ;AACA;AACA;IACInH,MAAM,EAAE,SAAAA,CAAA,EAAW;MACjB,IAAIvC,IAAI,GAAG,IAAI;;MAEf;MACA,IAAIiR,MAAM,GAAGjR,IAAI,CAACuH,OAAO;MACzB,KAAK,IAAI5F,CAAC,GAAC,CAAC,EAAEA,CAAC,GAACsP,MAAM,CAACrP,MAAM,EAAED,CAAC,EAAE,EAAE;QAClC;QACA,IAAI,CAACsP,MAAM,CAACtP,CAAC,CAAC,CAAC6F,OAAO,EAAE;UACtBxH,IAAI,CAACsC,IAAI,CAAC2O,MAAM,CAACtP,CAAC,CAAC,CAAC8K,GAAG,CAAC;QAC1B;;QAEA;QACA,IAAI,CAACzM,IAAI,CAAC6B,SAAS,EAAE;UACnB;UACA7B,IAAI,CAACgP,WAAW,CAACiC,MAAM,CAACtP,CAAC,CAAC,CAACQ,KAAK,CAAC;;UAEjC;UACA8O,MAAM,CAACtP,CAAC,CAAC,CAACQ,KAAK,CAACqE,mBAAmB,CAAC,OAAO,EAAEyK,MAAM,CAACtP,CAAC,CAAC,CAACuP,QAAQ,EAAE,KAAK,CAAC;UACvED,MAAM,CAACtP,CAAC,CAAC,CAACQ,KAAK,CAACqE,mBAAmB,CAACvG,MAAM,CAACQ,aAAa,EAAEwQ,MAAM,CAACtP,CAAC,CAAC,CAACwP,OAAO,EAAE,KAAK,CAAC;UACnFF,MAAM,CAACtP,CAAC,CAAC,CAACQ,KAAK,CAACqE,mBAAmB,CAAC,OAAO,EAAEyK,MAAM,CAACtP,CAAC,CAAC,CAACyP,MAAM,EAAE,KAAK,CAAC;;UAErE;UACAnR,MAAM,CAACyF,kBAAkB,CAACuL,MAAM,CAACtP,CAAC,CAAC,CAACQ,KAAK,CAAC;QAC5C;;QAEA;QACA,OAAO8O,MAAM,CAACtP,CAAC,CAAC,CAACQ,KAAK;;QAEtB;QACAnC,IAAI,CAACgO,WAAW,CAACiD,MAAM,CAACtP,CAAC,CAAC,CAAC8K,GAAG,CAAC;MACjC;;MAEA;MACA,IAAI0C,KAAK,GAAGlP,MAAM,CAACK,MAAM,CAACyD,OAAO,CAAC/D,IAAI,CAAC;MACvC,IAAImP,KAAK,IAAI,CAAC,EAAE;QACdlP,MAAM,CAACK,MAAM,CAAC+Q,MAAM,CAAClC,KAAK,EAAE,CAAC,CAAC;MAChC;;MAEA;MACA,IAAImC,QAAQ,GAAG,IAAI;MACnB,KAAK3P,CAAC,GAAC,CAAC,EAAEA,CAAC,GAAC1B,MAAM,CAACK,MAAM,CAACsB,MAAM,EAAED,CAAC,EAAE,EAAE;QACrC,IAAI1B,MAAM,CAACK,MAAM,CAACqB,CAAC,CAAC,CAACuH,IAAI,KAAKlJ,IAAI,CAACkJ,IAAI,IAAIlJ,IAAI,CAACkJ,IAAI,CAACnF,OAAO,CAAC9D,MAAM,CAACK,MAAM,CAACqB,CAAC,CAAC,CAACuH,IAAI,CAAC,IAAI,CAAC,EAAE;UACxFoI,QAAQ,GAAG,KAAK;UAChB;QACF;MACF;MAEA,IAAIC,KAAK,IAAID,QAAQ,EAAE;QACrB,OAAOC,KAAK,CAACvR,IAAI,CAACkJ,IAAI,CAAC;MACzB;;MAEA;MACAjJ,MAAM,CAACa,OAAO,GAAG,KAAK;;MAEtB;MACAd,IAAI,CAAC0J,MAAM,GAAG,UAAU;MACxB1J,IAAI,CAACuH,OAAO,GAAG,EAAE;MACjBvH,IAAI,GAAG,IAAI;MAEX,OAAO,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;IACIwR,EAAE,EAAE,SAAAA,CAAS9F,KAAK,EAAE1B,EAAE,EAAEsC,EAAE,EAAEyB,IAAI,EAAE;MAChC,IAAI/N,IAAI,GAAG,IAAI;MACf,IAAIyR,MAAM,GAAGzR,IAAI,CAAC,KAAK,GAAG0L,KAAK,CAAC;MAEhC,IAAI,OAAO1B,EAAE,KAAK,UAAU,EAAE;QAC5ByH,MAAM,CAACpK,IAAI,CAAC0G,IAAI,GAAG;UAACzB,EAAE,EAAEA,EAAE;UAAEtC,EAAE,EAAEA,EAAE;UAAE+D,IAAI,EAAEA;QAAI,CAAC,GAAG;UAACzB,EAAE,EAAEA,EAAE;UAAEtC,EAAE,EAAEA;QAAE,CAAC,CAAC;MACrE;MAEA,OAAOhK,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;AACA;AACA;IACI0R,GAAG,EAAE,SAAAA,CAAShG,KAAK,EAAE1B,EAAE,EAAEsC,EAAE,EAAE;MAC3B,IAAItM,IAAI,GAAG,IAAI;MACf,IAAIyR,MAAM,GAAGzR,IAAI,CAAC,KAAK,GAAG0L,KAAK,CAAC;MAChC,IAAI/J,CAAC,GAAG,CAAC;;MAET;MACA,IAAI,OAAOqI,EAAE,KAAK,QAAQ,EAAE;QAC1BsC,EAAE,GAAGtC,EAAE;QACPA,EAAE,GAAG,IAAI;MACX;MAEA,IAAIA,EAAE,IAAIsC,EAAE,EAAE;QACZ;QACA,KAAK3K,CAAC,GAAC,CAAC,EAAEA,CAAC,GAAC8P,MAAM,CAAC7P,MAAM,EAAED,CAAC,EAAE,EAAE;UAC9B,IAAIgQ,IAAI,GAAIrF,EAAE,KAAKmF,MAAM,CAAC9P,CAAC,CAAC,CAAC2K,EAAG;UAChC,IAAItC,EAAE,KAAKyH,MAAM,CAAC9P,CAAC,CAAC,CAACqI,EAAE,IAAI2H,IAAI,IAAI,CAAC3H,EAAE,IAAI2H,IAAI,EAAE;YAC9CF,MAAM,CAACJ,MAAM,CAAC1P,CAAC,EAAE,CAAC,CAAC;YACnB;UACF;QACF;MACF,CAAC,MAAM,IAAI+J,KAAK,EAAE;QAChB;QACA1L,IAAI,CAAC,KAAK,GAAG0L,KAAK,CAAC,GAAG,EAAE;MAC1B,CAAC,MAAM;QACL;QACA,IAAIkG,IAAI,GAAGC,MAAM,CAACD,IAAI,CAAC5R,IAAI,CAAC;QAC5B,KAAK2B,CAAC,GAAC,CAAC,EAAEA,CAAC,GAACiQ,IAAI,CAAChQ,MAAM,EAAED,CAAC,EAAE,EAAE;UAC5B,IAAKiQ,IAAI,CAACjQ,CAAC,CAAC,CAACoC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAK+N,KAAK,CAACC,OAAO,CAAC/R,IAAI,CAAC4R,IAAI,CAACjQ,CAAC,CAAC,CAAC,CAAC,EAAE;YAClE3B,IAAI,CAAC4R,IAAI,CAACjQ,CAAC,CAAC,CAAC,GAAG,EAAE;UACpB;QACF;MACF;MAEA,OAAO3B,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;AACA;AACA;IACI+N,IAAI,EAAE,SAAAA,CAASrC,KAAK,EAAE1B,EAAE,EAAEsC,EAAE,EAAE;MAC5B,IAAItM,IAAI,GAAG,IAAI;;MAEf;MACAA,IAAI,CAACwR,EAAE,CAAC9F,KAAK,EAAE1B,EAAE,EAAEsC,EAAE,EAAE,CAAC,CAAC;MAEzB,OAAOtM,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;AACA;AACA;IACIyG,KAAK,EAAE,SAAAA,CAASiF,KAAK,EAAEY,EAAE,EAAE0F,GAAG,EAAE;MAC9B,IAAIhS,IAAI,GAAG,IAAI;MACf,IAAIyR,MAAM,GAAGzR,IAAI,CAAC,KAAK,GAAG0L,KAAK,CAAC;;MAEhC;MACA,KAAK,IAAI/J,CAAC,GAAC8P,MAAM,CAAC7P,MAAM,GAAC,CAAC,EAAED,CAAC,IAAE,CAAC,EAAEA,CAAC,EAAE,EAAE;QACrC;QACA,IAAI,CAAC8P,MAAM,CAAC9P,CAAC,CAAC,CAAC2K,EAAE,IAAImF,MAAM,CAAC9P,CAAC,CAAC,CAAC2K,EAAE,KAAKA,EAAE,IAAIZ,KAAK,KAAK,MAAM,EAAE;UAC5D/D,UAAU,CAAC,UAASqC,EAAE,EAAE;YACtBA,EAAE,CAACiI,IAAI,CAAC,IAAI,EAAE3F,EAAE,EAAE0F,GAAG,CAAC;UACxB,CAAC,CAAClE,IAAI,CAAC9N,IAAI,EAAEyR,MAAM,CAAC9P,CAAC,CAAC,CAACqI,EAAE,CAAC,EAAE,CAAC,CAAC;;UAE9B;UACA,IAAIyH,MAAM,CAAC9P,CAAC,CAAC,CAACoM,IAAI,EAAE;YAClB/N,IAAI,CAAC0R,GAAG,CAAChG,KAAK,EAAE+F,MAAM,CAAC9P,CAAC,CAAC,CAACqI,EAAE,EAAEyH,MAAM,CAAC9P,CAAC,CAAC,CAAC2K,EAAE,CAAC;UAC7C;QACF;MACF;;MAEA;MACAtM,IAAI,CAAC4M,UAAU,CAAClB,KAAK,CAAC;MAEtB,OAAO1L,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;AACA;IACI4M,UAAU,EAAE,SAAAA,CAASlB,KAAK,EAAE;MAC1B,IAAI1L,IAAI,GAAG,IAAI;MAEf,IAAIA,IAAI,CAAC4J,MAAM,CAAChI,MAAM,GAAG,CAAC,EAAE;QAC1B,IAAIsQ,IAAI,GAAGlS,IAAI,CAAC4J,MAAM,CAAC,CAAC,CAAC;;QAEzB;QACA,IAAIsI,IAAI,CAACxG,KAAK,KAAKA,KAAK,EAAE;UACxB1L,IAAI,CAAC4J,MAAM,CAACuI,KAAK,CAAC,CAAC;UACnBnS,IAAI,CAAC4M,UAAU,CAAC,CAAC;QACnB;;QAEA;QACA,IAAI,CAAClB,KAAK,EAAE;UACVwG,IAAI,CAACvG,MAAM,CAAC,CAAC;QACf;MACF;MAEA,OAAO3L,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;IACIwM,MAAM,EAAE,SAAAA,CAASvK,KAAK,EAAE;MACtB,IAAIjC,IAAI,GAAG,IAAI;MACf,IAAIiJ,MAAM,GAAGhH,KAAK,CAAC+G,OAAO;;MAE1B;MACA;MACA;MACA,IAAI,CAAChJ,IAAI,CAAC6B,SAAS,IAAII,KAAK,CAACE,KAAK,IAAI,CAACF,KAAK,CAACE,KAAK,CAACgM,MAAM,IAAI,CAAClM,KAAK,CAACE,KAAK,CAACiQ,KAAK,IAAInQ,KAAK,CAACE,KAAK,CAACT,WAAW,GAAGO,KAAK,CAACqL,KAAK,EAAE;QACxH3F,UAAU,CAAC3H,IAAI,CAACwM,MAAM,CAACsB,IAAI,CAAC9N,IAAI,EAAEiC,KAAK,CAAC,EAAE,GAAG,CAAC;QAC9C,OAAOjC,IAAI;MACb;;MAEA;MACA,IAAIyI,IAAI,GAAG,CAAC,EAAExG,KAAK,CAACuG,KAAK,IAAIxI,IAAI,CAACgJ,OAAO,CAACC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;;MAErD;MACAjJ,IAAI,CAACyG,KAAK,CAAC,KAAK,EAAExE,KAAK,CAACwK,GAAG,CAAC;;MAE5B;MACA,IAAI,CAACzM,IAAI,CAAC6B,SAAS,IAAI4G,IAAI,EAAE;QAC3BzI,IAAI,CAACsC,IAAI,CAACL,KAAK,CAACwK,GAAG,EAAE,IAAI,CAAC,CAAC3F,IAAI,CAAC7E,KAAK,CAACwK,GAAG,CAAC;MAC5C;;MAEA;MACA,IAAIzM,IAAI,CAAC6B,SAAS,IAAI4G,IAAI,EAAE;QAC1BzI,IAAI,CAACyG,KAAK,CAAC,MAAM,EAAExE,KAAK,CAACwK,GAAG,CAAC;QAC7BxK,KAAK,CAAC+K,KAAK,GAAG/K,KAAK,CAACoL,MAAM,IAAI,CAAC;QAC/BpL,KAAK,CAACyM,SAAS,GAAG,CAAC;QACnBzM,KAAK,CAACyL,UAAU,GAAGzN,MAAM,CAACgB,GAAG,CAACS,WAAW;QAEzC,IAAIwL,OAAO,GAAI,CAACjL,KAAK,CAACqL,KAAK,GAAGrL,KAAK,CAACoL,MAAM,IAAI,IAAI,GAAIP,IAAI,CAACK,GAAG,CAAClL,KAAK,CAAC6G,KAAK,CAAC;QAC3E9I,IAAI,CAAC2J,UAAU,CAAC1H,KAAK,CAACwK,GAAG,CAAC,GAAG9E,UAAU,CAAC3H,IAAI,CAACwM,MAAM,CAACsB,IAAI,CAAC9N,IAAI,EAAEiC,KAAK,CAAC,EAAEiL,OAAO,CAAC;MACjF;;MAEA;MACA,IAAIlN,IAAI,CAAC6B,SAAS,IAAI,CAAC4G,IAAI,EAAE;QAC3BxG,KAAK,CAACuF,OAAO,GAAG,IAAI;QACpBvF,KAAK,CAACuK,MAAM,GAAG,IAAI;QACnBvK,KAAK,CAAC+K,KAAK,GAAG/K,KAAK,CAACoL,MAAM,IAAI,CAAC;QAC/BpL,KAAK,CAACyM,SAAS,GAAG,CAAC;QACnB1O,IAAI,CAACgO,WAAW,CAAC/L,KAAK,CAACwK,GAAG,CAAC;;QAE3B;QACAzM,IAAI,CAAC6O,YAAY,CAAC5M,KAAK,CAACE,KAAK,CAAC;;QAE9B;QACAlC,MAAM,CAAC4C,YAAY,CAAC,CAAC;MACvB;;MAEA;MACA,IAAI,CAAC7C,IAAI,CAAC6B,SAAS,IAAI,CAAC4G,IAAI,EAAE;QAC5BzI,IAAI,CAACsC,IAAI,CAACL,KAAK,CAACwK,GAAG,EAAE,IAAI,CAAC;MAC5B;MAEA,OAAOzM,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;IACIgO,WAAW,EAAE,SAAAA,CAAS1B,EAAE,EAAE;MACxB,IAAItM,IAAI,GAAG,IAAI;MAEf,IAAIA,IAAI,CAAC2J,UAAU,CAAC2C,EAAE,CAAC,EAAE;QACvB;QACA,IAAI,OAAOtM,IAAI,CAAC2J,UAAU,CAAC2C,EAAE,CAAC,KAAK,UAAU,EAAE;UAC7C5E,YAAY,CAAC1H,IAAI,CAAC2J,UAAU,CAAC2C,EAAE,CAAC,CAAC;QACnC,CAAC,MAAM;UACL,IAAIrK,KAAK,GAAGjC,IAAI,CAACkC,UAAU,CAACoK,EAAE,CAAC;UAC/B,IAAIrK,KAAK,IAAIA,KAAK,CAACE,KAAK,EAAE;YACxBF,KAAK,CAACE,KAAK,CAACqE,mBAAmB,CAAC,OAAO,EAAExG,IAAI,CAAC2J,UAAU,CAAC2C,EAAE,CAAC,EAAE,KAAK,CAAC;UACtE;QACF;QAEA,OAAOtM,IAAI,CAAC2J,UAAU,CAAC2C,EAAE,CAAC;MAC5B;MAEA,OAAOtM,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;IACIkC,UAAU,EAAE,SAAAA,CAASoK,EAAE,EAAE;MACvB,IAAItM,IAAI,GAAG,IAAI;;MAEf;MACA,KAAK,IAAI2B,CAAC,GAAC,CAAC,EAAEA,CAAC,GAAC3B,IAAI,CAACuH,OAAO,CAAC3F,MAAM,EAAED,CAAC,EAAE,EAAE;QACxC,IAAI2K,EAAE,KAAKtM,IAAI,CAACuH,OAAO,CAAC5F,CAAC,CAAC,CAAC8K,GAAG,EAAE;UAC9B,OAAOzM,IAAI,CAACuH,OAAO,CAAC5F,CAAC,CAAC;QACxB;MACF;MAEA,OAAO,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;IACI+K,cAAc,EAAE,SAAAA,CAAA,EAAW;MACzB,IAAI1M,IAAI,GAAG,IAAI;MAEfA,IAAI,CAACqS,MAAM,CAAC,CAAC;;MAEb;MACA,KAAK,IAAI1Q,CAAC,GAAC,CAAC,EAAEA,CAAC,GAAC3B,IAAI,CAACuH,OAAO,CAAC3F,MAAM,EAAED,CAAC,EAAE,EAAE;QACxC,IAAI3B,IAAI,CAACuH,OAAO,CAAC5F,CAAC,CAAC,CAAC6K,MAAM,EAAE;UAC1B,OAAOxM,IAAI,CAACuH,OAAO,CAAC5F,CAAC,CAAC,CAAC2Q,KAAK,CAAC,CAAC;QAChC;MACF;;MAEA;MACA,OAAO,IAAInG,KAAK,CAACnM,IAAI,CAAC;IACxB,CAAC;IAED;AACJ;AACA;IACIqS,MAAM,EAAE,SAAAA,CAAA,EAAW;MACjB,IAAIrS,IAAI,GAAG,IAAI;MACf,IAAIuS,KAAK,GAAGvS,IAAI,CAAC0I,KAAK;MACtB,IAAI8J,GAAG,GAAG,CAAC;MACX,IAAI7Q,CAAC,GAAG,CAAC;;MAET;MACA,IAAI3B,IAAI,CAACuH,OAAO,CAAC3F,MAAM,GAAG2Q,KAAK,EAAE;QAC/B;MACF;;MAEA;MACA,KAAK5Q,CAAC,GAAC,CAAC,EAAEA,CAAC,GAAC3B,IAAI,CAACuH,OAAO,CAAC3F,MAAM,EAAED,CAAC,EAAE,EAAE;QACpC,IAAI3B,IAAI,CAACuH,OAAO,CAAC5F,CAAC,CAAC,CAAC6K,MAAM,EAAE;UAC1BgG,GAAG,EAAE;QACP;MACF;;MAEA;MACA,KAAK7Q,CAAC,GAAC3B,IAAI,CAACuH,OAAO,CAAC3F,MAAM,GAAG,CAAC,EAAED,CAAC,IAAE,CAAC,EAAEA,CAAC,EAAE,EAAE;QACzC,IAAI6Q,GAAG,IAAID,KAAK,EAAE;UAChB;QACF;QAEA,IAAIvS,IAAI,CAACuH,OAAO,CAAC5F,CAAC,CAAC,CAAC6K,MAAM,EAAE;UAC1B;UACA,IAAIxM,IAAI,CAAC6B,SAAS,IAAI7B,IAAI,CAACuH,OAAO,CAAC5F,CAAC,CAAC,CAACQ,KAAK,EAAE;YAC3CnC,IAAI,CAACuH,OAAO,CAAC5F,CAAC,CAAC,CAACQ,KAAK,CAACmE,UAAU,CAAC,CAAC,CAAC;UACrC;;UAEA;UACAtG,IAAI,CAACuH,OAAO,CAAC8J,MAAM,CAAC1P,CAAC,EAAE,CAAC,CAAC;UACzB6Q,GAAG,EAAE;QACP;MACF;IACF,CAAC;IAED;AACJ;AACA;AACA;AACA;IACIzQ,YAAY,EAAE,SAAAA,CAASuK,EAAE,EAAE;MACzB,IAAItM,IAAI,GAAG,IAAI;MAEf,IAAI,OAAOsM,EAAE,KAAK,WAAW,EAAE;QAC7B,IAAIxK,GAAG,GAAG,EAAE;QACZ,KAAK,IAAIH,CAAC,GAAC,CAAC,EAAEA,CAAC,GAAC3B,IAAI,CAACuH,OAAO,CAAC3F,MAAM,EAAED,CAAC,EAAE,EAAE;UACxCG,GAAG,CAACuF,IAAI,CAACrH,IAAI,CAACuH,OAAO,CAAC5F,CAAC,CAAC,CAAC8K,GAAG,CAAC;QAC/B;QAEA,OAAO3K,GAAG;MACZ,CAAC,MAAM;QACL,OAAO,CAACwK,EAAE,CAAC;MACb;IACF,CAAC;IAED;AACJ;AACA;AACA;AACA;IACImB,cAAc,EAAE,SAAAA,CAASxL,KAAK,EAAE;MAC9B,IAAIjC,IAAI,GAAG,IAAI;;MAEf;MACAiC,KAAK,CAACE,KAAK,CAACwL,YAAY,GAAG1N,MAAM,CAACgB,GAAG,CAAC6E,kBAAkB,CAAC,CAAC;MAC1D7D,KAAK,CAACE,KAAK,CAACwL,YAAY,CAAC5H,MAAM,GAAGwL,KAAK,CAACvR,IAAI,CAACkJ,IAAI,CAAC;;MAElD;MACA,IAAIjH,KAAK,CAACwQ,OAAO,EAAE;QACjBxQ,KAAK,CAACE,KAAK,CAACwL,YAAY,CAAC3H,OAAO,CAAC/D,KAAK,CAACwQ,OAAO,CAAC;MACjD,CAAC,MAAM;QACLxQ,KAAK,CAACE,KAAK,CAACwL,YAAY,CAAC3H,OAAO,CAAC/D,KAAK,CAACE,KAAK,CAAC;MAC/C;;MAEA;MACAF,KAAK,CAACE,KAAK,CAACwL,YAAY,CAAClF,IAAI,GAAGxG,KAAK,CAACuG,KAAK;MAC3C,IAAIvG,KAAK,CAACuG,KAAK,EAAE;QACfvG,KAAK,CAACE,KAAK,CAACwL,YAAY,CAAC+C,SAAS,GAAGzO,KAAK,CAACoL,MAAM,IAAI,CAAC;QACtDpL,KAAK,CAACE,KAAK,CAACwL,YAAY,CAACgD,OAAO,GAAG1O,KAAK,CAACqL,KAAK,IAAI,CAAC;MACrD;MACArL,KAAK,CAACE,KAAK,CAACwL,YAAY,CAACO,YAAY,CAACzM,cAAc,CAACQ,KAAK,CAAC6G,KAAK,EAAE7I,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;MAEzF,OAAO1B,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;AACA;IACI6O,YAAY,EAAE,SAAAA,CAAStB,IAAI,EAAE;MAC3B,IAAIvN,IAAI,GAAG,IAAI;MACf,IAAI0S,KAAK,GAAGzS,MAAM,CAACS,UAAU,IAAIT,MAAM,CAACS,UAAU,CAACiS,MAAM,CAAC5O,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;MAE/E,IAAI9D,MAAM,CAACoF,cAAc,IAAIkI,IAAI,CAACI,YAAY,EAAE;QAC9CJ,IAAI,CAACI,YAAY,CAACtH,OAAO,GAAG,IAAI;QAChCkH,IAAI,CAACI,YAAY,CAACrH,UAAU,CAAC,CAAC,CAAC;QAC/B,IAAIoM,KAAK,EAAE;UACT,IAAI;YAAEnF,IAAI,CAACI,YAAY,CAAC5H,MAAM,GAAG9F,MAAM,CAACoF,cAAc;UAAE,CAAC,CAAC,OAAMpC,CAAC,EAAE,CAAC;QACtE;MACF;MACAsK,IAAI,CAACI,YAAY,GAAG,IAAI;MAExB,OAAO3N,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;IACIgP,WAAW,EAAE,SAAAA,CAASzB,IAAI,EAAE;MAC1B,IAAIqF,OAAO,GAAG,iBAAiB,CAAC7P,IAAI,CAAC9C,MAAM,CAACS,UAAU,IAAIT,MAAM,CAACS,UAAU,CAAC8C,SAAS,CAAC;MACtF,IAAI,CAACoP,OAAO,EAAE;QACZrF,IAAI,CAACvF,GAAG,GAAG,wFAAwF;MACrG;IACF;EACF,CAAC;;EAED;EACA;;EAEA;AACF;AACA;AACA;EACE,IAAImE,KAAK,GAAG,SAAAA,CAAS0G,IAAI,EAAE;IACzB,IAAI,CAACC,OAAO,GAAGD,IAAI;IACnB,IAAI,CAAC/S,IAAI,CAAC,CAAC;EACb,CAAC;EACDqM,KAAK,CAACpM,SAAS,GAAG;IAChB;AACJ;AACA;AACA;IACID,IAAI,EAAE,SAAAA,CAAA,EAAW;MACf,IAAIE,IAAI,GAAG,IAAI;MACf,IAAI+S,MAAM,GAAG/S,IAAI,CAAC8S,OAAO;;MAEzB;MACA9S,IAAI,CAACO,MAAM,GAAGwS,MAAM,CAACxS,MAAM;MAC3BP,IAAI,CAACwI,KAAK,GAAGuK,MAAM,CAACvK,KAAK;MACzBxI,IAAI,CAACQ,OAAO,GAAGuS,MAAM,CAACvS,OAAO;MAC7BR,IAAI,CAAC8I,KAAK,GAAGiK,MAAM,CAACjK,KAAK;MACzB9I,IAAI,CAACgN,KAAK,GAAG,CAAC;MACdhN,IAAI,CAACwH,OAAO,GAAG,IAAI;MACnBxH,IAAI,CAACwM,MAAM,GAAG,IAAI;MAClBxM,IAAI,CAACgJ,OAAO,GAAG,WAAW;;MAE1B;MACAhJ,IAAI,CAACyM,GAAG,GAAG,EAAExM,MAAM,CAACC,QAAQ;;MAE5B;MACA6S,MAAM,CAACxL,OAAO,CAACF,IAAI,CAACrH,IAAI,CAAC;;MAEzB;MACAA,IAAI,CAACgT,MAAM,CAAC,CAAC;MAEb,OAAOhT,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;IACIgT,MAAM,EAAE,SAAAA,CAAA,EAAW;MACjB,IAAIhT,IAAI,GAAG,IAAI;MACf,IAAI+S,MAAM,GAAG/S,IAAI,CAAC8S,OAAO;MACzB,IAAI1R,MAAM,GAAInB,MAAM,CAACM,MAAM,IAAIP,IAAI,CAACO,MAAM,IAAIP,IAAI,CAAC8S,OAAO,CAACvS,MAAM,GAAI,CAAC,GAAGP,IAAI,CAACQ,OAAO;MAErF,IAAIuS,MAAM,CAAClR,SAAS,EAAE;QACpB;QACA7B,IAAI,CAACmC,KAAK,GAAI,OAAOlC,MAAM,CAACgB,GAAG,CAACgS,UAAU,KAAK,WAAW,GAAIhT,MAAM,CAACgB,GAAG,CAACiS,cAAc,CAAC,CAAC,GAAGjT,MAAM,CAACgB,GAAG,CAACgS,UAAU,CAAC,CAAC;QACnHjT,IAAI,CAACmC,KAAK,CAACX,IAAI,CAACC,cAAc,CAACL,MAAM,EAAEnB,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;QAC9D1B,IAAI,CAACmC,KAAK,CAACgM,MAAM,GAAG,IAAI;QACxBnO,IAAI,CAACmC,KAAK,CAAC6D,OAAO,CAAC/F,MAAM,CAACY,UAAU,CAAC;MACvC,CAAC,MAAM,IAAI,CAACZ,MAAM,CAACa,OAAO,EAAE;QAC1B;QACAd,IAAI,CAACmC,KAAK,GAAGlC,MAAM,CAAC0G,iBAAiB,CAAC,CAAC;;QAEvC;QACA3G,IAAI,CAACkR,QAAQ,GAAGlR,IAAI,CAACmT,cAAc,CAACrF,IAAI,CAAC9N,IAAI,CAAC;QAC9CA,IAAI,CAACmC,KAAK,CAACuE,gBAAgB,CAAC,OAAO,EAAE1G,IAAI,CAACkR,QAAQ,EAAE,KAAK,CAAC;;QAE1D;QACAlR,IAAI,CAACmR,OAAO,GAAGnR,IAAI,CAACoT,aAAa,CAACtF,IAAI,CAAC9N,IAAI,CAAC;QAC5CA,IAAI,CAACmC,KAAK,CAACuE,gBAAgB,CAACzG,MAAM,CAACQ,aAAa,EAAET,IAAI,CAACmR,OAAO,EAAE,KAAK,CAAC;;QAEtE;QACA;QACAnR,IAAI,CAACoR,MAAM,GAAGpR,IAAI,CAACqT,YAAY,CAACvF,IAAI,CAAC9N,IAAI,CAAC;QAC1CA,IAAI,CAACmC,KAAK,CAACuE,gBAAgB,CAAC,OAAO,EAAE1G,IAAI,CAACoR,MAAM,EAAE,KAAK,CAAC;;QAExD;QACApR,IAAI,CAACmC,KAAK,CAAC6F,GAAG,GAAG+K,MAAM,CAAC7J,IAAI;QAC5BlJ,IAAI,CAACmC,KAAK,CAAC0G,OAAO,GAAGkK,MAAM,CAACnK,QAAQ,KAAK,IAAI,GAAG,MAAM,GAAGmK,MAAM,CAACnK,QAAQ;QACxE5I,IAAI,CAACmC,KAAK,CAACf,MAAM,GAAGA,MAAM,GAAGnB,MAAM,CAACmB,MAAM,CAAC,CAAC;;QAE5C;QACApB,IAAI,CAACmC,KAAK,CAACwD,IAAI,CAAC,CAAC;MACnB;MAEA,OAAO3F,IAAI;IACb,CAAC;IAED;AACJ;AACA;AACA;IACIsS,KAAK,EAAE,SAAAA,CAAA,EAAW;MAChB,IAAItS,IAAI,GAAG,IAAI;MACf,IAAI+S,MAAM,GAAG/S,IAAI,CAAC8S,OAAO;;MAEzB;MACA9S,IAAI,CAACO,MAAM,GAAGwS,MAAM,CAACxS,MAAM;MAC3BP,IAAI,CAACwI,KAAK,GAAGuK,MAAM,CAACvK,KAAK;MACzBxI,IAAI,CAACQ,OAAO,GAAGuS,MAAM,CAACvS,OAAO;MAC7BR,IAAI,CAAC8I,KAAK,GAAGiK,MAAM,CAACjK,KAAK;MACzB9I,IAAI,CAACgN,KAAK,GAAG,CAAC;MACdhN,IAAI,CAAC0O,SAAS,GAAG,CAAC;MAClB1O,IAAI,CAACwH,OAAO,GAAG,IAAI;MACnBxH,IAAI,CAACwM,MAAM,GAAG,IAAI;MAClBxM,IAAI,CAACgJ,OAAO,GAAG,WAAW;;MAE1B;MACAhJ,IAAI,CAACyM,GAAG,GAAG,EAAExM,MAAM,CAACC,QAAQ;MAE5B,OAAOF,IAAI;IACb,CAAC;IAED;AACJ;AACA;IACImT,cAAc,EAAE,SAAAA,CAAA,EAAW;MACzB,IAAInT,IAAI,GAAG,IAAI;;MAEf;MACAA,IAAI,CAAC8S,OAAO,CAACrM,KAAK,CAAC,WAAW,EAAEzG,IAAI,CAACyM,GAAG,EAAEzM,IAAI,CAACmC,KAAK,CAAC8F,KAAK,GAAGjI,IAAI,CAACmC,KAAK,CAAC8F,KAAK,CAACqL,IAAI,GAAG,CAAC,CAAC;;MAEvF;MACAtT,IAAI,CAACmC,KAAK,CAACqE,mBAAmB,CAAC,OAAO,EAAExG,IAAI,CAACkR,QAAQ,EAAE,KAAK,CAAC;IAC/D,CAAC;IAED;AACJ;AACA;IACIkC,aAAa,EAAE,SAAAA,CAAA,EAAW;MACxB,IAAIpT,IAAI,GAAG,IAAI;MACf,IAAI+S,MAAM,GAAG/S,IAAI,CAAC8S,OAAO;;MAEzB;MACAC,MAAM,CAACtJ,SAAS,GAAGqD,IAAI,CAACyG,IAAI,CAACvT,IAAI,CAACmC,KAAK,CAAC8K,QAAQ,GAAG,EAAE,CAAC,GAAG,EAAE;;MAE3D;MACA,IAAI4E,MAAM,CAACD,IAAI,CAACmB,MAAM,CAAC/J,OAAO,CAAC,CAACpH,MAAM,KAAK,CAAC,EAAE;QAC5CmR,MAAM,CAAC/J,OAAO,GAAG;UAACwK,SAAS,EAAE,CAAC,CAAC,EAAET,MAAM,CAACtJ,SAAS,GAAG,IAAI;QAAC,CAAC;MAC5D;MAEA,IAAIsJ,MAAM,CAACrJ,MAAM,KAAK,QAAQ,EAAE;QAC9BqJ,MAAM,CAACrJ,MAAM,GAAG,QAAQ;QACxBqJ,MAAM,CAACtM,KAAK,CAAC,MAAM,CAAC;QACpBsM,MAAM,CAACnG,UAAU,CAAC,CAAC;MACrB;;MAEA;MACA5M,IAAI,CAACmC,KAAK,CAACqE,mBAAmB,CAACvG,MAAM,CAACQ,aAAa,EAAET,IAAI,CAACmR,OAAO,EAAE,KAAK,CAAC;IAC3E,CAAC;IAED;AACJ;AACA;IACIkC,YAAY,EAAE,SAAAA,CAAA,EAAW;MACvB,IAAIrT,IAAI,GAAG,IAAI;MACf,IAAI+S,MAAM,GAAG/S,IAAI,CAAC8S,OAAO;;MAEzB;MACA,IAAIC,MAAM,CAACtJ,SAAS,KAAKoE,QAAQ,EAAE;QACjC;QACA;QACAkF,MAAM,CAACtJ,SAAS,GAAGqD,IAAI,CAACyG,IAAI,CAACvT,IAAI,CAACmC,KAAK,CAAC8K,QAAQ,GAAG,EAAE,CAAC,GAAG,EAAE;;QAE3D;QACA,IAAI8F,MAAM,CAAC/J,OAAO,CAACwK,SAAS,CAAC,CAAC,CAAC,KAAK3F,QAAQ,EAAE;UAC5CkF,MAAM,CAAC/J,OAAO,CAACwK,SAAS,CAAC,CAAC,CAAC,GAAGT,MAAM,CAACtJ,SAAS,GAAG,IAAI;QACvD;;QAEA;QACAsJ,MAAM,CAACvG,MAAM,CAACxM,IAAI,CAAC;MACrB;;MAEA;MACAA,IAAI,CAACmC,KAAK,CAACqE,mBAAmB,CAAC,OAAO,EAAExG,IAAI,CAACoR,MAAM,EAAE,KAAK,CAAC;IAC7D;EACF,CAAC;;EAED;EACA;;EAEA,IAAIG,KAAK,GAAG,CAAC,CAAC;;EAEd;AACF;AACA;AACA;EACE,IAAInF,UAAU,GAAG,SAAAA,CAASpM,IAAI,EAAE;IAC9B,IAAI4L,GAAG,GAAG5L,IAAI,CAACkJ,IAAI;;IAEnB;IACA,IAAIqI,KAAK,CAAC3F,GAAG,CAAC,EAAE;MACd;MACA5L,IAAI,CAACyJ,SAAS,GAAG8H,KAAK,CAAC3F,GAAG,CAAC,CAACqB,QAAQ;;MAEpC;MACAwG,SAAS,CAACzT,IAAI,CAAC;MAEf;IACF;IAEA,IAAI,qBAAqB,CAAC+C,IAAI,CAAC6I,GAAG,CAAC,EAAE;MACnC;MACA,IAAI8H,IAAI,GAAGC,IAAI,CAAC/H,GAAG,CAAC/H,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;MAClC,IAAI+P,QAAQ,GAAG,IAAIC,UAAU,CAACH,IAAI,CAAC9R,MAAM,CAAC;MAC1C,KAAK,IAAID,CAAC,GAAC,CAAC,EAAEA,CAAC,GAAC+R,IAAI,CAAC9R,MAAM,EAAE,EAAED,CAAC,EAAE;QAChCiS,QAAQ,CAACjS,CAAC,CAAC,GAAG+R,IAAI,CAACI,UAAU,CAACnS,CAAC,CAAC;MAClC;MAEAoS,eAAe,CAACH,QAAQ,CAAC7N,MAAM,EAAE/F,IAAI,CAAC;IACxC,CAAC,MAAM;MACL;MACA,IAAIsJ,GAAG,GAAG,IAAI0K,cAAc,CAAC,CAAC;MAC9B1K,GAAG,CAAC2K,IAAI,CAACjU,IAAI,CAACoJ,IAAI,CAACC,MAAM,EAAEuC,GAAG,EAAE,IAAI,CAAC;MACrCtC,GAAG,CAACE,eAAe,GAAGxJ,IAAI,CAACoJ,IAAI,CAACI,eAAe;MAC/CF,GAAG,CAAC4K,YAAY,GAAG,aAAa;;MAEhC;MACA,IAAIlU,IAAI,CAACoJ,IAAI,CAACG,OAAO,EAAE;QACrBsI,MAAM,CAACD,IAAI,CAAC5R,IAAI,CAACoJ,IAAI,CAACG,OAAO,CAAC,CAAC4K,OAAO,CAAC,UAASC,GAAG,EAAE;UACnD9K,GAAG,CAAC+K,gBAAgB,CAACD,GAAG,EAAEpU,IAAI,CAACoJ,IAAI,CAACG,OAAO,CAAC6K,GAAG,CAAC,CAAC;QACnD,CAAC,CAAC;MACJ;MAEA9K,GAAG,CAACc,MAAM,GAAG,YAAW;QACtB;QACA,IAAIkJ,IAAI,GAAG,CAAChK,GAAG,CAACgL,MAAM,GAAG,EAAE,EAAE,CAAC,CAAC;QAC/B,IAAIhB,IAAI,KAAK,GAAG,IAAIA,IAAI,KAAK,GAAG,IAAIA,IAAI,KAAK,GAAG,EAAE;UAChDtT,IAAI,CAACyG,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,yCAAyC,GAAG6C,GAAG,CAACgL,MAAM,GAAG,GAAG,CAAC;UAC3F;QACF;QAEAP,eAAe,CAACzK,GAAG,CAACiL,QAAQ,EAAEvU,IAAI,CAAC;MACrC,CAAC;MACDsJ,GAAG,CAACkL,OAAO,GAAG,YAAW;QACvB;QACA,IAAIxU,IAAI,CAAC6B,SAAS,EAAE;UAClB7B,IAAI,CAACsI,MAAM,GAAG,IAAI;UAClBtI,IAAI,CAAC6B,SAAS,GAAG,KAAK;UACtB7B,IAAI,CAACuH,OAAO,GAAG,EAAE;UACjB,OAAOgK,KAAK,CAAC3F,GAAG,CAAC;UACjB5L,IAAI,CAAC2F,IAAI,CAAC,CAAC;QACb;MACF,CAAC;MACD8O,WAAW,CAACnL,GAAG,CAAC;IAClB;EACF,CAAC;;EAED;AACF;AACA;AACA;EACE,IAAImL,WAAW,GAAG,SAAAA,CAASnL,GAAG,EAAE;IAC9B,IAAI;MACFA,GAAG,CAACoL,IAAI,CAAC,CAAC;IACZ,CAAC,CAAC,OAAOzR,CAAC,EAAE;MACVqG,GAAG,CAACkL,OAAO,CAAC,CAAC;IACf;EACF,CAAC;;EAED;AACF;AACA;AACA;AACA;EACE,IAAIT,eAAe,GAAG,SAAAA,CAASY,WAAW,EAAE3U,IAAI,EAAE;IAChD;IACA,IAAIiI,KAAK,GAAG,SAAAA,CAAA,EAAW;MACrBjI,IAAI,CAACyG,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,6BAA6B,CAAC;IAC9D,CAAC;;IAED;IACA,IAAImO,OAAO,GAAG,SAAAA,CAAS7O,MAAM,EAAE;MAC7B,IAAIA,MAAM,IAAI/F,IAAI,CAACuH,OAAO,CAAC3F,MAAM,GAAG,CAAC,EAAE;QACrC2P,KAAK,CAACvR,IAAI,CAACkJ,IAAI,CAAC,GAAGnD,MAAM;QACzB0N,SAAS,CAACzT,IAAI,EAAE+F,MAAM,CAAC;MACzB,CAAC,MAAM;QACLkC,KAAK,CAAC,CAAC;MACT;IACF,CAAC;;IAED;IACA,IAAI,OAAOlB,OAAO,KAAK,WAAW,IAAI9G,MAAM,CAACgB,GAAG,CAAC8S,eAAe,CAACnS,MAAM,KAAK,CAAC,EAAE;MAC7E3B,MAAM,CAACgB,GAAG,CAAC8S,eAAe,CAACY,WAAW,CAAC,CAAC3N,IAAI,CAAC4N,OAAO,CAAC,CAAC3N,KAAK,CAACgB,KAAK,CAAC;IACpE,CAAC,MAAM;MACLhI,MAAM,CAACgB,GAAG,CAAC8S,eAAe,CAACY,WAAW,EAAEC,OAAO,EAAE3M,KAAK,CAAC;IACzD;EACF,CAAC;;EAED;AACF;AACA;AACA;AACA;EACE,IAAIwL,SAAS,GAAG,SAAAA,CAASzT,IAAI,EAAE+F,MAAM,EAAE;IACrC;IACA,IAAIA,MAAM,IAAI,CAAC/F,IAAI,CAACyJ,SAAS,EAAE;MAC7BzJ,IAAI,CAACyJ,SAAS,GAAG1D,MAAM,CAACkH,QAAQ;IAClC;;IAEA;IACA,IAAI4E,MAAM,CAACD,IAAI,CAAC5R,IAAI,CAACgJ,OAAO,CAAC,CAACpH,MAAM,KAAK,CAAC,EAAE;MAC1C5B,IAAI,CAACgJ,OAAO,GAAG;QAACwK,SAAS,EAAE,CAAC,CAAC,EAAExT,IAAI,CAACyJ,SAAS,GAAG,IAAI;MAAC,CAAC;IACxD;;IAEA;IACA,IAAIzJ,IAAI,CAAC0J,MAAM,KAAK,QAAQ,EAAE;MAC5B1J,IAAI,CAAC0J,MAAM,GAAG,QAAQ;MACtB1J,IAAI,CAACyG,KAAK,CAAC,MAAM,CAAC;MAClBzG,IAAI,CAAC4M,UAAU,CAAC,CAAC;IACnB;EACF,CAAC;;EAED;AACF;AACA;EACE,IAAIrL,iBAAiB,GAAG,SAAAA,CAAA,EAAW;IACjC;IACA,IAAI,CAACtB,MAAM,CAACc,aAAa,EAAE;MACzB;IACF;;IAEA;IACA,IAAI;MACF,IAAI,OAAO8T,YAAY,KAAK,WAAW,EAAE;QACvC5U,MAAM,CAACgB,GAAG,GAAG,IAAI4T,YAAY,CAAC,CAAC;MACjC,CAAC,MAAM,IAAI,OAAOC,kBAAkB,KAAK,WAAW,EAAE;QACpD7U,MAAM,CAACgB,GAAG,GAAG,IAAI6T,kBAAkB,CAAC,CAAC;MACvC,CAAC,MAAM;QACL7U,MAAM,CAACc,aAAa,GAAG,KAAK;MAC9B;IACF,CAAC,CAAC,OAAMkC,CAAC,EAAE;MACThD,MAAM,CAACc,aAAa,GAAG,KAAK;IAC9B;;IAEA;IACA,IAAI,CAACd,MAAM,CAACgB,GAAG,EAAE;MACfhB,MAAM,CAACc,aAAa,GAAG,KAAK;IAC9B;;IAEA;IACA;IACA,IAAIgU,GAAG,GAAI,gBAAgB,CAAChS,IAAI,CAAC9C,MAAM,CAACS,UAAU,IAAIT,MAAM,CAACS,UAAU,CAACsU,QAAQ,CAAE;IAClF,IAAIC,UAAU,GAAGhV,MAAM,CAACS,UAAU,IAAIT,MAAM,CAACS,UAAU,CAACuU,UAAU,CAACvR,KAAK,CAAC,wBAAwB,CAAC;IAClG,IAAIwR,OAAO,GAAGD,UAAU,GAAGrR,QAAQ,CAACqR,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI;IAC7D,IAAIF,GAAG,IAAIG,OAAO,IAAIA,OAAO,GAAG,CAAC,EAAE;MACjC,IAAIC,MAAM,GAAG,QAAQ,CAACpS,IAAI,CAAC9C,MAAM,CAACS,UAAU,IAAIT,MAAM,CAACS,UAAU,CAAC8C,SAAS,CAACuI,WAAW,CAAC,CAAC,CAAC;MAC1F,IAAI9L,MAAM,CAACS,UAAU,IAAI,CAACyU,MAAM,EAAE;QAChClV,MAAM,CAACc,aAAa,GAAG,KAAK;MAC9B;IACF;;IAEA;IACA,IAAId,MAAM,CAACc,aAAa,EAAE;MACxBd,MAAM,CAACY,UAAU,GAAI,OAAOZ,MAAM,CAACgB,GAAG,CAACgS,UAAU,KAAK,WAAW,GAAIhT,MAAM,CAACgB,GAAG,CAACiS,cAAc,CAAC,CAAC,GAAGjT,MAAM,CAACgB,GAAG,CAACgS,UAAU,CAAC,CAAC;MAC1HhT,MAAM,CAACY,UAAU,CAACW,IAAI,CAACC,cAAc,CAACxB,MAAM,CAACM,MAAM,GAAG,CAAC,GAAGN,MAAM,CAACO,OAAO,EAAEP,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;MACjGzB,MAAM,CAACY,UAAU,CAACmF,OAAO,CAAC/F,MAAM,CAACgB,GAAG,CAACgF,WAAW,CAAC;IACnD;;IAEA;IACAhG,MAAM,CAACkB,MAAM,CAAC,CAAC;EACjB,CAAC;;EAED;EACA,IAAI,OAAOiU,MAAM,KAAK,UAAU,IAAIA,MAAM,CAACC,GAAG,EAAE;IAC9CD,MAAM,CAAC,EAAE,EAAE,YAAW;MACpB,OAAO;QACLnV,MAAM,EAAEA,MAAM;QACd6H,IAAI,EAAEA;MACR,CAAC;IACH,CAAC,CAAC;EACJ;;EAEA;EACA,IAAI,OAAOwN,OAAO,KAAK,WAAW,EAAE;IAClCA,OAAO,CAACrV,MAAM,GAAGA,MAAM;IACvBqV,OAAO,CAACxN,IAAI,GAAGA,IAAI;EACrB;;EAEA;EACA,IAAI,OAAOyN,MAAM,KAAK,WAAW,EAAE;IACjCA,MAAM,CAAC1V,YAAY,GAAGA,YAAY;IAClC0V,MAAM,CAACtV,MAAM,GAAGA,MAAM;IACtBsV,MAAM,CAACzN,IAAI,GAAGA,IAAI;IAClByN,MAAM,CAACpJ,KAAK,GAAGA,KAAK;EACtB,CAAC,MAAM,IAAI,OAAOxL,MAAM,KAAK,WAAW,EAAE;IAAG;IAC3CA,MAAM,CAACd,YAAY,GAAGA,YAAY;IAClCc,MAAM,CAACV,MAAM,GAAGA,MAAM;IACtBU,MAAM,CAACmH,IAAI,GAAGA,IAAI;IAClBnH,MAAM,CAACwL,KAAK,GAAGA,KAAK;EACtB;AACF,CAAC,EAAE,CAAC;;AAGJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,CAAC,YAAW;EAEV,YAAY;;EAEZ;EACAtM,YAAY,CAACE,SAAS,CAACyV,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;EACvC3V,YAAY,CAACE,SAAS,CAAC0V,YAAY,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;;EAEzD;EACA;;EAEA;AACF;AACA;AACA;AACA;AACA;EACE5V,YAAY,CAACE,SAAS,CAAC2V,MAAM,GAAG,UAASC,GAAG,EAAE;IAC5C,IAAI3V,IAAI,GAAG,IAAI;;IAEf;IACA,IAAI,CAACA,IAAI,CAACiB,GAAG,IAAI,CAACjB,IAAI,CAACiB,GAAG,CAACuN,QAAQ,EAAE;MACnC,OAAOxO,IAAI;IACb;;IAEA;IACA,KAAK,IAAI2B,CAAC,GAAC3B,IAAI,CAACM,MAAM,CAACsB,MAAM,GAAC,CAAC,EAAED,CAAC,IAAE,CAAC,EAAEA,CAAC,EAAE,EAAE;MAC1C3B,IAAI,CAACM,MAAM,CAACqB,CAAC,CAAC,CAAC+T,MAAM,CAACC,GAAG,CAAC;IAC5B;IAEA,OAAO3V,IAAI;EACb,CAAC;;EAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACEH,YAAY,CAACE,SAAS,CAAC6V,GAAG,GAAG,UAASC,CAAC,EAAEC,CAAC,EAAEC,CAAC,EAAE;IAC7C,IAAI/V,IAAI,GAAG,IAAI;;IAEf;IACA,IAAI,CAACA,IAAI,CAACiB,GAAG,IAAI,CAACjB,IAAI,CAACiB,GAAG,CAACuN,QAAQ,EAAE;MACnC,OAAOxO,IAAI;IACb;;IAEA;IACA8V,CAAC,GAAI,OAAOA,CAAC,KAAK,QAAQ,GAAI9V,IAAI,CAACwV,IAAI,CAAC,CAAC,CAAC,GAAGM,CAAC;IAC9CC,CAAC,GAAI,OAAOA,CAAC,KAAK,QAAQ,GAAI/V,IAAI,CAACwV,IAAI,CAAC,CAAC,CAAC,GAAGO,CAAC;IAE9C,IAAI,OAAOF,CAAC,KAAK,QAAQ,EAAE;MACzB7V,IAAI,CAACwV,IAAI,GAAG,CAACK,CAAC,EAAEC,CAAC,EAAEC,CAAC,CAAC;MAErB,IAAI,OAAO/V,IAAI,CAACiB,GAAG,CAACuN,QAAQ,CAACwH,SAAS,KAAK,WAAW,EAAE;QACtDhW,IAAI,CAACiB,GAAG,CAACuN,QAAQ,CAACwH,SAAS,CAACC,eAAe,CAACjW,IAAI,CAACwV,IAAI,CAAC,CAAC,CAAC,EAAEvV,MAAM,CAACgB,GAAG,CAACS,WAAW,EAAE,GAAG,CAAC;QACtF1B,IAAI,CAACiB,GAAG,CAACuN,QAAQ,CAAC0H,SAAS,CAACD,eAAe,CAACjW,IAAI,CAACwV,IAAI,CAAC,CAAC,CAAC,EAAEvV,MAAM,CAACgB,GAAG,CAACS,WAAW,EAAE,GAAG,CAAC;QACtF1B,IAAI,CAACiB,GAAG,CAACuN,QAAQ,CAAC2H,SAAS,CAACF,eAAe,CAACjW,IAAI,CAACwV,IAAI,CAAC,CAAC,CAAC,EAAEvV,MAAM,CAACgB,GAAG,CAACS,WAAW,EAAE,GAAG,CAAC;MACxF,CAAC,MAAM;QACL1B,IAAI,CAACiB,GAAG,CAACuN,QAAQ,CAAC4H,WAAW,CAACpW,IAAI,CAACwV,IAAI,CAAC,CAAC,CAAC,EAAExV,IAAI,CAACwV,IAAI,CAAC,CAAC,CAAC,EAAExV,IAAI,CAACwV,IAAI,CAAC,CAAC,CAAC,CAAC;MACzE;IACF,CAAC,MAAM;MACL,OAAOxV,IAAI,CAACwV,IAAI;IAClB;IAEA,OAAOxV,IAAI;EACb,CAAC;;EAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEH,YAAY,CAACE,SAAS,CAACsW,WAAW,GAAG,UAASR,CAAC,EAAEC,CAAC,EAAEC,CAAC,EAAEO,GAAG,EAAEC,GAAG,EAAEC,GAAG,EAAE;IACpE,IAAIxW,IAAI,GAAG,IAAI;;IAEf;IACA,IAAI,CAACA,IAAI,CAACiB,GAAG,IAAI,CAACjB,IAAI,CAACiB,GAAG,CAACuN,QAAQ,EAAE;MACnC,OAAOxO,IAAI;IACb;;IAEA;IACA,IAAIyW,EAAE,GAAGzW,IAAI,CAACyV,YAAY;IAC1BK,CAAC,GAAI,OAAOA,CAAC,KAAK,QAAQ,GAAIW,EAAE,CAAC,CAAC,CAAC,GAAGX,CAAC;IACvCC,CAAC,GAAI,OAAOA,CAAC,KAAK,QAAQ,GAAIU,EAAE,CAAC,CAAC,CAAC,GAAGV,CAAC;IACvCO,GAAG,GAAI,OAAOA,GAAG,KAAK,QAAQ,GAAIG,EAAE,CAAC,CAAC,CAAC,GAAGH,GAAG;IAC7CC,GAAG,GAAI,OAAOA,GAAG,KAAK,QAAQ,GAAIE,EAAE,CAAC,CAAC,CAAC,GAAGF,GAAG;IAC7CC,GAAG,GAAI,OAAOA,GAAG,KAAK,QAAQ,GAAIC,EAAE,CAAC,CAAC,CAAC,GAAGD,GAAG;IAE7C,IAAI,OAAOX,CAAC,KAAK,QAAQ,EAAE;MACzB7V,IAAI,CAACyV,YAAY,GAAG,CAACI,CAAC,EAAEC,CAAC,EAAEC,CAAC,EAAEO,GAAG,EAAEC,GAAG,EAAEC,GAAG,CAAC;MAE5C,IAAI,OAAOxW,IAAI,CAACiB,GAAG,CAACuN,QAAQ,CAACkI,QAAQ,KAAK,WAAW,EAAE;QACrD1W,IAAI,CAACiB,GAAG,CAACuN,QAAQ,CAACkI,QAAQ,CAACT,eAAe,CAACJ,CAAC,EAAE5V,MAAM,CAACgB,GAAG,CAACS,WAAW,EAAE,GAAG,CAAC;QAC1E1B,IAAI,CAACiB,GAAG,CAACuN,QAAQ,CAACmI,QAAQ,CAACV,eAAe,CAACH,CAAC,EAAE7V,MAAM,CAACgB,GAAG,CAACS,WAAW,EAAE,GAAG,CAAC;QAC1E1B,IAAI,CAACiB,GAAG,CAACuN,QAAQ,CAACoI,QAAQ,CAACX,eAAe,CAACF,CAAC,EAAE9V,MAAM,CAACgB,GAAG,CAACS,WAAW,EAAE,GAAG,CAAC;QAC1E1B,IAAI,CAACiB,GAAG,CAACuN,QAAQ,CAACqI,GAAG,CAACZ,eAAe,CAACK,GAAG,EAAErW,MAAM,CAACgB,GAAG,CAACS,WAAW,EAAE,GAAG,CAAC;QACvE1B,IAAI,CAACiB,GAAG,CAACuN,QAAQ,CAACsI,GAAG,CAACb,eAAe,CAACM,GAAG,EAAEtW,MAAM,CAACgB,GAAG,CAACS,WAAW,EAAE,GAAG,CAAC;QACvE1B,IAAI,CAACiB,GAAG,CAACuN,QAAQ,CAACuI,GAAG,CAACd,eAAe,CAACO,GAAG,EAAEvW,MAAM,CAACgB,GAAG,CAACS,WAAW,EAAE,GAAG,CAAC;MACzE,CAAC,MAAM;QACL1B,IAAI,CAACiB,GAAG,CAACuN,QAAQ,CAACwI,cAAc,CAACnB,CAAC,EAAEC,CAAC,EAAEC,CAAC,EAAEO,GAAG,EAAEC,GAAG,EAAEC,GAAG,CAAC;MAC1D;IACF,CAAC,MAAM;MACL,OAAOC,EAAE;IACX;IAEA,OAAOzW,IAAI;EACb,CAAC;;EAED;EACA;;EAEA;AACF;AACA;AACA;AACA;EACE8H,IAAI,CAAC/H,SAAS,CAACD,IAAI,GAAI,UAASmX,MAAM,EAAE;IACtC,OAAO,UAASlP,CAAC,EAAE;MACjB,IAAI/H,IAAI,GAAG,IAAI;;MAEf;MACAA,IAAI,CAACyV,YAAY,GAAG1N,CAAC,CAACsO,WAAW,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;MAC9CrW,IAAI,CAACkX,OAAO,GAAGnP,CAAC,CAAC2N,MAAM,IAAI,IAAI;MAC/B1V,IAAI,CAACwV,IAAI,GAAGzN,CAAC,CAAC6N,GAAG,IAAI,IAAI;MACzB5V,IAAI,CAACmX,WAAW,GAAG;QACjBC,cAAc,EAAE,OAAOrP,CAAC,CAACqP,cAAc,KAAK,WAAW,GAAGrP,CAAC,CAACqP,cAAc,GAAG,GAAG;QAChFC,cAAc,EAAE,OAAOtP,CAAC,CAACsP,cAAc,KAAK,WAAW,GAAGtP,CAAC,CAACsP,cAAc,GAAG,GAAG;QAChFC,aAAa,EAAE,OAAOvP,CAAC,CAACuP,aAAa,KAAK,WAAW,GAAGvP,CAAC,CAACuP,aAAa,GAAG,CAAC;QAC3EC,aAAa,EAAE,OAAOxP,CAAC,CAACwP,aAAa,KAAK,WAAW,GAAGxP,CAAC,CAACwP,aAAa,GAAG,SAAS;QACnFC,WAAW,EAAE,OAAOzP,CAAC,CAACyP,WAAW,KAAK,WAAW,GAAGzP,CAAC,CAACyP,WAAW,GAAG,KAAK;QACzEC,YAAY,EAAE,OAAO1P,CAAC,CAAC0P,YAAY,KAAK,WAAW,GAAG1P,CAAC,CAAC0P,YAAY,GAAG,MAAM;QAC7EC,WAAW,EAAE,OAAO3P,CAAC,CAAC2P,WAAW,KAAK,WAAW,GAAG3P,CAAC,CAAC2P,WAAW,GAAG,CAAC;QACrEC,aAAa,EAAE,OAAO5P,CAAC,CAAC4P,aAAa,KAAK,WAAW,GAAG5P,CAAC,CAAC4P,aAAa,GAAG;MAC5E,CAAC;;MAED;MACA3X,IAAI,CAAC4X,SAAS,GAAG7P,CAAC,CAAC8P,QAAQ,GAAG,CAAC;QAAC7N,EAAE,EAAEjC,CAAC,CAAC8P;MAAQ,CAAC,CAAC,GAAG,EAAE;MACrD7X,IAAI,CAAC8X,MAAM,GAAG/P,CAAC,CAACgQ,KAAK,GAAG,CAAC;QAAC/N,EAAE,EAAEjC,CAAC,CAACgQ;MAAK,CAAC,CAAC,GAAG,EAAE;MAC5C/X,IAAI,CAACgY,cAAc,GAAGjQ,CAAC,CAACkQ,aAAa,GAAG,CAAC;QAACjO,EAAE,EAAEjC,CAAC,CAACkQ;MAAa,CAAC,CAAC,GAAG,EAAE;;MAEpE;MACA,OAAOhB,MAAM,CAAChF,IAAI,CAAC,IAAI,EAAElK,CAAC,CAAC;IAC7B,CAAC;EACH,CAAC,CAAED,IAAI,CAAC/H,SAAS,CAACD,IAAI,CAAC;;EAEvB;AACF;AACA;AACA;AACA;AACA;EACEgI,IAAI,CAAC/H,SAAS,CAAC2V,MAAM,GAAG,UAASC,GAAG,EAAErJ,EAAE,EAAE;IACxC,IAAItM,IAAI,GAAG,IAAI;;IAEf;IACA,IAAI,CAACA,IAAI,CAAC6B,SAAS,EAAE;MACnB,OAAO7B,IAAI;IACb;;IAEA;IACA,IAAIA,IAAI,CAAC0J,MAAM,KAAK,QAAQ,EAAE;MAC5B1J,IAAI,CAAC4J,MAAM,CAACvC,IAAI,CAAC;QACfqE,KAAK,EAAE,QAAQ;QACfC,MAAM,EAAE,SAAAA,CAAA,EAAW;UACjB3L,IAAI,CAAC0V,MAAM,CAACC,GAAG,EAAErJ,EAAE,CAAC;QACtB;MACF,CAAC,CAAC;MAEF,OAAOtM,IAAI;IACb;;IAEA;IACA,IAAIkY,UAAU,GAAI,OAAOjY,MAAM,CAACgB,GAAG,CAACkX,kBAAkB,KAAK,WAAW,GAAI,SAAS,GAAG,QAAQ;;IAE9F;IACA,IAAI,OAAO7L,EAAE,KAAK,WAAW,EAAE;MAC7B;MACA,IAAI,OAAOqJ,GAAG,KAAK,QAAQ,EAAE;QAC3B3V,IAAI,CAACkX,OAAO,GAAGvB,GAAG;QAClB3V,IAAI,CAACwV,IAAI,GAAG,CAACG,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;MACzB,CAAC,MAAM;QACL,OAAO3V,IAAI,CAACkX,OAAO;MACrB;IACF;;IAEA;IACA,IAAIpV,GAAG,GAAG9B,IAAI,CAAC+B,YAAY,CAACuK,EAAE,CAAC;IAC/B,KAAK,IAAI3K,CAAC,GAAC,CAAC,EAAEA,CAAC,GAACG,GAAG,CAACF,MAAM,EAAED,CAAC,EAAE,EAAE;MAC/B;MACA,IAAIM,KAAK,GAAGjC,IAAI,CAACkC,UAAU,CAACJ,GAAG,CAACH,CAAC,CAAC,CAAC;MAEnC,IAAIM,KAAK,EAAE;QACT,IAAI,OAAO0T,GAAG,KAAK,QAAQ,EAAE;UAC3B1T,KAAK,CAACiV,OAAO,GAAGvB,GAAG;UACnB1T,KAAK,CAACuT,IAAI,GAAG,CAACG,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;UAExB,IAAI1T,KAAK,CAACE,KAAK,EAAE;YACf;YACAF,KAAK,CAACkV,WAAW,CAACM,YAAY,GAAG,YAAY;;YAE7C;YACA,IAAI,CAACxV,KAAK,CAACwQ,OAAO,IAAI,CAACxQ,KAAK,CAACwQ,OAAO,CAACkD,GAAG,EAAE;cACxCyC,WAAW,CAACnW,KAAK,EAAEiW,UAAU,CAAC;YAChC;YAEA,IAAIA,UAAU,KAAK,SAAS,EAAE;cAC5B,IAAI,OAAOjW,KAAK,CAACwQ,OAAO,CAACuD,SAAS,KAAK,WAAW,EAAE;gBAClD/T,KAAK,CAACwQ,OAAO,CAACuD,SAAS,CAACvU,cAAc,CAACkU,GAAG,EAAE1V,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;gBACnEO,KAAK,CAACwQ,OAAO,CAACyD,SAAS,CAACzU,cAAc,CAAC,CAAC,EAAExB,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;gBACjEO,KAAK,CAACwQ,OAAO,CAAC0D,SAAS,CAAC1U,cAAc,CAAC,CAAC,EAAExB,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;cACnE,CAAC,MAAM;gBACLO,KAAK,CAACwQ,OAAO,CAAC2D,WAAW,CAACT,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;cACtC;YACF,CAAC,MAAM;cACL1T,KAAK,CAACwQ,OAAO,CAACkD,GAAG,CAAClU,cAAc,CAACkU,GAAG,EAAE1V,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;YAC/D;UACF;UAEA1B,IAAI,CAACyG,KAAK,CAAC,QAAQ,EAAExE,KAAK,CAACwK,GAAG,CAAC;QACjC,CAAC,MAAM;UACL,OAAOxK,KAAK,CAACiV,OAAO;QACtB;MACF;IACF;IAEA,OAAOlX,IAAI;EACb,CAAC;;EAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACE8H,IAAI,CAAC/H,SAAS,CAAC6V,GAAG,GAAG,UAASC,CAAC,EAAEC,CAAC,EAAEC,CAAC,EAAEzJ,EAAE,EAAE;IACzC,IAAItM,IAAI,GAAG,IAAI;;IAEf;IACA,IAAI,CAACA,IAAI,CAAC6B,SAAS,EAAE;MACnB,OAAO7B,IAAI;IACb;;IAEA;IACA,IAAIA,IAAI,CAAC0J,MAAM,KAAK,QAAQ,EAAE;MAC5B1J,IAAI,CAAC4J,MAAM,CAACvC,IAAI,CAAC;QACfqE,KAAK,EAAE,KAAK;QACZC,MAAM,EAAE,SAAAA,CAAA,EAAW;UACjB3L,IAAI,CAAC4V,GAAG,CAACC,CAAC,EAAEC,CAAC,EAAEC,CAAC,EAAEzJ,EAAE,CAAC;QACvB;MACF,CAAC,CAAC;MAEF,OAAOtM,IAAI;IACb;;IAEA;IACA8V,CAAC,GAAI,OAAOA,CAAC,KAAK,QAAQ,GAAI,CAAC,GAAGA,CAAC;IACnCC,CAAC,GAAI,OAAOA,CAAC,KAAK,QAAQ,GAAI,CAAC,GAAG,GAAGA,CAAC;;IAEtC;IACA,IAAI,OAAOzJ,EAAE,KAAK,WAAW,EAAE;MAC7B;MACA,IAAI,OAAOuJ,CAAC,KAAK,QAAQ,EAAE;QACzB7V,IAAI,CAACwV,IAAI,GAAG,CAACK,CAAC,EAAEC,CAAC,EAAEC,CAAC,CAAC;MACvB,CAAC,MAAM;QACL,OAAO/V,IAAI,CAACwV,IAAI;MAClB;IACF;;IAEA;IACA,IAAI1T,GAAG,GAAG9B,IAAI,CAAC+B,YAAY,CAACuK,EAAE,CAAC;IAC/B,KAAK,IAAI3K,CAAC,GAAC,CAAC,EAAEA,CAAC,GAACG,GAAG,CAACF,MAAM,EAAED,CAAC,EAAE,EAAE;MAC/B;MACA,IAAIM,KAAK,GAAGjC,IAAI,CAACkC,UAAU,CAACJ,GAAG,CAACH,CAAC,CAAC,CAAC;MAEnC,IAAIM,KAAK,EAAE;QACT,IAAI,OAAO4T,CAAC,KAAK,QAAQ,EAAE;UACzB5T,KAAK,CAACuT,IAAI,GAAG,CAACK,CAAC,EAAEC,CAAC,EAAEC,CAAC,CAAC;UAEtB,IAAI9T,KAAK,CAACE,KAAK,EAAE;YACf;YACA,IAAI,CAACF,KAAK,CAACwQ,OAAO,IAAIxQ,KAAK,CAACwQ,OAAO,CAACkD,GAAG,EAAE;cACvCyC,WAAW,CAACnW,KAAK,EAAE,SAAS,CAAC;YAC/B;YAEA,IAAI,OAAOA,KAAK,CAACwQ,OAAO,CAACuD,SAAS,KAAK,WAAW,EAAE;cAClD/T,KAAK,CAACwQ,OAAO,CAACuD,SAAS,CAACvU,cAAc,CAACoU,CAAC,EAAE5V,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;cACjEO,KAAK,CAACwQ,OAAO,CAACyD,SAAS,CAACzU,cAAc,CAACqU,CAAC,EAAE7V,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;cACjEO,KAAK,CAACwQ,OAAO,CAAC0D,SAAS,CAAC1U,cAAc,CAACsU,CAAC,EAAE9V,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;YACnE,CAAC,MAAM;cACLO,KAAK,CAACwQ,OAAO,CAAC2D,WAAW,CAACP,CAAC,EAAEC,CAAC,EAAEC,CAAC,CAAC;YACpC;UACF;UAEA/V,IAAI,CAACyG,KAAK,CAAC,KAAK,EAAExE,KAAK,CAACwK,GAAG,CAAC;QAC9B,CAAC,MAAM;UACL,OAAOxK,KAAK,CAACuT,IAAI;QACnB;MACF;IACF;IAEA,OAAOxV,IAAI;EACb,CAAC;;EAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACE8H,IAAI,CAAC/H,SAAS,CAACsW,WAAW,GAAG,UAASR,CAAC,EAAEC,CAAC,EAAEC,CAAC,EAAEzJ,EAAE,EAAE;IACjD,IAAItM,IAAI,GAAG,IAAI;;IAEf;IACA,IAAI,CAACA,IAAI,CAAC6B,SAAS,EAAE;MACnB,OAAO7B,IAAI;IACb;;IAEA;IACA,IAAIA,IAAI,CAAC0J,MAAM,KAAK,QAAQ,EAAE;MAC5B1J,IAAI,CAAC4J,MAAM,CAACvC,IAAI,CAAC;QACfqE,KAAK,EAAE,aAAa;QACpBC,MAAM,EAAE,SAAAA,CAAA,EAAW;UACjB3L,IAAI,CAACqW,WAAW,CAACR,CAAC,EAAEC,CAAC,EAAEC,CAAC,EAAEzJ,EAAE,CAAC;QAC/B;MACF,CAAC,CAAC;MAEF,OAAOtM,IAAI;IACb;;IAEA;IACA8V,CAAC,GAAI,OAAOA,CAAC,KAAK,QAAQ,GAAI9V,IAAI,CAACyV,YAAY,CAAC,CAAC,CAAC,GAAGK,CAAC;IACtDC,CAAC,GAAI,OAAOA,CAAC,KAAK,QAAQ,GAAI/V,IAAI,CAACyV,YAAY,CAAC,CAAC,CAAC,GAAGM,CAAC;;IAEtD;IACA,IAAI,OAAOzJ,EAAE,KAAK,WAAW,EAAE;MAC7B;MACA,IAAI,OAAOuJ,CAAC,KAAK,QAAQ,EAAE;QACzB7V,IAAI,CAACyV,YAAY,GAAG,CAACI,CAAC,EAAEC,CAAC,EAAEC,CAAC,CAAC;MAC/B,CAAC,MAAM;QACL,OAAO/V,IAAI,CAACyV,YAAY;MAC1B;IACF;;IAEA;IACA,IAAI3T,GAAG,GAAG9B,IAAI,CAAC+B,YAAY,CAACuK,EAAE,CAAC;IAC/B,KAAK,IAAI3K,CAAC,GAAC,CAAC,EAAEA,CAAC,GAACG,GAAG,CAACF,MAAM,EAAED,CAAC,EAAE,EAAE;MAC/B;MACA,IAAIM,KAAK,GAAGjC,IAAI,CAACkC,UAAU,CAACJ,GAAG,CAACH,CAAC,CAAC,CAAC;MAEnC,IAAIM,KAAK,EAAE;QACT,IAAI,OAAO4T,CAAC,KAAK,QAAQ,EAAE;UACzB5T,KAAK,CAACwT,YAAY,GAAG,CAACI,CAAC,EAAEC,CAAC,EAAEC,CAAC,CAAC;UAE9B,IAAI9T,KAAK,CAACE,KAAK,EAAE;YACf;YACA,IAAI,CAACF,KAAK,CAACwQ,OAAO,EAAE;cAClB;cACA,IAAI,CAACxQ,KAAK,CAACuT,IAAI,EAAE;gBACfvT,KAAK,CAACuT,IAAI,GAAGxV,IAAI,CAACwV,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC;cACxC;cAEA4C,WAAW,CAACnW,KAAK,EAAE,SAAS,CAAC;YAC/B;YAEA,IAAI,OAAOA,KAAK,CAACwQ,OAAO,CAAC4F,YAAY,KAAK,WAAW,EAAE;cACrDpW,KAAK,CAACwQ,OAAO,CAAC4F,YAAY,CAAC5W,cAAc,CAACoU,CAAC,EAAE5V,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;cACpEO,KAAK,CAACwQ,OAAO,CAAC6F,YAAY,CAAC7W,cAAc,CAACqU,CAAC,EAAE7V,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;cACpEO,KAAK,CAACwQ,OAAO,CAAC8F,YAAY,CAAC9W,cAAc,CAACsU,CAAC,EAAE9V,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;YACtE,CAAC,MAAM;cACLO,KAAK,CAACwQ,OAAO,CAACuE,cAAc,CAACnB,CAAC,EAAEC,CAAC,EAAEC,CAAC,CAAC;YACvC;UACF;UAEA/V,IAAI,CAACyG,KAAK,CAAC,aAAa,EAAExE,KAAK,CAACwK,GAAG,CAAC;QACtC,CAAC,MAAM;UACL,OAAOxK,KAAK,CAACwT,YAAY;QAC3B;MACF;IACF;IAEA,OAAOzV,IAAI;EACb,CAAC;;EAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACE8H,IAAI,CAAC/H,SAAS,CAACyY,UAAU,GAAG,YAAW;IACrC,IAAIxY,IAAI,GAAG,IAAI;IACf,IAAIkP,IAAI,GAAGH,SAAS;IACpB,IAAIhH,CAAC,EAAEuE,EAAE,EAAErK,KAAK;;IAEhB;IACA,IAAI,CAACjC,IAAI,CAAC6B,SAAS,EAAE;MACnB,OAAO7B,IAAI;IACb;;IAEA;IACA,IAAIkP,IAAI,CAACtN,MAAM,KAAK,CAAC,EAAE;MACrB;MACA,OAAO5B,IAAI,CAACmX,WAAW;IACzB,CAAC,MAAM,IAAIjI,IAAI,CAACtN,MAAM,KAAK,CAAC,EAAE;MAC5B,IAAI,OAAOsN,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;QAC/BnH,CAAC,GAAGmH,IAAI,CAAC,CAAC,CAAC;;QAEX;QACA,IAAI,OAAO5C,EAAE,KAAK,WAAW,EAAE;UAC7B,IAAI,CAACvE,CAAC,CAACyQ,UAAU,EAAE;YACjBzQ,CAAC,CAACyQ,UAAU,GAAG;cACbpB,cAAc,EAAErP,CAAC,CAACqP,cAAc;cAChCC,cAAc,EAAEtP,CAAC,CAACsP,cAAc;cAChCC,aAAa,EAAEvP,CAAC,CAACuP,aAAa;cAC9BC,aAAa,EAAExP,CAAC,CAACwP,aAAa;cAC9BC,WAAW,EAAEzP,CAAC,CAACyP,WAAW;cAC1BE,WAAW,EAAE3P,CAAC,CAAC2P,WAAW;cAC1BC,aAAa,EAAE5P,CAAC,CAAC4P,aAAa;cAC9BF,YAAY,EAAE1P,CAAC,CAAC0P;YAClB,CAAC;UACH;UAEAzX,IAAI,CAACmX,WAAW,GAAG;YACjBC,cAAc,EAAE,OAAOrP,CAAC,CAACyQ,UAAU,CAACpB,cAAc,KAAK,WAAW,GAAGrP,CAAC,CAACyQ,UAAU,CAACpB,cAAc,GAAGpX,IAAI,CAACyY,eAAe;YACvHpB,cAAc,EAAE,OAAOtP,CAAC,CAACyQ,UAAU,CAACnB,cAAc,KAAK,WAAW,GAAGtP,CAAC,CAACyQ,UAAU,CAACnB,cAAc,GAAGrX,IAAI,CAAC0Y,eAAe;YACvHpB,aAAa,EAAE,OAAOvP,CAAC,CAACyQ,UAAU,CAAClB,aAAa,KAAK,WAAW,GAAGvP,CAAC,CAACyQ,UAAU,CAAClB,aAAa,GAAGtX,IAAI,CAAC2Y,cAAc;YACnHpB,aAAa,EAAE,OAAOxP,CAAC,CAACyQ,UAAU,CAACjB,aAAa,KAAK,WAAW,GAAGxP,CAAC,CAACyQ,UAAU,CAACjB,aAAa,GAAGvX,IAAI,CAAC4Y,cAAc;YACnHpB,WAAW,EAAE,OAAOzP,CAAC,CAACyQ,UAAU,CAAChB,WAAW,KAAK,WAAW,GAAGzP,CAAC,CAACyQ,UAAU,CAAChB,WAAW,GAAGxX,IAAI,CAAC6Y,YAAY;YAC3GnB,WAAW,EAAE,OAAO3P,CAAC,CAACyQ,UAAU,CAACd,WAAW,KAAK,WAAW,GAAG3P,CAAC,CAACyQ,UAAU,CAACd,WAAW,GAAG1X,IAAI,CAAC8Y,YAAY;YAC3GnB,aAAa,EAAE,OAAO5P,CAAC,CAACyQ,UAAU,CAACb,aAAa,KAAK,WAAW,GAAG5P,CAAC,CAACyQ,UAAU,CAACb,aAAa,GAAG3X,IAAI,CAAC+Y,cAAc;YACnHtB,YAAY,EAAE,OAAO1P,CAAC,CAACyQ,UAAU,CAACf,YAAY,KAAK,WAAW,GAAG1P,CAAC,CAACyQ,UAAU,CAACf,YAAY,GAAGzX,IAAI,CAACgZ;UACpG,CAAC;QACH;MACF,CAAC,MAAM;QACL;QACA/W,KAAK,GAAGjC,IAAI,CAACkC,UAAU,CAAC0B,QAAQ,CAACsL,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9C,OAAOjN,KAAK,GAAGA,KAAK,CAACkV,WAAW,GAAGnX,IAAI,CAACmX,WAAW;MACrD;IACF,CAAC,MAAM,IAAIjI,IAAI,CAACtN,MAAM,KAAK,CAAC,EAAE;MAC5BmG,CAAC,GAAGmH,IAAI,CAAC,CAAC,CAAC;MACX5C,EAAE,GAAG1I,QAAQ,CAACsL,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IAC5B;;IAEA;IACA,IAAIpN,GAAG,GAAG9B,IAAI,CAAC+B,YAAY,CAACuK,EAAE,CAAC;IAC/B,KAAK,IAAI3K,CAAC,GAAC,CAAC,EAAEA,CAAC,GAACG,GAAG,CAACF,MAAM,EAAED,CAAC,EAAE,EAAE;MAC/BM,KAAK,GAAGjC,IAAI,CAACkC,UAAU,CAACJ,GAAG,CAACH,CAAC,CAAC,CAAC;MAE/B,IAAIM,KAAK,EAAE;QACT;QACA,IAAIgX,EAAE,GAAGhX,KAAK,CAACkV,WAAW;QAC1B8B,EAAE,GAAG;UACH7B,cAAc,EAAE,OAAOrP,CAAC,CAACqP,cAAc,KAAK,WAAW,GAAGrP,CAAC,CAACqP,cAAc,GAAG6B,EAAE,CAAC7B,cAAc;UAC9FC,cAAc,EAAE,OAAOtP,CAAC,CAACsP,cAAc,KAAK,WAAW,GAAGtP,CAAC,CAACsP,cAAc,GAAG4B,EAAE,CAAC5B,cAAc;UAC9FC,aAAa,EAAE,OAAOvP,CAAC,CAACuP,aAAa,KAAK,WAAW,GAAGvP,CAAC,CAACuP,aAAa,GAAG2B,EAAE,CAAC3B,aAAa;UAC1FC,aAAa,EAAE,OAAOxP,CAAC,CAACwP,aAAa,KAAK,WAAW,GAAGxP,CAAC,CAACwP,aAAa,GAAG0B,EAAE,CAAC1B,aAAa;UAC1FC,WAAW,EAAE,OAAOzP,CAAC,CAACyP,WAAW,KAAK,WAAW,GAAGzP,CAAC,CAACyP,WAAW,GAAGyB,EAAE,CAACzB,WAAW;UAClFE,WAAW,EAAE,OAAO3P,CAAC,CAAC2P,WAAW,KAAK,WAAW,GAAG3P,CAAC,CAAC2P,WAAW,GAAGuB,EAAE,CAACvB,WAAW;UAClFC,aAAa,EAAE,OAAO5P,CAAC,CAAC4P,aAAa,KAAK,WAAW,GAAG5P,CAAC,CAAC4P,aAAa,GAAGsB,EAAE,CAACtB,aAAa;UAC1FF,YAAY,EAAE,OAAO1P,CAAC,CAAC0P,YAAY,KAAK,WAAW,GAAG1P,CAAC,CAAC0P,YAAY,GAAGwB,EAAE,CAACxB;QAC5E,CAAC;;QAED;QACA,IAAIyB,MAAM,GAAGjX,KAAK,CAACwQ,OAAO;QAC1B,IAAIyG,MAAM,EAAE;UACVA,MAAM,CAAC9B,cAAc,GAAG6B,EAAE,CAAC7B,cAAc;UACzC8B,MAAM,CAAC7B,cAAc,GAAG4B,EAAE,CAAC5B,cAAc;UACzC6B,MAAM,CAAC5B,aAAa,GAAG2B,EAAE,CAAC3B,aAAa;UACvC4B,MAAM,CAAC3B,aAAa,GAAG0B,EAAE,CAAC1B,aAAa;UACvC2B,MAAM,CAAC1B,WAAW,GAAGyB,EAAE,CAACzB,WAAW;UACnC0B,MAAM,CAACxB,WAAW,GAAGuB,EAAE,CAACvB,WAAW;UACnCwB,MAAM,CAACvB,aAAa,GAAGsB,EAAE,CAACtB,aAAa;UACvCuB,MAAM,CAACzB,YAAY,GAAGwB,EAAE,CAACxB,YAAY;QACvC,CAAC,MAAM;UACL;UACA,IAAI,CAACxV,KAAK,CAACuT,IAAI,EAAE;YACfvT,KAAK,CAACuT,IAAI,GAAGxV,IAAI,CAACwV,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC;UACxC;;UAEA;UACA4C,WAAW,CAACnW,KAAK,EAAE,SAAS,CAAC;QAC/B;MACF;IACF;IAEA,OAAOjC,IAAI;EACb,CAAC;;EAED;EACA;;EAEA;AACF;AACA;AACA;AACA;EACEmM,KAAK,CAACpM,SAAS,CAACD,IAAI,GAAI,UAASmX,MAAM,EAAE;IACvC,OAAO,YAAW;MAChB,IAAIjX,IAAI,GAAG,IAAI;MACf,IAAI+S,MAAM,GAAG/S,IAAI,CAAC8S,OAAO;;MAEzB;MACA9S,IAAI,CAACyV,YAAY,GAAG1C,MAAM,CAAC0C,YAAY;MACvCzV,IAAI,CAACkX,OAAO,GAAGnE,MAAM,CAACmE,OAAO;MAC7BlX,IAAI,CAACwV,IAAI,GAAGzC,MAAM,CAACyC,IAAI;MACvBxV,IAAI,CAACmX,WAAW,GAAGpE,MAAM,CAACoE,WAAW;;MAErC;MACAF,MAAM,CAAChF,IAAI,CAAC,IAAI,CAAC;;MAEjB;MACA,IAAIjS,IAAI,CAACkX,OAAO,EAAE;QAChBnE,MAAM,CAAC2C,MAAM,CAAC1V,IAAI,CAACkX,OAAO,CAAC;MAC7B,CAAC,MAAM,IAAIlX,IAAI,CAACwV,IAAI,EAAE;QACpBzC,MAAM,CAAC6C,GAAG,CAAC5V,IAAI,CAACwV,IAAI,CAAC,CAAC,CAAC,EAAExV,IAAI,CAACwV,IAAI,CAAC,CAAC,CAAC,EAAExV,IAAI,CAACwV,IAAI,CAAC,CAAC,CAAC,EAAExV,IAAI,CAACyM,GAAG,CAAC;MAChE;IACF,CAAC;EACH,CAAC,CAAEN,KAAK,CAACpM,SAAS,CAACD,IAAI,CAAC;;EAExB;AACF;AACA;AACA;AACA;EACEqM,KAAK,CAACpM,SAAS,CAACuS,KAAK,GAAI,UAAS2E,MAAM,EAAE;IACxC,OAAO,YAAW;MAChB,IAAIjX,IAAI,GAAG,IAAI;MACf,IAAI+S,MAAM,GAAG/S,IAAI,CAAC8S,OAAO;;MAEzB;MACA9S,IAAI,CAACyV,YAAY,GAAG1C,MAAM,CAAC0C,YAAY;MACvCzV,IAAI,CAACkX,OAAO,GAAGnE,MAAM,CAACmE,OAAO;MAC7BlX,IAAI,CAACwV,IAAI,GAAGzC,MAAM,CAACyC,IAAI;MACvBxV,IAAI,CAACmX,WAAW,GAAGpE,MAAM,CAACoE,WAAW;;MAErC;MACA,IAAInX,IAAI,CAACkX,OAAO,EAAE;QAChBnE,MAAM,CAAC2C,MAAM,CAAC1V,IAAI,CAACkX,OAAO,CAAC;MAC7B,CAAC,MAAM,IAAIlX,IAAI,CAACwV,IAAI,EAAE;QACpBzC,MAAM,CAAC6C,GAAG,CAAC5V,IAAI,CAACwV,IAAI,CAAC,CAAC,CAAC,EAAExV,IAAI,CAACwV,IAAI,CAAC,CAAC,CAAC,EAAExV,IAAI,CAACwV,IAAI,CAAC,CAAC,CAAC,EAAExV,IAAI,CAACyM,GAAG,CAAC;MAChE,CAAC,MAAM,IAAIzM,IAAI,CAACyS,OAAO,EAAE;QACvB;QACAzS,IAAI,CAACyS,OAAO,CAACnM,UAAU,CAAC,CAAC,CAAC;QAC1BtG,IAAI,CAACyS,OAAO,GAAGtJ,SAAS;QACxB4J,MAAM,CAACtF,cAAc,CAACzN,IAAI,CAAC;MAC7B;;MAEA;MACA,OAAOiX,MAAM,CAAChF,IAAI,CAAC,IAAI,CAAC;IAC1B,CAAC;EACH,CAAC,CAAE9F,KAAK,CAACpM,SAAS,CAACuS,KAAK,CAAC;;EAEzB;EACA;;EAEA;AACF;AACA;AACA;AACA;EACE,IAAI8F,WAAW,GAAG,SAAAA,CAASnW,KAAK,EAAEkX,IAAI,EAAE;IACtCA,IAAI,GAAGA,IAAI,IAAI,SAAS;;IAExB;IACA,IAAIA,IAAI,KAAK,SAAS,EAAE;MACtBlX,KAAK,CAACwQ,OAAO,GAAGxS,MAAM,CAACgB,GAAG,CAACmY,YAAY,CAAC,CAAC;MACzCnX,KAAK,CAACwQ,OAAO,CAAC2E,cAAc,GAAGnV,KAAK,CAACkV,WAAW,CAACC,cAAc;MAC/DnV,KAAK,CAACwQ,OAAO,CAAC4E,cAAc,GAAGpV,KAAK,CAACkV,WAAW,CAACE,cAAc;MAC/DpV,KAAK,CAACwQ,OAAO,CAAC6E,aAAa,GAAGrV,KAAK,CAACkV,WAAW,CAACG,aAAa;MAC7DrV,KAAK,CAACwQ,OAAO,CAAC8E,aAAa,GAAGtV,KAAK,CAACkV,WAAW,CAACI,aAAa;MAC7DtV,KAAK,CAACwQ,OAAO,CAAC+E,WAAW,GAAGvV,KAAK,CAACkV,WAAW,CAACK,WAAW;MACzDvV,KAAK,CAACwQ,OAAO,CAACiF,WAAW,GAAGzV,KAAK,CAACkV,WAAW,CAACO,WAAW;MACzDzV,KAAK,CAACwQ,OAAO,CAACkF,aAAa,GAAG1V,KAAK,CAACkV,WAAW,CAACQ,aAAa;MAC7D1V,KAAK,CAACwQ,OAAO,CAACgF,YAAY,GAAGxV,KAAK,CAACkV,WAAW,CAACM,YAAY;MAE3D,IAAI,OAAOxV,KAAK,CAACwQ,OAAO,CAACuD,SAAS,KAAK,WAAW,EAAE;QAClD/T,KAAK,CAACwQ,OAAO,CAACuD,SAAS,CAACvU,cAAc,CAACQ,KAAK,CAACuT,IAAI,CAAC,CAAC,CAAC,EAAEvV,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;QAC7EO,KAAK,CAACwQ,OAAO,CAACyD,SAAS,CAACzU,cAAc,CAACQ,KAAK,CAACuT,IAAI,CAAC,CAAC,CAAC,EAAEvV,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;QAC7EO,KAAK,CAACwQ,OAAO,CAAC0D,SAAS,CAAC1U,cAAc,CAACQ,KAAK,CAACuT,IAAI,CAAC,CAAC,CAAC,EAAEvV,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;MAC/E,CAAC,MAAM;QACLO,KAAK,CAACwQ,OAAO,CAAC2D,WAAW,CAACnU,KAAK,CAACuT,IAAI,CAAC,CAAC,CAAC,EAAEvT,KAAK,CAACuT,IAAI,CAAC,CAAC,CAAC,EAAEvT,KAAK,CAACuT,IAAI,CAAC,CAAC,CAAC,CAAC;MACxE;MAEA,IAAI,OAAOvT,KAAK,CAACwQ,OAAO,CAAC4F,YAAY,KAAK,WAAW,EAAE;QACrDpW,KAAK,CAACwQ,OAAO,CAAC4F,YAAY,CAAC5W,cAAc,CAACQ,KAAK,CAACwT,YAAY,CAAC,CAAC,CAAC,EAAExV,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;QACxFO,KAAK,CAACwQ,OAAO,CAAC6F,YAAY,CAAC7W,cAAc,CAACQ,KAAK,CAACwT,YAAY,CAAC,CAAC,CAAC,EAAExV,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;QACxFO,KAAK,CAACwQ,OAAO,CAAC8F,YAAY,CAAC9W,cAAc,CAACQ,KAAK,CAACwT,YAAY,CAAC,CAAC,CAAC,EAAExV,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;MAC1F,CAAC,MAAM;QACLO,KAAK,CAACwQ,OAAO,CAACuE,cAAc,CAAC/U,KAAK,CAACwT,YAAY,CAAC,CAAC,CAAC,EAAExT,KAAK,CAACwT,YAAY,CAAC,CAAC,CAAC,EAAExT,KAAK,CAACwT,YAAY,CAAC,CAAC,CAAC,CAAC;MACnG;IACF,CAAC,MAAM;MACLxT,KAAK,CAACwQ,OAAO,GAAGxS,MAAM,CAACgB,GAAG,CAACkX,kBAAkB,CAAC,CAAC;MAC/ClW,KAAK,CAACwQ,OAAO,CAACkD,GAAG,CAAClU,cAAc,CAACQ,KAAK,CAACiV,OAAO,EAAEjX,MAAM,CAACgB,GAAG,CAACS,WAAW,CAAC;IACzE;IAEAO,KAAK,CAACwQ,OAAO,CAACzM,OAAO,CAAC/D,KAAK,CAACE,KAAK,CAAC;;IAElC;IACA,IAAI,CAACF,KAAK,CAACuF,OAAO,EAAE;MAClBvF,KAAK,CAAC6Q,OAAO,CAACrE,KAAK,CAACxM,KAAK,CAACwK,GAAG,EAAE,IAAI,CAAC,CAAC3F,IAAI,CAAC7E,KAAK,CAACwK,GAAG,EAAE,IAAI,CAAC;IAC5D;EACF,CAAC;AACH,CAAC,EAAE,CAAC"},"metadata":{},"sourceType":"script"}