Subversion Repository Public Repository

Nextrek

Diff Revisions 1085 vs 1086 for /s2s/data/564F8E31K64F3A4823S8E83E87FB6B24717C.json

Diff revisions: vs.
  @@ -6,8 +6,8 @@
6 6 "name": "AudioManager",
7 7 "type": "game_script",
8 8 "order": 5,
9 - "content": "# ===================================================================\n#\n# Script: AudioManager\n#\n# $$COPYRIGHT$$\n#\n# ===================================================================\nclass AudioManager\n ###*\n * Manages the audio playback of the game. \n *\n * @module gs\n * @class AudioManager\n * @memberof gs\n * @constructor\n ###\n constructor: ->\n ###*\n * Stores all audio buffers.\n * @property buffers\n * @type gs.AudioBuffer[]\n * @protected\n ### \n @audioBuffers = []\n \n ###*\n * Stores all audio buffers by layer.\n * @property buffers\n * @type gs.AudioBuffer[]\n * @protected\n ### \n @audioBuffersByLayer = []\n \n ###*\n * Stores all audio buffer references for sounds.\n * @property soundReferences\n * @type gs.AudioBufferReference[]\n * @protected\n ### \n @soundReferences = {}\n \n ###*\n * Current Music (Layer 0)\n * @property music\n * @type Object\n * @protected\n ### \n @music = null\n \n ###*\n * Current music volume.\n * @property musicVolume\n * @type number\n * @protected\n ### \n @musicVolume = 100\n \n ###*\n * Current sound volume.\n * @property soundVolume\n * @type number\n * @protected\n ### \n @soundVolume = 100\n \n ###*\n * Current voice volume.\n * @property voiceVolume\n * @type number\n * @protected\n ### \n @voiceVolume = 100\n \n ###*\n * General music volume\n * @property generalMusicVolume\n * @type number\n * @protected\n ### \n @generalMusicVolume = 100\n \n ###*\n * General sound volume\n * @property generalSoundVolume\n * @type number\n * @protected\n ### \n @generalSoundVolume = 100\n \n ###*\n * General voice volume\n * @property generalVoiceVolume\n * @type number\n * @protected\n ### \n @generalVoiceVolume = 100\n \n ###*\n * Stores audio layer info-data for each layer.\n * @property audioLayers\n * @type gs.AudioLayerInfo[]\n * @protected\n ### \n @audioLayers = []\n \n ###*\n * Restores audio-playback from a specified array of audio layers.\n *\n * @method restore\n * @param {gs.AudioLayerInfo[]} layers - An array of audio layer info objects.\n ### \n restore: (layers) ->\n @audioLayers = layers\n \n for layer, i in layers\n if layer and layer.playing\n if layer.customData\n @playMusicRandom(layer, layer.customData.fadeTime, i, layer.customData.playTime, layer.customData.playRange)\n else\n @playMusic(layer, layer.fadeInTime, i)\n \n ###*\n * Loads the specified music.\n *\n * @method loadMusic\n * @param {String} name - The name of the music to load.\n ### \n loadMusic: (name) -> \n name = if name? then (name.name || name) else name\n if name and name.length > 0\n ResourceManager.getAudioStream(\"Audio/Music/#{name}\")\n \n ###*\n * Loads the specified sound.\n *\n * @method loadSound\n * @param {String} name - The name of the sound to load.\n ### \n loadSound: (name) -> \n name = if name? then name.name || name else name\n if name and name.length > 0\n ResourceManager.getAudioBuffer(\"Audio/Sounds/#{name}\")\n \n ###*\n * Updates a randomly played audio buffer.\n *\n * @method updateRandomAudio\n * @param {gs.AudioBuffer} buffer - The audio buffer to update.\n * @protected\n ### \n # FIXME: Refactoring necessary. \n updateRandomAudio: (buffer) ->\n if buffer.customData.startTimer > 0\n buffer.customData.startTimer--\n if buffer.customData.startTimer <= 0\n buffer.fadeInVolume = 1.0 / (buffer.customData.fadeTime||1)\n buffer.fadeInTime = buffer.customData.fadeTime||1\n buffer.fadeOutTime = buffer.customData.fadeTime||1\n buffer.playTime = buffer.customData.playTime.min + Math.random() * (buffer.customData.playTime.max - buffer.customData.playTime.min)\n currentTime = buffer.currentTime # - buffer.startTime\n timeLeft = buffer.duration - currentTime\n buffer.playTime = Math.min(timeLeft * 1000 / 16.6, buffer.playTime)\n \n buffer.customData.startTimer = buffer.playTime + buffer.customData.playRange.start + Math.random() * (buffer.customData.playRange.end - buffer.customData.playRange.start)\n \n ###*\n * Updates all audio-buffers depending on the play-type.\n *\n * @method updateAudioBuffers\n * @protected\n ### \n updateAudioBuffers: ->\n for buffer in @audioBuffers\n if buffer?\n if buffer.customData.playType == 1\n @updateRandomAudio(buffer)\n \n if GameManager.settings.bgmVolume != @generalMusicVolume\n buffer.volume = (@musicVolume * GameManager.settings.bgmVolume / 100) / 100\n @generalMusicVolume = GameManager.settings.bgmVolume\n buffer.update()\n \n \n ###*\n * Updates all audio-buffers depending on the play-type.\n *\n * @method updateAudioBuffers\n * @protected\n ### \n updateGeneralVolume: ->\n if GameManager.settings.seVolume != @generalSoundVolume or GameManager.settings.voiceVolume != @generalVoiceVolume\n @generalSoundVolume = GameManager.settings.seVolume\n @generalVoiceVolume = GameManager.settings.voiceVolume\n for k of @soundReferences\n for reference in @soundReferences[k]\n if reference.voice\n reference.volume = (@voiceVolume * GameManager.settings.voiceVolume / 100) / 100\n else\n reference.volume = (@soundVolume * GameManager.settings.seVolume / 100) / 100\n ###*\n * Updates the audio-playback.\n *\n * @method update\n ### \n update: ->\n @updateAudioBuffers()\n @updateGeneralVolume()\n \n ###*\n * Changes the current music to the specified one.\n *\n * @method changeMusic\n * @param {Object} music - The music to play. If <b>null</b> the current music will stop playing.\n ### \n changeMusic: (music) ->\n if music? and music.name?\n if @music? and @music.name != music.name\n @playMusic(music)\n else if not @music?\n @playMusic(music)\n else\n @stopMusic()\n \n # FIXME: Is this still used?\n ###*\n * Prepares. \n *\n * @method prepare\n * @param {Object} music - The music to play. If <b>null</b> the current music will stop playing.\n ### \n prepare: (path, volume, rate) -> \n buffer = ResourceManager.getAudioBuffer(path)\n \n if buffer.decoded\n buffer.volume = if volume? then volume / 100 else 1.0\n buffer.playbackRate = if rate? then rate / 100 else 1.0\n else\n buffer.onFinishDecode = (source) => \n source.volume = if volume? then volume / 100 else 1.0\n source.playbackRate = if rate? then rate / 100 else 1.0\n buffer.decode()\n \n return buffer\n \n ###*\n * Plays an audio resource.\n *\n * @method play\n * @param {String} path - The path to the audio resource.\n * @param {number} volume - The volume.\n * @param {number} rate - The playback rate.\n * @param {number} fadeInTime - The fade-in time in frames.\n ### \n play: (path, volume, rate, fadeInTime) ->\n buffer = ResourceManager.getAudioStream(path)\n \n if buffer.decoded\n buffer.volume = if volume? then volume / 100 else 1.0\n buffer.playbackRate = if rate? then rate / 100 else 1.0\n buffer.play(fadeInTime) if GameManager.settings.bgmEnabled\n else\n buffer.onFinishDecode = (source) => \n source.volume = if volume? then volume / 100 else 1.0\n source.playbackRate = if rate? then rate / 100 else 1.0\n source.play(fadeInTime) if GameManager.settings.bgmEnabled\n buffer.decode()\n \n return buffer\n \n ###*\n * Stops all sounds.\n *\n * @method stopAllSounds\n ### \n stopAllSounds: ->\n for k of @soundReferences\n for reference in @soundReferences[k]\n reference?.stop()\n \n ###*\n * Stops a sound and all references of it.\n *\n * @method stopSound\n * @param {String} name - The name of the sound to stop.\n ### \n stopSound: (name) ->\n if @soundReferences[name]?\n for reference in @soundReferences[name]\n reference.stop()\n \n \n ###*\n * Stops a voice.\n *\n * @method stopVoice\n * @param {String} name - The name of the voice to stop.\n ### \n stopVoice: (name) ->\n @stopSound(name)\n \n ###*\n * Stops all voices.\n *\n * @method stopAllVoices\n ### \n stopAllVoices: ->\n for k of @soundReferences\n for reference in @soundReferences[k]\n reference.stop() if reference.voice\n \n ###*\n * Plays a voice.\n *\n * @method playVoice\n * @param {String} name - The name of the voice to play.\n * @param {number} volume - The voice volume.\n * @param {number} rate - The voice playback rate.\n ### \n playVoice: (name, volume, rate) ->\n voice = null\n if GameManager.settings.voiceEnabled and not $PARAMS.preview?.settings.voiceDisabled\n voice = @playSound(name?.name, volume || GameManager.defaults.audio.voiceVolume, rate || GameManager.defaults.audio.voicePlaybackRate, no, yes)\n \n return voice \n \n ###*\n * Plays a sound.\n *\n * @method playSound\n * @param {String} name - The name of the sound to play.\n * @param {number} volume - The sound's volume.\n * @param {number} rate - The sound's playback rate.\n * @param {boolean} musicEffect - Indicates if the sound should be played as a music effect. In that case, the current music\n * at audio-layer will be paused until the sound finishes playing.\n * @param {boolean} voice - Indicates if the sound should be handled as a voice.\n ### \n playSound: (name, volume, rate, musicEffect, voice) ->\n if $PARAMS.preview?.settings.soundDisabled then return\n if not name? or (!voice and !GameManager.settings.soundEnabled) then return\n if name.name?\n volume = name.volume\n rate = name.playbackRate\n name = name.name\n \n if name.length == 0 then return\n \n if musicEffect\n @stopMusic()\n \n if not @soundReferences[name]?\n @soundReferences[name] = []\n \n volume = volume ? 100\n volume *= if voice then @generalVoiceVolume / 100 else @generalSoundVolume / 100\n \n reference = null\n for r in @soundReferences[name]\n if not r.isPlaying\n reference = r\n if musicEffect then reference.onEnd = => @resumeMusic(40)\n reference.voice = voice\n reference.volume = volume / 100\n reference.playbackRate = rate / 100\n @voice = reference if voice\n reference.play()\n break\n \n if not reference?\n buffer = ResourceManager.getAudioBuffer(\"Audio/Sounds/#{name}\")\n if buffer and buffer.loaded\n if buffer.decoded\n reference = new GS.AudioBufferReference(buffer, voice)\n if musicEffect then reference.onEnd = => @resumeMusic(40)\n reference.volume = volume / 100\n reference.playbackRate = rate / 100\n reference.voice = voice\n reference.play()\n @voice = reference if voice\n @soundReferences[name].push(reference)\n else\n buffer.name = name\n buffer.onDecodeFinish = (source) =>\n reference = new GS.AudioBufferReference(source, voice)\n if musicEffect then reference.onEnd = => @resumeMusic(40)\n reference.voice = voice\n reference.volume = volume / 100\n reference.playbackRate = rate / 100\n @voice = reference if voice\n reference.play()\n @soundReferences[source.name].push(reference)\n buffer.decode()\n \n return reference \n \n ###*\n * Plays a music as a random music. A random music will fade-in and fade-out\n * at random times. That can be combined with other audio-layers to create a\n * much better looping of an audio track.\n *\n * @method playMusicRandom\n * @param {Object} music - The music to play.\n * @param {number} fadeTime - The time for a single fade-in/out in frames.\n * @param {number} layer - The audio layer to use.\n * @param {gs.Range} playTime - Play-Time range like 10s to 30s.\n * @param {gs.Range} playRange - Play-Range.\n ### \n playMusicRandom: (music, fadeTime, layer, playTime, playRange) ->\n return if $PARAMS.preview?.settings.musicDisabled\n layer = layer ? 0\n\n volume = if music.volume? then music.volume else 100\n volume = volume * (@generalMusicVolume / 100)\n @musicVolume = volume\n @disposeMusic(layer)\n \n if music.name? and music.name.length > 0\n musicBuffer = @play(\"Audio/Music/#{music.name}\", volume, music.rate)\n musicBuffer.loop = yes\n musicBuffer.volume = 0\n musicBuffer.duration = Math.round(musicBuffer.duration * 1000 / 16.6)\n musicBuffer.customData.playType = 1\n musicBuffer.customData.playTime = playTime\n if playRange.end == 0\n musicBuffer.customData.playRange = { start: playRange.start, end: musicBuffer.duration }\n else\n musicBuffer.customData.playRange = playRange\n musicBuffer.customData.fadeTime = fadeTime\n \n musicBuffer.customData.startTimer = Math.round(musicBuffer.customData.playRange.start + Math.random() * (musicBuffer.customData.playRange.end - musicBuffer.customData.playRange.start))\n \n @audioBuffers.push(musicBuffer) if not @audioBuffers.contains(musicBuffer)\n @audioBuffersByLayer[layer] = musicBuffer\n @audioLayers[layer] = name: music.name, time: music.currentTime, volume: music.volume, rate: music.playbackRate, fadeInTime: fadeTime, customData: musicBuffer.customData\n \n ###*\n * Plays a music.\n *\n * @method playMusic\n * @param {string|Object} name - The music to play. Can be just a name or a music data-object.\n * @param {number} volume - The music's volume in percent.\n * @param {number} rate - The music's playback rate in percent.\n * @param {number} fadeInTime - The fade-in time.\n * @param {number} layer - The layer to play the music on.\n ### \n playMusic: (name, volume, rate, fadeInTime, layer) ->\n return if $PARAMS.preview?.settings.musicDisabled\n \n if name? and name.name?\n layer = if layer? then layer else rate || 0\n fadeInTime = volume\n volume = name.volume\n rate = name.playbackRate\n name = name.name\n else\n layer = layer ? 0\n \n @disposeMusic(layer)\n @audioLayers[layer] = name: name, volume: volume, rate: rate, fadeInTime: fadeInTime, playing: true\n \n volume = if volume? then volume else 100\n volume = volume * (@generalMusicVolume / 100)\n @musicVolume = volume\n \n \n if name? and name.length > 0\n @music = name: name\n musicBuffer = @play(\"Audio/Music/#{name}\", volume, rate, fadeInTime)\n musicBuffer.loop = yes\n @audioBuffers.push(musicBuffer) if not @audioBuffers.contains(musicBuffer)\n @audioBuffersByLayer[layer] = musicBuffer\n \n ###*\n * Resumes a paused music.\n *\n * @method resumeMusic\n * @param {number} fadeInTime - The fade-in time in frames.\n * @param {number} layer - The audio layer to resume.\n ### \n resumeMusic: (fadeInTime, layer) ->\n layer = layer ? 0\n if @audioBuffersByLayer[layer]? and not @audioBuffersByLayer[layer].isPlaying\n @audioBuffersByLayer[layer].resume(fadeInTime)\n @audioLayers[layer]?.playing = true\n \n ###*\n * Stops a music.\n *\n * @method stopMusic\n * @param {number} fadeOutTime - The fade-out time in frames.\n * @param {number} layer - The audio layer to stop.\n ### \n stopMusic: (fadeOutTime, layer) -> \n layer = layer ? 0\n @audioBuffersByLayer[layer]?.stop(fadeOutTime)\n @audioBuffersByLayer[layer]?.customData = {}\n @audioLayers[layer]?.playing = false\n @music = null\n \n ###*\n * Stops all music/audio layers.\n *\n * @method stopAllMusic\n * @param {number} fadeOutTime - The fade-out time in frames.\n ### \n stopAllMusic: (fadeOutTime) -> \n for buffer in @audioBuffers\n if buffer?\n buffer.stop(fadeOutTime)\n buffer.customData = {}\n @music = null\n\n\n dispose: (context) ->\n data = context.resources.select (r) -> r.data\n for buffer, layer in @audioBuffersByLayer\n if buffer and data.indexOf(buffer) != -1\n buffer.dispose()\n \n @audioBuffers.remove(buffer)\n @audioBuffersByLayer[layer] = null\n @audioLayers[layer] = null\n \n ###*\n * Disposes a music.\n *\n * @method disposeMusic\n * @param {number} layer - The audio layer of the music to dispose.\n ### \n disposeMusic: (layer) ->\n layer = layer ? 0\n \n @stopMusic(0, layer)\n #@audioBuffers[layer]?.dispose()\n @audioBuffers.remove(@audioBuffersByLayer[layer])\n @audioBuffersByLayer[layer] = null\n @audioLayers[layer] = null\n \nwindow.AudioManager = new AudioManager()\ngs.AudioManager = AudioManager",
10 - "compiledContent": "var AudioManager;\n\nAudioManager = (function() {\n\n /**\n * Manages the audio playback of the game. \n *\n * @module gs\n * @class AudioManager\n * @memberof gs\n * @constructor\n */\n function AudioManager() {\n\n /**\n * Stores all audio buffers.\n * @property buffers\n * @type gs.AudioBuffer[]\n * @protected\n */\n this.audioBuffers = [];\n\n /**\n * Stores all audio buffers by layer.\n * @property buffers\n * @type gs.AudioBuffer[]\n * @protected\n */\n this.audioBuffersByLayer = [];\n\n /**\n * Stores all audio buffer references for sounds.\n * @property soundReferences\n * @type gs.AudioBufferReference[]\n * @protected\n */\n this.soundReferences = {};\n\n /**\n * Current Music (Layer 0)\n * @property music\n * @type Object\n * @protected\n */\n this.music = null;\n\n /**\n * Current music volume.\n * @property musicVolume\n * @type number\n * @protected\n */\n this.musicVolume = 100;\n\n /**\n * Current sound volume.\n * @property soundVolume\n * @type number\n * @protected\n */\n this.soundVolume = 100;\n\n /**\n * Current voice volume.\n * @property voiceVolume\n * @type number\n * @protected\n */\n this.voiceVolume = 100;\n\n /**\n * General music volume\n * @property generalMusicVolume\n * @type number\n * @protected\n */\n this.generalMusicVolume = 100;\n\n /**\n * General sound volume\n * @property generalSoundVolume\n * @type number\n * @protected\n */\n this.generalSoundVolume = 100;\n\n /**\n * General voice volume\n * @property generalVoiceVolume\n * @type number\n * @protected\n */\n this.generalVoiceVolume = 100;\n\n /**\n * Stores audio layer info-data for each layer.\n * @property audioLayers\n * @type gs.AudioLayerInfo[]\n * @protected\n */\n this.audioLayers = [];\n }\n\n\n /**\n * Restores audio-playback from a specified array of audio layers.\n *\n * @method restore\n * @param {gs.AudioLayerInfo[]} layers - An array of audio layer info objects.\n */\n\n AudioManager.prototype.restore = function(layers) {\n var i, j, layer, len, results;\n this.audioLayers = layers;\n results = [];\n for (i = j = 0, len = layers.length; j < len; i = ++j) {\n layer = layers[i];\n if (layer && layer.playing) {\n if (layer.customData) {\n results.push(this.playMusicRandom(layer, layer.customData.fadeTime, i, layer.customData.playTime, layer.customData.playRange));\n } else {\n results.push(this.playMusic(layer, layer.fadeInTime, i));\n }\n } else {\n results.push(void 0);\n }\n }\n return results;\n };\n\n\n /**\n * Loads the specified music.\n *\n * @method loadMusic\n * @param {String} name - The name of the music to load.\n */\n\n AudioManager.prototype.loadMusic = function(name) {\n name = name != null ? name.name || name : name;\n if (name && name.length > 0) {\n return ResourceManager.getAudioStream(\"Audio/Music/\" + name);\n }\n };\n\n\n /**\n * Loads the specified sound.\n *\n * @method loadSound\n * @param {String} name - The name of the sound to load.\n */\n\n AudioManager.prototype.loadSound = function(name) {\n name = name != null ? name.name || name : name;\n if (name && name.length > 0) {\n return ResourceManager.getAudioBuffer(\"Audio/Sounds/\" + name);\n }\n };\n\n\n /**\n * Updates a randomly played audio buffer.\n *\n * @method updateRandomAudio\n * @param {gs.AudioBuffer} buffer - The audio buffer to update.\n * @protected\n */\n\n AudioManager.prototype.updateRandomAudio = function(buffer) {\n var currentTime, timeLeft;\n if (buffer.customData.startTimer > 0) {\n buffer.customData.startTimer--;\n if (buffer.customData.startTimer <= 0) {\n buffer.fadeInVolume = 1.0 / (buffer.customData.fadeTime || 1);\n buffer.fadeInTime = buffer.customData.fadeTime || 1;\n buffer.fadeOutTime = buffer.customData.fadeTime || 1;\n buffer.playTime = buffer.customData.playTime.min + Math.random() * (buffer.customData.playTime.max - buffer.customData.playTime.min);\n currentTime = buffer.currentTime;\n timeLeft = buffer.duration - currentTime;\n buffer.playTime = Math.min(timeLeft * 1000 / 16.6, buffer.playTime);\n return buffer.customData.startTimer = buffer.playTime + buffer.customData.playRange.start + Math.random() * (buffer.customData.playRange.end - buffer.customData.playRange.start);\n }\n }\n };\n\n\n /**\n * Updates all audio-buffers depending on the play-type.\n *\n * @method updateAudioBuffers\n * @protected\n */\n\n AudioManager.prototype.updateAudioBuffers = function() {\n var buffer, j, len, ref, results;\n ref = this.audioBuffers;\n results = [];\n for (j = 0, len = ref.length; j < len; j++) {\n buffer = ref[j];\n if (buffer != null) {\n if (buffer.customData.playType === 1) {\n this.updateRandomAudio(buffer);\n }\n if (GameManager.settings.bgmVolume !== this.generalMusicVolume) {\n buffer.volume = (this.musicVolume * GameManager.settings.bgmVolume / 100) / 100;\n this.generalMusicVolume = GameManager.settings.bgmVolume;\n }\n results.push(buffer.update());\n } else {\n results.push(void 0);\n }\n }\n return results;\n };\n\n\n /**\n * Updates all audio-buffers depending on the play-type.\n *\n * @method updateAudioBuffers\n * @protected\n */\n\n AudioManager.prototype.updateGeneralVolume = function() {\n var k, reference, results;\n if (GameManager.settings.seVolume !== this.generalSoundVolume || GameManager.settings.voiceVolume !== this.generalVoiceVolume) {\n this.generalSoundVolume = GameManager.settings.seVolume;\n this.generalVoiceVolume = GameManager.settings.voiceVolume;\n results = [];\n for (k in this.soundReferences) {\n results.push((function() {\n var j, len, ref, results1;\n ref = this.soundReferences[k];\n results1 = [];\n for (j = 0, len = ref.length; j < len; j++) {\n reference = ref[j];\n if (reference.voice) {\n results1.push(reference.volume = (this.voiceVolume * GameManager.settings.voiceVolume / 100) / 100);\n } else {\n results1.push(reference.volume = (this.soundVolume * GameManager.settings.seVolume / 100) / 100);\n }\n }\n return results1;\n }).call(this));\n }\n return results;\n }\n };\n\n\n /**\n * Updates the audio-playback.\n *\n * @method update\n */\n\n AudioManager.prototype.update = function() {\n this.updateAudioBuffers();\n return this.updateGeneralVolume();\n };\n\n\n /**\n * Changes the current music to the specified one.\n *\n * @method changeMusic\n * @param {Object} music - The music to play. If <b>null</b> the current music will stop playing.\n */\n\n AudioManager.prototype.changeMusic = function(music) {\n if ((music != null) && (music.name != null)) {\n if ((this.music != null) && this.music.name !== music.name) {\n return this.playMusic(music);\n } else if (this.music == null) {\n return this.playMusic(music);\n }\n } else {\n return this.stopMusic();\n }\n };\n\n\n /**\n * Prepares. \n *\n * @method prepare\n * @param {Object} music - The music to play. If <b>null</b> the current music will stop playing.\n */\n\n AudioManager.prototype.prepare = function(path, volume, rate) {\n var buffer;\n buffer = ResourceManager.getAudioBuffer(path);\n if (buffer.decoded) {\n buffer.volume = volume != null ? volume / 100 : 1.0;\n buffer.playbackRate = rate != null ? rate / 100 : 1.0;\n } else {\n buffer.onFinishDecode = (function(_this) {\n return function(source) {\n source.volume = volume != null ? volume / 100 : 1.0;\n return source.playbackRate = rate != null ? rate / 100 : 1.0;\n };\n })(this);\n buffer.decode();\n }\n return buffer;\n };\n\n\n /**\n * Plays an audio resource.\n *\n * @method play\n * @param {String} path - The path to the audio resource.\n * @param {number} volume - The volume.\n * @param {number} rate - The playback rate.\n * @param {number} fadeInTime - The fade-in time in frames.\n */\n\n AudioManager.prototype.play = function(path, volume, rate, fadeInTime) {\n var buffer;\n buffer = ResourceManager.getAudioStream(path);\n if (buffer.decoded) {\n buffer.volume = volume != null ? volume / 100 : 1.0;\n buffer.playbackRate = rate != null ? rate / 100 : 1.0;\n if (GameManager.settings.bgmEnabled) {\n buffer.play(fadeInTime);\n }\n } else {\n buffer.onFinishDecode = (function(_this) {\n return function(source) {\n source.volume = volume != null ? volume / 100 : 1.0;\n source.playbackRate = rate != null ? rate / 100 : 1.0;\n if (GameManager.settings.bgmEnabled) {\n return source.play(fadeInTime);\n }\n };\n })(this);\n buffer.decode();\n }\n return buffer;\n };\n\n\n /**\n * Stops all sounds.\n *\n * @method stopAllSounds\n */\n\n AudioManager.prototype.stopAllSounds = function() {\n var k, reference, results;\n results = [];\n for (k in this.soundReferences) {\n results.push((function() {\n var j, len, ref, results1;\n ref = this.soundReferences[k];\n results1 = [];\n for (j = 0, len = ref.length; j < len; j++) {\n reference = ref[j];\n results1.push(reference != null ? reference.stop() : void 0);\n }\n return results1;\n }).call(this));\n }\n return results;\n };\n\n\n /**\n * Stops a sound and all references of it.\n *\n * @method stopSound\n * @param {String} name - The name of the sound to stop.\n */\n\n AudioManager.prototype.stopSound = function(name) {\n var j, len, ref, reference, results;\n if (this.soundReferences[name] != null) {\n ref = this.soundReferences[name];\n results = [];\n for (j = 0, len = ref.length; j < len; j++) {\n reference = ref[j];\n results.push(reference.stop());\n }\n return results;\n }\n };\n\n\n /**\n * Stops a voice.\n *\n * @method stopVoice\n * @param {String} name - The name of the voice to stop.\n */\n\n AudioManager.prototype.stopVoice = function(name) {\n return this.stopSound(name);\n };\n\n\n /**\n * Stops all voices.\n *\n * @method stopAllVoices\n */\n\n AudioManager.prototype.stopAllVoices = function() {\n var k, reference, results;\n results = [];\n for (k in this.soundReferences) {\n results.push((function() {\n var j, len, ref, results1;\n ref = this.soundReferences[k];\n results1 = [];\n for (j = 0, len = ref.length; j < len; j++) {\n reference = ref[j];\n if (reference.voice) {\n results1.push(reference.stop());\n } else {\n results1.push(void 0);\n }\n }\n return results1;\n }).call(this));\n }\n return results;\n };\n\n\n /**\n * Plays a voice.\n *\n * @method playVoice\n * @param {String} name - The name of the voice to play.\n * @param {number} volume - The voice volume.\n * @param {number} rate - The voice playback rate.\n */\n\n AudioManager.prototype.playVoice = function(name, volume, rate) {\n var ref, voice;\n voice = null;\n if (GameManager.settings.voiceEnabled && !((ref = $PARAMS.preview) != null ? ref.settings.voiceDisabled : void 0)) {\n voice = this.playSound(name != null ? name.name : void 0, volume || GameManager.defaults.audio.voiceVolume, rate || GameManager.defaults.audio.voicePlaybackRate, false, true);\n }\n return voice;\n };\n\n\n /**\n * Plays a sound.\n *\n * @method playSound\n * @param {String} name - The name of the sound to play.\n * @param {number} volume - The sound's volume.\n * @param {number} rate - The sound's playback rate.\n * @param {boolean} musicEffect - Indicates if the sound should be played as a music effect. In that case, the current music\n * at audio-layer will be paused until the sound finishes playing.\n * @param {boolean} voice - Indicates if the sound should be handled as a voice.\n */\n\n AudioManager.prototype.playSound = function(name, volume, rate, musicEffect, voice) {\n var buffer, j, len, r, ref, ref1, reference;\n if ((ref = $PARAMS.preview) != null ? ref.settings.soundDisabled : void 0) {\n return;\n }\n if ((name == null) || (!voice && !GameManager.settings.soundEnabled)) {\n return;\n }\n if (name.name != null) {\n volume = name.volume;\n rate = name.playbackRate;\n name = name.name;\n }\n if (name.length === 0) {\n return;\n }\n if (musicEffect) {\n this.stopMusic();\n }\n if (this.soundReferences[name] == null) {\n this.soundReferences[name] = [];\n }\n volume = volume != null ? volume : 100;\n volume *= voice ? this.generalVoiceVolume / 100 : this.generalSoundVolume / 100;\n reference = null;\n ref1 = this.soundReferences[name];\n for (j = 0, len = ref1.length; j < len; j++) {\n r = ref1[j];\n if (!r.isPlaying) {\n reference = r;\n if (musicEffect) {\n reference.onEnd = (function(_this) {\n return function() {\n return _this.resumeMusic(40);\n };\n })(this);\n }\n reference.voice = voice;\n reference.volume = volume / 100;\n reference.playbackRate = rate / 100;\n if (voice) {\n this.voice = reference;\n }\n reference.play();\n break;\n }\n }\n if (reference == null) {\n buffer = ResourceManager.getAudioBuffer(\"Audio/Sounds/\" + name);\n if (buffer && buffer.loaded) {\n if (buffer.decoded) {\n reference = new GS.AudioBufferReference(buffer, voice);\n if (musicEffect) {\n reference.onEnd = (function(_this) {\n return function() {\n return _this.resumeMusic(40);\n };\n })(this);\n }\n reference.volume = volume / 100;\n reference.playbackRate = rate / 100;\n reference.voice = voice;\n reference.play();\n if (voice) {\n this.voice = reference;\n }\n this.soundReferences[name].push(reference);\n } else {\n buffer.name = name;\n buffer.onDecodeFinish = (function(_this) {\n return function(source) {\n reference = new GS.AudioBufferReference(source, voice);\n if (musicEffect) {\n reference.onEnd = function() {\n return _this.resumeMusic(40);\n };\n }\n reference.voice = voice;\n reference.volume = volume / 100;\n reference.playbackRate = rate / 100;\n if (voice) {\n _this.voice = reference;\n }\n reference.play();\n return _this.soundReferences[source.name].push(reference);\n };\n })(this);\n buffer.decode();\n }\n }\n }\n return reference;\n };\n\n\n /**\n * Plays a music as a random music. A random music will fade-in and fade-out\n * at random times. That can be combined with other audio-layers to create a\n * much better looping of an audio track.\n *\n * @method playMusicRandom\n * @param {Object} music - The music to play.\n * @param {number} fadeTime - The time for a single fade-in/out in frames.\n * @param {number} layer - The audio layer to use.\n * @param {gs.Range} playTime - Play-Time range like 10s to 30s.\n * @param {gs.Range} playRange - Play-Range.\n */\n\n AudioManager.prototype.playMusicRandom = function(music, fadeTime, layer, playTime, playRange) {\n var musicBuffer, ref, volume;\n if ((ref = $PARAMS.preview) != null ? ref.settings.musicDisabled : void 0) {\n return;\n }\n layer = layer != null ? layer : 0;\n volume = music.volume != null ? music.volume : 100;\n volume = volume * (this.generalMusicVolume / 100);\n this.musicVolume = volume;\n this.disposeMusic(layer);\n if ((music.name != null) && music.name.length > 0) {\n musicBuffer = this.play(\"Audio/Music/\" + music.name, volume, music.rate);\n musicBuffer.loop = true;\n musicBuffer.volume = 0;\n musicBuffer.duration = Math.round(musicBuffer.duration * 1000 / 16.6);\n musicBuffer.customData.playType = 1;\n musicBuffer.customData.playTime = playTime;\n if (playRange.end === 0) {\n musicBuffer.customData.playRange = {\n start: playRange.start,\n end: musicBuffer.duration\n };\n } else {\n musicBuffer.customData.playRange = playRange;\n }\n musicBuffer.customData.fadeTime = fadeTime;\n musicBuffer.customData.startTimer = Math.round(musicBuffer.customData.playRange.start + Math.random() * (musicBuffer.customData.playRange.end - musicBuffer.customData.playRange.start));\n if (!this.audioBuffers.contains(musicBuffer)) {\n this.audioBuffers.push(musicBuffer);\n }\n this.audioBuffersByLayer[layer] = musicBuffer;\n return this.audioLayers[layer] = {\n name: music.name,\n time: music.currentTime,\n volume: music.volume,\n rate: music.playbackRate,\n fadeInTime: fadeTime,\n customData: musicBuffer.customData\n };\n }\n };\n\n\n /**\n * Plays a music.\n *\n * @method playMusic\n * @param {string|Object} name - The music to play. Can be just a name or a music data-object.\n * @param {number} volume - The music's volume in percent.\n * @param {number} rate - The music's playback rate in percent.\n * @param {number} fadeInTime - The fade-in time.\n * @param {number} layer - The layer to play the music on.\n */\n\n AudioManager.prototype.playMusic = function(name, volume, rate, fadeInTime, layer) {\n var musicBuffer, ref;\n if ((ref = $PARAMS.preview) != null ? ref.settings.musicDisabled : void 0) {\n return;\n }\n if ((name != null) && (name.name != null)) {\n layer = layer != null ? layer : rate || 0;\n fadeInTime = volume;\n volume = name.volume;\n rate = name.playbackRate;\n name = name.name;\n } else {\n layer = layer != null ? layer : 0;\n }\n this.disposeMusic(layer);\n this.audioLayers[layer] = {\n name: name,\n volume: volume,\n rate: rate,\n fadeInTime: fadeInTime,\n playing: true\n };\n volume = volume != null ? volume : 100;\n volume = volume * (this.generalMusicVolume / 100);\n this.musicVolume = volume;\n if ((name != null) && name.length > 0) {\n this.music = {\n name: name\n };\n musicBuffer = this.play(\"Audio/Music/\" + name, volume, rate, fadeInTime);\n musicBuffer.loop = true;\n if (!this.audioBuffers.contains(musicBuffer)) {\n this.audioBuffers.push(musicBuffer);\n }\n return this.audioBuffersByLayer[layer] = musicBuffer;\n }\n };\n\n\n /**\n * Resumes a paused music.\n *\n * @method resumeMusic\n * @param {number} fadeInTime - The fade-in time in frames.\n * @param {number} layer - The audio layer to resume.\n */\n\n AudioManager.prototype.resumeMusic = function(fadeInTime, layer) {\n var ref;\n layer = layer != null ? layer : 0;\n if ((this.audioBuffersByLayer[layer] != null) && !this.audioBuffersByLayer[layer].isPlaying) {\n this.audioBuffersByLayer[layer].resume(fadeInTime);\n return (ref = this.audioLayers[layer]) != null ? ref.playing = true : void 0;\n }\n };\n\n\n /**\n * Stops a music.\n *\n * @method stopMusic\n * @param {number} fadeOutTime - The fade-out time in frames.\n * @param {number} layer - The audio layer to stop.\n */\n\n AudioManager.prototype.stopMusic = function(fadeOutTime, layer) {\n var ref, ref1, ref2;\n layer = layer != null ? layer : 0;\n if ((ref = this.audioBuffersByLayer[layer]) != null) {\n ref.stop(fadeOutTime);\n }\n if ((ref1 = this.audioBuffersByLayer[layer]) != null) {\n ref1.customData = {};\n }\n if ((ref2 = this.audioLayers[layer]) != null) {\n ref2.playing = false;\n }\n return this.music = null;\n };\n\n\n /**\n * Stops all music/audio layers.\n *\n * @method stopAllMusic\n * @param {number} fadeOutTime - The fade-out time in frames.\n */\n\n AudioManager.prototype.stopAllMusic = function(fadeOutTime) {\n var buffer, j, len, ref;\n ref = this.audioBuffers;\n for (j = 0, len = ref.length; j < len; j++) {\n buffer = ref[j];\n if (buffer != null) {\n buffer.stop(fadeOutTime);\n buffer.customData = {};\n }\n }\n return this.music = null;\n };\n\n AudioManager.prototype.dispose = function(context) {\n var buffer, data, j, layer, len, ref, results;\n data = context.resources.select(function(r) {\n return r.data;\n });\n ref = this.audioBuffersByLayer;\n results = [];\n for (layer = j = 0, len = ref.length; j < len; layer = ++j) {\n buffer = ref[layer];\n if (buffer && data.indexOf(buffer) !== -1) {\n buffer.dispose();\n this.audioBuffers.remove(buffer);\n this.audioBuffersByLayer[layer] = null;\n results.push(this.audioLayers[layer] = null);\n } else {\n results.push(void 0);\n }\n }\n return results;\n };\n\n\n /**\n * Disposes a music.\n *\n * @method disposeMusic\n * @param {number} layer - The audio layer of the music to dispose.\n */\n\n AudioManager.prototype.disposeMusic = function(layer) {\n layer = layer != null ? layer : 0;\n this.stopMusic(0, layer);\n this.audioBuffers.remove(this.audioBuffersByLayer[layer]);\n this.audioBuffersByLayer[layer] = null;\n return this.audioLayers[layer] = null;\n };\n\n return AudioManager;\n\n})();\n\nwindow.AudioManager = new AudioManager();\n\ngs.AudioManager = AudioManager;\n\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU9BLElBQUE7O0FBQU07O0FBQ0Y7Ozs7Ozs7O0VBUWEsc0JBQUE7O0FBQ1Q7Ozs7OztJQU1BLElBQUMsQ0FBQSxZQUFELEdBQWdCOztBQUVoQjs7Ozs7O0lBTUEsSUFBQyxDQUFBLG1CQUFELEdBQXVCOztBQUV2Qjs7Ozs7O0lBTUEsSUFBQyxDQUFBLGVBQUQsR0FBbUI7O0FBRW5COzs7Ozs7SUFNQSxJQUFDLENBQUEsS0FBRCxHQUFTOztBQUVUOzs7Ozs7SUFNQSxJQUFDLENBQUEsV0FBRCxHQUFlOztBQUVmOzs7Ozs7SUFNQSxJQUFDLENBQUEsV0FBRCxHQUFlOztBQUVmOzs7Ozs7SUFNQSxJQUFDLENBQUEsV0FBRCxHQUFlOztBQUVmOzs7Ozs7SUFNQSxJQUFDLENBQUEsa0JBQUQsR0FBc0I7O0FBRXRCOzs7Ozs7SUFNQSxJQUFDLENBQUEsa0JBQUQsR0FBc0I7O0FBRXRCOzs7Ozs7SUFNQSxJQUFDLENBQUEsa0JBQUQsR0FBc0I7O0FBRXRCOzs7Ozs7SUFNQSxJQUFDLENBQUEsV0FBRCxHQUFlO0VBdkZOOzs7QUF5RmI7Ozs7Ozs7eUJBTUEsT0FBQSxHQUFTLFNBQUMsTUFBRDtBQUNMLFFBQUE7SUFBQSxJQUFDLENBQUEsV0FBRCxHQUFlO0FBRWY7U0FBQSxnREFBQTs7TUFDSSxJQUFHLEtBQUEsSUFBVSxLQUFLLENBQUMsT0FBbkI7UUFDSSxJQUFHLEtBQUssQ0FBQyxVQUFUO3VCQUNJLElBQUMsQ0FBQSxlQUFELENBQWlCLEtBQWpCLEVBQXdCLEtBQUssQ0FBQyxVQUFVLENBQUMsUUFBekMsRUFBbUQsQ0FBbkQsRUFBc0QsS0FBSyxDQUFDLFVBQVUsQ0FBQyxRQUF2RSxFQUFpRixLQUFLLENBQUMsVUFBVSxDQUFDLFNBQWxHLEdBREo7U0FBQSxNQUFBO3VCQUdJLElBQUMsQ0FBQSxTQUFELENBQVcsS0FBWCxFQUFrQixLQUFLLENBQUMsVUFBeEIsRUFBb0MsQ0FBcEMsR0FISjtTQURKO09BQUEsTUFBQTs2QkFBQTs7QUFESjs7RUFISzs7O0FBVVQ7Ozs7Ozs7eUJBTUEsU0FBQSxHQUFXLFNBQUMsSUFBRDtJQUNQLElBQUEsR0FBVSxZQUFILEdBQWUsSUFBSSxDQUFDLElBQUwsSUFBYSxJQUE1QixHQUF1QztJQUM5QyxJQUFHLElBQUEsSUFBUyxJQUFJLENBQUMsTUFBTCxHQUFjLENBQTFCO2FBQ0ksZUFBZSxDQUFDLGNBQWhCLENBQStCLGNBQUEsR0FBZSxJQUE5QyxFQURKOztFQUZPOzs7QUFLWDs7Ozs7Ozt5QkFNQSxTQUFBLEdBQVcsU0FBQyxJQUFEO0lBQ1AsSUFBQSxHQUFVLFlBQUgsR0FBYyxJQUFJLENBQUMsSUFBTCxJQUFhLElBQTNCLEdBQXFDO0lBQzVDLElBQUcsSUFBQSxJQUFTLElBQUksQ0FBQyxNQUFMLEdBQWMsQ0FBMUI7YUFDSSxlQUFlLENBQUMsY0FBaEIsQ0FBK0IsZUFBQSxHQUFnQixJQUEvQyxFQURKOztFQUZPOzs7QUFLWDs7Ozs7Ozs7eUJBUUEsaUJBQUEsR0FBbUIsU0FBQyxNQUFEO0FBQ2YsUUFBQTtJQUFBLElBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxVQUFsQixHQUErQixDQUFsQztNQUNJLE1BQU0sQ0FBQyxVQUFVLENBQUMsVUFBbEI7TUFDQSxJQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsVUFBbEIsSUFBZ0MsQ0FBbkM7UUFDSSxNQUFNLENBQUMsWUFBUCxHQUFzQixHQUFBLEdBQU0sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFFBQWxCLElBQTRCLENBQTdCO1FBQzVCLE1BQU0sQ0FBQyxVQUFQLEdBQW9CLE1BQU0sQ0FBQyxVQUFVLENBQUMsUUFBbEIsSUFBNEI7UUFDaEQsTUFBTSxDQUFDLFdBQVAsR0FBcUIsTUFBTSxDQUFDLFVBQVUsQ0FBQyxRQUFsQixJQUE0QjtRQUNqRCxNQUFNLENBQUMsUUFBUCxHQUFrQixNQUFNLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxHQUEzQixHQUFpQyxJQUFJLENBQUMsTUFBTCxDQUFBLENBQUEsR0FBZ0IsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxHQUEzQixHQUFpQyxNQUFNLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxHQUE3RDtRQUNuRSxXQUFBLEdBQWMsTUFBTSxDQUFDO1FBQ3JCLFFBQUEsR0FBVyxNQUFNLENBQUMsUUFBUCxHQUFrQjtRQUM3QixNQUFNLENBQUMsUUFBUCxHQUFrQixJQUFJLENBQUMsR0FBTCxDQUFTLFFBQUEsR0FBVyxJQUFYLEdBQWtCLElBQTNCLEVBQWlDLE1BQU0sQ0FBQyxRQUF4QztlQUVsQixNQUFNLENBQUMsVUFBVSxDQUFDLFVBQWxCLEdBQStCLE1BQU0sQ0FBQyxRQUFQLEdBQWtCLE1BQU0sQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLEtBQTlDLEdBQXNELElBQUksQ0FBQyxNQUFMLENBQUEsQ0FBQSxHQUFnQixDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLEdBQTVCLEdBQWtDLE1BQU0sQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLEtBQS9ELEVBVHpHO09BRko7O0VBRGU7OztBQWNuQjs7Ozs7Ozt5QkFNQSxrQkFBQSxHQUFvQixTQUFBO0FBQ2hCLFFBQUE7QUFBQTtBQUFBO1NBQUEscUNBQUE7O01BQ0ksSUFBRyxjQUFIO1FBQ0ksSUFBRyxNQUFNLENBQUMsVUFBVSxDQUFDLFFBQWxCLEtBQThCLENBQWpDO1VBQ0ksSUFBQyxDQUFBLGlCQUFELENBQW1CLE1BQW5CLEVBREo7O1FBR0EsSUFBRyxXQUFXLENBQUMsUUFBUSxDQUFDLFNBQXJCLEtBQWtDLElBQUMsQ0FBQSxrQkFBdEM7VUFDSSxNQUFNLENBQUMsTUFBUCxHQUFnQixDQUFDLElBQUMsQ0FBQSxXQUFELEdBQWUsV0FBVyxDQUFDLFFBQVEsQ0FBQyxTQUFwQyxHQUFnRCxHQUFqRCxDQUFBLEdBQXdEO1VBQ3hFLElBQUMsQ0FBQSxrQkFBRCxHQUFzQixXQUFXLENBQUMsUUFBUSxDQUFDLFVBRi9DOztxQkFHQSxNQUFNLENBQUMsTUFBUCxDQUFBLEdBUEo7T0FBQSxNQUFBOzZCQUFBOztBQURKOztFQURnQjs7O0FBWXBCOzs7Ozs7O3lCQU1BLG1CQUFBLEdBQXFCLFNBQUE7QUFDakIsUUFBQTtJQUFBLElBQUcsV0FBVyxDQUFDLFFBQVEsQ0FBQyxRQUFyQixLQUFpQyxJQUFDLENBQUEsa0JBQWxDLElBQXdELFdBQVcsQ0FBQyxRQUFRLENBQUMsV0FBckIsS0FBb0MsSUFBQyxDQUFBLGtCQUFoRztNQUNJLElBQUMsQ0FBQSxrQkFBRCxHQUFzQixXQUFXLENBQUMsUUFBUSxDQUFDO01BQzNDLElBQUMsQ0FBQSxrQkFBRCxHQUFzQixXQUFXLENBQUMsUUFBUSxDQUFDO0FBQzNDO1dBQUEseUJBQUE7OztBQUNJO0FBQUE7ZUFBQSxxQ0FBQTs7WUFDSSxJQUFHLFNBQVMsQ0FBQyxLQUFiOzRCQUNJLFNBQVMsQ0FBQyxNQUFWLEdBQW1CLENBQUMsSUFBQyxDQUFBLFdBQUQsR0FBZSxXQUFXLENBQUMsUUFBUSxDQUFDLFdBQXBDLEdBQWtELEdBQW5ELENBQUEsR0FBMEQsS0FEakY7YUFBQSxNQUFBOzRCQUdJLFNBQVMsQ0FBQyxNQUFWLEdBQW1CLENBQUMsSUFBQyxDQUFBLFdBQUQsR0FBZSxXQUFXLENBQUMsUUFBUSxDQUFDLFFBQXBDLEdBQStDLEdBQWhELENBQUEsR0FBdUQsS0FIOUU7O0FBREo7OztBQURKO3FCQUhKOztFQURpQjs7O0FBVXJCOzs7Ozs7eUJBS0EsTUFBQSxHQUFRLFNBQUE7SUFDSixJQUFDLENBQUEsa0JBQUQsQ0FBQTtXQUNBLElBQUMsQ0FBQSxtQkFBRCxDQUFBO0VBRkk7OztBQUlSOzs7Ozs7O3lCQU1BLFdBQUEsR0FBYSxTQUFDLEtBQUQ7SUFDVCxJQUFHLGVBQUEsSUFBVyxvQkFBZDtNQUNJLElBQUcsb0JBQUEsSUFBWSxJQUFDLENBQUEsS0FBSyxDQUFDLElBQVAsS0FBZSxLQUFLLENBQUMsSUFBcEM7ZUFDSSxJQUFDLENBQUEsU0FBRCxDQUFXLEtBQVgsRUFESjtPQUFBLE1BRUssSUFBTyxrQkFBUDtlQUNELElBQUMsQ0FBQSxTQUFELENBQVcsS0FBWCxFQURDO09BSFQ7S0FBQSxNQUFBO2FBTUksSUFBQyxDQUFBLFNBQUQsQ0FBQSxFQU5KOztFQURTOzs7QUFVYjs7Ozs7Ozt5QkFNQSxPQUFBLEdBQVMsU0FBQyxJQUFELEVBQU8sTUFBUCxFQUFlLElBQWY7QUFDTCxRQUFBO0lBQUEsTUFBQSxHQUFTLGVBQWUsQ0FBQyxjQUFoQixDQUErQixJQUEvQjtJQUVULElBQUcsTUFBTSxDQUFDLE9BQVY7TUFDSSxNQUFNLENBQUMsTUFBUCxHQUFtQixjQUFILEdBQWdCLE1BQUEsR0FBUyxHQUF6QixHQUFrQztNQUNsRCxNQUFNLENBQUMsWUFBUCxHQUF5QixZQUFILEdBQWMsSUFBQSxHQUFPLEdBQXJCLEdBQThCLElBRnhEO0tBQUEsTUFBQTtNQUlHLE1BQU0sQ0FBQyxjQUFQLEdBQXdCLENBQUEsU0FBQSxLQUFBO2VBQUEsU0FBQyxNQUFEO1VBQ3BCLE1BQU0sQ0FBQyxNQUFQLEdBQW1CLGNBQUgsR0FBZ0IsTUFBQSxHQUFTLEdBQXpCLEdBQWtDO2lCQUNsRCxNQUFNLENBQUMsWUFBUCxHQUF5QixZQUFILEdBQWMsSUFBQSxHQUFPLEdBQXJCLEdBQThCO1FBRmhDO01BQUEsQ0FBQSxDQUFBLENBQUEsSUFBQTtNQUd4QixNQUFNLENBQUMsTUFBUCxDQUFBLEVBUEg7O0FBU0EsV0FBTztFQVpGOzs7QUFjVDs7Ozs7Ozs7Ozt5QkFTQSxJQUFBLEdBQU0sU0FBQyxJQUFELEVBQU8sTUFBUCxFQUFlLElBQWYsRUFBcUIsVUFBckI7QUFDRixRQUFBO0lBQUEsTUFBQSxHQUFTLGVBQWUsQ0FBQyxjQUFoQixDQUErQixJQUEvQjtJQUVULElBQUcsTUFBTSxDQUFDLE9BQVY7TUFDSSxNQUFNLENBQUMsTUFBUCxHQUFtQixjQUFILEdBQWdCLE1BQUEsR0FBUyxHQUF6QixHQUFrQztNQUNsRCxNQUFNLENBQUMsWUFBUCxHQUF5QixZQUFILEdBQWMsSUFBQSxHQUFPLEdBQXJCLEdBQThCO01BQ3BELElBQTJCLFdBQVcsQ0FBQyxRQUFRLENBQUMsVUFBaEQ7UUFBQSxNQUFNLENBQUMsSUFBUCxDQUFZLFVBQVosRUFBQTtPQUhKO0tBQUEsTUFBQTtNQUtHLE1BQU0sQ0FBQyxjQUFQLEdBQXdCLENBQUEsU0FBQSxLQUFBO2VBQUEsU0FBQyxNQUFEO1VBQ3BCLE1BQU0sQ0FBQyxNQUFQLEdBQW1CLGNBQUgsR0FBZ0IsTUFBQSxHQUFTLEdBQXpCLEdBQWtDO1VBQ2xELE1BQU0sQ0FBQyxZQUFQLEdBQXlCLFlBQUgsR0FBYyxJQUFBLEdBQU8sR0FBckIsR0FBOEI7VUFDcEQsSUFBMkIsV0FBVyxDQUFDLFFBQVEsQ0FBQyxVQUFoRDttQkFBQSxNQUFNLENBQUMsSUFBUCxDQUFZLFVBQVosRUFBQTs7UUFIb0I7TUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBO01BSXhCLE1BQU0sQ0FBQyxNQUFQLENBQUEsRUFUSDs7QUFXQSxXQUFPO0VBZEw7OztBQWdCTjs7Ozs7O3lCQUtBLGFBQUEsR0FBZSxTQUFBO0FBQ1gsUUFBQTtBQUFBO1NBQUEseUJBQUE7OztBQUNJO0FBQUE7YUFBQSxxQ0FBQTs7NENBQ0ksU0FBUyxDQUFFLElBQVgsQ0FBQTtBQURKOzs7QUFESjs7RUFEVzs7O0FBS2Y7Ozs7Ozs7eUJBTUEsU0FBQSxHQUFXLFNBQUMsSUFBRDtBQUNQLFFBQUE7SUFBQSxJQUFHLGtDQUFIO0FBQ0k7QUFBQTtXQUFBLHFDQUFBOztxQkFDSSxTQUFTLENBQUMsSUFBVixDQUFBO0FBREo7cUJBREo7O0VBRE87OztBQU1YOzs7Ozs7O3lCQU1BLFNBQUEsR0FBVyxTQUFDLElBQUQ7V0FDUCxJQUFDLENBQUEsU0FBRCxDQUFXLElBQVg7RUFETzs7O0FBR1g7Ozs7Ozt5QkFLQSxhQUFBLEdBQWUsU0FBQTtBQUNYLFFBQUE7QUFBQTtTQUFBLHlCQUFBOzs7QUFDSTtBQUFBO2FBQUEscUNBQUE7O1VBQ0ksSUFBb0IsU0FBUyxDQUFDLEtBQTlCOzBCQUFBLFNBQVMsQ0FBQyxJQUFWLENBQUEsR0FBQTtXQUFBLE1BQUE7a0NBQUE7O0FBREo7OztBQURKOztFQURXOzs7QUFLZjs7Ozs7Ozs7O3lCQVFBLFNBQUEsR0FBVyxTQUFDLElBQUQsRUFBTyxNQUFQLEVBQWUsSUFBZjtBQUNQLFFBQUE7SUFBQSxLQUFBLEdBQVE7SUFDUixJQUFHLFdBQVcsQ0FBQyxRQUFRLENBQUMsWUFBckIsSUFBc0MsdUNBQW1CLENBQUUsUUFBUSxDQUFDLHVCQUF2RTtNQUNJLEtBQUEsR0FBUSxJQUFDLENBQUEsU0FBRCxnQkFBVyxJQUFJLENBQUUsYUFBakIsRUFBdUIsTUFBQSxJQUFVLFdBQVcsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLFdBQTVELEVBQXlFLElBQUEsSUFBUSxXQUFXLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxpQkFBNUcsRUFBK0gsS0FBL0gsRUFBbUksSUFBbkksRUFEWjs7QUFHQSxXQUFPO0VBTEE7OztBQU9YOzs7Ozs7Ozs7Ozs7eUJBV0EsU0FBQSxHQUFXLFNBQUMsSUFBRCxFQUFPLE1BQVAsRUFBZSxJQUFmLEVBQXFCLFdBQXJCLEVBQWtDLEtBQWxDO0FBQ1AsUUFBQTtJQUFBLHlDQUFrQixDQUFFLFFBQVEsQ0FBQyxzQkFBN0I7QUFBZ0QsYUFBaEQ7O0lBQ0EsSUFBTyxjQUFKLElBQWEsQ0FBQyxDQUFDLEtBQUQsSUFBVyxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsWUFBbEMsQ0FBaEI7QUFBcUUsYUFBckU7O0lBQ0EsSUFBRyxpQkFBSDtNQUNJLE1BQUEsR0FBUyxJQUFJLENBQUM7TUFDZCxJQUFBLEdBQU8sSUFBSSxDQUFDO01BQ1osSUFBQSxHQUFPLElBQUksQ0FBQyxLQUhoQjs7SUFLQSxJQUFHLElBQUksQ0FBQyxNQUFMLEtBQWUsQ0FBbEI7QUFBeUIsYUFBekI7O0lBRUEsSUFBRyxXQUFIO01BQ0ksSUFBQyxDQUFBLFNBQUQsQ0FBQSxFQURKOztJQUdBLElBQU8sa0NBQVA7TUFDSSxJQUFDLENBQUEsZUFBZ0IsQ0FBQSxJQUFBLENBQWpCLEdBQXlCLEdBRDdCOztJQUdBLE1BQUEsb0JBQVMsU0FBUztJQUNsQixNQUFBLElBQWEsS0FBSCxHQUFjLElBQUMsQ0FBQSxrQkFBRCxHQUFzQixHQUFwQyxHQUE2QyxJQUFDLENBQUEsa0JBQUQsR0FBc0I7SUFFN0UsU0FBQSxHQUFZO0FBQ1o7QUFBQSxTQUFBLHNDQUFBOztNQUNJLElBQUcsQ0FBSSxDQUFDLENBQUMsU0FBVDtRQUNJLFNBQUEsR0FBWTtRQUNaLElBQUcsV0FBSDtVQUFvQixTQUFTLENBQUMsS0FBVixHQUFrQixDQUFBLFNBQUEsS0FBQTttQkFBQSxTQUFBO3FCQUFHLEtBQUMsQ0FBQSxXQUFELENBQWEsRUFBYjtZQUFIO1VBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxFQUF0Qzs7UUFDQSxTQUFTLENBQUMsS0FBVixHQUFrQjtRQUNsQixTQUFTLENBQUMsTUFBVixHQUFtQixNQUFBLEdBQVM7UUFDNUIsU0FBUyxDQUFDLFlBQVYsR0FBeUIsSUFBQSxHQUFPO1FBQ2hDLElBQXNCLEtBQXRCO1VBQUEsSUFBQyxDQUFBLEtBQUQsR0FBUyxVQUFUOztRQUNBLFNBQVMsQ0FBQyxJQUFWLENBQUE7QUFDQSxjQVJKOztBQURKO0lBV0EsSUFBTyxpQkFBUDtNQUNJLE1BQUEsR0FBUyxlQUFlLENBQUMsY0FBaEIsQ0FBK0IsZUFBQSxHQUFnQixJQUEvQztNQUNULElBQUcsTUFBQSxJQUFXLE1BQU0sQ0FBQyxNQUFyQjtRQUNJLElBQUcsTUFBTSxDQUFDLE9BQVY7VUFDSSxTQUFBLEdBQWdCLElBQUEsRUFBRSxDQUFDLG9CQUFILENBQXdCLE1BQXhCLEVBQWdDLEtBQWhDO1VBQ2hCLElBQUcsV0FBSDtZQUFvQixTQUFTLENBQUMsS0FBVixHQUFrQixDQUFBLFNBQUEsS0FBQTtxQkFBQSxTQUFBO3VCQUFHLEtBQUMsQ0FBQSxXQUFELENBQWEsRUFBYjtjQUFIO1lBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxFQUF0Qzs7VUFDQSxTQUFTLENBQUMsTUFBVixHQUFtQixNQUFBLEdBQVM7VUFDNUIsU0FBUyxDQUFDLFlBQVYsR0FBeUIsSUFBQSxHQUFPO1VBQ2hDLFNBQVMsQ0FBQyxLQUFWLEdBQWtCO1VBQ2xCLFNBQVMsQ0FBQyxJQUFWLENBQUE7VUFDQSxJQUFzQixLQUF0QjtZQUFBLElBQUMsQ0FBQSxLQUFELEdBQVMsVUFBVDs7VUFDQSxJQUFDLENBQUEsZUFBZ0IsQ0FBQSxJQUFBLENBQUssQ0FBQyxJQUF2QixDQUE0QixTQUE1QixFQVJKO1NBQUEsTUFBQTtVQVVJLE1BQU0sQ0FBQyxJQUFQLEdBQWM7VUFDZCxNQUFNLENBQUMsY0FBUCxHQUF3QixDQUFBLFNBQUEsS0FBQTttQkFBQSxTQUFDLE1BQUQ7Y0FDcEIsU0FBQSxHQUFnQixJQUFBLEVBQUUsQ0FBQyxvQkFBSCxDQUF3QixNQUF4QixFQUFnQyxLQUFoQztjQUNoQixJQUFHLFdBQUg7Z0JBQW9CLFNBQVMsQ0FBQyxLQUFWLEdBQWtCLFNBQUE7eUJBQUcsS0FBQyxDQUFBLFdBQUQsQ0FBYSxFQUFiO2dCQUFILEVBQXRDOztjQUNBLFNBQVMsQ0FBQyxLQUFWLEdBQWtCO2NBQ2xCLFNBQVMsQ0FBQyxNQUFWLEdBQW1CLE1BQUEsR0FBUztjQUM1QixTQUFTLENBQUMsWUFBVixHQUF5QixJQUFBLEdBQU87Y0FDaEMsSUFBc0IsS0FBdEI7Z0JBQUEsS0FBQyxDQUFBLEtBQUQsR0FBUyxVQUFUOztjQUNBLFNBQVMsQ0FBQyxJQUFWLENBQUE7cUJBQ0EsS0FBQyxDQUFBLGVBQWdCLENBQUEsTUFBTSxDQUFDLElBQVAsQ0FBWSxDQUFDLElBQTlCLENBQW1DLFNBQW5DO1lBUm9CO1VBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQTtVQVN4QixNQUFNLENBQUMsTUFBUCxDQUFBLEVBcEJKO1NBREo7T0FGSjs7QUF5QkEsV0FBTztFQXhEQTs7O0FBMERYOzs7Ozs7Ozs7Ozs7O3lCQVlBLGVBQUEsR0FBaUIsU0FBQyxLQUFELEVBQVEsUUFBUixFQUFrQixLQUFsQixFQUF5QixRQUF6QixFQUFtQyxTQUFuQztBQUNiLFFBQUE7SUFBQSx5Q0FBeUIsQ0FBRSxRQUFRLENBQUMsc0JBQXBDO0FBQUEsYUFBQTs7SUFDQSxLQUFBLG1CQUFRLFFBQVE7SUFFaEIsTUFBQSxHQUFZLG9CQUFILEdBQXNCLEtBQUssQ0FBQyxNQUE1QixHQUF3QztJQUNqRCxNQUFBLEdBQVMsTUFBQSxHQUFTLENBQUMsSUFBQyxDQUFBLGtCQUFELEdBQXNCLEdBQXZCO0lBQ2xCLElBQUMsQ0FBQSxXQUFELEdBQWU7SUFDZixJQUFDLENBQUEsWUFBRCxDQUFjLEtBQWQ7SUFFQSxJQUFHLG9CQUFBLElBQWdCLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBWCxHQUFvQixDQUF2QztNQUNJLFdBQUEsR0FBYyxJQUFDLENBQUEsSUFBRCxDQUFNLGNBQUEsR0FBZSxLQUFLLENBQUMsSUFBM0IsRUFBbUMsTUFBbkMsRUFBMkMsS0FBSyxDQUFDLElBQWpEO01BQ2QsV0FBVyxDQUFDLElBQVosR0FBbUI7TUFDbkIsV0FBVyxDQUFDLE1BQVosR0FBcUI7TUFDckIsV0FBVyxDQUFDLFFBQVosR0FBdUIsSUFBSSxDQUFDLEtBQUwsQ0FBVyxXQUFXLENBQUMsUUFBWixHQUF1QixJQUF2QixHQUE4QixJQUF6QztNQUN2QixXQUFXLENBQUMsVUFBVSxDQUFDLFFBQXZCLEdBQWtDO01BQ2xDLFdBQVcsQ0FBQyxVQUFVLENBQUMsUUFBdkIsR0FBa0M7TUFDbEMsSUFBRyxTQUFTLENBQUMsR0FBVixLQUFpQixDQUFwQjtRQUNJLFdBQVcsQ0FBQyxVQUFVLENBQUMsU0FBdkIsR0FBbUM7VUFBRSxLQUFBLEVBQU8sU0FBUyxDQUFDLEtBQW5CO1VBQTBCLEdBQUEsRUFBSyxXQUFXLENBQUMsUUFBM0M7VUFEdkM7T0FBQSxNQUFBO1FBR0ksV0FBVyxDQUFDLFVBQVUsQ0FBQyxTQUF2QixHQUFtQyxVQUh2Qzs7TUFJQSxXQUFXLENBQUMsVUFBVSxDQUFDLFFBQXZCLEdBQWtDO01BRWxDLFdBQVcsQ0FBQyxVQUFVLENBQUMsVUFBdkIsR0FBb0MsSUFBSSxDQUFDLEtBQUwsQ0FBVyxXQUFXLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxLQUFqQyxHQUF5QyxJQUFJLENBQUMsTUFBTCxDQUFBLENBQUEsR0FBZ0IsQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxHQUFqQyxHQUF1QyxXQUFXLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxLQUF6RSxDQUFwRTtNQUVwQyxJQUFtQyxDQUFJLElBQUMsQ0FBQSxZQUFZLENBQUMsUUFBZCxDQUF1QixXQUF2QixDQUF2QztRQUFBLElBQUMsQ0FBQSxZQUFZLENBQUMsSUFBZCxDQUFtQixXQUFuQixFQUFBOztNQUNBLElBQUMsQ0FBQSxtQkFBb0IsQ0FBQSxLQUFBLENBQXJCLEdBQThCO2FBQzlCLElBQUMsQ0FBQSxXQUFZLENBQUEsS0FBQSxDQUFiLEdBQXNCO1FBQUEsSUFBQSxFQUFNLEtBQUssQ0FBQyxJQUFaO1FBQWtCLElBQUEsRUFBTSxLQUFLLENBQUMsV0FBOUI7UUFBMkMsTUFBQSxFQUFRLEtBQUssQ0FBQyxNQUF6RDtRQUFpRSxJQUFBLEVBQU0sS0FBSyxDQUFDLFlBQTdFO1FBQTJGLFVBQUEsRUFBWSxRQUF2RztRQUFpSCxVQUFBLEVBQVksV0FBVyxDQUFDLFVBQXpJO1FBakIxQjs7RUFUYTs7O0FBNEJqQjs7Ozs7Ozs7Ozs7eUJBVUEsU0FBQSxHQUFXLFNBQUMsSUFBRCxFQUFPLE1BQVAsRUFBZSxJQUFmLEVBQXFCLFVBQXJCLEVBQWlDLEtBQWpDO0FBQ1AsUUFBQTtJQUFBLHlDQUF5QixDQUFFLFFBQVEsQ0FBQyxzQkFBcEM7QUFBQSxhQUFBOztJQUVBLElBQUcsY0FBQSxJQUFVLG1CQUFiO01BQ0ksS0FBQSxHQUFXLGFBQUgsR0FBZSxLQUFmLEdBQTBCLElBQUEsSUFBUTtNQUMxQyxVQUFBLEdBQWE7TUFDYixNQUFBLEdBQVMsSUFBSSxDQUFDO01BQ2QsSUFBQSxHQUFPLElBQUksQ0FBQztNQUNaLElBQUEsR0FBTyxJQUFJLENBQUMsS0FMaEI7S0FBQSxNQUFBO01BT0ksS0FBQSxtQkFBUSxRQUFRLEVBUHBCOztJQVNBLElBQUMsQ0FBQSxZQUFELENBQWMsS0FBZDtJQUNBLElBQUMsQ0FBQSxXQUFZLENBQUEsS0FBQSxDQUFiLEdBQXNCO01BQUEsSUFBQSxFQUFNLElBQU47TUFBWSxNQUFBLEVBQVEsTUFBcEI7TUFBNEIsSUFBQSxFQUFNLElBQWxDO01BQXdDLFVBQUEsRUFBWSxVQUFwRDtNQUFnRSxPQUFBLEVBQVMsSUFBekU7O0lBRXRCLE1BQUEsR0FBWSxjQUFILEdBQWdCLE1BQWhCLEdBQTRCO0lBQ3JDLE1BQUEsR0FBUyxNQUFBLEdBQVMsQ0FBQyxJQUFDLENBQUEsa0JBQUQsR0FBc0IsR0FBdkI7SUFDbEIsSUFBQyxDQUFBLFdBQUQsR0FBZTtJQUdmLElBQUcsY0FBQSxJQUFVLElBQUksQ0FBQyxNQUFMLEdBQWMsQ0FBM0I7TUFDSSxJQUFDLENBQUEsS0FBRCxHQUFTO1FBQUEsSUFBQSxFQUFNLElBQU47O01BQ1QsV0FBQSxHQUFjLElBQUMsQ0FBQSxJQUFELENBQU0sY0FBQSxHQUFlLElBQXJCLEVBQTZCLE1BQTdCLEVBQXFDLElBQXJDLEVBQTJDLFVBQTNDO01BQ2QsV0FBVyxDQUFDLElBQVosR0FBbUI7TUFDbkIsSUFBbUMsQ0FBSSxJQUFDLENBQUEsWUFBWSxDQUFDLFFBQWQsQ0FBdUIsV0FBdkIsQ0FBdkM7UUFBQSxJQUFDLENBQUEsWUFBWSxDQUFDLElBQWQsQ0FBbUIsV0FBbkIsRUFBQTs7YUFDQSxJQUFDLENBQUEsbUJBQW9CLENBQUEsS0FBQSxDQUFyQixHQUE4QixZQUxsQzs7RUFwQk87OztBQTJCWDs7Ozs7Ozs7eUJBT0EsV0FBQSxHQUFhLFNBQUMsVUFBRCxFQUFhLEtBQWI7QUFDVCxRQUFBO0lBQUEsS0FBQSxtQkFBUSxRQUFRO0lBQ2hCLElBQUcseUNBQUEsSUFBaUMsQ0FBSSxJQUFDLENBQUEsbUJBQW9CLENBQUEsS0FBQSxDQUFNLENBQUMsU0FBcEU7TUFDSSxJQUFDLENBQUEsbUJBQW9CLENBQUEsS0FBQSxDQUFNLENBQUMsTUFBNUIsQ0FBbUMsVUFBbkM7MERBQ21CLENBQUUsT0FBckIsR0FBK0IsY0FGbkM7O0VBRlM7OztBQU1iOzs7Ozs7Ozt5QkFPQSxTQUFBLEdBQVcsU0FBQyxXQUFELEVBQWMsS0FBZDtBQUNQLFFBQUE7SUFBQSxLQUFBLG1CQUFRLFFBQVE7O1NBQ1csQ0FBRSxJQUE3QixDQUFrQyxXQUFsQzs7O1VBQzJCLENBQUUsVUFBN0IsR0FBMEM7OztVQUN2QixDQUFFLE9BQXJCLEdBQStCOztXQUMvQixJQUFDLENBQUEsS0FBRCxHQUFTO0VBTEY7OztBQU9YOzs7Ozs7O3lCQU1BLFlBQUEsR0FBYyxTQUFDLFdBQUQ7QUFDVixRQUFBO0FBQUE7QUFBQSxTQUFBLHFDQUFBOztNQUNJLElBQUcsY0FBSDtRQUNJLE1BQU0sQ0FBQyxJQUFQLENBQVksV0FBWjtRQUNBLE1BQU0sQ0FBQyxVQUFQLEdBQW9CLEdBRnhCOztBQURKO1dBSUEsSUFBQyxDQUFBLEtBQUQsR0FBUztFQUxDOzt5QkFRZCxPQUFBLEdBQVMsU0FBQyxPQUFEO0FBQ0wsUUFBQTtJQUFBLElBQUEsR0FBTyxPQUFPLENBQUMsU0FBUyxDQUFDLE1BQWxCLENBQXlCLFNBQUMsQ0FBRDthQUFPLENBQUMsQ0FBQztJQUFULENBQXpCO0FBQ1A7QUFBQTtTQUFBLHFEQUFBOztNQUNJLElBQUcsTUFBQSxJQUFXLElBQUksQ0FBQyxPQUFMLENBQWEsTUFBYixDQUFBLEtBQXdCLENBQUMsQ0FBdkM7UUFDSSxNQUFNLENBQUMsT0FBUCxDQUFBO1FBRUEsSUFBQyxDQUFBLFlBQVksQ0FBQyxNQUFkLENBQXFCLE1BQXJCO1FBQ0EsSUFBQyxDQUFBLG1CQUFvQixDQUFBLEtBQUEsQ0FBckIsR0FBOEI7cUJBQzlCLElBQUMsQ0FBQSxXQUFZLENBQUEsS0FBQSxDQUFiLEdBQXNCLE1BTDFCO09BQUEsTUFBQTs2QkFBQTs7QUFESjs7RUFGSzs7O0FBVVQ7Ozs7Ozs7eUJBTUEsWUFBQSxHQUFjLFNBQUMsS0FBRDtJQUNWLEtBQUEsbUJBQVEsUUFBUTtJQUVoQixJQUFDLENBQUEsU0FBRCxDQUFXLENBQVgsRUFBYyxLQUFkO0lBRUEsSUFBQyxDQUFBLFlBQVksQ0FBQyxNQUFkLENBQXFCLElBQUMsQ0FBQSxtQkFBb0IsQ0FBQSxLQUFBLENBQTFDO0lBQ0EsSUFBQyxDQUFBLG1CQUFvQixDQUFBLEtBQUEsQ0FBckIsR0FBOEI7V0FDOUIsSUFBQyxDQUFBLFdBQVksQ0FBQSxLQUFBLENBQWIsR0FBc0I7RUFQWjs7Ozs7O0FBU2xCLE1BQU0sQ0FBQyxZQUFQLEdBQTBCLElBQUEsWUFBQSxDQUFBOztBQUMxQixFQUFFLENBQUMsWUFBSCxHQUFrQiIsInNvdXJjZXNDb250ZW50IjpbIiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuI1xuIyAgIFNjcmlwdDogQXVkaW9NYW5hZ2VyXG4jXG4jICAgJCRDT1BZUklHSFQkJFxuI1xuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5jbGFzcyBBdWRpb01hbmFnZXJcbiAgICAjIyMqXG4gICAgKiBNYW5hZ2VzIHRoZSBhdWRpbyBwbGF5YmFjayBvZiB0aGUgZ2FtZS4gXG4gICAgKlxuICAgICogQG1vZHVsZSBnc1xuICAgICogQGNsYXNzIEF1ZGlvTWFuYWdlclxuICAgICogQG1lbWJlcm9mIGdzXG4gICAgKiBAY29uc3RydWN0b3JcbiAgICAjIyNcbiAgICBjb25zdHJ1Y3RvcjogLT5cbiAgICAgICAgIyMjKlxuICAgICAgICAqIFN0b3JlcyBhbGwgYXVkaW8gYnVmZmVycy5cbiAgICAgICAgKiBAcHJvcGVydHkgYnVmZmVyc1xuICAgICAgICAqIEB0eXBlIGdzLkF1ZGlvQnVmZmVyW11cbiAgICAgICAgKiBAcHJvdGVjdGVkXG4gICAgICAgICMjIyAgXG4gICAgICAgIEBhdWRpb0J1ZmZlcnMgPSBbXVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFN0b3JlcyBhbGwgYXVkaW8gYnVmZmVycyBieSBsYXllci5cbiAgICAgICAgKiBAcHJvcGVydHkgYnVmZmVyc1xuICAgICAgICAqIEB0eXBlIGdzLkF1ZGlvQnVmZmVyW11cbiAgICAgICAgKiBAcHJvdGVjdGVkXG4gICAgICAgICMjIyAgXG4gICAgICAgIEBhdWRpb0J1ZmZlcnNCeUxheWVyID0gW11cbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBTdG9yZXMgYWxsIGF1ZGlvIGJ1ZmZlciByZWZlcmVuY2VzIGZvciBzb3VuZHMuXG4gICAgICAgICogQHByb3BlcnR5IHNvdW5kUmVmZXJlbmNlc1xuICAgICAgICAqIEB0eXBlIGdzLkF1ZGlvQnVmZmVyUmVmZXJlbmNlW11cbiAgICAgICAgKiBAcHJvdGVjdGVkXG4gICAgICAgICMjIyAgXG4gICAgICAgIEBzb3VuZFJlZmVyZW5jZXMgPSB7fVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEN1cnJlbnQgTXVzaWMgKExheWVyIDApXG4gICAgICAgICogQHByb3BlcnR5IG11c2ljXG4gICAgICAgICogQHR5cGUgT2JqZWN0XG4gICAgICAgICogQHByb3RlY3RlZFxuICAgICAgICAjIyMgXG4gICAgICAgIEBtdXNpYyA9IG51bGxcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBDdXJyZW50IG11c2ljIHZvbHVtZS5cbiAgICAgICAgKiBAcHJvcGVydHkgbXVzaWNWb2x1bWVcbiAgICAgICAgKiBAdHlwZSBudW1iZXJcbiAgICAgICAgKiBAcHJvdGVjdGVkXG4gICAgICAgICMjIyBcbiAgICAgICAgQG11c2ljVm9sdW1lID0gMTAwXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogQ3VycmVudCBzb3VuZCB2b2x1bWUuXG4gICAgICAgICogQHByb3BlcnR5IHNvdW5kVm9sdW1lXG4gICAgICAgICogQHR5cGUgbnVtYmVyXG4gICAgICAgICogQHByb3RlY3RlZFxuICAgICAgICAjIyMgXG4gICAgICAgIEBzb3VuZFZvbHVtZSA9IDEwMFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEN1cnJlbnQgdm9pY2Ugdm9sdW1lLlxuICAgICAgICAqIEBwcm9wZXJ0eSB2b2ljZVZvbHVtZVxuICAgICAgICAqIEB0eXBlIG51bWJlclxuICAgICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgICAgIyMjIFxuICAgICAgICBAdm9pY2VWb2x1bWUgPSAxMDBcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBHZW5lcmFsIG11c2ljIHZvbHVtZVxuICAgICAgICAqIEBwcm9wZXJ0eSBnZW5lcmFsTXVzaWNWb2x1bWVcbiAgICAgICAgKiBAdHlwZSBudW1iZXJcbiAgICAgICAgKiBAcHJvdGVjdGVkXG4gICAgICAgICMjIyBcbiAgICAgICAgQGdlbmVyYWxNdXNpY1ZvbHVtZSA9IDEwMFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEdlbmVyYWwgc291bmQgdm9sdW1lXG4gICAgICAgICogQHByb3BlcnR5IGdlbmVyYWxTb3VuZFZvbHVtZVxuICAgICAgICAqIEB0eXBlIG51bWJlclxuICAgICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgICAgIyMjIFxuICAgICAgICBAZ2VuZXJhbFNvdW5kVm9sdW1lID0gMTAwXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogR2VuZXJhbCB2b2ljZSB2b2x1bWVcbiAgICAgICAgKiBAcHJvcGVydHkgZ2VuZXJhbFZvaWNlVm9sdW1lXG4gICAgICAgICogQHR5cGUgbnVtYmVyXG4gICAgICAgICogQHByb3RlY3RlZFxuICAgICAgICAjIyMgXG4gICAgICAgIEBnZW5lcmFsVm9pY2VWb2x1bWUgPSAxMDBcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBTdG9yZXMgYXVkaW8gbGF5ZXIgaW5mby1kYXRhIGZvciBlYWNoIGxheWVyLlxuICAgICAgICAqIEBwcm9wZXJ0eSBhdWRpb0xheWVyc1xuICAgICAgICAqIEB0eXBlIGdzLkF1ZGlvTGF5ZXJJbmZvW11cbiAgICAgICAgKiBAcHJvdGVjdGVkXG4gICAgICAgICMjIyBcbiAgICAgICAgQGF1ZGlvTGF5ZXJzID0gW11cbiAgICAgIFxuICAgICMjIypcbiAgICAqIFJlc3RvcmVzIGF1ZGlvLXBsYXliYWNrIGZyb20gYSBzcGVjaWZpZWQgYXJyYXkgb2YgYXVkaW8gbGF5ZXJzLlxuICAgICpcbiAgICAqIEBtZXRob2QgcmVzdG9yZVxuICAgICogQHBhcmFtIHtncy5BdWRpb0xheWVySW5mb1tdfSBsYXllcnMgLSBBbiBhcnJheSBvZiBhdWRpbyBsYXllciBpbmZvIG9iamVjdHMuXG4gICAgIyMjICBcbiAgICByZXN0b3JlOiAobGF5ZXJzKSAtPlxuICAgICAgICBAYXVkaW9MYXllcnMgPSBsYXllcnNcbiAgICAgICAgXG4gICAgICAgIGZvciBsYXllciwgaSBpbiBsYXllcnNcbiAgICAgICAgICAgIGlmIGxheWVyIGFuZCBsYXllci5wbGF5aW5nXG4gICAgICAgICAgICAgICAgaWYgbGF5ZXIuY3VzdG9tRGF0YVxuICAgICAgICAgICAgICAgICAgICBAcGxheU11c2ljUmFuZG9tKGxheWVyLCBsYXllci5jdXN0b21EYXRhLmZhZGVUaW1lLCBpLCBsYXllci5jdXN0b21EYXRhLnBsYXlUaW1lLCBsYXllci5jdXN0b21EYXRhLnBsYXlSYW5nZSlcbiAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgIEBwbGF5TXVzaWMobGF5ZXIsIGxheWVyLmZhZGVJblRpbWUsIGkpXG4gICAgIFxuICAgICMjIypcbiAgICAqIExvYWRzIHRoZSBzcGVjaWZpZWQgbXVzaWMuXG4gICAgKlxuICAgICogQG1ldGhvZCBsb2FkTXVzaWNcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIG11c2ljIHRvIGxvYWQuXG4gICAgIyMjICAgIFxuICAgIGxvYWRNdXNpYzogKG5hbWUpIC0+IFxuICAgICAgICBuYW1lID0gaWYgbmFtZT8gdGhlbiAobmFtZS5uYW1lIHx8IG5hbWUpIGVsc2UgbmFtZVxuICAgICAgICBpZiBuYW1lIGFuZCBuYW1lLmxlbmd0aCA+IDBcbiAgICAgICAgICAgIFJlc291cmNlTWFuYWdlci5nZXRBdWRpb1N0cmVhbShcIkF1ZGlvL011c2ljLyN7bmFtZX1cIilcbiAgICAgXG4gICAgIyMjKlxuICAgICogTG9hZHMgdGhlIHNwZWNpZmllZCBzb3VuZC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGxvYWRTb3VuZFxuICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgc291bmQgdG8gbG9hZC5cbiAgICAjIyMgICAgICAgICAgIFxuICAgIGxvYWRTb3VuZDogKG5hbWUpIC0+IFxuICAgICAgICBuYW1lID0gaWYgbmFtZT8gdGhlbiBuYW1lLm5hbWUgfHwgbmFtZSBlbHNlIG5hbWVcbiAgICAgICAgaWYgbmFtZSBhbmQgbmFtZS5sZW5ndGggPiAwXG4gICAgICAgICAgICBSZXNvdXJjZU1hbmFnZXIuZ2V0QXVkaW9CdWZmZXIoXCJBdWRpby9Tb3VuZHMvI3tuYW1lfVwiKVxuICAgIFxuICAgICMjIypcbiAgICAqIFVwZGF0ZXMgYSByYW5kb21seSBwbGF5ZWQgYXVkaW8gYnVmZmVyLlxuICAgICpcbiAgICAqIEBtZXRob2QgdXBkYXRlUmFuZG9tQXVkaW9cbiAgICAqIEBwYXJhbSB7Z3MuQXVkaW9CdWZmZXJ9IGJ1ZmZlciAtIFRoZSBhdWRpbyBidWZmZXIgdG8gdXBkYXRlLlxuICAgICogQHByb3RlY3RlZFxuICAgICMjIyAgICBcbiAgICAjIEZJWE1FOiBSZWZhY3RvcmluZyBuZWNlc3NhcnkuICAgICAgXG4gICAgdXBkYXRlUmFuZG9tQXVkaW86IChidWZmZXIpIC0+XG4gICAgICAgIGlmIGJ1ZmZlci5jdXN0b21EYXRhLnN0YXJ0VGltZXIgPiAwXG4gICAgICAgICAgICBidWZmZXIuY3VzdG9tRGF0YS5zdGFydFRpbWVyLS1cbiAgICAgICAgICAgIGlmIGJ1ZmZlci5jdXN0b21EYXRhLnN0YXJ0VGltZXIgPD0gMFxuICAgICAgICAgICAgICAgIGJ1ZmZlci5mYWRlSW5Wb2x1bWUgPSAxLjAgLyAoYnVmZmVyLmN1c3RvbURhdGEuZmFkZVRpbWV8fDEpXG4gICAgICAgICAgICAgICAgYnVmZmVyLmZhZGVJblRpbWUgPSBidWZmZXIuY3VzdG9tRGF0YS5mYWRlVGltZXx8MVxuICAgICAgICAgICAgICAgIGJ1ZmZlci5mYWRlT3V0VGltZSA9IGJ1ZmZlci5jdXN0b21EYXRhLmZhZGVUaW1lfHwxXG4gICAgICAgICAgICAgICAgYnVmZmVyLnBsYXlUaW1lID0gYnVmZmVyLmN1c3RvbURhdGEucGxheVRpbWUubWluICsgTWF0aC5yYW5kb20oKSAqIChidWZmZXIuY3VzdG9tRGF0YS5wbGF5VGltZS5tYXggLSBidWZmZXIuY3VzdG9tRGF0YS5wbGF5VGltZS5taW4pXG4gICAgICAgICAgICAgICAgY3VycmVudFRpbWUgPSBidWZmZXIuY3VycmVudFRpbWUgIyAtIGJ1ZmZlci5zdGFydFRpbWVcbiAgICAgICAgICAgICAgICB0aW1lTGVmdCA9IGJ1ZmZlci5kdXJhdGlvbiAtIGN1cnJlbnRUaW1lXG4gICAgICAgICAgICAgICAgYnVmZmVyLnBsYXlUaW1lID0gTWF0aC5taW4odGltZUxlZnQgKiAxMDAwIC8gMTYuNiwgYnVmZmVyLnBsYXlUaW1lKVxuICAgIFxuICAgICAgICAgICAgICAgIGJ1ZmZlci5jdXN0b21EYXRhLnN0YXJ0VGltZXIgPSBidWZmZXIucGxheVRpbWUgKyBidWZmZXIuY3VzdG9tRGF0YS5wbGF5UmFuZ2Uuc3RhcnQgKyBNYXRoLnJhbmRvbSgpICogKGJ1ZmZlci5jdXN0b21EYXRhLnBsYXlSYW5nZS5lbmQgLSBidWZmZXIuY3VzdG9tRGF0YS5wbGF5UmFuZ2Uuc3RhcnQpXG4gICAgXG4gICAgIyMjKlxuICAgICogVXBkYXRlcyBhbGwgYXVkaW8tYnVmZmVycyBkZXBlbmRpbmcgb24gdGhlIHBsYXktdHlwZS5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHVwZGF0ZUF1ZGlvQnVmZmVyc1xuICAgICogQHByb3RlY3RlZFxuICAgICMjIyAgIFxuICAgIHVwZGF0ZUF1ZGlvQnVmZmVyczogLT5cbiAgICAgICAgZm9yIGJ1ZmZlciBpbiBAYXVkaW9CdWZmZXJzXG4gICAgICAgICAgICBpZiBidWZmZXI/XG4gICAgICAgICAgICAgICAgaWYgYnVmZmVyLmN1c3RvbURhdGEucGxheVR5cGUgPT0gMVxuICAgICAgICAgICAgICAgICAgICBAdXBkYXRlUmFuZG9tQXVkaW8oYnVmZmVyKVxuICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICBpZiBHYW1lTWFuYWdlci5zZXR0aW5ncy5iZ21Wb2x1bWUgIT0gQGdlbmVyYWxNdXNpY1ZvbHVtZVxuICAgICAgICAgICAgICAgICAgICBidWZmZXIudm9sdW1lID0gKEBtdXNpY1ZvbHVtZSAqIEdhbWVNYW5hZ2VyLnNldHRpbmdzLmJnbVZvbHVtZSAvIDEwMCkgLyAxMDBcbiAgICAgICAgICAgICAgICAgICAgQGdlbmVyYWxNdXNpY1ZvbHVtZSA9IEdhbWVNYW5hZ2VyLnNldHRpbmdzLmJnbVZvbHVtZVxuICAgICAgICAgICAgICAgIGJ1ZmZlci51cGRhdGUoKVxuICAgIFxuICAgIFxuICAgICMjIypcbiAgICAqIFVwZGF0ZXMgYWxsIGF1ZGlvLWJ1ZmZlcnMgZGVwZW5kaW5nIG9uIHRoZSBwbGF5LXR5cGUuXG4gICAgKlxuICAgICogQG1ldGhvZCB1cGRhdGVBdWRpb0J1ZmZlcnNcbiAgICAqIEBwcm90ZWN0ZWRcbiAgICAjIyMgICAgICAgICAgICAgXG4gICAgdXBkYXRlR2VuZXJhbFZvbHVtZTogLT5cbiAgICAgICAgaWYgR2FtZU1hbmFnZXIuc2V0dGluZ3Muc2VWb2x1bWUgIT0gQGdlbmVyYWxTb3VuZFZvbHVtZSBvciBHYW1lTWFuYWdlci5zZXR0aW5ncy52b2ljZVZvbHVtZSAhPSBAZ2VuZXJhbFZvaWNlVm9sdW1lXG4gICAgICAgICAgICBAZ2VuZXJhbFNvdW5kVm9sdW1lID0gR2FtZU1hbmFnZXIuc2V0dGluZ3Muc2VWb2x1bWVcbiAgICAgICAgICAgIEBnZW5lcmFsVm9pY2VWb2x1bWUgPSBHYW1lTWFuYWdlci5zZXR0aW5ncy52b2ljZVZvbHVtZVxuICAgICAgICAgICAgZm9yIGsgb2YgQHNvdW5kUmVmZXJlbmNlc1xuICAgICAgICAgICAgICAgIGZvciByZWZlcmVuY2UgaW4gQHNvdW5kUmVmZXJlbmNlc1trXVxuICAgICAgICAgICAgICAgICAgICBpZiByZWZlcmVuY2Uudm9pY2VcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZmVyZW5jZS52b2x1bWUgPSAoQHZvaWNlVm9sdW1lICogR2FtZU1hbmFnZXIuc2V0dGluZ3Mudm9pY2VWb2x1bWUgLyAxMDApIC8gMTAwXG4gICAgICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZmVyZW5jZS52b2x1bWUgPSAoQHNvdW5kVm9sdW1lICogR2FtZU1hbmFnZXIuc2V0dGluZ3Muc2VWb2x1bWUgLyAxMDApIC8gMTAwXG4gICAgIyMjKlxuICAgICogVXBkYXRlcyB0aGUgYXVkaW8tcGxheWJhY2suXG4gICAgKlxuICAgICogQG1ldGhvZCB1cGRhdGVcbiAgICAjIyMgICAgICAgICAgICAgICAgXG4gICAgdXBkYXRlOiAtPlxuICAgICAgICBAdXBkYXRlQXVkaW9CdWZmZXJzKClcbiAgICAgICAgQHVwZGF0ZUdlbmVyYWxWb2x1bWUoKVxuICAgICBcbiAgICAjIyMqXG4gICAgKiBDaGFuZ2VzIHRoZSBjdXJyZW50IG11c2ljIHRvIHRoZSBzcGVjaWZpZWQgb25lLlxuICAgICpcbiAgICAqIEBtZXRob2QgY2hhbmdlTXVzaWNcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBtdXNpYyAtIFRoZSBtdXNpYyB0byBwbGF5LiBJZiA8Yj5udWxsPC9iPiB0aGUgY3VycmVudCBtdXNpYyB3aWxsIHN0b3AgcGxheWluZy5cbiAgICAjIyMgICAgICAgICAgIFxuICAgIGNoYW5nZU11c2ljOiAobXVzaWMpIC0+XG4gICAgICAgIGlmIG11c2ljPyBhbmQgbXVzaWMubmFtZT9cbiAgICAgICAgICAgIGlmIEBtdXNpYz8gYW5kIEBtdXNpYy5uYW1lICE9IG11c2ljLm5hbWVcbiAgICAgICAgICAgICAgICBAcGxheU11c2ljKG11c2ljKVxuICAgICAgICAgICAgZWxzZSBpZiBub3QgQG11c2ljP1xuICAgICAgICAgICAgICAgIEBwbGF5TXVzaWMobXVzaWMpXG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIEBzdG9wTXVzaWMoKVxuICAgICBcbiAgICAjIEZJWE1FOiBJcyB0aGlzIHN0aWxsIHVzZWQ/XG4gICAgIyMjKlxuICAgICogUHJlcGFyZXMuIFxuICAgICpcbiAgICAqIEBtZXRob2QgcHJlcGFyZVxuICAgICogQHBhcmFtIHtPYmplY3R9IG11c2ljIC0gVGhlIG11c2ljIHRvIHBsYXkuIElmIDxiPm51bGw8L2I+IHRoZSBjdXJyZW50IG11c2ljIHdpbGwgc3RvcCBwbGF5aW5nLlxuICAgICMjIyAgICAgICAgICAgIFxuICAgIHByZXBhcmU6IChwYXRoLCB2b2x1bWUsIHJhdGUpIC0+IFxuICAgICAgICBidWZmZXIgPSBSZXNvdXJjZU1hbmFnZXIuZ2V0QXVkaW9CdWZmZXIocGF0aClcbiAgICAgICAgXG4gICAgICAgIGlmIGJ1ZmZlci5kZWNvZGVkXG4gICAgICAgICAgICBidWZmZXIudm9sdW1lID0gaWYgdm9sdW1lPyB0aGVuIHZvbHVtZSAvIDEwMCBlbHNlIDEuMFxuICAgICAgICAgICAgYnVmZmVyLnBsYXliYWNrUmF0ZSA9IGlmIHJhdGU/IHRoZW4gcmF0ZSAvIDEwMCBlbHNlIDEuMFxuICAgICAgICBlbHNlXG4gICAgICAgICAgIGJ1ZmZlci5vbkZpbmlzaERlY29kZSA9IChzb3VyY2UpID0+IFxuICAgICAgICAgICAgICAgc291cmNlLnZvbHVtZSA9IGlmIHZvbHVtZT8gdGhlbiB2b2x1bWUgLyAxMDAgZWxzZSAxLjBcbiAgICAgICAgICAgICAgIHNvdXJjZS5wbGF5YmFja1JhdGUgPSBpZiByYXRlPyB0aGVuIHJhdGUgLyAxMDAgZWxzZSAxLjBcbiAgICAgICAgICAgYnVmZmVyLmRlY29kZSgpXG4gICAgICAgICAgIFxuICAgICAgICByZXR1cm4gYnVmZmVyXG4gICAgICAgIFxuICAgICMjIypcbiAgICAqIFBsYXlzIGFuIGF1ZGlvIHJlc291cmNlLlxuICAgICpcbiAgICAqIEBtZXRob2QgcGxheVxuICAgICogQHBhcmFtIHtTdHJpbmd9IHBhdGggLSBUaGUgcGF0aCB0byB0aGUgYXVkaW8gcmVzb3VyY2UuXG4gICAgKiBAcGFyYW0ge251bWJlcn0gdm9sdW1lIC0gVGhlIHZvbHVtZS5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSByYXRlIC0gVGhlIHBsYXliYWNrIHJhdGUuXG4gICAgKiBAcGFyYW0ge251bWJlcn0gZmFkZUluVGltZSAtIFRoZSBmYWRlLWluIHRpbWUgaW4gZnJhbWVzLlxuICAgICMjIyAgICAgXG4gICAgcGxheTogKHBhdGgsIHZvbHVtZSwgcmF0ZSwgZmFkZUluVGltZSkgLT5cbiAgICAgICAgYnVmZmVyID0gUmVzb3VyY2VNYW5hZ2VyLmdldEF1ZGlvU3RyZWFtKHBhdGgpXG4gICAgXG4gICAgICAgIGlmIGJ1ZmZlci5kZWNvZGVkXG4gICAgICAgICAgICBidWZmZXIudm9sdW1lID0gaWYgdm9sdW1lPyB0aGVuIHZvbHVtZSAvIDEwMCBlbHNlIDEuMFxuICAgICAgICAgICAgYnVmZmVyLnBsYXliYWNrUmF0ZSA9IGlmIHJhdGU/IHRoZW4gcmF0ZSAvIDEwMCBlbHNlIDEuMFxuICAgICAgICAgICAgYnVmZmVyLnBsYXkoZmFkZUluVGltZSkgaWYgR2FtZU1hbmFnZXIuc2V0dGluZ3MuYmdtRW5hYmxlZFxuICAgICAgICBlbHNlXG4gICAgICAgICAgIGJ1ZmZlci5vbkZpbmlzaERlY29kZSA9IChzb3VyY2UpID0+IFxuICAgICAgICAgICAgICAgc291cmNlLnZvbHVtZSA9IGlmIHZvbHVtZT8gdGhlbiB2b2x1bWUgLyAxMDAgZWxzZSAxLjBcbiAgICAgICAgICAgICAgIHNvdXJjZS5wbGF5YmFja1JhdGUgPSBpZiByYXRlPyB0aGVuIHJhdGUgLyAxMDAgZWxzZSAxLjBcbiAgICAgICAgICAgICAgIHNvdXJjZS5wbGF5KGZhZGVJblRpbWUpIGlmIEdhbWVNYW5hZ2VyLnNldHRpbmdzLmJnbUVuYWJsZWRcbiAgICAgICAgICAgYnVmZmVyLmRlY29kZSgpXG4gICAgICAgICAgIFxuICAgICAgICByZXR1cm4gYnVmZmVyXG4gICAgIFxuICAgICMjIypcbiAgICAqIFN0b3BzIGFsbCBzb3VuZHMuXG4gICAgKlxuICAgICogQG1ldGhvZCBzdG9wQWxsU291bmRzXG4gICAgIyMjICAgIFxuICAgIHN0b3BBbGxTb3VuZHM6IC0+XG4gICAgICAgIGZvciBrIG9mIEBzb3VuZFJlZmVyZW5jZXNcbiAgICAgICAgICAgIGZvciByZWZlcmVuY2UgaW4gQHNvdW5kUmVmZXJlbmNlc1trXVxuICAgICAgICAgICAgICAgIHJlZmVyZW5jZT8uc3RvcCgpXG4gICAgXG4gICAgIyMjKlxuICAgICogU3RvcHMgYSBzb3VuZCBhbmQgYWxsIHJlZmVyZW5jZXMgb2YgaXQuXG4gICAgKlxuICAgICogQG1ldGhvZCBzdG9wU291bmRcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHNvdW5kIHRvIHN0b3AuXG4gICAgIyMjICAgICAgICAgICAgIFxuICAgIHN0b3BTb3VuZDogKG5hbWUpIC0+XG4gICAgICAgIGlmIEBzb3VuZFJlZmVyZW5jZXNbbmFtZV0/XG4gICAgICAgICAgICBmb3IgcmVmZXJlbmNlIGluIEBzb3VuZFJlZmVyZW5jZXNbbmFtZV1cbiAgICAgICAgICAgICAgICByZWZlcmVuY2Uuc3RvcCgpXG4gICAgXG4gICAgXG4gICAgIyMjKlxuICAgICogU3RvcHMgYSB2b2ljZS5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHN0b3BWb2ljZVxuICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgdm9pY2UgdG8gc3RvcC5cbiAgICAjIyMgICAgICAgICAgICAgXG4gICAgc3RvcFZvaWNlOiAobmFtZSkgLT5cbiAgICAgICAgQHN0b3BTb3VuZChuYW1lKVxuICAgIFxuICAgICMjIypcbiAgICAqIFN0b3BzIGFsbCB2b2ljZXMuXG4gICAgKlxuICAgICogQG1ldGhvZCBzdG9wQWxsVm9pY2VzXG4gICAgIyMjICAgICBcbiAgICBzdG9wQWxsVm9pY2VzOiAtPlxuICAgICAgICBmb3IgayBvZiBAc291bmRSZWZlcmVuY2VzXG4gICAgICAgICAgICBmb3IgcmVmZXJlbmNlIGluIEBzb3VuZFJlZmVyZW5jZXNba11cbiAgICAgICAgICAgICAgICByZWZlcmVuY2Uuc3RvcCgpIGlmIHJlZmVyZW5jZS52b2ljZVxuICAgIFxuICAgICMjIypcbiAgICAqIFBsYXlzIGEgdm9pY2UuXG4gICAgKlxuICAgICogQG1ldGhvZCBwbGF5Vm9pY2VcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHZvaWNlIHRvIHBsYXkuXG4gICAgKiBAcGFyYW0ge251bWJlcn0gdm9sdW1lIC0gVGhlIHZvaWNlIHZvbHVtZS5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSByYXRlIC0gVGhlIHZvaWNlIHBsYXliYWNrIHJhdGUuXG4gICAgIyMjICAgICBcbiAgICBwbGF5Vm9pY2U6IChuYW1lLCB2b2x1bWUsIHJhdGUpIC0+XG4gICAgICAgIHZvaWNlID0gbnVsbFxuICAgICAgICBpZiBHYW1lTWFuYWdlci5zZXR0aW5ncy52b2ljZUVuYWJsZWQgYW5kIG5vdCAkUEFSQU1TLnByZXZpZXc/LnNldHRpbmdzLnZvaWNlRGlzYWJsZWRcbiAgICAgICAgICAgIHZvaWNlID0gQHBsYXlTb3VuZChuYW1lPy5uYW1lLCB2b2x1bWUgfHwgR2FtZU1hbmFnZXIuZGVmYXVsdHMuYXVkaW8udm9pY2VWb2x1bWUsIHJhdGUgfHwgR2FtZU1hbmFnZXIuZGVmYXVsdHMuYXVkaW8udm9pY2VQbGF5YmFja1JhdGUsIG5vLCB5ZXMpXG4gICAgICAgIFxuICAgICAgICByZXR1cm4gdm9pY2UgICAgXG4gICAgXG4gICAgIyMjKlxuICAgICogUGxheXMgYSBzb3VuZC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHBsYXlTb3VuZFxuICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgc291bmQgdG8gcGxheS5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSB2b2x1bWUgLSBUaGUgc291bmQncyB2b2x1bWUuXG4gICAgKiBAcGFyYW0ge251bWJlcn0gcmF0ZSAtIFRoZSBzb3VuZCdzIHBsYXliYWNrIHJhdGUuXG4gICAgKiBAcGFyYW0ge2Jvb2xlYW59IG11c2ljRWZmZWN0IC0gSW5kaWNhdGVzIGlmIHRoZSBzb3VuZCBzaG91bGQgYmUgcGxheWVkIGFzIGEgbXVzaWMgZWZmZWN0LiBJbiB0aGF0IGNhc2UsIHRoZSBjdXJyZW50IG11c2ljXG4gICAgKiBhdCBhdWRpby1sYXllciB3aWxsIGJlIHBhdXNlZCB1bnRpbCB0aGUgc291bmQgZmluaXNoZXMgcGxheWluZy5cbiAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gdm9pY2UgLSBJbmRpY2F0ZXMgaWYgdGhlIHNvdW5kIHNob3VsZCBiZSBoYW5kbGVkIGFzIGEgdm9pY2UuXG4gICAgIyMjICAgICAgICAgIFxuICAgIHBsYXlTb3VuZDogKG5hbWUsIHZvbHVtZSwgcmF0ZSwgbXVzaWNFZmZlY3QsIHZvaWNlKSAtPlxuICAgICAgICBpZiAkUEFSQU1TLnByZXZpZXc/LnNldHRpbmdzLnNvdW5kRGlzYWJsZWQgdGhlbiByZXR1cm5cbiAgICAgICAgaWYgbm90IG5hbWU/IG9yICghdm9pY2UgYW5kICFHYW1lTWFuYWdlci5zZXR0aW5ncy5zb3VuZEVuYWJsZWQpIHRoZW4gcmV0dXJuXG4gICAgICAgIGlmIG5hbWUubmFtZT9cbiAgICAgICAgICAgIHZvbHVtZSA9IG5hbWUudm9sdW1lXG4gICAgICAgICAgICByYXRlID0gbmFtZS5wbGF5YmFja1JhdGVcbiAgICAgICAgICAgIG5hbWUgPSBuYW1lLm5hbWVcbiAgICAgICAgIFxuICAgICAgICBpZiBuYW1lLmxlbmd0aCA9PSAwIHRoZW4gcmV0dXJuXG4gICAgICAgIFxuICAgICAgICBpZiBtdXNpY0VmZmVjdFxuICAgICAgICAgICAgQHN0b3BNdXNpYygpXG4gICAgICAgIFxuICAgICAgICBpZiBub3QgQHNvdW5kUmVmZXJlbmNlc1tuYW1lXT9cbiAgICAgICAgICAgIEBzb3VuZFJlZmVyZW5jZXNbbmFtZV0gPSBbXVxuICAgICAgICBcbiAgICAgICAgdm9sdW1lID0gdm9sdW1lID8gMTAwXG4gICAgICAgIHZvbHVtZSAqPSBpZiB2b2ljZSB0aGVuIEBnZW5lcmFsVm9pY2VWb2x1bWUgLyAxMDAgZWxzZSBAZ2VuZXJhbFNvdW5kVm9sdW1lIC8gMTAwXG4gICAgICAgIFxuICAgICAgICByZWZlcmVuY2UgPSBudWxsXG4gICAgICAgIGZvciByIGluIEBzb3VuZFJlZmVyZW5jZXNbbmFtZV1cbiAgICAgICAgICAgIGlmIG5vdCByLmlzUGxheWluZ1xuICAgICAgICAgICAgICAgIHJlZmVyZW5jZSA9IHJcbiAgICAgICAgICAgICAgICBpZiBtdXNpY0VmZmVjdCB0aGVuIHJlZmVyZW5jZS5vbkVuZCA9ID0+IEByZXN1bWVNdXNpYyg0MClcbiAgICAgICAgICAgICAgICByZWZlcmVuY2Uudm9pY2UgPSB2b2ljZVxuICAgICAgICAgICAgICAgIHJlZmVyZW5jZS52b2x1bWUgPSB2b2x1bWUgLyAxMDBcbiAgICAgICAgICAgICAgICByZWZlcmVuY2UucGxheWJhY2tSYXRlID0gcmF0ZSAvIDEwMFxuICAgICAgICAgICAgICAgIEB2b2ljZSA9IHJlZmVyZW5jZSBpZiB2b2ljZVxuICAgICAgICAgICAgICAgIHJlZmVyZW5jZS5wbGF5KClcbiAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgXG4gICAgICAgIGlmIG5vdCByZWZlcmVuY2U/XG4gICAgICAgICAgICBidWZmZXIgPSBSZXNvdXJjZU1hbmFnZXIuZ2V0QXVkaW9CdWZmZXIoXCJBdWRpby9Tb3VuZHMvI3tuYW1lfVwiKVxuICAgICAgICAgICAgaWYgYnVmZmVyIGFuZCBidWZmZXIubG9hZGVkXG4gICAgICAgICAgICAgICAgaWYgYnVmZmVyLmRlY29kZWRcbiAgICAgICAgICAgICAgICAgICAgcmVmZXJlbmNlID0gbmV3IEdTLkF1ZGlvQnVmZmVyUmVmZXJlbmNlKGJ1ZmZlciwgdm9pY2UpXG4gICAgICAgICAgICAgICAgICAgIGlmIG11c2ljRWZmZWN0IHRoZW4gcmVmZXJlbmNlLm9uRW5kID0gPT4gQHJlc3VtZU11c2ljKDQwKVxuICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2Uudm9sdW1lID0gdm9sdW1lIC8gMTAwXG4gICAgICAgICAgICAgICAgICAgIHJlZmVyZW5jZS5wbGF5YmFja1JhdGUgPSByYXRlIC8gMTAwXG4gICAgICAgICAgICAgICAgICAgIHJlZmVyZW5jZS52b2ljZSA9IHZvaWNlXG4gICAgICAgICAgICAgICAgICAgIHJlZmVyZW5jZS5wbGF5KClcbiAgICAgICAgICAgICAgICAgICAgQHZvaWNlID0gcmVmZXJlbmNlIGlmIHZvaWNlXG4gICAgICAgICAgICAgICAgICAgIEBzb3VuZFJlZmVyZW5jZXNbbmFtZV0ucHVzaChyZWZlcmVuY2UpXG4gICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICBidWZmZXIubmFtZSA9IG5hbWVcbiAgICAgICAgICAgICAgICAgICAgYnVmZmVyLm9uRGVjb2RlRmluaXNoID0gKHNvdXJjZSkgPT5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZmVyZW5jZSA9IG5ldyBHUy5BdWRpb0J1ZmZlclJlZmVyZW5jZShzb3VyY2UsIHZvaWNlKVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgbXVzaWNFZmZlY3QgdGhlbiByZWZlcmVuY2Uub25FbmQgPSA9PiBAcmVzdW1lTXVzaWMoNDApXG4gICAgICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2Uudm9pY2UgPSB2b2ljZVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVmZXJlbmNlLnZvbHVtZSA9IHZvbHVtZSAvIDEwMFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVmZXJlbmNlLnBsYXliYWNrUmF0ZSA9IHJhdGUgLyAxMDBcbiAgICAgICAgICAgICAgICAgICAgICAgIEB2b2ljZSA9IHJlZmVyZW5jZSBpZiB2b2ljZVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVmZXJlbmNlLnBsYXkoKVxuICAgICAgICAgICAgICAgICAgICAgICAgQHNvdW5kUmVmZXJlbmNlc1tzb3VyY2UubmFtZV0ucHVzaChyZWZlcmVuY2UpXG4gICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5kZWNvZGUoKVxuICAgICAgICBcbiAgICAgICAgcmV0dXJuIHJlZmVyZW5jZSAgICAgICAgICAgIFxuICAgIFxuICAgICMjIypcbiAgICAqIFBsYXlzIGEgbXVzaWMgYXMgYSByYW5kb20gbXVzaWMuIEEgcmFuZG9tIG11c2ljIHdpbGwgZmFkZS1pbiBhbmQgZmFkZS1vdXRcbiAgICAqIGF0IHJhbmRvbSB0aW1lcy4gVGhhdCBjYW4gYmUgY29tYmluZWQgd2l0aCBvdGhlciBhdWRpby1sYXllcnMgdG8gY3JlYXRlIGFcbiAgICAqIG11Y2ggYmV0dGVyIGxvb3Bpbmcgb2YgYW4gYXVkaW8gdHJhY2suXG4gICAgKlxuICAgICogQG1ldGhvZCBwbGF5TXVzaWNSYW5kb21cbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBtdXNpYyAtIFRoZSBtdXNpYyB0byBwbGF5LlxuICAgICogQHBhcmFtIHtudW1iZXJ9IGZhZGVUaW1lIC0gVGhlIHRpbWUgZm9yIGEgc2luZ2xlIGZhZGUtaW4vb3V0IGluIGZyYW1lcy5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSBsYXllciAtIFRoZSBhdWRpbyBsYXllciB0byB1c2UuXG4gICAgKiBAcGFyYW0ge2dzLlJhbmdlfSBwbGF5VGltZSAtIFBsYXktVGltZSByYW5nZSBsaWtlIDEwcyB0byAzMHMuXG4gICAgKiBAcGFyYW0ge2dzLlJhbmdlfSBwbGF5UmFuZ2UgLSBQbGF5LVJhbmdlLlxuICAgICMjIyAgICAgXG4gICAgcGxheU11c2ljUmFuZG9tOiAobXVzaWMsIGZhZGVUaW1lLCBsYXllciwgcGxheVRpbWUsIHBsYXlSYW5nZSkgLT5cbiAgICAgICAgcmV0dXJuIGlmICRQQVJBTVMucHJldmlldz8uc2V0dGluZ3MubXVzaWNEaXNhYmxlZFxuICAgICAgICBsYXllciA9IGxheWVyID8gMFxuXG4gICAgICAgIHZvbHVtZSA9IGlmIG11c2ljLnZvbHVtZT8gdGhlbiBtdXNpYy52b2x1bWUgZWxzZSAxMDBcbiAgICAgICAgdm9sdW1lID0gdm9sdW1lICogKEBnZW5lcmFsTXVzaWNWb2x1bWUgLyAxMDApXG4gICAgICAgIEBtdXNpY1ZvbHVtZSA9IHZvbHVtZVxuICAgICAgICBAZGlzcG9zZU11c2ljKGxheWVyKVxuICAgICAgICBcbiAgICAgICAgaWYgbXVzaWMubmFtZT8gYW5kIG11c2ljLm5hbWUubGVuZ3RoID4gMFxuICAgICAgICAgICAgbXVzaWNCdWZmZXIgPSBAcGxheShcIkF1ZGlvL011c2ljLyN7bXVzaWMubmFtZX1cIiwgdm9sdW1lLCBtdXNpYy5yYXRlKVxuICAgICAgICAgICAgbXVzaWNCdWZmZXIubG9vcCA9IHllc1xuICAgICAgICAgICAgbXVzaWNCdWZmZXIudm9sdW1lID0gMFxuICAgICAgICAgICAgbXVzaWNCdWZmZXIuZHVyYXRpb24gPSBNYXRoLnJvdW5kKG11c2ljQnVmZmVyLmR1cmF0aW9uICogMTAwMCAvIDE2LjYpXG4gICAgICAgICAgICBtdXNpY0J1ZmZlci5jdXN0b21EYXRhLnBsYXlUeXBlID0gMVxuICAgICAgICAgICAgbXVzaWNCdWZmZXIuY3VzdG9tRGF0YS5wbGF5VGltZSA9IHBsYXlUaW1lXG4gICAgICAgICAgICBpZiBwbGF5UmFuZ2UuZW5kID09IDBcbiAgICAgICAgICAgICAgICBtdXNpY0J1ZmZlci5jdXN0b21EYXRhLnBsYXlSYW5nZSA9IHsgc3RhcnQ6IHBsYXlSYW5nZS5zdGFydCwgZW5kOiBtdXNpY0J1ZmZlci5kdXJhdGlvbiB9XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgbXVzaWNCdWZmZXIuY3VzdG9tRGF0YS5wbGF5UmFuZ2UgPSBwbGF5UmFuZ2VcbiAgICAgICAgICAgIG11c2ljQnVmZmVyLmN1c3RvbURhdGEuZmFkZVRpbWUgPSBmYWRlVGltZVxuICAgICAgICAgICAgXG4gICAgICAgICAgICBtdXNpY0J1ZmZlci5jdXN0b21EYXRhLnN0YXJ0VGltZXIgPSBNYXRoLnJvdW5kKG11c2ljQnVmZmVyLmN1c3RvbURhdGEucGxheVJhbmdlLnN0YXJ0ICsgTWF0aC5yYW5kb20oKSAqIChtdXNpY0J1ZmZlci5jdXN0b21EYXRhLnBsYXlSYW5nZS5lbmQgLSBtdXNpY0J1ZmZlci5jdXN0b21EYXRhLnBsYXlSYW5nZS5zdGFydCkpXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIEBhdWRpb0J1ZmZlcnMucHVzaChtdXNpY0J1ZmZlcikgaWYgbm90IEBhdWRpb0J1ZmZlcnMuY29udGFpbnMobXVzaWNCdWZmZXIpXG4gICAgICAgICAgICBAYXVkaW9CdWZmZXJzQnlMYXllcltsYXllcl0gPSBtdXNpY0J1ZmZlclxuICAgICAgICAgICAgQGF1ZGlvTGF5ZXJzW2xheWVyXSA9IG5hbWU6IG11c2ljLm5hbWUsIHRpbWU6IG11c2ljLmN1cnJlbnRUaW1lLCB2b2x1bWU6IG11c2ljLnZvbHVtZSwgcmF0ZTogbXVzaWMucGxheWJhY2tSYXRlLCBmYWRlSW5UaW1lOiBmYWRlVGltZSwgY3VzdG9tRGF0YTogbXVzaWNCdWZmZXIuY3VzdG9tRGF0YVxuICAgICBcbiAgICAjIyMqXG4gICAgKiBQbGF5cyBhIG11c2ljLlxuICAgICpcbiAgICAqIEBtZXRob2QgcGxheU11c2ljXG4gICAgKiBAcGFyYW0ge3N0cmluZ3xPYmplY3R9IG5hbWUgLSBUaGUgbXVzaWMgdG8gcGxheS4gQ2FuIGJlIGp1c3QgYSBuYW1lIG9yIGEgbXVzaWMgZGF0YS1vYmplY3QuXG4gICAgKiBAcGFyYW0ge251bWJlcn0gdm9sdW1lIC0gVGhlIG11c2ljJ3Mgdm9sdW1lIGluIHBlcmNlbnQuXG4gICAgKiBAcGFyYW0ge251bWJlcn0gcmF0ZSAtIFRoZSBtdXNpYydzIHBsYXliYWNrIHJhdGUgaW4gcGVyY2VudC5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSBmYWRlSW5UaW1lIC0gVGhlIGZhZGUtaW4gdGltZS5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSBsYXllciAtIFRoZSBsYXllciB0byBwbGF5IHRoZSBtdXNpYyBvbi5cbiAgICAjIyMgICAgICAgICAgXG4gICAgcGxheU11c2ljOiAobmFtZSwgdm9sdW1lLCByYXRlLCBmYWRlSW5UaW1lLCBsYXllcikgLT5cbiAgICAgICAgcmV0dXJuIGlmICRQQVJBTVMucHJldmlldz8uc2V0dGluZ3MubXVzaWNEaXNhYmxlZFxuICAgICAgICBcbiAgICAgICAgaWYgbmFtZT8gYW5kIG5hbWUubmFtZT9cbiAgICAgICAgICAgIGxheWVyID0gaWYgbGF5ZXI/IHRoZW4gbGF5ZXIgZWxzZSByYXRlIHx8IDBcbiAgICAgICAgICAgIGZhZGVJblRpbWUgPSB2b2x1bWVcbiAgICAgICAgICAgIHZvbHVtZSA9IG5hbWUudm9sdW1lXG4gICAgICAgICAgICByYXRlID0gbmFtZS5wbGF5YmFja1JhdGVcbiAgICAgICAgICAgIG5hbWUgPSBuYW1lLm5hbWVcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgbGF5ZXIgPSBsYXllciA/IDBcbiAgICAgICAgICAgIFxuICAgICAgICBAZGlzcG9zZU11c2ljKGxheWVyKVxuICAgICAgICBAYXVkaW9MYXllcnNbbGF5ZXJdID0gbmFtZTogbmFtZSwgdm9sdW1lOiB2b2x1bWUsIHJhdGU6IHJhdGUsIGZhZGVJblRpbWU6IGZhZGVJblRpbWUsIHBsYXlpbmc6IHRydWVcbiAgICAgICAgICAgXG4gICAgICAgIHZvbHVtZSA9IGlmIHZvbHVtZT8gdGhlbiB2b2x1bWUgZWxzZSAxMDBcbiAgICAgICAgdm9sdW1lID0gdm9sdW1lICogKEBnZW5lcmFsTXVzaWNWb2x1bWUgLyAxMDApXG4gICAgICAgIEBtdXNpY1ZvbHVtZSA9IHZvbHVtZVxuICAgICAgICBcbiAgICAgICAgXG4gICAgICAgIGlmIG5hbWU/IGFuZCBuYW1lLmxlbmd0aCA+IDBcbiAgICAgICAgICAgIEBtdXNpYyA9IG5hbWU6IG5hbWVcbiAgICAgICAgICAgIG11c2ljQnVmZmVyID0gQHBsYXkoXCJBdWRpby9NdXNpYy8je25hbWV9XCIsIHZvbHVtZSwgcmF0ZSwgZmFkZUluVGltZSlcbiAgICAgICAgICAgIG11c2ljQnVmZmVyLmxvb3AgPSB5ZXNcbiAgICAgICAgICAgIEBhdWRpb0J1ZmZlcnMucHVzaChtdXNpY0J1ZmZlcikgaWYgbm90IEBhdWRpb0J1ZmZlcnMuY29udGFpbnMobXVzaWNCdWZmZXIpXG4gICAgICAgICAgICBAYXVkaW9CdWZmZXJzQnlMYXllcltsYXllcl0gPSBtdXNpY0J1ZmZlclxuICAgICAgICAgICAgXG4gICAgIyMjKlxuICAgICogUmVzdW1lcyBhIHBhdXNlZCBtdXNpYy5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHJlc3VtZU11c2ljXG4gICAgKiBAcGFyYW0ge251bWJlcn0gZmFkZUluVGltZSAtIFRoZSBmYWRlLWluIHRpbWUgaW4gZnJhbWVzLlxuICAgICogQHBhcmFtIHtudW1iZXJ9IGxheWVyIC0gVGhlIGF1ZGlvIGxheWVyIHRvIHJlc3VtZS5cbiAgICAjIyMgICBcbiAgICByZXN1bWVNdXNpYzogKGZhZGVJblRpbWUsIGxheWVyKSAtPlxuICAgICAgICBsYXllciA9IGxheWVyID8gMFxuICAgICAgICBpZiBAYXVkaW9CdWZmZXJzQnlMYXllcltsYXllcl0/IGFuZCBub3QgQGF1ZGlvQnVmZmVyc0J5TGF5ZXJbbGF5ZXJdLmlzUGxheWluZ1xuICAgICAgICAgICAgQGF1ZGlvQnVmZmVyc0J5TGF5ZXJbbGF5ZXJdLnJlc3VtZShmYWRlSW5UaW1lKVxuICAgICAgICAgICAgQGF1ZGlvTGF5ZXJzW2xheWVyXT8ucGxheWluZyA9IHRydWVcbiAgICBcbiAgICAjIyMqXG4gICAgKiBTdG9wcyBhIG11c2ljLlxuICAgICpcbiAgICAqIEBtZXRob2Qgc3RvcE11c2ljXG4gICAgKiBAcGFyYW0ge251bWJlcn0gZmFkZU91dFRpbWUgLSBUaGUgZmFkZS1vdXQgdGltZSBpbiBmcmFtZXMuXG4gICAgKiBAcGFyYW0ge251bWJlcn0gbGF5ZXIgLSBUaGUgYXVkaW8gbGF5ZXIgdG8gc3RvcC5cbiAgICAjIyMgICAgICAgICBcbiAgICBzdG9wTXVzaWM6IChmYWRlT3V0VGltZSwgbGF5ZXIpIC0+IFxuICAgICAgICBsYXllciA9IGxheWVyID8gMFxuICAgICAgICBAYXVkaW9CdWZmZXJzQnlMYXllcltsYXllcl0/LnN0b3AoZmFkZU91dFRpbWUpXG4gICAgICAgIEBhdWRpb0J1ZmZlcnNCeUxheWVyW2xheWVyXT8uY3VzdG9tRGF0YSA9IHt9XG4gICAgICAgIEBhdWRpb0xheWVyc1tsYXllcl0/LnBsYXlpbmcgPSBmYWxzZVxuICAgICAgICBAbXVzaWMgPSBudWxsXG4gICAgICAgIFxuICAgICMjIypcbiAgICAqIFN0b3BzIGFsbCBtdXNpYy9hdWRpbyBsYXllcnMuXG4gICAgKlxuICAgICogQG1ldGhvZCBzdG9wQWxsTXVzaWNcbiAgICAqIEBwYXJhbSB7bnVtYmVyfSBmYWRlT3V0VGltZSAtIFRoZSBmYWRlLW91dCB0aW1lIGluIGZyYW1lcy5cbiAgICAjIyMgICAgICAgICBcbiAgICBzdG9wQWxsTXVzaWM6IChmYWRlT3V0VGltZSkgLT4gXG4gICAgICAgIGZvciBidWZmZXIgaW4gQGF1ZGlvQnVmZmVyc1xuICAgICAgICAgICAgaWYgYnVmZmVyP1xuICAgICAgICAgICAgICAgIGJ1ZmZlci5zdG9wKGZhZGVPdXRUaW1lKVxuICAgICAgICAgICAgICAgIGJ1ZmZlci5jdXN0b21EYXRhID0ge31cbiAgICAgICAgQG11c2ljID0gbnVsbFxuXG5cbiAgICBkaXNwb3NlOiAoY29udGV4dCkgLT5cbiAgICAgICAgZGF0YSA9IGNvbnRleHQucmVzb3VyY2VzLnNlbGVjdCAocikgLT4gci5kYXRhXG4gICAgICAgIGZvciBidWZmZXIsIGxheWVyIGluIEBhdWRpb0J1ZmZlcnNCeUxheWVyXG4gICAgICAgICAgICBpZiBidWZmZXIgYW5kIGRhdGEuaW5kZXhPZihidWZmZXIpICE9IC0xXG4gICAgICAgICAgICAgICAgYnVmZmVyLmRpc3Bvc2UoKVxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIEBhdWRpb0J1ZmZlcnMucmVtb3ZlKGJ1ZmZlcilcbiAgICAgICAgICAgICAgICBAYXVkaW9CdWZmZXJzQnlMYXllcltsYXllcl0gPSBudWxsXG4gICAgICAgICAgICAgICAgQGF1ZGlvTGF5ZXJzW2xheWVyXSA9IG51bGxcbiAgICAgICAgICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBEaXNwb3NlcyBhIG11c2ljLlxuICAgICpcbiAgICAqIEBtZXRob2QgZGlzcG9zZU11c2ljXG4gICAgKiBAcGFyYW0ge251bWJlcn0gbGF5ZXIgLSBUaGUgYXVkaW8gbGF5ZXIgb2YgdGhlIG11c2ljIHRvIGRpc3Bvc2UuXG4gICAgIyMjIFxuICAgIGRpc3Bvc2VNdXNpYzogKGxheWVyKSAtPlxuICAgICAgICBsYXllciA9IGxheWVyID8gMFxuICAgICAgICBcbiAgICAgICAgQHN0b3BNdXNpYygwLCBsYXllcilcbiAgICAgICAgI0BhdWRpb0J1ZmZlcnNbbGF5ZXJdPy5kaXNwb3NlKClcbiAgICAgICAgQGF1ZGlvQnVmZmVycy5yZW1vdmUoQGF1ZGlvQnVmZmVyc0J5TGF5ZXJbbGF5ZXJdKVxuICAgICAgICBAYXVkaW9CdWZmZXJzQnlMYXllcltsYXllcl0gPSBudWxsXG4gICAgICAgIEBhdWRpb0xheWVyc1tsYXllcl0gPSBudWxsXG4gICAgXG53aW5kb3cuQXVkaW9NYW5hZ2VyID0gbmV3IEF1ZGlvTWFuYWdlcigpXG5ncy5BdWRpb01hbmFnZXIgPSBBdWRpb01hbmFnZXIiXX0=\n//# sourceURL=AudioManager_71.js",
9 + "content": "# ===================================================================\n#\n# Script: AudioManager\n#\n# $$COPYRIGHT$$\n#\n# ===================================================================\nclass AudioManager\n ###*\n * Manages the audio playback of the game. \n *\n * @module gs\n * @class AudioManager\n * @memberof gs\n * @constructor\n ###\n constructor: ->\n ###*\n * Stores all audio buffers.\n * @property buffers\n * @type gs.AudioBuffer[]\n * @protected\n ### \n @audioBuffers = []\n \n ###*\n * Stores all audio buffers by layer.\n * @property buffers\n * @type gs.AudioBuffer[]\n * @protected\n ### \n @audioBuffersByLayer = []\n \n ###*\n * Stores all audio buffer references for sounds.\n * @property soundReferences\n * @type gs.AudioBufferReference[]\n * @protected\n ### \n @soundReferences = {}\n \n ###*\n * Current Music (Layer 0)\n * @property music\n * @type Object\n * @protected\n ### \n @music = null\n \n ###*\n * Current music volume.\n * @property musicVolume\n * @type number\n * @protected\n ### \n @musicVolume = 100\n \n ###*\n * Current sound volume.\n * @property soundVolume\n * @type number\n * @protected\n ### \n @soundVolume = 100\n \n ###*\n * Current voice volume.\n * @property voiceVolume\n * @type number\n * @protected\n ### \n @voiceVolume = 100\n \n ###*\n * General music volume\n * @property generalMusicVolume\n * @type number\n * @protected\n ### \n @generalMusicVolume = 100\n \n ###*\n * General sound volume\n * @property generalSoundVolume\n * @type number\n * @protected\n ### \n @generalSoundVolume = 100\n \n ###*\n * General voice volume\n * @property generalVoiceVolume\n * @type number\n * @protected\n ### \n @generalVoiceVolume = 100\n \n ###*\n * Stores audio layer info-data for each layer.\n * @property audioLayers\n * @type gs.AudioLayerInfo[]\n * @protected\n ### \n @audioLayers = []\n \n ###*\n * Restores audio-playback from a specified array of audio layers.\n *\n * @method restore\n * @param {gs.AudioLayerInfo[]} layers - An array of audio layer info objects.\n ### \n restore: (layers) ->\n @audioLayers = layers\n \n for layer, i in layers\n if layer and layer.playing\n if layer.customData\n @playMusicRandom(layer, layer.customData.fadeTime, i, layer.customData.playTime, layer.customData.playRange)\n else\n @playMusic(layer, layer.fadeInTime, i)\n \n ###*\n * Loads the specified music.\n *\n * @method loadMusic\n * @param {String} name - The name of the music to load.\n ### \n loadMusic: (name) -> \n name = if name? then (name.name || name) else name\n if name and name.length > 0\n ResourceManager.getAudioStream(\"Audio/Music/#{name}\")\n \n ###*\n * Loads the specified sound.\n *\n * @method loadSound\n * @param {String} name - The name of the sound to load.\n ### \n loadSound: (name) -> \n name = if name? then name.name || name else name\n if name and name.length > 0\n ResourceManager.getAudioBuffer(\"Audio/Sounds/#{name}\")\n \n ###*\n * Updates a randomly played audio buffer.\n *\n * @method updateRandomAudio\n * @param {gs.AudioBuffer} buffer - The audio buffer to update.\n * @protected\n ### \n # FIXME: Refactoring necessary. \n updateRandomAudio: (buffer) ->\n if buffer.customData.startTimer > 0\n buffer.customData.startTimer--\n if buffer.customData.startTimer <= 0\n buffer.fadeInVolume = 1.0 / (buffer.customData.fadeTime||1)\n buffer.fadeInTime = buffer.customData.fadeTime||1\n buffer.fadeOutTime = buffer.customData.fadeTime||1\n buffer.playTime = buffer.customData.playTime.min + Math.random() * (buffer.customData.playTime.max - buffer.customData.playTime.min)\n currentTime = buffer.currentTime # - buffer.startTime\n timeLeft = buffer.duration - currentTime\n buffer.playTime = Math.min(timeLeft * 1000 / 16.6, buffer.playTime)\n \n buffer.customData.startTimer = buffer.playTime + buffer.customData.playRange.start + Math.random() * (buffer.customData.playRange.end - buffer.customData.playRange.start)\n \n ###*\n * Updates all audio-buffers depending on the play-type.\n *\n * @method updateAudioBuffers\n * @protected\n ### \n updateAudioBuffers: ->\n for buffer in @audioBuffers\n if buffer?\n if buffer.customData.playType == 1\n @updateRandomAudio(buffer)\n \n if GameManager.settings.bgmVolume != @generalMusicVolume\n buffer.volume = (@musicVolume * GameManager.settings.bgmVolume / 100) / 100\n \n buffer.update()\n if GameManager.settings.bgmVolume != @generalMusicVolume\n @generalMusicVolume = GameManager.settings.bgmVolume\n \n \n ###*\n * Updates all audio-buffers depending on the play-type.\n *\n * @method updateAudioBuffers\n * @protected\n ### \n updateGeneralVolume: ->\n if GameManager.settings.seVolume != @generalSoundVolume or GameManager.settings.voiceVolume != @generalVoiceVolume\n @generalSoundVolume = GameManager.settings.seVolume\n @generalVoiceVolume = GameManager.settings.voiceVolume\n for k of @soundReferences\n for reference in @soundReferences[k]\n if reference.voice\n reference.volume = (@voiceVolume * GameManager.settings.voiceVolume / 100) / 100\n else\n reference.volume = (@soundVolume * GameManager.settings.seVolume / 100) / 100\n ###*\n * Updates the audio-playback.\n *\n * @method update\n ### \n update: ->\n @updateAudioBuffers()\n @updateGeneralVolume()\n \n ###*\n * Changes the current music to the specified one.\n *\n * @method changeMusic\n * @param {Object} music - The music to play. If <b>null</b> the current music will stop playing.\n ### \n changeMusic: (music) ->\n if music? and music.name?\n if @music? and @music.name != music.name\n @playMusic(music)\n else if not @music?\n @playMusic(music)\n else\n @stopMusic()\n \n # FIXME: Is this still used?\n ###*\n * Prepares. \n *\n * @method prepare\n * @param {Object} music - The music to play. If <b>null</b> the current music will stop playing.\n ### \n prepare: (path, volume, rate) -> \n buffer = ResourceManager.getAudioBuffer(path)\n \n if buffer.decoded\n buffer.volume = if volume? then volume / 100 else 1.0\n buffer.playbackRate = if rate? then rate / 100 else 1.0\n else\n buffer.onFinishDecode = (source) => \n source.volume = if volume? then volume / 100 else 1.0\n source.playbackRate = if rate? then rate / 100 else 1.0\n buffer.decode()\n \n return buffer\n \n ###*\n * Plays an audio resource.\n *\n * @method play\n * @param {String} path - The path to the audio resource.\n * @param {number} volume - The volume.\n * @param {number} rate - The playback rate.\n * @param {number} fadeInTime - The fade-in time in frames.\n ### \n play: (path, volume, rate, fadeInTime) ->\n buffer = ResourceManager.getAudioStream(path)\n \n if buffer.decoded\n buffer.volume = if volume? then volume / 100 else 1.0\n buffer.playbackRate = if rate? then rate / 100 else 1.0\n buffer.play(fadeInTime) if GameManager.settings.bgmEnabled\n else\n buffer.onFinishDecode = (source) => \n source.volume = if volume? then volume / 100 else 1.0\n source.playbackRate = if rate? then rate / 100 else 1.0\n source.play(fadeInTime) if GameManager.settings.bgmEnabled\n buffer.decode()\n \n return buffer\n \n ###*\n * Stops all sounds.\n *\n * @method stopAllSounds\n ### \n stopAllSounds: ->\n for k of @soundReferences\n for reference in @soundReferences[k]\n reference?.stop()\n \n ###*\n * Stops a sound and all references of it.\n *\n * @method stopSound\n * @param {String} name - The name of the sound to stop.\n ### \n stopSound: (name) ->\n if @soundReferences[name]?\n for reference in @soundReferences[name]\n reference.stop()\n \n \n ###*\n * Stops a voice.\n *\n * @method stopVoice\n * @param {String} name - The name of the voice to stop.\n ### \n stopVoice: (name) ->\n @stopSound(name)\n \n ###*\n * Stops all voices.\n *\n * @method stopAllVoices\n ### \n stopAllVoices: ->\n for k of @soundReferences\n for reference in @soundReferences[k]\n reference.stop() if reference.voice\n \n ###*\n * Plays a voice.\n *\n * @method playVoice\n * @param {String} name - The name of the voice to play.\n * @param {number} volume - The voice volume.\n * @param {number} rate - The voice playback rate.\n ### \n playVoice: (name, volume, rate) ->\n voice = null\n if GameManager.settings.voiceEnabled and not $PARAMS.preview?.settings.voiceDisabled\n voice = @playSound(name?.name, volume || GameManager.defaults.audio.voiceVolume, rate || GameManager.defaults.audio.voicePlaybackRate, no, yes)\n \n return voice \n \n ###*\n * Plays a sound.\n *\n * @method playSound\n * @param {String} name - The name of the sound to play.\n * @param {number} volume - The sound's volume.\n * @param {number} rate - The sound's playback rate.\n * @param {boolean} musicEffect - Indicates if the sound should be played as a music effect. In that case, the current music\n * at audio-layer will be paused until the sound finishes playing.\n * @param {boolean} voice - Indicates if the sound should be handled as a voice.\n ### \n playSound: (name, volume, rate, musicEffect, voice, loopSound) ->\n if $PARAMS.preview?.settings.soundDisabled then return\n if not name? or (!voice and !GameManager.settings.soundEnabled) then return\n if name.name?\n volume = name.volume\n rate = name.playbackRate\n name = name.name\n \n if name.length == 0 then return\n \n if musicEffect\n @stopMusic()\n \n if not @soundReferences[name]?\n @soundReferences[name] = []\n \n volume = volume ? 100\n volume *= if voice then @generalVoiceVolume / 100 else @generalSoundVolume / 100\n \n reference = null\n for r in @soundReferences[name]\n if not r.isPlaying\n reference = r\n if musicEffect then reference.onEnd = => @resumeMusic(40)\n reference.voice = voice\n reference.volume = volume / 100\n reference.playbackRate = rate / 100\n reference.loop = loopSound\n @voice = reference if voice\n reference.play()\n break\n \n if not reference?\n buffer = ResourceManager.getAudioBuffer(\"Audio/Sounds/#{name}\")\n if buffer and buffer.loaded\n if buffer.decoded\n reference = new GS.AudioBufferReference(buffer, voice)\n if musicEffect then reference.onEnd = => @resumeMusic(40)\n reference.volume = volume / 100\n reference.playbackRate = rate / 100\n reference.voice = voice\n reference.loop = loopSound\n reference.play()\n @voice = reference if voice\n @soundReferences[name].push(reference)\n else\n buffer.name = name\n buffer.onDecodeFinish = (source) =>\n reference = new GS.AudioBufferReference(source, voice)\n if musicEffect then reference.onEnd = => @resumeMusic(40)\n reference.voice = voice\n reference.volume = volume / 100\n reference.playbackRate = rate / 100\n reference.loop = loopSound\n @voice = reference if voice\n reference.play()\n @soundReferences[source.name].push(reference)\n buffer.decode()\n \n return reference \n \n ###*\n * Plays a music as a random music. A random music will fade-in and fade-out\n * at random times. That can be combined with other audio-layers to create a\n * much better looping of an audio track.\n *\n * @method playMusicRandom\n * @param {Object} music - The music to play.\n * @param {number} fadeTime - The time for a single fade-in/out in frames.\n * @param {number} layer - The audio layer to use.\n * @param {gs.Range} playTime - Play-Time range like 10s to 30s.\n * @param {gs.Range} playRange - Play-Range.\n ### \n playMusicRandom: (music, fadeTime, layer, playTime, playRange) ->\n return if $PARAMS.preview?.settings.musicDisabled\n layer = layer ? 0\n\n volume = if music.volume? then music.volume else 100\n volume = volume * (@generalMusicVolume / 100)\n @musicVolume = volume\n @disposeMusic(layer)\n \n if music.name? and music.name.length > 0\n musicBuffer = @play(\"Audio/Music/#{music.name}\", volume, music.rate)\n musicBuffer.loop = yes\n musicBuffer.volume = 0\n musicBuffer.duration = Math.round(musicBuffer.duration * 1000 / 16.6)\n musicBuffer.customData.playType = 1\n musicBuffer.customData.playTime = playTime\n if playRange.end == 0\n musicBuffer.customData.playRange = { start: playRange.start, end: musicBuffer.duration }\n else\n musicBuffer.customData.playRange = playRange\n musicBuffer.customData.fadeTime = fadeTime\n \n musicBuffer.customData.startTimer = Math.round(musicBuffer.customData.playRange.start + Math.random() * (musicBuffer.customData.playRange.end - musicBuffer.customData.playRange.start))\n \n @audioBuffers.push(musicBuffer) if not @audioBuffers.contains(musicBuffer)\n @audioBuffersByLayer[layer] = musicBuffer\n @audioLayers[layer] = name: music.name, time: music.currentTime, volume: music.volume, rate: music.playbackRate, fadeInTime: fadeTime, customData: musicBuffer.customData\n \n ###*\n * Plays a music.\n *\n * @method playMusic\n * @param {string|Object} name - The music to play. Can be just a name or a music data-object.\n * @param {number} volume - The music's volume in percent.\n * @param {number} rate - The music's playback rate in percent.\n * @param {number} fadeInTime - The fade-in time.\n * @param {number} layer - The layer to play the music on.\n * @param {boolean} loop - Indicates if the music should be looped\n ### \n playMusic: (name, volume, rate, fadeInTime, layer, loopMusic) ->\n return if $PARAMS.preview?.settings.musicDisabled\n loopMusic ?= yes\n if name? and name.name?\n layer = if layer? then layer else rate || 0\n fadeInTime = volume\n volume = name.volume\n rate = name.playbackRate\n name = name.name\n else\n layer = layer ? 0\n \n @disposeMusic(layer)\n @audioLayers[layer] = name: name, volume: volume, rate: rate, fadeInTime: fadeInTime, playing: true\n \n volume = if volume? then volume else 100\n volume = volume * (@generalMusicVolume / 100)\n @musicVolume = volume\n \n \n if name? and name.length > 0\n @music = name: name\n musicBuffer = @play(\"Audio/Music/#{name}\", volume, rate, fadeInTime)\n musicBuffer.loop = loopMusic\n @audioBuffers.push(musicBuffer) if not @audioBuffers.contains(musicBuffer)\n @audioBuffersByLayer[layer] = musicBuffer\n \n return musicBuffer\n \n ###*\n * Resumes a paused music.\n *\n * @method resumeMusic\n * @param {number} fadeInTime - The fade-in time in frames.\n * @param {number} layer - The audio layer to resume.\n ### \n resumeMusic: (fadeInTime, layer) ->\n layer = layer ? 0\n if @audioBuffersByLayer[layer]? and not @audioBuffersByLayer[layer].isPlaying\n @audioBuffersByLayer[layer].resume(fadeInTime)\n @audioLayers[layer]?.playing = true\n \n ###*\n * Stops a music.\n *\n * @method stopMusic\n * @param {number} fadeOutTime - The fade-out time in frames.\n * @param {number} layer - The audio layer to stop.\n ### \n stopMusic: (fadeOutTime, layer) -> \n layer = layer ? 0\n @audioBuffersByLayer[layer]?.stop(fadeOutTime)\n @audioBuffersByLayer[layer]?.customData = {}\n @audioLayers[layer]?.playing = false\n @music = null\n \n ###*\n * Stops all music/audio layers.\n *\n * @method stopAllMusic\n * @param {number} fadeOutTime - The fade-out time in frames.\n ### \n stopAllMusic: (fadeOutTime) -> \n for buffer in @audioBuffers\n if buffer?\n buffer.stop(fadeOutTime)\n buffer.customData = {}\n @music = null\n\n\n dispose: (context) ->\n data = context.resources.select (r) -> r.data\n for buffer, layer in @audioBuffersByLayer\n if buffer and data.indexOf(buffer) != -1\n buffer.dispose()\n \n @audioBuffers.remove(buffer)\n @audioBuffersByLayer[layer] = null\n @audioLayers[layer] = null\n \n ###*\n * Disposes a music.\n *\n * @method disposeMusic\n * @param {number} layer - The audio layer of the music to dispose.\n ### \n disposeMusic: (layer) ->\n layer = layer ? 0\n \n @stopMusic(0, layer)\n #@audioBuffers[layer]?.dispose()\n @audioBuffers.remove(@audioBuffersByLayer[layer])\n @audioBuffersByLayer[layer] = null\n @audioLayers[layer] = null\n \nwindow.AudioManager = new AudioManager()\ngs.AudioManager = AudioManager",
10 + "compiledContent": "var AudioManager;\n\nAudioManager = (function() {\n\n /**\n * Manages the audio playback of the game. \n *\n * @module gs\n * @class AudioManager\n * @memberof gs\n * @constructor\n */\n function AudioManager() {\n\n /**\n * Stores all audio buffers.\n * @property buffers\n * @type gs.AudioBuffer[]\n * @protected\n */\n this.audioBuffers = [];\n\n /**\n * Stores all audio buffers by layer.\n * @property buffers\n * @type gs.AudioBuffer[]\n * @protected\n */\n this.audioBuffersByLayer = [];\n\n /**\n * Stores all audio buffer references for sounds.\n * @property soundReferences\n * @type gs.AudioBufferReference[]\n * @protected\n */\n this.soundReferences = {};\n\n /**\n * Current Music (Layer 0)\n * @property music\n * @type Object\n * @protected\n */\n this.music = null;\n\n /**\n * Current music volume.\n * @property musicVolume\n * @type number\n * @protected\n */\n this.musicVolume = 100;\n\n /**\n * Current sound volume.\n * @property soundVolume\n * @type number\n * @protected\n */\n this.soundVolume = 100;\n\n /**\n * Current voice volume.\n * @property voiceVolume\n * @type number\n * @protected\n */\n this.voiceVolume = 100;\n\n /**\n * General music volume\n * @property generalMusicVolume\n * @type number\n * @protected\n */\n this.generalMusicVolume = 100;\n\n /**\n * General sound volume\n * @property generalSoundVolume\n * @type number\n * @protected\n */\n this.generalSoundVolume = 100;\n\n /**\n * General voice volume\n * @property generalVoiceVolume\n * @type number\n * @protected\n */\n this.generalVoiceVolume = 100;\n\n /**\n * Stores audio layer info-data for each layer.\n * @property audioLayers\n * @type gs.AudioLayerInfo[]\n * @protected\n */\n this.audioLayers = [];\n }\n\n\n /**\n * Restores audio-playback from a specified array of audio layers.\n *\n * @method restore\n * @param {gs.AudioLayerInfo[]} layers - An array of audio layer info objects.\n */\n\n AudioManager.prototype.restore = function(layers) {\n var i, j, layer, len, results;\n this.audioLayers = layers;\n results = [];\n for (i = j = 0, len = layers.length; j < len; i = ++j) {\n layer = layers[i];\n if (layer && layer.playing) {\n if (layer.customData) {\n results.push(this.playMusicRandom(layer, layer.customData.fadeTime, i, layer.customData.playTime, layer.customData.playRange));\n } else {\n results.push(this.playMusic(layer, layer.fadeInTime, i));\n }\n } else {\n results.push(void 0);\n }\n }\n return results;\n };\n\n\n /**\n * Loads the specified music.\n *\n * @method loadMusic\n * @param {String} name - The name of the music to load.\n */\n\n AudioManager.prototype.loadMusic = function(name) {\n name = name != null ? name.name || name : name;\n if (name && name.length > 0) {\n return ResourceManager.getAudioStream(\"Audio/Music/\" + name);\n }\n };\n\n\n /**\n * Loads the specified sound.\n *\n * @method loadSound\n * @param {String} name - The name of the sound to load.\n */\n\n AudioManager.prototype.loadSound = function(name) {\n name = name != null ? name.name || name : name;\n if (name && name.length > 0) {\n return ResourceManager.getAudioBuffer(\"Audio/Sounds/\" + name);\n }\n };\n\n\n /**\n * Updates a randomly played audio buffer.\n *\n * @method updateRandomAudio\n * @param {gs.AudioBuffer} buffer - The audio buffer to update.\n * @protected\n */\n\n AudioManager.prototype.updateRandomAudio = function(buffer) {\n var currentTime, timeLeft;\n if (buffer.customData.startTimer > 0) {\n buffer.customData.startTimer--;\n if (buffer.customData.startTimer <= 0) {\n buffer.fadeInVolume = 1.0 / (buffer.customData.fadeTime || 1);\n buffer.fadeInTime = buffer.customData.fadeTime || 1;\n buffer.fadeOutTime = buffer.customData.fadeTime || 1;\n buffer.playTime = buffer.customData.playTime.min + Math.random() * (buffer.customData.playTime.max - buffer.customData.playTime.min);\n currentTime = buffer.currentTime;\n timeLeft = buffer.duration - currentTime;\n buffer.playTime = Math.min(timeLeft * 1000 / 16.6, buffer.playTime);\n return buffer.customData.startTimer = buffer.playTime + buffer.customData.playRange.start + Math.random() * (buffer.customData.playRange.end - buffer.customData.playRange.start);\n }\n }\n };\n\n\n /**\n * Updates all audio-buffers depending on the play-type.\n *\n * @method updateAudioBuffers\n * @protected\n */\n\n AudioManager.prototype.updateAudioBuffers = function() {\n var buffer, j, len, ref;\n ref = this.audioBuffers;\n for (j = 0, len = ref.length; j < len; j++) {\n buffer = ref[j];\n if (buffer != null) {\n if (buffer.customData.playType === 1) {\n this.updateRandomAudio(buffer);\n }\n if (GameManager.settings.bgmVolume !== this.generalMusicVolume) {\n buffer.volume = (this.musicVolume * GameManager.settings.bgmVolume / 100) / 100;\n }\n buffer.update();\n }\n }\n if (GameManager.settings.bgmVolume !== this.generalMusicVolume) {\n return this.generalMusicVolume = GameManager.settings.bgmVolume;\n }\n };\n\n\n /**\n * Updates all audio-buffers depending on the play-type.\n *\n * @method updateAudioBuffers\n * @protected\n */\n\n AudioManager.prototype.updateGeneralVolume = function() {\n var k, reference, results;\n if (GameManager.settings.seVolume !== this.generalSoundVolume || GameManager.settings.voiceVolume !== this.generalVoiceVolume) {\n this.generalSoundVolume = GameManager.settings.seVolume;\n this.generalVoiceVolume = GameManager.settings.voiceVolume;\n results = [];\n for (k in this.soundReferences) {\n results.push((function() {\n var j, len, ref, results1;\n ref = this.soundReferences[k];\n results1 = [];\n for (j = 0, len = ref.length; j < len; j++) {\n reference = ref[j];\n if (reference.voice) {\n results1.push(reference.volume = (this.voiceVolume * GameManager.settings.voiceVolume / 100) / 100);\n } else {\n results1.push(reference.volume = (this.soundVolume * GameManager.settings.seVolume / 100) / 100);\n }\n }\n return results1;\n }).call(this));\n }\n return results;\n }\n };\n\n\n /**\n * Updates the audio-playback.\n *\n * @method update\n */\n\n AudioManager.prototype.update = function() {\n this.updateAudioBuffers();\n return this.updateGeneralVolume();\n };\n\n\n /**\n * Changes the current music to the specified one.\n *\n * @method changeMusic\n * @param {Object} music - The music to play. If <b>null</b> the current music will stop playing.\n */\n\n AudioManager.prototype.changeMusic = function(music) {\n if ((music != null) && (music.name != null)) {\n if ((this.music != null) && this.music.name !== music.name) {\n return this.playMusic(music);\n } else if (this.music == null) {\n return this.playMusic(music);\n }\n } else {\n return this.stopMusic();\n }\n };\n\n\n /**\n * Prepares. \n *\n * @method prepare\n * @param {Object} music - The music to play. If <b>null</b> the current music will stop playing.\n */\n\n AudioManager.prototype.prepare = function(path, volume, rate) {\n var buffer;\n buffer = ResourceManager.getAudioBuffer(path);\n if (buffer.decoded) {\n buffer.volume = volume != null ? volume / 100 : 1.0;\n buffer.playbackRate = rate != null ? rate / 100 : 1.0;\n } else {\n buffer.onFinishDecode = (function(_this) {\n return function(source) {\n source.volume = volume != null ? volume / 100 : 1.0;\n return source.playbackRate = rate != null ? rate / 100 : 1.0;\n };\n })(this);\n buffer.decode();\n }\n return buffer;\n };\n\n\n /**\n * Plays an audio resource.\n *\n * @method play\n * @param {String} path - The path to the audio resource.\n * @param {number} volume - The volume.\n * @param {number} rate - The playback rate.\n * @param {number} fadeInTime - The fade-in time in frames.\n */\n\n AudioManager.prototype.play = function(path, volume, rate, fadeInTime) {\n var buffer;\n buffer = ResourceManager.getAudioStream(path);\n if (buffer.decoded) {\n buffer.volume = volume != null ? volume / 100 : 1.0;\n buffer.playbackRate = rate != null ? rate / 100 : 1.0;\n if (GameManager.settings.bgmEnabled) {\n buffer.play(fadeInTime);\n }\n } else {\n buffer.onFinishDecode = (function(_this) {\n return function(source) {\n source.volume = volume != null ? volume / 100 : 1.0;\n source.playbackRate = rate != null ? rate / 100 : 1.0;\n if (GameManager.settings.bgmEnabled) {\n return source.play(fadeInTime);\n }\n };\n })(this);\n buffer.decode();\n }\n return buffer;\n };\n\n\n /**\n * Stops all sounds.\n *\n * @method stopAllSounds\n */\n\n AudioManager.prototype.stopAllSounds = function() {\n var k, reference, results;\n results = [];\n for (k in this.soundReferences) {\n results.push((function() {\n var j, len, ref, results1;\n ref = this.soundReferences[k];\n results1 = [];\n for (j = 0, len = ref.length; j < len; j++) {\n reference = ref[j];\n results1.push(reference != null ? reference.stop() : void 0);\n }\n return results1;\n }).call(this));\n }\n return results;\n };\n\n\n /**\n * Stops a sound and all references of it.\n *\n * @method stopSound\n * @param {String} name - The name of the sound to stop.\n */\n\n AudioManager.prototype.stopSound = function(name) {\n var j, len, ref, reference, results;\n if (this.soundReferences[name] != null) {\n ref = this.soundReferences[name];\n results = [];\n for (j = 0, len = ref.length; j < len; j++) {\n reference = ref[j];\n results.push(reference.stop());\n }\n return results;\n }\n };\n\n\n /**\n * Stops a voice.\n *\n * @method stopVoice\n * @param {String} name - The name of the voice to stop.\n */\n\n AudioManager.prototype.stopVoice = function(name) {\n return this.stopSound(name);\n };\n\n\n /**\n * Stops all voices.\n *\n * @method stopAllVoices\n */\n\n AudioManager.prototype.stopAllVoices = function() {\n var k, reference, results;\n results = [];\n for (k in this.soundReferences) {\n results.push((function() {\n var j, len, ref, results1;\n ref = this.soundReferences[k];\n results1 = [];\n for (j = 0, len = ref.length; j < len; j++) {\n reference = ref[j];\n if (reference.voice) {\n results1.push(reference.stop());\n } else {\n results1.push(void 0);\n }\n }\n return results1;\n }).call(this));\n }\n return results;\n };\n\n\n /**\n * Plays a voice.\n *\n * @method playVoice\n * @param {String} name - The name of the voice to play.\n * @param {number} volume - The voice volume.\n * @param {number} rate - The voice playback rate.\n */\n\n AudioManager.prototype.playVoice = function(name, volume, rate) {\n var ref, voice;\n voice = null;\n if (GameManager.settings.voiceEnabled && !((ref = $PARAMS.preview) != null ? ref.settings.voiceDisabled : void 0)) {\n voice = this.playSound(name != null ? name.name : void 0, volume || GameManager.defaults.audio.voiceVolume, rate || GameManager.defaults.audio.voicePlaybackRate, false, true);\n }\n return voice;\n };\n\n\n /**\n * Plays a sound.\n *\n * @method playSound\n * @param {String} name - The name of the sound to play.\n * @param {number} volume - The sound's volume.\n * @param {number} rate - The sound's playback rate.\n * @param {boolean} musicEffect - Indicates if the sound should be played as a music effect. In that case, the current music\n * at audio-layer will be paused until the sound finishes playing.\n * @param {boolean} voice - Indicates if the sound should be handled as a voice.\n */\n\n AudioManager.prototype.playSound = function(name, volume, rate, musicEffect, voice, loopSound) {\n var buffer, j, len, r, ref, ref1, reference;\n if ((ref = $PARAMS.preview) != null ? ref.settings.soundDisabled : void 0) {\n return;\n }\n if ((name == null) || (!voice && !GameManager.settings.soundEnabled)) {\n return;\n }\n if (name.name != null) {\n volume = name.volume;\n rate = name.playbackRate;\n name = name.name;\n }\n if (name.length === 0) {\n return;\n }\n if (musicEffect) {\n this.stopMusic();\n }\n if (this.soundReferences[name] == null) {\n this.soundReferences[name] = [];\n }\n volume = volume != null ? volume : 100;\n volume *= voice ? this.generalVoiceVolume / 100 : this.generalSoundVolume / 100;\n reference = null;\n ref1 = this.soundReferences[name];\n for (j = 0, len = ref1.length; j < len; j++) {\n r = ref1[j];\n if (!r.isPlaying) {\n reference = r;\n if (musicEffect) {\n reference.onEnd = (function(_this) {\n return function() {\n return _this.resumeMusic(40);\n };\n })(this);\n }\n reference.voice = voice;\n reference.volume = volume / 100;\n reference.playbackRate = rate / 100;\n reference.loop = loopSound;\n if (voice) {\n this.voice = reference;\n }\n reference.play();\n break;\n }\n }\n if (reference == null) {\n buffer = ResourceManager.getAudioBuffer(\"Audio/Sounds/\" + name);\n if (buffer && buffer.loaded) {\n if (buffer.decoded) {\n reference = new GS.AudioBufferReference(buffer, voice);\n if (musicEffect) {\n reference.onEnd = (function(_this) {\n return function() {\n return _this.resumeMusic(40);\n };\n })(this);\n }\n reference.volume = volume / 100;\n reference.playbackRate = rate / 100;\n reference.voice = voice;\n reference.loop = loopSound;\n reference.play();\n if (voice) {\n this.voice = reference;\n }\n this.soundReferences[name].push(reference);\n } else {\n buffer.name = name;\n buffer.onDecodeFinish = (function(_this) {\n return function(source) {\n reference = new GS.AudioBufferReference(source, voice);\n if (musicEffect) {\n reference.onEnd = function() {\n return _this.resumeMusic(40);\n };\n }\n reference.voice = voice;\n reference.volume = volume / 100;\n reference.playbackRate = rate / 100;\n reference.loop = loopSound;\n if (voice) {\n _this.voice = reference;\n }\n reference.play();\n return _this.soundReferences[source.name].push(reference);\n };\n })(this);\n buffer.decode();\n }\n }\n }\n return reference;\n };\n\n\n /**\n * Plays a music as a random music. A random music will fade-in and fade-out\n * at random times. That can be combined with other audio-layers to create a\n * much better looping of an audio track.\n *\n * @method playMusicRandom\n * @param {Object} music - The music to play.\n * @param {number} fadeTime - The time for a single fade-in/out in frames.\n * @param {number} layer - The audio layer to use.\n * @param {gs.Range} playTime - Play-Time range like 10s to 30s.\n * @param {gs.Range} playRange - Play-Range.\n */\n\n AudioManager.prototype.playMusicRandom = function(music, fadeTime, layer, playTime, playRange) {\n var musicBuffer, ref, volume;\n if ((ref = $PARAMS.preview) != null ? ref.settings.musicDisabled : void 0) {\n return;\n }\n layer = layer != null ? layer : 0;\n volume = music.volume != null ? music.volume : 100;\n volume = volume * (this.generalMusicVolume / 100);\n this.musicVolume = volume;\n this.disposeMusic(layer);\n if ((music.name != null) && music.name.length > 0) {\n musicBuffer = this.play(\"Audio/Music/\" + music.name, volume, music.rate);\n musicBuffer.loop = true;\n musicBuffer.volume = 0;\n musicBuffer.duration = Math.round(musicBuffer.duration * 1000 / 16.6);\n musicBuffer.customData.playType = 1;\n musicBuffer.customData.playTime = playTime;\n if (playRange.end === 0) {\n musicBuffer.customData.playRange = {\n start: playRange.start,\n end: musicBuffer.duration\n };\n } else {\n musicBuffer.customData.playRange = playRange;\n }\n musicBuffer.customData.fadeTime = fadeTime;\n musicBuffer.customData.startTimer = Math.round(musicBuffer.customData.playRange.start + Math.random() * (musicBuffer.customData.playRange.end - musicBuffer.customData.playRange.start));\n if (!this.audioBuffers.contains(musicBuffer)) {\n this.audioBuffers.push(musicBuffer);\n }\n this.audioBuffersByLayer[layer] = musicBuffer;\n return this.audioLayers[layer] = {\n name: music.name,\n time: music.currentTime,\n volume: music.volume,\n rate: music.playbackRate,\n fadeInTime: fadeTime,\n customData: musicBuffer.customData\n };\n }\n };\n\n\n /**\n * Plays a music.\n *\n * @method playMusic\n * @param {string|Object} name - The music to play. Can be just a name or a music data-object.\n * @param {number} volume - The music's volume in percent.\n * @param {number} rate - The music's playback rate in percent.\n * @param {number} fadeInTime - The fade-in time.\n * @param {number} layer - The layer to play the music on.\n * @param {boolean} loop - Indicates if the music should be looped\n */\n\n AudioManager.prototype.playMusic = function(name, volume, rate, fadeInTime, layer, loopMusic) {\n var musicBuffer, ref;\n if ((ref = $PARAMS.preview) != null ? ref.settings.musicDisabled : void 0) {\n return;\n }\n if (loopMusic == null) {\n loopMusic = true;\n }\n if ((name != null) && (name.name != null)) {\n layer = layer != null ? layer : rate || 0;\n fadeInTime = volume;\n volume = name.volume;\n rate = name.playbackRate;\n name = name.name;\n } else {\n layer = layer != null ? layer : 0;\n }\n this.disposeMusic(layer);\n this.audioLayers[layer] = {\n name: name,\n volume: volume,\n rate: rate,\n fadeInTime: fadeInTime,\n playing: true\n };\n volume = volume != null ? volume : 100;\n volume = volume * (this.generalMusicVolume / 100);\n this.musicVolume = volume;\n if ((name != null) && name.length > 0) {\n this.music = {\n name: name\n };\n musicBuffer = this.play(\"Audio/Music/\" + name, volume, rate, fadeInTime);\n musicBuffer.loop = loopMusic;\n if (!this.audioBuffers.contains(musicBuffer)) {\n this.audioBuffers.push(musicBuffer);\n }\n this.audioBuffersByLayer[layer] = musicBuffer;\n }\n return musicBuffer;\n };\n\n\n /**\n * Resumes a paused music.\n *\n * @method resumeMusic\n * @param {number} fadeInTime - The fade-in time in frames.\n * @param {number} layer - The audio layer to resume.\n */\n\n AudioManager.prototype.resumeMusic = function(fadeInTime, layer) {\n var ref;\n layer = layer != null ? layer : 0;\n if ((this.audioBuffersByLayer[layer] != null) && !this.audioBuffersByLayer[layer].isPlaying) {\n this.audioBuffersByLayer[layer].resume(fadeInTime);\n return (ref = this.audioLayers[layer]) != null ? ref.playing = true : void 0;\n }\n };\n\n\n /**\n * Stops a music.\n *\n * @method stopMusic\n * @param {number} fadeOutTime - The fade-out time in frames.\n * @param {number} layer - The audio layer to stop.\n */\n\n AudioManager.prototype.stopMusic = function(fadeOutTime, layer) {\n var ref, ref1, ref2;\n layer = layer != null ? layer : 0;\n if ((ref = this.audioBuffersByLayer[layer]) != null) {\n ref.stop(fadeOutTime);\n }\n if ((ref1 = this.audioBuffersByLayer[layer]) != null) {\n ref1.customData = {};\n }\n if ((ref2 = this.audioLayers[layer]) != null) {\n ref2.playing = false;\n }\n return this.music = null;\n };\n\n\n /**\n * Stops all music/audio layers.\n *\n * @method stopAllMusic\n * @param {number} fadeOutTime - The fade-out time in frames.\n */\n\n AudioManager.prototype.stopAllMusic = function(fadeOutTime) {\n var buffer, j, len, ref;\n ref = this.audioBuffers;\n for (j = 0, len = ref.length; j < len; j++) {\n buffer = ref[j];\n if (buffer != null) {\n buffer.stop(fadeOutTime);\n buffer.customData = {};\n }\n }\n return this.music = null;\n };\n\n AudioManager.prototype.dispose = function(context) {\n var buffer, data, j, layer, len, ref, results;\n data = context.resources.select(function(r) {\n return r.data;\n });\n ref = this.audioBuffersByLayer;\n results = [];\n for (layer = j = 0, len = ref.length; j < len; layer = ++j) {\n buffer = ref[layer];\n if (buffer && data.indexOf(buffer) !== -1) {\n buffer.dispose();\n this.audioBuffers.remove(buffer);\n this.audioBuffersByLayer[layer] = null;\n results.push(this.audioLayers[layer] = null);\n } else {\n results.push(void 0);\n }\n }\n return results;\n };\n\n\n /**\n * Disposes a music.\n *\n * @method disposeMusic\n * @param {number} layer - The audio layer of the music to dispose.\n */\n\n AudioManager.prototype.disposeMusic = function(layer) {\n layer = layer != null ? layer : 0;\n this.stopMusic(0, layer);\n this.audioBuffers.remove(this.audioBuffersByLayer[layer]);\n this.audioBuffersByLayer[layer] = null;\n return this.audioLayers[layer] = null;\n };\n\n return AudioManager;\n\n})();\n\nwindow.AudioManager = new AudioManager();\n\ngs.AudioManager = AudioManager;\n\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU9BLElBQUE7O0FBQU07O0FBQ0Y7Ozs7Ozs7O0VBUWEsc0JBQUE7O0FBQ1Q7Ozs7OztJQU1BLElBQUMsQ0FBQSxZQUFELEdBQWdCOztBQUVoQjs7Ozs7O0lBTUEsSUFBQyxDQUFBLG1CQUFELEdBQXVCOztBQUV2Qjs7Ozs7O0lBTUEsSUFBQyxDQUFBLGVBQUQsR0FBbUI7O0FBRW5COzs7Ozs7SUFNQSxJQUFDLENBQUEsS0FBRCxHQUFTOztBQUVUOzs7Ozs7SUFNQSxJQUFDLENBQUEsV0FBRCxHQUFlOztBQUVmOzs7Ozs7SUFNQSxJQUFDLENBQUEsV0FBRCxHQUFlOztBQUVmOzs7Ozs7SUFNQSxJQUFDLENBQUEsV0FBRCxHQUFlOztBQUVmOzs7Ozs7SUFNQSxJQUFDLENBQUEsa0JBQUQsR0FBc0I7O0FBRXRCOzs7Ozs7SUFNQSxJQUFDLENBQUEsa0JBQUQsR0FBc0I7O0FBRXRCOzs7Ozs7SUFNQSxJQUFDLENBQUEsa0JBQUQsR0FBc0I7O0FBRXRCOzs7Ozs7SUFNQSxJQUFDLENBQUEsV0FBRCxHQUFlO0VBdkZOOzs7QUF5RmI7Ozs7Ozs7eUJBTUEsT0FBQSxHQUFTLFNBQUMsTUFBRDtBQUNMLFFBQUE7SUFBQSxJQUFDLENBQUEsV0FBRCxHQUFlO0FBRWY7U0FBQSxnREFBQTs7TUFDSSxJQUFHLEtBQUEsSUFBVSxLQUFLLENBQUMsT0FBbkI7UUFDSSxJQUFHLEtBQUssQ0FBQyxVQUFUO3VCQUNJLElBQUMsQ0FBQSxlQUFELENBQWlCLEtBQWpCLEVBQXdCLEtBQUssQ0FBQyxVQUFVLENBQUMsUUFBekMsRUFBbUQsQ0FBbkQsRUFBc0QsS0FBSyxDQUFDLFVBQVUsQ0FBQyxRQUF2RSxFQUFpRixLQUFLLENBQUMsVUFBVSxDQUFDLFNBQWxHLEdBREo7U0FBQSxNQUFBO3VCQUdJLElBQUMsQ0FBQSxTQUFELENBQVcsS0FBWCxFQUFrQixLQUFLLENBQUMsVUFBeEIsRUFBb0MsQ0FBcEMsR0FISjtTQURKO09BQUEsTUFBQTs2QkFBQTs7QUFESjs7RUFISzs7O0FBVVQ7Ozs7Ozs7eUJBTUEsU0FBQSxHQUFXLFNBQUMsSUFBRDtJQUNQLElBQUEsR0FBVSxZQUFILEdBQWUsSUFBSSxDQUFDLElBQUwsSUFBYSxJQUE1QixHQUF1QztJQUM5QyxJQUFHLElBQUEsSUFBUyxJQUFJLENBQUMsTUFBTCxHQUFjLENBQTFCO2FBQ0ksZUFBZSxDQUFDLGNBQWhCLENBQStCLGNBQUEsR0FBZSxJQUE5QyxFQURKOztFQUZPOzs7QUFLWDs7Ozs7Ozt5QkFNQSxTQUFBLEdBQVcsU0FBQyxJQUFEO0lBQ1AsSUFBQSxHQUFVLFlBQUgsR0FBYyxJQUFJLENBQUMsSUFBTCxJQUFhLElBQTNCLEdBQXFDO0lBQzVDLElBQUcsSUFBQSxJQUFTLElBQUksQ0FBQyxNQUFMLEdBQWMsQ0FBMUI7YUFDSSxlQUFlLENBQUMsY0FBaEIsQ0FBK0IsZUFBQSxHQUFnQixJQUEvQyxFQURKOztFQUZPOzs7QUFLWDs7Ozs7Ozs7eUJBUUEsaUJBQUEsR0FBbUIsU0FBQyxNQUFEO0FBQ2YsUUFBQTtJQUFBLElBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxVQUFsQixHQUErQixDQUFsQztNQUNJLE1BQU0sQ0FBQyxVQUFVLENBQUMsVUFBbEI7TUFDQSxJQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsVUFBbEIsSUFBZ0MsQ0FBbkM7UUFDSSxNQUFNLENBQUMsWUFBUCxHQUFzQixHQUFBLEdBQU0sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFFBQWxCLElBQTRCLENBQTdCO1FBQzVCLE1BQU0sQ0FBQyxVQUFQLEdBQW9CLE1BQU0sQ0FBQyxVQUFVLENBQUMsUUFBbEIsSUFBNEI7UUFDaEQsTUFBTSxDQUFDLFdBQVAsR0FBcUIsTUFBTSxDQUFDLFVBQVUsQ0FBQyxRQUFsQixJQUE0QjtRQUNqRCxNQUFNLENBQUMsUUFBUCxHQUFrQixNQUFNLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxHQUEzQixHQUFpQyxJQUFJLENBQUMsTUFBTCxDQUFBLENBQUEsR0FBZ0IsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxHQUEzQixHQUFpQyxNQUFNLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxHQUE3RDtRQUNuRSxXQUFBLEdBQWMsTUFBTSxDQUFDO1FBQ3JCLFFBQUEsR0FBVyxNQUFNLENBQUMsUUFBUCxHQUFrQjtRQUM3QixNQUFNLENBQUMsUUFBUCxHQUFrQixJQUFJLENBQUMsR0FBTCxDQUFTLFFBQUEsR0FBVyxJQUFYLEdBQWtCLElBQTNCLEVBQWlDLE1BQU0sQ0FBQyxRQUF4QztlQUVsQixNQUFNLENBQUMsVUFBVSxDQUFDLFVBQWxCLEdBQStCLE1BQU0sQ0FBQyxRQUFQLEdBQWtCLE1BQU0sQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLEtBQTlDLEdBQXNELElBQUksQ0FBQyxNQUFMLENBQUEsQ0FBQSxHQUFnQixDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLEdBQTVCLEdBQWtDLE1BQU0sQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLEtBQS9ELEVBVHpHO09BRko7O0VBRGU7OztBQWNuQjs7Ozs7Ozt5QkFNQSxrQkFBQSxHQUFvQixTQUFBO0FBQ2hCLFFBQUE7QUFBQTtBQUFBLFNBQUEscUNBQUE7O01BQ0ksSUFBRyxjQUFIO1FBQ0ksSUFBRyxNQUFNLENBQUMsVUFBVSxDQUFDLFFBQWxCLEtBQThCLENBQWpDO1VBQ0ksSUFBQyxDQUFBLGlCQUFELENBQW1CLE1BQW5CLEVBREo7O1FBR0EsSUFBRyxXQUFXLENBQUMsUUFBUSxDQUFDLFNBQXJCLEtBQWtDLElBQUMsQ0FBQSxrQkFBdEM7VUFDSSxNQUFNLENBQUMsTUFBUCxHQUFnQixDQUFDLElBQUMsQ0FBQSxXQUFELEdBQWUsV0FBVyxDQUFDLFFBQVEsQ0FBQyxTQUFwQyxHQUFnRCxHQUFqRCxDQUFBLEdBQXdELElBRDVFOztRQUdBLE1BQU0sQ0FBQyxNQUFQLENBQUEsRUFQSjs7QUFESjtJQVNBLElBQUcsV0FBVyxDQUFDLFFBQVEsQ0FBQyxTQUFyQixLQUFrQyxJQUFDLENBQUEsa0JBQXRDO2FBQ0ksSUFBQyxDQUFBLGtCQUFELEdBQXNCLFdBQVcsQ0FBQyxRQUFRLENBQUMsVUFEL0M7O0VBVmdCOzs7QUFjcEI7Ozs7Ozs7eUJBTUEsbUJBQUEsR0FBcUIsU0FBQTtBQUNqQixRQUFBO0lBQUEsSUFBRyxXQUFXLENBQUMsUUFBUSxDQUFDLFFBQXJCLEtBQWlDLElBQUMsQ0FBQSxrQkFBbEMsSUFBd0QsV0FBVyxDQUFDLFFBQVEsQ0FBQyxXQUFyQixLQUFvQyxJQUFDLENBQUEsa0JBQWhHO01BQ0ksSUFBQyxDQUFBLGtCQUFELEdBQXNCLFdBQVcsQ0FBQyxRQUFRLENBQUM7TUFDM0MsSUFBQyxDQUFBLGtCQUFELEdBQXNCLFdBQVcsQ0FBQyxRQUFRLENBQUM7QUFDM0M7V0FBQSx5QkFBQTs7O0FBQ0k7QUFBQTtlQUFBLHFDQUFBOztZQUNJLElBQUcsU0FBUyxDQUFDLEtBQWI7NEJBQ0ksU0FBUyxDQUFDLE1BQVYsR0FBbUIsQ0FBQyxJQUFDLENBQUEsV0FBRCxHQUFlLFdBQVcsQ0FBQyxRQUFRLENBQUMsV0FBcEMsR0FBa0QsR0FBbkQsQ0FBQSxHQUEwRCxLQURqRjthQUFBLE1BQUE7NEJBR0ksU0FBUyxDQUFDLE1BQVYsR0FBbUIsQ0FBQyxJQUFDLENBQUEsV0FBRCxHQUFlLFdBQVcsQ0FBQyxRQUFRLENBQUMsUUFBcEMsR0FBK0MsR0FBaEQsQ0FBQSxHQUF1RCxLQUg5RTs7QUFESjs7O0FBREo7cUJBSEo7O0VBRGlCOzs7QUFVckI7Ozs7Ozt5QkFLQSxNQUFBLEdBQVEsU0FBQTtJQUNKLElBQUMsQ0FBQSxrQkFBRCxDQUFBO1dBQ0EsSUFBQyxDQUFBLG1CQUFELENBQUE7RUFGSTs7O0FBSVI7Ozs7Ozs7eUJBTUEsV0FBQSxHQUFhLFNBQUMsS0FBRDtJQUNULElBQUcsZUFBQSxJQUFXLG9CQUFkO01BQ0ksSUFBRyxvQkFBQSxJQUFZLElBQUMsQ0FBQSxLQUFLLENBQUMsSUFBUCxLQUFlLEtBQUssQ0FBQyxJQUFwQztlQUNJLElBQUMsQ0FBQSxTQUFELENBQVcsS0FBWCxFQURKO09BQUEsTUFFSyxJQUFPLGtCQUFQO2VBQ0QsSUFBQyxDQUFBLFNBQUQsQ0FBVyxLQUFYLEVBREM7T0FIVDtLQUFBLE1BQUE7YUFNSSxJQUFDLENBQUEsU0FBRCxDQUFBLEVBTko7O0VBRFM7OztBQVViOzs7Ozs7O3lCQU1BLE9BQUEsR0FBUyxTQUFDLElBQUQsRUFBTyxNQUFQLEVBQWUsSUFBZjtBQUNMLFFBQUE7SUFBQSxNQUFBLEdBQVMsZUFBZSxDQUFDLGNBQWhCLENBQStCLElBQS9CO0lBRVQsSUFBRyxNQUFNLENBQUMsT0FBVjtNQUNJLE1BQU0sQ0FBQyxNQUFQLEdBQW1CLGNBQUgsR0FBZ0IsTUFBQSxHQUFTLEdBQXpCLEdBQWtDO01BQ2xELE1BQU0sQ0FBQyxZQUFQLEdBQXlCLFlBQUgsR0FBYyxJQUFBLEdBQU8sR0FBckIsR0FBOEIsSUFGeEQ7S0FBQSxNQUFBO01BSUcsTUFBTSxDQUFDLGNBQVAsR0FBd0IsQ0FBQSxTQUFBLEtBQUE7ZUFBQSxTQUFDLE1BQUQ7VUFDcEIsTUFBTSxDQUFDLE1BQVAsR0FBbUIsY0FBSCxHQUFnQixNQUFBLEdBQVMsR0FBekIsR0FBa0M7aUJBQ2xELE1BQU0sQ0FBQyxZQUFQLEdBQXlCLFlBQUgsR0FBYyxJQUFBLEdBQU8sR0FBckIsR0FBOEI7UUFGaEM7TUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBO01BR3hCLE1BQU0sQ0FBQyxNQUFQLENBQUEsRUFQSDs7QUFTQSxXQUFPO0VBWkY7OztBQWNUOzs7Ozs7Ozs7O3lCQVNBLElBQUEsR0FBTSxTQUFDLElBQUQsRUFBTyxNQUFQLEVBQWUsSUFBZixFQUFxQixVQUFyQjtBQUNGLFFBQUE7SUFBQSxNQUFBLEdBQVMsZUFBZSxDQUFDLGNBQWhCLENBQStCLElBQS9CO0lBRVQsSUFBRyxNQUFNLENBQUMsT0FBVjtNQUNJLE1BQU0sQ0FBQyxNQUFQLEdBQW1CLGNBQUgsR0FBZ0IsTUFBQSxHQUFTLEdBQXpCLEdBQWtDO01BQ2xELE1BQU0sQ0FBQyxZQUFQLEdBQXlCLFlBQUgsR0FBYyxJQUFBLEdBQU8sR0FBckIsR0FBOEI7TUFDcEQsSUFBMkIsV0FBVyxDQUFDLFFBQVEsQ0FBQyxVQUFoRDtRQUFBLE1BQU0sQ0FBQyxJQUFQLENBQVksVUFBWixFQUFBO09BSEo7S0FBQSxNQUFBO01BS0csTUFBTSxDQUFDLGNBQVAsR0FBd0IsQ0FBQSxTQUFBLEtBQUE7ZUFBQSxTQUFDLE1BQUQ7VUFDcEIsTUFBTSxDQUFDLE1BQVAsR0FBbUIsY0FBSCxHQUFnQixNQUFBLEdBQVMsR0FBekIsR0FBa0M7VUFDbEQsTUFBTSxDQUFDLFlBQVAsR0FBeUIsWUFBSCxHQUFjLElBQUEsR0FBTyxHQUFyQixHQUE4QjtVQUNwRCxJQUEyQixXQUFXLENBQUMsUUFBUSxDQUFDLFVBQWhEO21CQUFBLE1BQU0sQ0FBQyxJQUFQLENBQVksVUFBWixFQUFBOztRQUhvQjtNQUFBLENBQUEsQ0FBQSxDQUFBLElBQUE7TUFJeEIsTUFBTSxDQUFDLE1BQVAsQ0FBQSxFQVRIOztBQVdBLFdBQU87RUFkTDs7O0FBZ0JOOzs7Ozs7eUJBS0EsYUFBQSxHQUFlLFNBQUE7QUFDWCxRQUFBO0FBQUE7U0FBQSx5QkFBQTs7O0FBQ0k7QUFBQTthQUFBLHFDQUFBOzs0Q0FDSSxTQUFTLENBQUUsSUFBWCxDQUFBO0FBREo7OztBQURKOztFQURXOzs7QUFLZjs7Ozs7Ozt5QkFNQSxTQUFBLEdBQVcsU0FBQyxJQUFEO0FBQ1AsUUFBQTtJQUFBLElBQUcsa0NBQUg7QUFDSTtBQUFBO1dBQUEscUNBQUE7O3FCQUNJLFNBQVMsQ0FBQyxJQUFWLENBQUE7QUFESjtxQkFESjs7RUFETzs7O0FBTVg7Ozs7Ozs7eUJBTUEsU0FBQSxHQUFXLFNBQUMsSUFBRDtXQUNQLElBQUMsQ0FBQSxTQUFELENBQVcsSUFBWDtFQURPOzs7QUFHWDs7Ozs7O3lCQUtBLGFBQUEsR0FBZSxTQUFBO0FBQ1gsUUFBQTtBQUFBO1NBQUEseUJBQUE7OztBQUNJO0FBQUE7YUFBQSxxQ0FBQTs7VUFDSSxJQUFvQixTQUFTLENBQUMsS0FBOUI7MEJBQUEsU0FBUyxDQUFDLElBQVYsQ0FBQSxHQUFBO1dBQUEsTUFBQTtrQ0FBQTs7QUFESjs7O0FBREo7O0VBRFc7OztBQUtmOzs7Ozs7Ozs7eUJBUUEsU0FBQSxHQUFXLFNBQUMsSUFBRCxFQUFPLE1BQVAsRUFBZSxJQUFmO0FBQ1AsUUFBQTtJQUFBLEtBQUEsR0FBUTtJQUNSLElBQUcsV0FBVyxDQUFDLFFBQVEsQ0FBQyxZQUFyQixJQUFzQyx1Q0FBbUIsQ0FBRSxRQUFRLENBQUMsdUJBQXZFO01BQ0ksS0FBQSxHQUFRLElBQUMsQ0FBQSxTQUFELGdCQUFXLElBQUksQ0FBRSxhQUFqQixFQUF1QixNQUFBLElBQVUsV0FBVyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsV0FBNUQsRUFBeUUsSUFBQSxJQUFRLFdBQVcsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLGlCQUE1RyxFQUErSCxLQUEvSCxFQUFtSSxJQUFuSSxFQURaOztBQUdBLFdBQU87RUFMQTs7O0FBT1g7Ozs7Ozs7Ozs7Ozt5QkFXQSxTQUFBLEdBQVcsU0FBQyxJQUFELEVBQU8sTUFBUCxFQUFlLElBQWYsRUFBcUIsV0FBckIsRUFBa0MsS0FBbEMsRUFBeUMsU0FBekM7QUFDUCxRQUFBO0lBQUEseUNBQWtCLENBQUUsUUFBUSxDQUFDLHNCQUE3QjtBQUFnRCxhQUFoRDs7SUFDQSxJQUFPLGNBQUosSUFBYSxDQUFDLENBQUMsS0FBRCxJQUFXLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxZQUFsQyxDQUFoQjtBQUFxRSxhQUFyRTs7SUFDQSxJQUFHLGlCQUFIO01BQ0ksTUFBQSxHQUFTLElBQUksQ0FBQztNQUNkLElBQUEsR0FBTyxJQUFJLENBQUM7TUFDWixJQUFBLEdBQU8sSUFBSSxDQUFDLEtBSGhCOztJQUtBLElBQUcsSUFBSSxDQUFDLE1BQUwsS0FBZSxDQUFsQjtBQUF5QixhQUF6Qjs7SUFFQSxJQUFHLFdBQUg7TUFDSSxJQUFDLENBQUEsU0FBRCxDQUFBLEVBREo7O0lBR0EsSUFBTyxrQ0FBUDtNQUNJLElBQUMsQ0FBQSxlQUFnQixDQUFBLElBQUEsQ0FBakIsR0FBeUIsR0FEN0I7O0lBR0EsTUFBQSxvQkFBUyxTQUFTO0lBQ2xCLE1BQUEsSUFBYSxLQUFILEdBQWMsSUFBQyxDQUFBLGtCQUFELEdBQXNCLEdBQXBDLEdBQTZDLElBQUMsQ0FBQSxrQkFBRCxHQUFzQjtJQUU3RSxTQUFBLEdBQVk7QUFDWjtBQUFBLFNBQUEsc0NBQUE7O01BQ0ksSUFBRyxDQUFJLENBQUMsQ0FBQyxTQUFUO1FBQ0ksU0FBQSxHQUFZO1FBQ1osSUFBRyxXQUFIO1VBQW9CLFNBQVMsQ0FBQyxLQUFWLEdBQWtCLENBQUEsU0FBQSxLQUFBO21CQUFBLFNBQUE7cUJBQUcsS0FBQyxDQUFBLFdBQUQsQ0FBYSxFQUFiO1lBQUg7VUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLEVBQXRDOztRQUNBLFNBQVMsQ0FBQyxLQUFWLEdBQWtCO1FBQ2xCLFNBQVMsQ0FBQyxNQUFWLEdBQW1CLE1BQUEsR0FBUztRQUM1QixTQUFTLENBQUMsWUFBVixHQUF5QixJQUFBLEdBQU87UUFDaEMsU0FBUyxDQUFDLElBQVYsR0FBaUI7UUFDakIsSUFBc0IsS0FBdEI7VUFBQSxJQUFDLENBQUEsS0FBRCxHQUFTLFVBQVQ7O1FBQ0EsU0FBUyxDQUFDLElBQVYsQ0FBQTtBQUNBLGNBVEo7O0FBREo7SUFZQSxJQUFPLGlCQUFQO01BQ0ksTUFBQSxHQUFTLGVBQWUsQ0FBQyxjQUFoQixDQUErQixlQUFBLEdBQWdCLElBQS9DO01BQ1QsSUFBRyxNQUFBLElBQVcsTUFBTSxDQUFDLE1BQXJCO1FBQ0ksSUFBRyxNQUFNLENBQUMsT0FBVjtVQUNJLFNBQUEsR0FBZ0IsSUFBQSxFQUFFLENBQUMsb0JBQUgsQ0FBd0IsTUFBeEIsRUFBZ0MsS0FBaEM7VUFDaEIsSUFBRyxXQUFIO1lBQW9CLFNBQVMsQ0FBQyxLQUFWLEdBQWtCLENBQUEsU0FBQSxLQUFBO3FCQUFBLFNBQUE7dUJBQUcsS0FBQyxDQUFBLFdBQUQsQ0FBYSxFQUFiO2NBQUg7WUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLEVBQXRDOztVQUNBLFNBQVMsQ0FBQyxNQUFWLEdBQW1CLE1BQUEsR0FBUztVQUM1QixTQUFTLENBQUMsWUFBVixHQUF5QixJQUFBLEdBQU87VUFDaEMsU0FBUyxDQUFDLEtBQVYsR0FBa0I7VUFDbEIsU0FBUyxDQUFDLElBQVYsR0FBaUI7VUFDakIsU0FBUyxDQUFDLElBQVYsQ0FBQTtVQUNBLElBQXNCLEtBQXRCO1lBQUEsSUFBQyxDQUFBLEtBQUQsR0FBUyxVQUFUOztVQUNBLElBQUMsQ0FBQSxlQUFnQixDQUFBLElBQUEsQ0FBSyxDQUFDLElBQXZCLENBQTRCLFNBQTVCLEVBVEo7U0FBQSxNQUFBO1VBV0ksTUFBTSxDQUFDLElBQVAsR0FBYztVQUNkLE1BQU0sQ0FBQyxjQUFQLEdBQXdCLENBQUEsU0FBQSxLQUFBO21CQUFBLFNBQUMsTUFBRDtjQUNwQixTQUFBLEdBQWdCLElBQUEsRUFBRSxDQUFDLG9CQUFILENBQXdCLE1BQXhCLEVBQWdDLEtBQWhDO2NBQ2hCLElBQUcsV0FBSDtnQkFBb0IsU0FBUyxDQUFDLEtBQVYsR0FBa0IsU0FBQTt5QkFBRyxLQUFDLENBQUEsV0FBRCxDQUFhLEVBQWI7Z0JBQUgsRUFBdEM7O2NBQ0EsU0FBUyxDQUFDLEtBQVYsR0FBa0I7Y0FDbEIsU0FBUyxDQUFDLE1BQVYsR0FBbUIsTUFBQSxHQUFTO2NBQzVCLFNBQVMsQ0FBQyxZQUFWLEdBQXlCLElBQUEsR0FBTztjQUNoQyxTQUFTLENBQUMsSUFBVixHQUFpQjtjQUNqQixJQUFzQixLQUF0QjtnQkFBQSxLQUFDLENBQUEsS0FBRCxHQUFTLFVBQVQ7O2NBQ0EsU0FBUyxDQUFDLElBQVYsQ0FBQTtxQkFDQSxLQUFDLENBQUEsZUFBZ0IsQ0FBQSxNQUFNLENBQUMsSUFBUCxDQUFZLENBQUMsSUFBOUIsQ0FBbUMsU0FBbkM7WUFUb0I7VUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBO1VBVXhCLE1BQU0sQ0FBQyxNQUFQLENBQUEsRUF0Qko7U0FESjtPQUZKOztBQTJCQSxXQUFPO0VBM0RBOzs7QUE2RFg7Ozs7Ozs7Ozs7Ozs7eUJBWUEsZUFBQSxHQUFpQixTQUFDLEtBQUQsRUFBUSxRQUFSLEVBQWtCLEtBQWxCLEVBQXlCLFFBQXpCLEVBQW1DLFNBQW5DO0FBQ2IsUUFBQTtJQUFBLHlDQUF5QixDQUFFLFFBQVEsQ0FBQyxzQkFBcEM7QUFBQSxhQUFBOztJQUNBLEtBQUEsbUJBQVEsUUFBUTtJQUVoQixNQUFBLEdBQVksb0JBQUgsR0FBc0IsS0FBSyxDQUFDLE1BQTVCLEdBQXdDO0lBQ2pELE1BQUEsR0FBUyxNQUFBLEdBQVMsQ0FBQyxJQUFDLENBQUEsa0JBQUQsR0FBc0IsR0FBdkI7SUFDbEIsSUFBQyxDQUFBLFdBQUQsR0FBZTtJQUNmLElBQUMsQ0FBQSxZQUFELENBQWMsS0FBZDtJQUVBLElBQUcsb0JBQUEsSUFBZ0IsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFYLEdBQW9CLENBQXZDO01BQ0ksV0FBQSxHQUFjLElBQUMsQ0FBQSxJQUFELENBQU0sY0FBQSxHQUFlLEtBQUssQ0FBQyxJQUEzQixFQUFtQyxNQUFuQyxFQUEyQyxLQUFLLENBQUMsSUFBakQ7TUFDZCxXQUFXLENBQUMsSUFBWixHQUFtQjtNQUNuQixXQUFXLENBQUMsTUFBWixHQUFxQjtNQUNyQixXQUFXLENBQUMsUUFBWixHQUF1QixJQUFJLENBQUMsS0FBTCxDQUFXLFdBQVcsQ0FBQyxRQUFaLEdBQXVCLElBQXZCLEdBQThCLElBQXpDO01BQ3ZCLFdBQVcsQ0FBQyxVQUFVLENBQUMsUUFBdkIsR0FBa0M7TUFDbEMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxRQUF2QixHQUFrQztNQUNsQyxJQUFHLFNBQVMsQ0FBQyxHQUFWLEtBQWlCLENBQXBCO1FBQ0ksV0FBVyxDQUFDLFVBQVUsQ0FBQyxTQUF2QixHQUFtQztVQUFFLEtBQUEsRUFBTyxTQUFTLENBQUMsS0FBbkI7VUFBMEIsR0FBQSxFQUFLLFdBQVcsQ0FBQyxRQUEzQztVQUR2QztPQUFBLE1BQUE7UUFHSSxXQUFXLENBQUMsVUFBVSxDQUFDLFNBQXZCLEdBQW1DLFVBSHZDOztNQUlBLFdBQVcsQ0FBQyxVQUFVLENBQUMsUUFBdkIsR0FBa0M7TUFFbEMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxVQUF2QixHQUFvQyxJQUFJLENBQUMsS0FBTCxDQUFXLFdBQVcsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLEtBQWpDLEdBQXlDLElBQUksQ0FBQyxNQUFMLENBQUEsQ0FBQSxHQUFnQixDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLEdBQWpDLEdBQXVDLFdBQVcsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLEtBQXpFLENBQXBFO01BRXBDLElBQW1DLENBQUksSUFBQyxDQUFBLFlBQVksQ0FBQyxRQUFkLENBQXVCLFdBQXZCLENBQXZDO1FBQUEsSUFBQyxDQUFBLFlBQVksQ0FBQyxJQUFkLENBQW1CLFdBQW5CLEVBQUE7O01BQ0EsSUFBQyxDQUFBLG1CQUFvQixDQUFBLEtBQUEsQ0FBckIsR0FBOEI7YUFDOUIsSUFBQyxDQUFBLFdBQVksQ0FBQSxLQUFBLENBQWIsR0FBc0I7UUFBQSxJQUFBLEVBQU0sS0FBSyxDQUFDLElBQVo7UUFBa0IsSUFBQSxFQUFNLEtBQUssQ0FBQyxXQUE5QjtRQUEyQyxNQUFBLEVBQVEsS0FBSyxDQUFDLE1BQXpEO1FBQWlFLElBQUEsRUFBTSxLQUFLLENBQUMsWUFBN0U7UUFBMkYsVUFBQSxFQUFZLFFBQXZHO1FBQWlILFVBQUEsRUFBWSxXQUFXLENBQUMsVUFBekk7UUFqQjFCOztFQVRhOzs7QUE0QmpCOzs7Ozs7Ozs7Ozs7eUJBV0EsU0FBQSxHQUFXLFNBQUMsSUFBRCxFQUFPLE1BQVAsRUFBZSxJQUFmLEVBQXFCLFVBQXJCLEVBQWlDLEtBQWpDLEVBQXdDLFNBQXhDO0FBQ1AsUUFBQTtJQUFBLHlDQUF5QixDQUFFLFFBQVEsQ0FBQyxzQkFBcEM7QUFBQSxhQUFBOzs7TUFDQSxZQUFhOztJQUNiLElBQUcsY0FBQSxJQUFVLG1CQUFiO01BQ0ksS0FBQSxHQUFXLGFBQUgsR0FBZSxLQUFmLEdBQTBCLElBQUEsSUFBUTtNQUMxQyxVQUFBLEdBQWE7TUFDYixNQUFBLEdBQVMsSUFBSSxDQUFDO01BQ2QsSUFBQSxHQUFPLElBQUksQ0FBQztNQUNaLElBQUEsR0FBTyxJQUFJLENBQUMsS0FMaEI7S0FBQSxNQUFBO01BT0ksS0FBQSxtQkFBUSxRQUFRLEVBUHBCOztJQVNBLElBQUMsQ0FBQSxZQUFELENBQWMsS0FBZDtJQUNBLElBQUMsQ0FBQSxXQUFZLENBQUEsS0FBQSxDQUFiLEdBQXNCO01BQUEsSUFBQSxFQUFNLElBQU47TUFBWSxNQUFBLEVBQVEsTUFBcEI7TUFBNEIsSUFBQSxFQUFNLElBQWxDO01BQXdDLFVBQUEsRUFBWSxVQUFwRDtNQUFnRSxPQUFBLEVBQVMsSUFBekU7O0lBRXRCLE1BQUEsR0FBWSxjQUFILEdBQWdCLE1BQWhCLEdBQTRCO0lBQ3JDLE1BQUEsR0FBUyxNQUFBLEdBQVMsQ0FBQyxJQUFDLENBQUEsa0JBQUQsR0FBc0IsR0FBdkI7SUFDbEIsSUFBQyxDQUFBLFdBQUQsR0FBZTtJQUdmLElBQUcsY0FBQSxJQUFVLElBQUksQ0FBQyxNQUFMLEdBQWMsQ0FBM0I7TUFDSSxJQUFDLENBQUEsS0FBRCxHQUFTO1FBQUEsSUFBQSxFQUFNLElBQU47O01BQ1QsV0FBQSxHQUFjLElBQUMsQ0FBQSxJQUFELENBQU0sY0FBQSxHQUFlLElBQXJCLEVBQTZCLE1BQTdCLEVBQXFDLElBQXJDLEVBQTJDLFVBQTNDO01BQ2QsV0FBVyxDQUFDLElBQVosR0FBbUI7TUFDbkIsSUFBbUMsQ0FBSSxJQUFDLENBQUEsWUFBWSxDQUFDLFFBQWQsQ0FBdUIsV0FBdkIsQ0FBdkM7UUFBQSxJQUFDLENBQUEsWUFBWSxDQUFDLElBQWQsQ0FBbUIsV0FBbkIsRUFBQTs7TUFDQSxJQUFDLENBQUEsbUJBQW9CLENBQUEsS0FBQSxDQUFyQixHQUE4QixZQUxsQzs7QUFPQSxXQUFPO0VBM0JBOzs7QUE2Qlg7Ozs7Ozs7O3lCQU9BLFdBQUEsR0FBYSxTQUFDLFVBQUQsRUFBYSxLQUFiO0FBQ1QsUUFBQTtJQUFBLEtBQUEsbUJBQVEsUUFBUTtJQUNoQixJQUFHLHlDQUFBLElBQWlDLENBQUksSUFBQyxDQUFBLG1CQUFvQixDQUFBLEtBQUEsQ0FBTSxDQUFDLFNBQXBFO01BQ0ksSUFBQyxDQUFBLG1CQUFvQixDQUFBLEtBQUEsQ0FBTSxDQUFDLE1BQTVCLENBQW1DLFVBQW5DOzBEQUNtQixDQUFFLE9BQXJCLEdBQStCLGNBRm5DOztFQUZTOzs7QUFNYjs7Ozs7Ozs7eUJBT0EsU0FBQSxHQUFXLFNBQUMsV0FBRCxFQUFjLEtBQWQ7QUFDUCxRQUFBO0lBQUEsS0FBQSxtQkFBUSxRQUFROztTQUNXLENBQUUsSUFBN0IsQ0FBa0MsV0FBbEM7OztVQUMyQixDQUFFLFVBQTdCLEdBQTBDOzs7VUFDdkIsQ0FBRSxPQUFyQixHQUErQjs7V0FDL0IsSUFBQyxDQUFBLEtBQUQsR0FBUztFQUxGOzs7QUFPWDs7Ozs7Ozt5QkFNQSxZQUFBLEdBQWMsU0FBQyxXQUFEO0FBQ1YsUUFBQTtBQUFBO0FBQUEsU0FBQSxxQ0FBQTs7TUFDSSxJQUFHLGNBQUg7UUFDSSxNQUFNLENBQUMsSUFBUCxDQUFZLFdBQVo7UUFDQSxNQUFNLENBQUMsVUFBUCxHQUFvQixHQUZ4Qjs7QUFESjtXQUlBLElBQUMsQ0FBQSxLQUFELEdBQVM7RUFMQzs7eUJBUWQsT0FBQSxHQUFTLFNBQUMsT0FBRDtBQUNMLFFBQUE7SUFBQSxJQUFBLEdBQU8sT0FBTyxDQUFDLFNBQVMsQ0FBQyxNQUFsQixDQUF5QixTQUFDLENBQUQ7YUFBTyxDQUFDLENBQUM7SUFBVCxDQUF6QjtBQUNQO0FBQUE7U0FBQSxxREFBQTs7TUFDSSxJQUFHLE1BQUEsSUFBVyxJQUFJLENBQUMsT0FBTCxDQUFhLE1BQWIsQ0FBQSxLQUF3QixDQUFDLENBQXZDO1FBQ0ksTUFBTSxDQUFDLE9BQVAsQ0FBQTtRQUVBLElBQUMsQ0FBQSxZQUFZLENBQUMsTUFBZCxDQUFxQixNQUFyQjtRQUNBLElBQUMsQ0FBQSxtQkFBb0IsQ0FBQSxLQUFBLENBQXJCLEdBQThCO3FCQUM5QixJQUFDLENBQUEsV0FBWSxDQUFBLEtBQUEsQ0FBYixHQUFzQixNQUwxQjtPQUFBLE1BQUE7NkJBQUE7O0FBREo7O0VBRks7OztBQVVUOzs7Ozs7O3lCQU1BLFlBQUEsR0FBYyxTQUFDLEtBQUQ7SUFDVixLQUFBLG1CQUFRLFFBQVE7SUFFaEIsSUFBQyxDQUFBLFNBQUQsQ0FBVyxDQUFYLEVBQWMsS0FBZDtJQUVBLElBQUMsQ0FBQSxZQUFZLENBQUMsTUFBZCxDQUFxQixJQUFDLENBQUEsbUJBQW9CLENBQUEsS0FBQSxDQUExQztJQUNBLElBQUMsQ0FBQSxtQkFBb0IsQ0FBQSxLQUFBLENBQXJCLEdBQThCO1dBQzlCLElBQUMsQ0FBQSxXQUFZLENBQUEsS0FBQSxDQUFiLEdBQXNCO0VBUFo7Ozs7OztBQVNsQixNQUFNLENBQUMsWUFBUCxHQUEwQixJQUFBLFlBQUEsQ0FBQTs7QUFDMUIsRUFBRSxDQUFDLFlBQUgsR0FBa0IiLCJzb3VyY2VzQ29udGVudCI6WyIjID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiNcbiMgICBTY3JpcHQ6IEF1ZGlvTWFuYWdlclxuI1xuIyAgICQkQ09QWVJJR0hUJCRcbiNcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuY2xhc3MgQXVkaW9NYW5hZ2VyXG4gICAgIyMjKlxuICAgICogTWFuYWdlcyB0aGUgYXVkaW8gcGxheWJhY2sgb2YgdGhlIGdhbWUuIFxuICAgICpcbiAgICAqIEBtb2R1bGUgZ3NcbiAgICAqIEBjbGFzcyBBdWRpb01hbmFnZXJcbiAgICAqIEBtZW1iZXJvZiBnc1xuICAgICogQGNvbnN0cnVjdG9yXG4gICAgIyMjXG4gICAgY29uc3RydWN0b3I6IC0+XG4gICAgICAgICMjIypcbiAgICAgICAgKiBTdG9yZXMgYWxsIGF1ZGlvIGJ1ZmZlcnMuXG4gICAgICAgICogQHByb3BlcnR5IGJ1ZmZlcnNcbiAgICAgICAgKiBAdHlwZSBncy5BdWRpb0J1ZmZlcltdXG4gICAgICAgICogQHByb3RlY3RlZFxuICAgICAgICAjIyMgIFxuICAgICAgICBAYXVkaW9CdWZmZXJzID0gW11cbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBTdG9yZXMgYWxsIGF1ZGlvIGJ1ZmZlcnMgYnkgbGF5ZXIuXG4gICAgICAgICogQHByb3BlcnR5IGJ1ZmZlcnNcbiAgICAgICAgKiBAdHlwZSBncy5BdWRpb0J1ZmZlcltdXG4gICAgICAgICogQHByb3RlY3RlZFxuICAgICAgICAjIyMgIFxuICAgICAgICBAYXVkaW9CdWZmZXJzQnlMYXllciA9IFtdXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogU3RvcmVzIGFsbCBhdWRpbyBidWZmZXIgcmVmZXJlbmNlcyBmb3Igc291bmRzLlxuICAgICAgICAqIEBwcm9wZXJ0eSBzb3VuZFJlZmVyZW5jZXNcbiAgICAgICAgKiBAdHlwZSBncy5BdWRpb0J1ZmZlclJlZmVyZW5jZVtdXG4gICAgICAgICogQHByb3RlY3RlZFxuICAgICAgICAjIyMgIFxuICAgICAgICBAc291bmRSZWZlcmVuY2VzID0ge31cbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBDdXJyZW50IE11c2ljIChMYXllciAwKVxuICAgICAgICAqIEBwcm9wZXJ0eSBtdXNpY1xuICAgICAgICAqIEB0eXBlIE9iamVjdFxuICAgICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgICAgIyMjIFxuICAgICAgICBAbXVzaWMgPSBudWxsXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogQ3VycmVudCBtdXNpYyB2b2x1bWUuXG4gICAgICAgICogQHByb3BlcnR5IG11c2ljVm9sdW1lXG4gICAgICAgICogQHR5cGUgbnVtYmVyXG4gICAgICAgICogQHByb3RlY3RlZFxuICAgICAgICAjIyMgXG4gICAgICAgIEBtdXNpY1ZvbHVtZSA9IDEwMFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEN1cnJlbnQgc291bmQgdm9sdW1lLlxuICAgICAgICAqIEBwcm9wZXJ0eSBzb3VuZFZvbHVtZVxuICAgICAgICAqIEB0eXBlIG51bWJlclxuICAgICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgICAgIyMjIFxuICAgICAgICBAc291bmRWb2x1bWUgPSAxMDBcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBDdXJyZW50IHZvaWNlIHZvbHVtZS5cbiAgICAgICAgKiBAcHJvcGVydHkgdm9pY2VWb2x1bWVcbiAgICAgICAgKiBAdHlwZSBudW1iZXJcbiAgICAgICAgKiBAcHJvdGVjdGVkXG4gICAgICAgICMjIyBcbiAgICAgICAgQHZvaWNlVm9sdW1lID0gMTAwXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogR2VuZXJhbCBtdXNpYyB2b2x1bWVcbiAgICAgICAgKiBAcHJvcGVydHkgZ2VuZXJhbE11c2ljVm9sdW1lXG4gICAgICAgICogQHR5cGUgbnVtYmVyXG4gICAgICAgICogQHByb3RlY3RlZFxuICAgICAgICAjIyMgXG4gICAgICAgIEBnZW5lcmFsTXVzaWNWb2x1bWUgPSAxMDBcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBHZW5lcmFsIHNvdW5kIHZvbHVtZVxuICAgICAgICAqIEBwcm9wZXJ0eSBnZW5lcmFsU291bmRWb2x1bWVcbiAgICAgICAgKiBAdHlwZSBudW1iZXJcbiAgICAgICAgKiBAcHJvdGVjdGVkXG4gICAgICAgICMjIyBcbiAgICAgICAgQGdlbmVyYWxTb3VuZFZvbHVtZSA9IDEwMFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEdlbmVyYWwgdm9pY2Ugdm9sdW1lXG4gICAgICAgICogQHByb3BlcnR5IGdlbmVyYWxWb2ljZVZvbHVtZVxuICAgICAgICAqIEB0eXBlIG51bWJlclxuICAgICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgICAgIyMjIFxuICAgICAgICBAZ2VuZXJhbFZvaWNlVm9sdW1lID0gMTAwXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogU3RvcmVzIGF1ZGlvIGxheWVyIGluZm8tZGF0YSBmb3IgZWFjaCBsYXllci5cbiAgICAgICAgKiBAcHJvcGVydHkgYXVkaW9MYXllcnNcbiAgICAgICAgKiBAdHlwZSBncy5BdWRpb0xheWVySW5mb1tdXG4gICAgICAgICogQHByb3RlY3RlZFxuICAgICAgICAjIyMgXG4gICAgICAgIEBhdWRpb0xheWVycyA9IFtdXG4gICAgICBcbiAgICAjIyMqXG4gICAgKiBSZXN0b3JlcyBhdWRpby1wbGF5YmFjayBmcm9tIGEgc3BlY2lmaWVkIGFycmF5IG9mIGF1ZGlvIGxheWVycy5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHJlc3RvcmVcbiAgICAqIEBwYXJhbSB7Z3MuQXVkaW9MYXllckluZm9bXX0gbGF5ZXJzIC0gQW4gYXJyYXkgb2YgYXVkaW8gbGF5ZXIgaW5mbyBvYmplY3RzLlxuICAgICMjIyAgXG4gICAgcmVzdG9yZTogKGxheWVycykgLT5cbiAgICAgICAgQGF1ZGlvTGF5ZXJzID0gbGF5ZXJzXG4gICAgICAgIFxuICAgICAgICBmb3IgbGF5ZXIsIGkgaW4gbGF5ZXJzXG4gICAgICAgICAgICBpZiBsYXllciBhbmQgbGF5ZXIucGxheWluZ1xuICAgICAgICAgICAgICAgIGlmIGxheWVyLmN1c3RvbURhdGFcbiAgICAgICAgICAgICAgICAgICAgQHBsYXlNdXNpY1JhbmRvbShsYXllciwgbGF5ZXIuY3VzdG9tRGF0YS5mYWRlVGltZSwgaSwgbGF5ZXIuY3VzdG9tRGF0YS5wbGF5VGltZSwgbGF5ZXIuY3VzdG9tRGF0YS5wbGF5UmFuZ2UpXG4gICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICBAcGxheU11c2ljKGxheWVyLCBsYXllci5mYWRlSW5UaW1lLCBpKVxuICAgICBcbiAgICAjIyMqXG4gICAgKiBMb2FkcyB0aGUgc3BlY2lmaWVkIG11c2ljLlxuICAgICpcbiAgICAqIEBtZXRob2QgbG9hZE11c2ljXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBtdXNpYyB0byBsb2FkLlxuICAgICMjIyAgICBcbiAgICBsb2FkTXVzaWM6IChuYW1lKSAtPiBcbiAgICAgICAgbmFtZSA9IGlmIG5hbWU/IHRoZW4gKG5hbWUubmFtZSB8fCBuYW1lKSBlbHNlIG5hbWVcbiAgICAgICAgaWYgbmFtZSBhbmQgbmFtZS5sZW5ndGggPiAwXG4gICAgICAgICAgICBSZXNvdXJjZU1hbmFnZXIuZ2V0QXVkaW9TdHJlYW0oXCJBdWRpby9NdXNpYy8je25hbWV9XCIpXG4gICAgIFxuICAgICMjIypcbiAgICAqIExvYWRzIHRoZSBzcGVjaWZpZWQgc291bmQuXG4gICAgKlxuICAgICogQG1ldGhvZCBsb2FkU291bmRcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHNvdW5kIHRvIGxvYWQuXG4gICAgIyMjICAgICAgICAgICBcbiAgICBsb2FkU291bmQ6IChuYW1lKSAtPiBcbiAgICAgICAgbmFtZSA9IGlmIG5hbWU/IHRoZW4gbmFtZS5uYW1lIHx8IG5hbWUgZWxzZSBuYW1lXG4gICAgICAgIGlmIG5hbWUgYW5kIG5hbWUubGVuZ3RoID4gMFxuICAgICAgICAgICAgUmVzb3VyY2VNYW5hZ2VyLmdldEF1ZGlvQnVmZmVyKFwiQXVkaW8vU291bmRzLyN7bmFtZX1cIilcbiAgICBcbiAgICAjIyMqXG4gICAgKiBVcGRhdGVzIGEgcmFuZG9tbHkgcGxheWVkIGF1ZGlvIGJ1ZmZlci5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHVwZGF0ZVJhbmRvbUF1ZGlvXG4gICAgKiBAcGFyYW0ge2dzLkF1ZGlvQnVmZmVyfSBidWZmZXIgLSBUaGUgYXVkaW8gYnVmZmVyIHRvIHVwZGF0ZS5cbiAgICAqIEBwcm90ZWN0ZWRcbiAgICAjIyMgICAgXG4gICAgIyBGSVhNRTogUmVmYWN0b3JpbmcgbmVjZXNzYXJ5LiAgICAgIFxuICAgIHVwZGF0ZVJhbmRvbUF1ZGlvOiAoYnVmZmVyKSAtPlxuICAgICAgICBpZiBidWZmZXIuY3VzdG9tRGF0YS5zdGFydFRpbWVyID4gMFxuICAgICAgICAgICAgYnVmZmVyLmN1c3RvbURhdGEuc3RhcnRUaW1lci0tXG4gICAgICAgICAgICBpZiBidWZmZXIuY3VzdG9tRGF0YS5zdGFydFRpbWVyIDw9IDBcbiAgICAgICAgICAgICAgICBidWZmZXIuZmFkZUluVm9sdW1lID0gMS4wIC8gKGJ1ZmZlci5jdXN0b21EYXRhLmZhZGVUaW1lfHwxKVxuICAgICAgICAgICAgICAgIGJ1ZmZlci5mYWRlSW5UaW1lID0gYnVmZmVyLmN1c3RvbURhdGEuZmFkZVRpbWV8fDFcbiAgICAgICAgICAgICAgICBidWZmZXIuZmFkZU91dFRpbWUgPSBidWZmZXIuY3VzdG9tRGF0YS5mYWRlVGltZXx8MVxuICAgICAgICAgICAgICAgIGJ1ZmZlci5wbGF5VGltZSA9IGJ1ZmZlci5jdXN0b21EYXRhLnBsYXlUaW1lLm1pbiArIE1hdGgucmFuZG9tKCkgKiAoYnVmZmVyLmN1c3RvbURhdGEucGxheVRpbWUubWF4IC0gYnVmZmVyLmN1c3RvbURhdGEucGxheVRpbWUubWluKVxuICAgICAgICAgICAgICAgIGN1cnJlbnRUaW1lID0gYnVmZmVyLmN1cnJlbnRUaW1lICMgLSBidWZmZXIuc3RhcnRUaW1lXG4gICAgICAgICAgICAgICAgdGltZUxlZnQgPSBidWZmZXIuZHVyYXRpb24gLSBjdXJyZW50VGltZVxuICAgICAgICAgICAgICAgIGJ1ZmZlci5wbGF5VGltZSA9IE1hdGgubWluKHRpbWVMZWZ0ICogMTAwMCAvIDE2LjYsIGJ1ZmZlci5wbGF5VGltZSlcbiAgICBcbiAgICAgICAgICAgICAgICBidWZmZXIuY3VzdG9tRGF0YS5zdGFydFRpbWVyID0gYnVmZmVyLnBsYXlUaW1lICsgYnVmZmVyLmN1c3RvbURhdGEucGxheVJhbmdlLnN0YXJ0ICsgTWF0aC5yYW5kb20oKSAqIChidWZmZXIuY3VzdG9tRGF0YS5wbGF5UmFuZ2UuZW5kIC0gYnVmZmVyLmN1c3RvbURhdGEucGxheVJhbmdlLnN0YXJ0KVxuICAgIFxuICAgICMjIypcbiAgICAqIFVwZGF0ZXMgYWxsIGF1ZGlvLWJ1ZmZlcnMgZGVwZW5kaW5nIG9uIHRoZSBwbGF5LXR5cGUuXG4gICAgKlxuICAgICogQG1ldGhvZCB1cGRhdGVBdWRpb0J1ZmZlcnNcbiAgICAqIEBwcm90ZWN0ZWRcbiAgICAjIyMgICBcbiAgICB1cGRhdGVBdWRpb0J1ZmZlcnM6IC0+XG4gICAgICAgIGZvciBidWZmZXIgaW4gQGF1ZGlvQnVmZmVyc1xuICAgICAgICAgICAgaWYgYnVmZmVyP1xuICAgICAgICAgICAgICAgIGlmIGJ1ZmZlci5jdXN0b21EYXRhLnBsYXlUeXBlID09IDFcbiAgICAgICAgICAgICAgICAgICAgQHVwZGF0ZVJhbmRvbUF1ZGlvKGJ1ZmZlcilcbiAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgaWYgR2FtZU1hbmFnZXIuc2V0dGluZ3MuYmdtVm9sdW1lICE9IEBnZW5lcmFsTXVzaWNWb2x1bWVcbiAgICAgICAgICAgICAgICAgICAgYnVmZmVyLnZvbHVtZSA9IChAbXVzaWNWb2x1bWUgKiBHYW1lTWFuYWdlci5zZXR0aW5ncy5iZ21Wb2x1bWUgLyAxMDApIC8gMTAwXG4gICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIGJ1ZmZlci51cGRhdGUoKVxuICAgICAgICBpZiBHYW1lTWFuYWdlci5zZXR0aW5ncy5iZ21Wb2x1bWUgIT0gQGdlbmVyYWxNdXNpY1ZvbHVtZVxuICAgICAgICAgICAgQGdlbmVyYWxNdXNpY1ZvbHVtZSA9IEdhbWVNYW5hZ2VyLnNldHRpbmdzLmJnbVZvbHVtZVxuICAgIFxuICAgIFxuICAgICMjIypcbiAgICAqIFVwZGF0ZXMgYWxsIGF1ZGlvLWJ1ZmZlcnMgZGVwZW5kaW5nIG9uIHRoZSBwbGF5LXR5cGUuXG4gICAgKlxuICAgICogQG1ldGhvZCB1cGRhdGVBdWRpb0J1ZmZlcnNcbiAgICAqIEBwcm90ZWN0ZWRcbiAgICAjIyMgICAgICAgICAgICAgXG4gICAgdXBkYXRlR2VuZXJhbFZvbHVtZTogLT5cbiAgICAgICAgaWYgR2FtZU1hbmFnZXIuc2V0dGluZ3Muc2VWb2x1bWUgIT0gQGdlbmVyYWxTb3VuZFZvbHVtZSBvciBHYW1lTWFuYWdlci5zZXR0aW5ncy52b2ljZVZvbHVtZSAhPSBAZ2VuZXJhbFZvaWNlVm9sdW1lXG4gICAgICAgICAgICBAZ2VuZXJhbFNvdW5kVm9sdW1lID0gR2FtZU1hbmFnZXIuc2V0dGluZ3Muc2VWb2x1bWVcbiAgICAgICAgICAgIEBnZW5lcmFsVm9pY2VWb2x1bWUgPSBHYW1lTWFuYWdlci5zZXR0aW5ncy52b2ljZVZvbHVtZVxuICAgICAgICAgICAgZm9yIGsgb2YgQHNvdW5kUmVmZXJlbmNlc1xuICAgICAgICAgICAgICAgIGZvciByZWZlcmVuY2UgaW4gQHNvdW5kUmVmZXJlbmNlc1trXVxuICAgICAgICAgICAgICAgICAgICBpZiByZWZlcmVuY2Uudm9pY2VcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZmVyZW5jZS52b2x1bWUgPSAoQHZvaWNlVm9sdW1lICogR2FtZU1hbmFnZXIuc2V0dGluZ3Mudm9pY2VWb2x1bWUgLyAxMDApIC8gMTAwXG4gICAgICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZmVyZW5jZS52b2x1bWUgPSAoQHNvdW5kVm9sdW1lICogR2FtZU1hbmFnZXIuc2V0dGluZ3Muc2VWb2x1bWUgLyAxMDApIC8gMTAwXG4gICAgIyMjKlxuICAgICogVXBkYXRlcyB0aGUgYXVkaW8tcGxheWJhY2suXG4gICAgKlxuICAgICogQG1ldGhvZCB1cGRhdGVcbiAgICAjIyMgICAgICAgICAgICAgICAgXG4gICAgdXBkYXRlOiAtPlxuICAgICAgICBAdXBkYXRlQXVkaW9CdWZmZXJzKClcbiAgICAgICAgQHVwZGF0ZUdlbmVyYWxWb2x1bWUoKVxuICAgICBcbiAgICAjIyMqXG4gICAgKiBDaGFuZ2VzIHRoZSBjdXJyZW50IG11c2ljIHRvIHRoZSBzcGVjaWZpZWQgb25lLlxuICAgICpcbiAgICAqIEBtZXRob2QgY2hhbmdlTXVzaWNcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBtdXNpYyAtIFRoZSBtdXNpYyB0byBwbGF5LiBJZiA8Yj5udWxsPC9iPiB0aGUgY3VycmVudCBtdXNpYyB3aWxsIHN0b3AgcGxheWluZy5cbiAgICAjIyMgICAgICAgICAgIFxuICAgIGNoYW5nZU11c2ljOiAobXVzaWMpIC0+XG4gICAgICAgIGlmIG11c2ljPyBhbmQgbXVzaWMubmFtZT9cbiAgICAgICAgICAgIGlmIEBtdXNpYz8gYW5kIEBtdXNpYy5uYW1lICE9IG11c2ljLm5hbWVcbiAgICAgICAgICAgICAgICBAcGxheU11c2ljKG11c2ljKVxuICAgICAgICAgICAgZWxzZSBpZiBub3QgQG11c2ljP1xuICAgICAgICAgICAgICAgIEBwbGF5TXVzaWMobXVzaWMpXG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIEBzdG9wTXVzaWMoKVxuICAgICBcbiAgICAjIEZJWE1FOiBJcyB0aGlzIHN0aWxsIHVzZWQ/XG4gICAgIyMjKlxuICAgICogUHJlcGFyZXMuIFxuICAgICpcbiAgICAqIEBtZXRob2QgcHJlcGFyZVxuICAgICogQHBhcmFtIHtPYmplY3R9IG11c2ljIC0gVGhlIG11c2ljIHRvIHBsYXkuIElmIDxiPm51bGw8L2I+IHRoZSBjdXJyZW50IG11c2ljIHdpbGwgc3RvcCBwbGF5aW5nLlxuICAgICMjIyAgICAgICAgICAgIFxuICAgIHByZXBhcmU6IChwYXRoLCB2b2x1bWUsIHJhdGUpIC0+IFxuICAgICAgICBidWZmZXIgPSBSZXNvdXJjZU1hbmFnZXIuZ2V0QXVkaW9CdWZmZXIocGF0aClcbiAgICAgICAgXG4gICAgICAgIGlmIGJ1ZmZlci5kZWNvZGVkXG4gICAgICAgICAgICBidWZmZXIudm9sdW1lID0gaWYgdm9sdW1lPyB0aGVuIHZvbHVtZSAvIDEwMCBlbHNlIDEuMFxuICAgICAgICAgICAgYnVmZmVyLnBsYXliYWNrUmF0ZSA9IGlmIHJhdGU/IHRoZW4gcmF0ZSAvIDEwMCBlbHNlIDEuMFxuICAgICAgICBlbHNlXG4gICAgICAgICAgIGJ1ZmZlci5vbkZpbmlzaERlY29kZSA9IChzb3VyY2UpID0+IFxuICAgICAgICAgICAgICAgc291cmNlLnZvbHVtZSA9IGlmIHZvbHVtZT8gdGhlbiB2b2x1bWUgLyAxMDAgZWxzZSAxLjBcbiAgICAgICAgICAgICAgIHNvdXJjZS5wbGF5YmFja1JhdGUgPSBpZiByYXRlPyB0aGVuIHJhdGUgLyAxMDAgZWxzZSAxLjBcbiAgICAgICAgICAgYnVmZmVyLmRlY29kZSgpXG4gICAgICAgICAgIFxuICAgICAgICByZXR1cm4gYnVmZmVyXG4gICAgICAgIFxuICAgICMjIypcbiAgICAqIFBsYXlzIGFuIGF1ZGlvIHJlc291cmNlLlxuICAgICpcbiAgICAqIEBtZXRob2QgcGxheVxuICAgICogQHBhcmFtIHtTdHJpbmd9IHBhdGggLSBUaGUgcGF0aCB0byB0aGUgYXVkaW8gcmVzb3VyY2UuXG4gICAgKiBAcGFyYW0ge251bWJlcn0gdm9sdW1lIC0gVGhlIHZvbHVtZS5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSByYXRlIC0gVGhlIHBsYXliYWNrIHJhdGUuXG4gICAgKiBAcGFyYW0ge251bWJlcn0gZmFkZUluVGltZSAtIFRoZSBmYWRlLWluIHRpbWUgaW4gZnJhbWVzLlxuICAgICMjIyAgICAgXG4gICAgcGxheTogKHBhdGgsIHZvbHVtZSwgcmF0ZSwgZmFkZUluVGltZSkgLT5cbiAgICAgICAgYnVmZmVyID0gUmVzb3VyY2VNYW5hZ2VyLmdldEF1ZGlvU3RyZWFtKHBhdGgpXG4gICAgXG4gICAgICAgIGlmIGJ1ZmZlci5kZWNvZGVkXG4gICAgICAgICAgICBidWZmZXIudm9sdW1lID0gaWYgdm9sdW1lPyB0aGVuIHZvbHVtZSAvIDEwMCBlbHNlIDEuMFxuICAgICAgICAgICAgYnVmZmVyLnBsYXliYWNrUmF0ZSA9IGlmIHJhdGU/IHRoZW4gcmF0ZSAvIDEwMCBlbHNlIDEuMFxuICAgICAgICAgICAgYnVmZmVyLnBsYXkoZmFkZUluVGltZSkgaWYgR2FtZU1hbmFnZXIuc2V0dGluZ3MuYmdtRW5hYmxlZFxuICAgICAgICBlbHNlXG4gICAgICAgICAgIGJ1ZmZlci5vbkZpbmlzaERlY29kZSA9IChzb3VyY2UpID0+IFxuICAgICAgICAgICAgICAgc291cmNlLnZvbHVtZSA9IGlmIHZvbHVtZT8gdGhlbiB2b2x1bWUgLyAxMDAgZWxzZSAxLjBcbiAgICAgICAgICAgICAgIHNvdXJjZS5wbGF5YmFja1JhdGUgPSBpZiByYXRlPyB0aGVuIHJhdGUgLyAxMDAgZWxzZSAxLjBcbiAgICAgICAgICAgICAgIHNvdXJjZS5wbGF5KGZhZGVJblRpbWUpIGlmIEdhbWVNYW5hZ2VyLnNldHRpbmdzLmJnbUVuYWJsZWRcbiAgICAgICAgICAgYnVmZmVyLmRlY29kZSgpXG4gICAgICAgICAgIFxuICAgICAgICByZXR1cm4gYnVmZmVyXG4gICAgIFxuICAgICMjIypcbiAgICAqIFN0b3BzIGFsbCBzb3VuZHMuXG4gICAgKlxuICAgICogQG1ldGhvZCBzdG9wQWxsU291bmRzXG4gICAgIyMjICAgIFxuICAgIHN0b3BBbGxTb3VuZHM6IC0+XG4gICAgICAgIGZvciBrIG9mIEBzb3VuZFJlZmVyZW5jZXNcbiAgICAgICAgICAgIGZvciByZWZlcmVuY2UgaW4gQHNvdW5kUmVmZXJlbmNlc1trXVxuICAgICAgICAgICAgICAgIHJlZmVyZW5jZT8uc3RvcCgpXG4gICAgXG4gICAgIyMjKlxuICAgICogU3RvcHMgYSBzb3VuZCBhbmQgYWxsIHJlZmVyZW5jZXMgb2YgaXQuXG4gICAgKlxuICAgICogQG1ldGhvZCBzdG9wU291bmRcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHNvdW5kIHRvIHN0b3AuXG4gICAgIyMjICAgICAgICAgICAgIFxuICAgIHN0b3BTb3VuZDogKG5hbWUpIC0+XG4gICAgICAgIGlmIEBzb3VuZFJlZmVyZW5jZXNbbmFtZV0/XG4gICAgICAgICAgICBmb3IgcmVmZXJlbmNlIGluIEBzb3VuZFJlZmVyZW5jZXNbbmFtZV1cbiAgICAgICAgICAgICAgICByZWZlcmVuY2Uuc3RvcCgpXG4gICAgXG4gICAgXG4gICAgIyMjKlxuICAgICogU3RvcHMgYSB2b2ljZS5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHN0b3BWb2ljZVxuICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgdm9pY2UgdG8gc3RvcC5cbiAgICAjIyMgICAgICAgICAgICAgXG4gICAgc3RvcFZvaWNlOiAobmFtZSkgLT5cbiAgICAgICAgQHN0b3BTb3VuZChuYW1lKVxuICAgIFxuICAgICMjIypcbiAgICAqIFN0b3BzIGFsbCB2b2ljZXMuXG4gICAgKlxuICAgICogQG1ldGhvZCBzdG9wQWxsVm9pY2VzXG4gICAgIyMjICAgICBcbiAgICBzdG9wQWxsVm9pY2VzOiAtPlxuICAgICAgICBmb3IgayBvZiBAc291bmRSZWZlcmVuY2VzXG4gICAgICAgICAgICBmb3IgcmVmZXJlbmNlIGluIEBzb3VuZFJlZmVyZW5jZXNba11cbiAgICAgICAgICAgICAgICByZWZlcmVuY2Uuc3RvcCgpIGlmIHJlZmVyZW5jZS52b2ljZVxuICAgIFxuICAgICMjIypcbiAgICAqIFBsYXlzIGEgdm9pY2UuXG4gICAgKlxuICAgICogQG1ldGhvZCBwbGF5Vm9pY2VcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHZvaWNlIHRvIHBsYXkuXG4gICAgKiBAcGFyYW0ge251bWJlcn0gdm9sdW1lIC0gVGhlIHZvaWNlIHZvbHVtZS5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSByYXRlIC0gVGhlIHZvaWNlIHBsYXliYWNrIHJhdGUuXG4gICAgIyMjICAgICBcbiAgICBwbGF5Vm9pY2U6IChuYW1lLCB2b2x1bWUsIHJhdGUpIC0+XG4gICAgICAgIHZvaWNlID0gbnVsbFxuICAgICAgICBpZiBHYW1lTWFuYWdlci5zZXR0aW5ncy52b2ljZUVuYWJsZWQgYW5kIG5vdCAkUEFSQU1TLnByZXZpZXc/LnNldHRpbmdzLnZvaWNlRGlzYWJsZWRcbiAgICAgICAgICAgIHZvaWNlID0gQHBsYXlTb3VuZChuYW1lPy5uYW1lLCB2b2x1bWUgfHwgR2FtZU1hbmFnZXIuZGVmYXVsdHMuYXVkaW8udm9pY2VWb2x1bWUsIHJhdGUgfHwgR2FtZU1hbmFnZXIuZGVmYXVsdHMuYXVkaW8udm9pY2VQbGF5YmFja1JhdGUsIG5vLCB5ZXMpXG4gICAgICAgIFxuICAgICAgICByZXR1cm4gdm9pY2UgICAgXG4gICAgXG4gICAgIyMjKlxuICAgICogUGxheXMgYSBzb3VuZC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHBsYXlTb3VuZFxuICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgc291bmQgdG8gcGxheS5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSB2b2x1bWUgLSBUaGUgc291bmQncyB2b2x1bWUuXG4gICAgKiBAcGFyYW0ge251bWJlcn0gcmF0ZSAtIFRoZSBzb3VuZCdzIHBsYXliYWNrIHJhdGUuXG4gICAgKiBAcGFyYW0ge2Jvb2xlYW59IG11c2ljRWZmZWN0IC0gSW5kaWNhdGVzIGlmIHRoZSBzb3VuZCBzaG91bGQgYmUgcGxheWVkIGFzIGEgbXVzaWMgZWZmZWN0LiBJbiB0aGF0IGNhc2UsIHRoZSBjdXJyZW50IG11c2ljXG4gICAgKiBhdCBhdWRpby1sYXllciB3aWxsIGJlIHBhdXNlZCB1bnRpbCB0aGUgc291bmQgZmluaXNoZXMgcGxheWluZy5cbiAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gdm9pY2UgLSBJbmRpY2F0ZXMgaWYgdGhlIHNvdW5kIHNob3VsZCBiZSBoYW5kbGVkIGFzIGEgdm9pY2UuXG4gICAgIyMjICAgICAgICAgIFxuICAgIHBsYXlTb3VuZDogKG5hbWUsIHZvbHVtZSwgcmF0ZSwgbXVzaWNFZmZlY3QsIHZvaWNlLCBsb29wU291bmQpIC0+XG4gICAgICAgIGlmICRQQVJBTVMucHJldmlldz8uc2V0dGluZ3Muc291bmREaXNhYmxlZCB0aGVuIHJldHVyblxuICAgICAgICBpZiBub3QgbmFtZT8gb3IgKCF2b2ljZSBhbmQgIUdhbWVNYW5hZ2VyLnNldHRpbmdzLnNvdW5kRW5hYmxlZCkgdGhlbiByZXR1cm5cbiAgICAgICAgaWYgbmFtZS5uYW1lP1xuICAgICAgICAgICAgdm9sdW1lID0gbmFtZS52b2x1bWVcbiAgICAgICAgICAgIHJhdGUgPSBuYW1lLnBsYXliYWNrUmF0ZVxuICAgICAgICAgICAgbmFtZSA9IG5hbWUubmFtZVxuICAgICAgICAgXG4gICAgICAgIGlmIG5hbWUubGVuZ3RoID09IDAgdGhlbiByZXR1cm5cbiAgICAgICAgXG4gICAgICAgIGlmIG11c2ljRWZmZWN0XG4gICAgICAgICAgICBAc3RvcE11c2ljKClcbiAgICAgICAgXG4gICAgICAgIGlmIG5vdCBAc291bmRSZWZlcmVuY2VzW25hbWVdP1xuICAgICAgICAgICAgQHNvdW5kUmVmZXJlbmNlc1tuYW1lXSA9IFtdXG4gICAgICAgIFxuICAgICAgICB2b2x1bWUgPSB2b2x1bWUgPyAxMDBcbiAgICAgICAgdm9sdW1lICo9IGlmIHZvaWNlIHRoZW4gQGdlbmVyYWxWb2ljZVZvbHVtZSAvIDEwMCBlbHNlIEBnZW5lcmFsU291bmRWb2x1bWUgLyAxMDBcbiAgICAgICAgXG4gICAgICAgIHJlZmVyZW5jZSA9IG51bGxcbiAgICAgICAgZm9yIHIgaW4gQHNvdW5kUmVmZXJlbmNlc1tuYW1lXVxuICAgICAgICAgICAgaWYgbm90IHIuaXNQbGF5aW5nXG4gICAgICAgICAgICAgICAgcmVmZXJlbmNlID0gclxuICAgICAgICAgICAgICAgIGlmIG11c2ljRWZmZWN0IHRoZW4gcmVmZXJlbmNlLm9uRW5kID0gPT4gQHJlc3VtZU11c2ljKDQwKVxuICAgICAgICAgICAgICAgIHJlZmVyZW5jZS52b2ljZSA9IHZvaWNlXG4gICAgICAgICAgICAgICAgcmVmZXJlbmNlLnZvbHVtZSA9IHZvbHVtZSAvIDEwMFxuICAgICAgICAgICAgICAgIHJlZmVyZW5jZS5wbGF5YmFja1JhdGUgPSByYXRlIC8gMTAwXG4gICAgICAgICAgICAgICAgcmVmZXJlbmNlLmxvb3AgPSBsb29wU291bmRcbiAgICAgICAgICAgICAgICBAdm9pY2UgPSByZWZlcmVuY2UgaWYgdm9pY2VcbiAgICAgICAgICAgICAgICByZWZlcmVuY2UucGxheSgpXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgIFxuICAgICAgICBpZiBub3QgcmVmZXJlbmNlP1xuICAgICAgICAgICAgYnVmZmVyID0gUmVzb3VyY2VNYW5hZ2VyLmdldEF1ZGlvQnVmZmVyKFwiQXVkaW8vU291bmRzLyN7bmFtZX1cIilcbiAgICAgICAgICAgIGlmIGJ1ZmZlciBhbmQgYnVmZmVyLmxvYWRlZFxuICAgICAgICAgICAgICAgIGlmIGJ1ZmZlci5kZWNvZGVkXG4gICAgICAgICAgICAgICAgICAgIHJlZmVyZW5jZSA9IG5ldyBHUy5BdWRpb0J1ZmZlclJlZmVyZW5jZShidWZmZXIsIHZvaWNlKVxuICAgICAgICAgICAgICAgICAgICBpZiBtdXNpY0VmZmVjdCB0aGVuIHJlZmVyZW5jZS5vbkVuZCA9ID0+IEByZXN1bWVNdXNpYyg0MClcbiAgICAgICAgICAgICAgICAgICAgcmVmZXJlbmNlLnZvbHVtZSA9IHZvbHVtZSAvIDEwMFxuICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2UucGxheWJhY2tSYXRlID0gcmF0ZSAvIDEwMFxuICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2Uudm9pY2UgPSB2b2ljZVxuICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2UubG9vcCA9IGxvb3BTb3VuZFxuICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2UucGxheSgpXG4gICAgICAgICAgICAgICAgICAgIEB2b2ljZSA9IHJlZmVyZW5jZSBpZiB2b2ljZVxuICAgICAgICAgICAgICAgICAgICBAc291bmRSZWZlcmVuY2VzW25hbWVdLnB1c2gocmVmZXJlbmNlKVxuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgYnVmZmVyLm5hbWUgPSBuYW1lXG4gICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5vbkRlY29kZUZpbmlzaCA9IChzb3VyY2UpID0+XG4gICAgICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2UgPSBuZXcgR1MuQXVkaW9CdWZmZXJSZWZlcmVuY2Uoc291cmNlLCB2b2ljZSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIG11c2ljRWZmZWN0IHRoZW4gcmVmZXJlbmNlLm9uRW5kID0gPT4gQHJlc3VtZU11c2ljKDQwKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVmZXJlbmNlLnZvaWNlID0gdm9pY2VcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZmVyZW5jZS52b2x1bWUgPSB2b2x1bWUgLyAxMDBcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZmVyZW5jZS5wbGF5YmFja1JhdGUgPSByYXRlIC8gMTAwXG4gICAgICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2UubG9vcCA9IGxvb3BTb3VuZFxuICAgICAgICAgICAgICAgICAgICAgICAgQHZvaWNlID0gcmVmZXJlbmNlIGlmIHZvaWNlXG4gICAgICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2UucGxheSgpXG4gICAgICAgICAgICAgICAgICAgICAgICBAc291bmRSZWZlcmVuY2VzW3NvdXJjZS5uYW1lXS5wdXNoKHJlZmVyZW5jZSlcbiAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmRlY29kZSgpXG4gICAgICAgIFxuICAgICAgICByZXR1cm4gcmVmZXJlbmNlICAgICAgICAgICAgXG4gICAgXG4gICAgIyMjKlxuICAgICogUGxheXMgYSBtdXNpYyBhcyBhIHJhbmRvbSBtdXNpYy4gQSByYW5kb20gbXVzaWMgd2lsbCBmYWRlLWluIGFuZCBmYWRlLW91dFxuICAgICogYXQgcmFuZG9tIHRpbWVzLiBUaGF0IGNhbiBiZSBjb21iaW5lZCB3aXRoIG90aGVyIGF1ZGlvLWxheWVycyB0byBjcmVhdGUgYVxuICAgICogbXVjaCBiZXR0ZXIgbG9vcGluZyBvZiBhbiBhdWRpbyB0cmFjay5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHBsYXlNdXNpY1JhbmRvbVxuICAgICogQHBhcmFtIHtPYmplY3R9IG11c2ljIC0gVGhlIG11c2ljIHRvIHBsYXkuXG4gICAgKiBAcGFyYW0ge251bWJlcn0gZmFkZVRpbWUgLSBUaGUgdGltZSBmb3IgYSBzaW5nbGUgZmFkZS1pbi9vdXQgaW4gZnJhbWVzLlxuICAgICogQHBhcmFtIHtudW1iZXJ9IGxheWVyIC0gVGhlIGF1ZGlvIGxheWVyIHRvIHVzZS5cbiAgICAqIEBwYXJhbSB7Z3MuUmFuZ2V9IHBsYXlUaW1lIC0gUGxheS1UaW1lIHJhbmdlIGxpa2UgMTBzIHRvIDMwcy5cbiAgICAqIEBwYXJhbSB7Z3MuUmFuZ2V9IHBsYXlSYW5nZSAtIFBsYXktUmFuZ2UuXG4gICAgIyMjICAgICBcbiAgICBwbGF5TXVzaWNSYW5kb206IChtdXNpYywgZmFkZVRpbWUsIGxheWVyLCBwbGF5VGltZSwgcGxheVJhbmdlKSAtPlxuICAgICAgICByZXR1cm4gaWYgJFBBUkFNUy5wcmV2aWV3Py5zZXR0aW5ncy5tdXNpY0Rpc2FibGVkXG4gICAgICAgIGxheWVyID0gbGF5ZXIgPyAwXG5cbiAgICAgICAgdm9sdW1lID0gaWYgbXVzaWMudm9sdW1lPyB0aGVuIG11c2ljLnZvbHVtZSBlbHNlIDEwMFxuICAgICAgICB2b2x1bWUgPSB2b2x1bWUgKiAoQGdlbmVyYWxNdXNpY1ZvbHVtZSAvIDEwMClcbiAgICAgICAgQG11c2ljVm9sdW1lID0gdm9sdW1lXG4gICAgICAgIEBkaXNwb3NlTXVzaWMobGF5ZXIpXG4gICAgICAgIFxuICAgICAgICBpZiBtdXNpYy5uYW1lPyBhbmQgbXVzaWMubmFtZS5sZW5ndGggPiAwXG4gICAgICAgICAgICBtdXNpY0J1ZmZlciA9IEBwbGF5KFwiQXVkaW8vTXVzaWMvI3ttdXNpYy5uYW1lfVwiLCB2b2x1bWUsIG11c2ljLnJhdGUpXG4gICAgICAgICAgICBtdXNpY0J1ZmZlci5sb29wID0geWVzXG4gICAgICAgICAgICBtdXNpY0J1ZmZlci52b2x1bWUgPSAwXG4gICAgICAgICAgICBtdXNpY0J1ZmZlci5kdXJhdGlvbiA9IE1hdGgucm91bmQobXVzaWNCdWZmZXIuZHVyYXRpb24gKiAxMDAwIC8gMTYuNilcbiAgICAgICAgICAgIG11c2ljQnVmZmVyLmN1c3RvbURhdGEucGxheVR5cGUgPSAxXG4gICAgICAgICAgICBtdXNpY0J1ZmZlci5jdXN0b21EYXRhLnBsYXlUaW1lID0gcGxheVRpbWVcbiAgICAgICAgICAgIGlmIHBsYXlSYW5nZS5lbmQgPT0gMFxuICAgICAgICAgICAgICAgIG11c2ljQnVmZmVyLmN1c3RvbURhdGEucGxheVJhbmdlID0geyBzdGFydDogcGxheVJhbmdlLnN0YXJ0LCBlbmQ6IG11c2ljQnVmZmVyLmR1cmF0aW9uIH1cbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBtdXNpY0J1ZmZlci5jdXN0b21EYXRhLnBsYXlSYW5nZSA9IHBsYXlSYW5nZVxuICAgICAgICAgICAgbXVzaWNCdWZmZXIuY3VzdG9tRGF0YS5mYWRlVGltZSA9IGZhZGVUaW1lXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIG11c2ljQnVmZmVyLmN1c3RvbURhdGEuc3RhcnRUaW1lciA9IE1hdGgucm91bmQobXVzaWNCdWZmZXIuY3VzdG9tRGF0YS5wbGF5UmFuZ2Uuc3RhcnQgKyBNYXRoLnJhbmRvbSgpICogKG11c2ljQnVmZmVyLmN1c3RvbURhdGEucGxheVJhbmdlLmVuZCAtIG11c2ljQnVmZmVyLmN1c3RvbURhdGEucGxheVJhbmdlLnN0YXJ0KSlcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgQGF1ZGlvQnVmZmVycy5wdXNoKG11c2ljQnVmZmVyKSBpZiBub3QgQGF1ZGlvQnVmZmVycy5jb250YWlucyhtdXNpY0J1ZmZlcilcbiAgICAgICAgICAgIEBhdWRpb0J1ZmZlcnNCeUxheWVyW2xheWVyXSA9IG11c2ljQnVmZmVyXG4gICAgICAgICAgICBAYXVkaW9MYXllcnNbbGF5ZXJdID0gbmFtZTogbXVzaWMubmFtZSwgdGltZTogbXVzaWMuY3VycmVudFRpbWUsIHZvbHVtZTogbXVzaWMudm9sdW1lLCByYXRlOiBtdXNpYy5wbGF5YmFja1JhdGUsIGZhZGVJblRpbWU6IGZhZGVUaW1lLCBjdXN0b21EYXRhOiBtdXNpY0J1ZmZlci5jdXN0b21EYXRhXG4gICAgIFxuICAgICMjIypcbiAgICAqIFBsYXlzIGEgbXVzaWMuXG4gICAgKlxuICAgICogQG1ldGhvZCBwbGF5TXVzaWNcbiAgICAqIEBwYXJhbSB7c3RyaW5nfE9iamVjdH0gbmFtZSAtIFRoZSBtdXNpYyB0byBwbGF5LiBDYW4gYmUganVzdCBhIG5hbWUgb3IgYSBtdXNpYyBkYXRhLW9iamVjdC5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSB2b2x1bWUgLSBUaGUgbXVzaWMncyB2b2x1bWUgaW4gcGVyY2VudC5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSByYXRlIC0gVGhlIG11c2ljJ3MgcGxheWJhY2sgcmF0ZSBpbiBwZXJjZW50LlxuICAgICogQHBhcmFtIHtudW1iZXJ9IGZhZGVJblRpbWUgLSBUaGUgZmFkZS1pbiB0aW1lLlxuICAgICogQHBhcmFtIHtudW1iZXJ9IGxheWVyIC0gVGhlIGxheWVyIHRvIHBsYXkgdGhlIG11c2ljIG9uLlxuICAgICogQHBhcmFtIHtib29sZWFufSBsb29wIC0gSW5kaWNhdGVzIGlmIHRoZSBtdXNpYyBzaG91bGQgYmUgbG9vcGVkXG4gICAgIyMjICAgICAgICAgIFxuICAgIHBsYXlNdXNpYzogKG5hbWUsIHZvbHVtZSwgcmF0ZSwgZmFkZUluVGltZSwgbGF5ZXIsIGxvb3BNdXNpYykgLT5cbiAgICAgICAgcmV0dXJuIGlmICRQQVJBTVMucHJldmlldz8uc2V0dGluZ3MubXVzaWNEaXNhYmxlZFxuICAgICAgICBsb29wTXVzaWMgPz0geWVzXG4gICAgICAgIGlmIG5hbWU/IGFuZCBuYW1lLm5hbWU/XG4gICAgICAgICAgICBsYXllciA9IGlmIGxheWVyPyB0aGVuIGxheWVyIGVsc2UgcmF0ZSB8fCAwXG4gICAgICAgICAgICBmYWRlSW5UaW1lID0gdm9sdW1lXG4gICAgICAgICAgICB2b2x1bWUgPSBuYW1lLnZvbHVtZVxuICAgICAgICAgICAgcmF0ZSA9IG5hbWUucGxheWJhY2tSYXRlXG4gICAgICAgICAgICBuYW1lID0gbmFtZS5uYW1lXG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIGxheWVyID0gbGF5ZXIgPyAwXG4gICAgICAgICAgICBcbiAgICAgICAgQGRpc3Bvc2VNdXNpYyhsYXllcilcbiAgICAgICAgQGF1ZGlvTGF5ZXJzW2xheWVyXSA9IG5hbWU6IG5hbWUsIHZvbHVtZTogdm9sdW1lLCByYXRlOiByYXRlLCBmYWRlSW5UaW1lOiBmYWRlSW5UaW1lLCBwbGF5aW5nOiB0cnVlXG4gICAgICAgICAgIFxuICAgICAgICB2b2x1bWUgPSBpZiB2b2x1bWU/IHRoZW4gdm9sdW1lIGVsc2UgMTAwXG4gICAgICAgIHZvbHVtZSA9IHZvbHVtZSAqIChAZ2VuZXJhbE11c2ljVm9sdW1lIC8gMTAwKVxuICAgICAgICBAbXVzaWNWb2x1bWUgPSB2b2x1bWVcbiAgICAgICAgXG4gICAgICAgIFxuICAgICAgICBpZiBuYW1lPyBhbmQgbmFtZS5sZW5ndGggPiAwXG4gICAgICAgICAgICBAbXVzaWMgPSBuYW1lOiBuYW1lXG4gICAgICAgICAgICBtdXNpY0J1ZmZlciA9IEBwbGF5KFwiQXVkaW8vTXVzaWMvI3tuYW1lfVwiLCB2b2x1bWUsIHJhdGUsIGZhZGVJblRpbWUpXG4gICAgICAgICAgICBtdXNpY0J1ZmZlci5sb29wID0gbG9vcE11c2ljXG4gICAgICAgICAgICBAYXVkaW9CdWZmZXJzLnB1c2gobXVzaWNCdWZmZXIpIGlmIG5vdCBAYXVkaW9CdWZmZXJzLmNvbnRhaW5zKG11c2ljQnVmZmVyKVxuICAgICAgICAgICAgQGF1ZGlvQnVmZmVyc0J5TGF5ZXJbbGF5ZXJdID0gbXVzaWNCdWZmZXJcbiAgICAgICAgICAgIFxuICAgICAgICByZXR1cm4gbXVzaWNCdWZmZXJcbiAgICAgICAgICAgIFxuICAgICMjIypcbiAgICAqIFJlc3VtZXMgYSBwYXVzZWQgbXVzaWMuXG4gICAgKlxuICAgICogQG1ldGhvZCByZXN1bWVNdXNpY1xuICAgICogQHBhcmFtIHtudW1iZXJ9IGZhZGVJblRpbWUgLSBUaGUgZmFkZS1pbiB0aW1lIGluIGZyYW1lcy5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSBsYXllciAtIFRoZSBhdWRpbyBsYXllciB0byByZXN1bWUuXG4gICAgIyMjICAgXG4gICAgcmVzdW1lTXVzaWM6IChmYWRlSW5UaW1lLCBsYXllcikgLT5cbiAgICAgICAgbGF5ZXIgPSBsYXllciA/IDBcbiAgICAgICAgaWYgQGF1ZGlvQnVmZmVyc0J5TGF5ZXJbbGF5ZXJdPyBhbmQgbm90IEBhdWRpb0J1ZmZlcnNCeUxheWVyW2xheWVyXS5pc1BsYXlpbmdcbiAgICAgICAgICAgIEBhdWRpb0J1ZmZlcnNCeUxheWVyW2xheWVyXS5yZXN1bWUoZmFkZUluVGltZSlcbiAgICAgICAgICAgIEBhdWRpb0xheWVyc1tsYXllcl0/LnBsYXlpbmcgPSB0cnVlXG4gICAgXG4gICAgIyMjKlxuICAgICogU3RvcHMgYSBtdXNpYy5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHN0b3BNdXNpY1xuICAgICogQHBhcmFtIHtudW1iZXJ9IGZhZGVPdXRUaW1lIC0gVGhlIGZhZGUtb3V0IHRpbWUgaW4gZnJhbWVzLlxuICAgICogQHBhcmFtIHtudW1iZXJ9IGxheWVyIC0gVGhlIGF1ZGlvIGxheWVyIHRvIHN0b3AuXG4gICAgIyMjICAgICAgICAgXG4gICAgc3RvcE11c2ljOiAoZmFkZU91dFRpbWUsIGxheWVyKSAtPiBcbiAgICAgICAgbGF5ZXIgPSBsYXllciA/IDBcbiAgICAgICAgQGF1ZGlvQnVmZmVyc0J5TGF5ZXJbbGF5ZXJdPy5zdG9wKGZhZGVPdXRUaW1lKVxuICAgICAgICBAYXVkaW9CdWZmZXJzQnlMYXllcltsYXllcl0/LmN1c3RvbURhdGEgPSB7fVxuICAgICAgICBAYXVkaW9MYXllcnNbbGF5ZXJdPy5wbGF5aW5nID0gZmFsc2VcbiAgICAgICAgQG11c2ljID0gbnVsbFxuICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBTdG9wcyBhbGwgbXVzaWMvYXVkaW8gbGF5ZXJzLlxuICAgICpcbiAgICAqIEBtZXRob2Qgc3RvcEFsbE11c2ljXG4gICAgKiBAcGFyYW0ge251bWJlcn0gZmFkZU91dFRpbWUgLSBUaGUgZmFkZS1vdXQgdGltZSBpbiBmcmFtZXMuXG4gICAgIyMjICAgICAgICAgXG4gICAgc3RvcEFsbE11c2ljOiAoZmFkZU91dFRpbWUpIC0+IFxuICAgICAgICBmb3IgYnVmZmVyIGluIEBhdWRpb0J1ZmZlcnNcbiAgICAgICAgICAgIGlmIGJ1ZmZlcj9cbiAgICAgICAgICAgICAgICBidWZmZXIuc3RvcChmYWRlT3V0VGltZSlcbiAgICAgICAgICAgICAgICBidWZmZXIuY3VzdG9tRGF0YSA9IHt9XG4gICAgICAgIEBtdXNpYyA9IG51bGxcblxuXG4gICAgZGlzcG9zZTogKGNvbnRleHQpIC0+XG4gICAgICAgIGRhdGEgPSBjb250ZXh0LnJlc291cmNlcy5zZWxlY3QgKHIpIC0+IHIuZGF0YVxuICAgICAgICBmb3IgYnVmZmVyLCBsYXllciBpbiBAYXVkaW9CdWZmZXJzQnlMYXllclxuICAgICAgICAgICAgaWYgYnVmZmVyIGFuZCBkYXRhLmluZGV4T2YoYnVmZmVyKSAhPSAtMVxuICAgICAgICAgICAgICAgIGJ1ZmZlci5kaXNwb3NlKClcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICBAYXVkaW9CdWZmZXJzLnJlbW92ZShidWZmZXIpXG4gICAgICAgICAgICAgICAgQGF1ZGlvQnVmZmVyc0J5TGF5ZXJbbGF5ZXJdID0gbnVsbFxuICAgICAgICAgICAgICAgIEBhdWRpb0xheWVyc1tsYXllcl0gPSBudWxsXG4gICAgICAgICAgICAgICAgXG4gICAgIyMjKlxuICAgICogRGlzcG9zZXMgYSBtdXNpYy5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGRpc3Bvc2VNdXNpY1xuICAgICogQHBhcmFtIHtudW1iZXJ9IGxheWVyIC0gVGhlIGF1ZGlvIGxheWVyIG9mIHRoZSBtdXNpYyB0byBkaXNwb3NlLlxuICAgICMjIyBcbiAgICBkaXNwb3NlTXVzaWM6IChsYXllcikgLT5cbiAgICAgICAgbGF5ZXIgPSBsYXllciA/IDBcbiAgICAgICAgXG4gICAgICAgIEBzdG9wTXVzaWMoMCwgbGF5ZXIpXG4gICAgICAgICNAYXVkaW9CdWZmZXJzW2xheWVyXT8uZGlzcG9zZSgpXG4gICAgICAgIEBhdWRpb0J1ZmZlcnMucmVtb3ZlKEBhdWRpb0J1ZmZlcnNCeUxheWVyW2xheWVyXSlcbiAgICAgICAgQGF1ZGlvQnVmZmVyc0J5TGF5ZXJbbGF5ZXJdID0gbnVsbFxuICAgICAgICBAYXVkaW9MYXllcnNbbGF5ZXJdID0gbnVsbFxuICAgIFxud2luZG93LkF1ZGlvTWFuYWdlciA9IG5ldyBBdWRpb01hbmFnZXIoKVxuZ3MuQXVkaW9NYW5hZ2VyID0gQXVkaW9NYW5hZ2VyIl19\n//# sourceURL=AudioManager_73.js",
11 11 "parentId": "C0268943K60B3A42B7SA6F1EDDCF2F642FD7"
12 12 },
13 13 "summary": [