-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbitlisten.min.js.map
1 lines (1 loc) · 183 KB
/
bitlisten.min.js.map
1
{"version":3,"sources":["lib/extend.js","src/block.js","src/floatable.js","src/main.js","src/ratebox.js","src/socket.js","src/sound.js","src/statusbox.js","src/transaction.js","lib/easteregg.js","lib/howler.js","lib/jquery-qr.js","lib/jquery.nouislider.js","lib/polyfills.js","lib/reconnecting-websocket.js"],"names":["surrogateCtor","extend","base","sub","prototype","constructor","Block","height","numTransactions","outputTotal","blockSize","document","visibilityState","Floatable","call","this","outputBTC","Math","floor","satoshi","blockSizeKB","width","addImage","blockImage","addText","initPosition","Sound","playRandomSwell","velocity","x","y","pageDiv","getElementById","updateContainerSize","div","createElement","className","appendChild","innerDiv","updateTargets","push","zerocalc","btcprice","$","html","zerobtcprice","parseFloat","toFixed","setGlobalRate","rate","cur","accu","globalRate","checkbox","prop","parent","removeClass","TransactionSocket","dump","obj","out","i","alert","zeroPad","num","places","zero","toString","length","Array","join","StatusBox","Transaction","bitcoins","highlight","currency","currencyName","area","sqrt","PI","bubbleImage","bitcoinString","bitcoinVal","globalShowDollar","globalRateZerToBtc","maxBitcoins","minVolume","maxVolume","volume","maxPitch","logUsed","pitch","min","log","globalScalePitch","playPitchAtVolume","playRandomAtVolume","transaction_count","style","opacity","Konami","callback","konami","addEvent","type","fn","ref_obj","addEventListener","attachEvent","window","event","input","pattern","load","link","e","keyCode","substr","code","preventDefault","iphone","location","start_x","start_y","stop_x","stop_y","tap","capture","orig_keys","keys","touches","touch","pageX","pageY","check_direction","evt","changedTouches","x_magnitude","abs","y_magnitude","result","slice","cache","ctx","usingWebAudio","noAudio","AudioContext","webkitAudioContext","Audio","masterGain","createGain","createGainNode","gain","value","connect","destination","HowlerGlobal","codecs","_volume","_muted","_howls","_codecs","iOSAutoEnable","vol","self","key","hasOwnProperty","_webAudio","_audioNode","mute","_setMuted","unmute","muted","ext","_enableiOSAudio","_iOSEnabled","test","navigator","userAgent","unlock","buffer","createBuffer","source","createBufferSource","start","noteOn","setTimeout","playbackState","PLAYING_STATE","FINISHED_STATE","removeEventListener","audioTest","mp3","canPlayType","replace","opus","ogg","wav","aac","m4a","mp4","weba","Howler","Howl","o","_autoplay","autoplay","_buffer","_duration","duration","_format","format","_loop","loop","_loaded","_sprite","sprite","_src","src","_pos3d","pos3d","undefined","_urls","urls","_rate","_model","model","_onload","onload","_onloaderror","onloaderror","_onend","onend","_onpause","onpause","_onplay","onplay","_onendTimer","_setupAudioNode","url","on","urlItem","exec","split","toLowerCase","loadBuffer","newNode","error","_pos","preload","listener","ceil","Object","getOwnPropertyNames","_default","play","stop","_inactiveNode","node","pos","timerId","soundId","round","Date","now","random","data","id","_nodeById","paused","_clearEndTimer","timer","loopStart","loopEnd","refreshBuffer","_playStart","currentTime","bufferSource","noteGrainOn","readyState","isCocoonJS","sound","playSprite","pause","activeNode","_activeNode","noteOff","isNaN","z","panner","setPosition","panningModel","fade","from","to","len","diff","dir","steps","stepTime","change","toVol","fadeIn","fadeOut","_drainPool","listenerEvent","inactive","disconnect","splice","index","clearTimeout","createPanner","events","off","fnString","unload","nodes","indexOf","loadSound","atob","dataView","Uint8Array","charCodeAt","decodeAudioData","xhr","XMLHttpRequest","open","responseType","response","onerror","_gainNode","send","arraybuffer","err","playbackRate","define","amd","exports","qr","options","createQR","href","size","escape","$qr","css","background","display","border-style","border-width","position","z-index","append","each","settings","delay","$this","qr_div","attr","mouseenter","qr_timeout_id","top","left","mouseleave","jQuery","throwError","message","RangeError","throwEqualError","F","a","b","limit","max","closest","subRangeRatio","pa","pb","typeMatch","isInstance","isNumeric","isFinite","asArray","isArray","addClassFor","element","addClass","fromPercentage","range","toPercentage","isPercentage","toStepping","xVal","va","vb","j","xPct","fromStepping","getStep","snap","xSteps","fixEvent","mouse","pointer","originalEvent","pageXOffset","documentElement","scrollLeft","pageYOffset","scrollTop","clientX","clientY","points","cursor","Format","Formatting","val","FormatDefaults","Link","entry","update","Error","formatting","that","target","method","isTooltip","isHidden","isMethod","is$","isInput","is","methodIsFunction","methodIsName","el","name","at","c","output","N","testStep","parsed","testRange","percentage","n","testStart","handles","testSnap","testConnect","testOrientation","ort","testMargin","margin","testDirection","testBehaviour","drag","fixed","testSerialization","sliders","ser","scope","reverse","tests","step","r","t","orientation","direction","behaviour","serialization","lower","upper","addHandle","handle","Classes","additions","children","addElement","clone","appendTo","addElements","elements","list","addLinks","links","addConnection","addHandles","addSlider","closure","originalOptions","baseSize","$Base","fireEvents","values","$Target","trigger","setHandle","delimit","$Handles","$Locations","toggleClass","$Serialization","write","getPositions","d","jump","instant","attach","namespace","disabled","hasClass","calcPoint","move","positions","state","proposal","h","end","doc","stopPropagation","actions","total","offset","edge","find","add","not","vSet","animate","valueOf","vGet","retour","saved","destroy","empty","initialize","rebuild","newOptions","noUiSlider","$val","pointerEnabled","msPointerEnabled","v","number","negative","preNegative","mark","match","esc","s","isNeg","RegExp","slider","re","set","args","arguments","apply","requestAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","oRequestAnimationFrame","msRequestAnimationFrame","visibly","q","p","prefixes","props","m","visibleCallbacks","hiddenCallbacks","_callbacks","onVisible","_callback","onHidden","isSupported","_supports","runCallbacks","_visible","_hidden","_nativeSwitch","listen","init","global","factory","module","ReconnectingWebSocket","protocols","reconnectAttempt","ws","WebSocket","onconnecting","debug","debugAll","console","localWs","timeout","timedOut","close","timeoutInterval","onopen","OPEN","reconnectAttempts","onclose","forcedClose","CLOSED","CONNECTING","reconnectInterval","pow","reconnectDecay","onmessage","URL","refresh","pageDivWidth","pageDivHeight","deltatime","HVEL_MAX","updateDiv","removeSelf","transform","removeChild","image","canvas","getContext","drawImage","text","innerHTML","offsetHeight","easterSuccess","derpy","time","-moz-transform","-o-transform","-webkit-transform","DEBUG_MODE","DONATION_ADDRESS","SOUND_DONATION_ADDRESS","globalMute","instanceId","pageDivId","last_update","Image","debugSpawner","updateLayoutWidth","updateLayoutHeight","newHeight","innerHeight","outerHeight","ready","prevChartWidth","hide","click","slideUp","order","switchExchange","toggleInterface","globalUpdate","delta","bind","setInterval","TradeSocket","loadup","endResize","hideChart","show","colResizable","disable","showChart","liveDrag","onDrag","onResize","resize","onbeforeunload","clearInterval","rateboxTimeout","currentExchange","ratebox_ms","rateboxGetRate","getJSON","USD","last","Data","LastPrice","ajaxSetup","Pusher","subscribe","ticker","price","exchangeName","DELAY_CAP","lastBlockHeight","provider_name","transactionSocketDelay","connection","io","eventToListenTo","room","connected","emit","txid","valueOut","reconnecting","newTransactions","op","newBlocks","JSON","stringify","closed","parse","transacted","blockHeight","transactions","nTx","volumeSent","estimatedBTCSent","nosupport","globalVolume","globalBank","soundBank","sound0","sound1","sound2","swells0","swells1","swells2","instrument_number","musicianString","istring","newSound","currentSound","currentSwells","currentNotes","noteTimeout","randomPitch","lastBlockSound","randomIndex","CONNECTED","NO_SUPPORT","debugmode","blockchain","mtgox"],"mappings":"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","file":"bitlisten.min.js","sourcesContent":["function surrogateCtor() {}\n\nfunction extend(base, sub) {\n // Copy the prototype from the base to setup inheritance\n surrogateCtor.prototype = base.prototype;\n // Tricky huh?\n sub.prototype = new surrogateCtor();\n // Remember the constructor property was set wrong, let's fix it\n sub.prototype.constructor = sub;\n}","/** \n * @constructor\n * @extends Floatable\n */\nfunction Block(height, numTransactions, outputTotal, blockSize) {\n\tif (document.visibilityState === \"visible\") {\n\t\tFloatable.call(this);\n\n\t\tvar outputBTC = Math.floor(outputTotal / satoshi) + \" BTC\";\n\t\tvar blockSizeKB = Math.floor(blockSize / 1024) + \" KB\";\n\n\t\tthis.width = this.height = 500;\n\n\t\tthis.addImage(blockImage, this.width, this.height);\n\t\tthis.addText(\"Block #\" + height + \"<br />Number of Transactions: \" + numTransactions + \"<br />Transaction Volume: \" + outputBTC + \"<br />Block Size: \" + blockSizeKB);\n\t\tthis.initPosition();\n\t}\n\t\n\t// Sound\n\tSound.playRandomSwell();\n}\n\nextend(Floatable, Block);\n","/** @constructor */\nfunction Floatable() {\n\tthis.velocity = {\n\t\tx : 0,\n\t\ty : -1\n\t};\n\t\n\tthis.pageDiv = document.getElementById(\"bubbleDiv\");\n\tthis.updateContainerSize();\n\n\tthis.div = document.createElement(\"div\");\n\tthis.div.className = \"floatableDiv\";\n\tthis.pageDiv.appendChild(this.div);\n\tthis.innerDiv = document.createElement(\"div\");\n\tthis.div.appendChild(this.innerDiv);\n\tthis.innerDiv.className = \"innerDiv\";\n\n\t// Add this object to the update array\n\tupdateTargets.push(this);\n}\n\nFloatable.prototype.updateContainerSize = function() {\n\tthis.pageDivWidth = $(this.pageDiv).width();\n\tthis.pageDivHeight = $(this.pageDiv).height();\n};\n\nFloatable.prototype.update = function(deltatime) {\n\tvar HVEL_MAX = 1;\n\tvar step = deltatime / 50;\n\t\n\tthis.x += this.velocity.x * step;\n\tthis.y += this.velocity.y * step;\n\n\tthis.velocity.x += (Math.random() * 0.1 - 0.05) * step;\n\tif (this.velocity.x > HVEL_MAX) {\n\t\tthis.velocity.x = HVEL_MAX;\n\t} else if (this.velocity.x < -HVEL_MAX) {\n\t\tthis.velocity.x = -HVEL_MAX;\n\t}\n\tif (this.x < 0) {\n\t\tthis.velocity.x += 0.005 * step;\n\t} else if (this.x > this.pageDivWidth - this.width) {\n\t\tthis.velocity.x -= 0.005 * step;\n\t}\n\n\tthis.updateDiv();\n\n\tif (this.y < -this.height)\n\t\tthis.removeSelf();\n};\n\nFloatable.prototype.updateDiv = function() {\n\tthis.div.style[\"-webkit-transform\"] = \"translate(\" + this.x + \"px,\" + this.y + \"px)\";\n\tthis.div.style.transform = \"translate(\" + this.x + \"px,\" + this.y + \"px)\";\n};\n\nFloatable.prototype.removeSelf = function() {\n\tthis.pageDiv.removeChild(this.div);\n\t// Remove self from update array\n\tupdateTargets.splice(updateTargets.indexOf(this), 1);\n};\n\nFloatable.prototype.addImage = function(image, width, height) {\n\tthis.canvas = document.createElement('canvas');\n\tthis.image = image;\n\tthis.canvas.height = height;\n\tthis.canvas.width = width;\n\tthis.canvas.style.position = \"absolute\";\n\tthis.canvas.style.top = \"0px\";\n\tthis.canvas.style.left = \"0px\";\n\tvar ctx = this.canvas.getContext(\"2d\");\n\tctx.drawImage(this.image, 0, 0, width - 1, height - 1);\n\n\tthis.div.appendChild(this.canvas);\n};\n\nFloatable.prototype.addText = function(text) {\n\tthis.innerDiv.innerHTML += text;\n};\n\nFloatable.prototype.initPosition = function() {\n\tthis.x = Math.random() * (this.pageDivWidth - this.width);\n\tthis.y = this.pageDivHeight;\n\tthis.updateDiv();\n\tthis.div.style.width = this.width + \"px\";\n\tthis.div.style.height = this.height + \"px\";\n\tthis.innerDiv.style.top = (this.height / 2 - this.innerDiv.offsetHeight / 2) + 'px';\n\t// Centers the text within the bubble\n};\n\n// Thanks to Myself-Remastered for the image used in this easter egg\n// http://myself-remastered.deviantart.com/art/Derpy-Delivery-251264643\nvar easterSuccess = function() {\n\tvar derpy = new Floatable();\n\tderpy.width = 53;\n\tderpy.height = 48;\n\t\n\tderpy.image = document.createElement('img');\n\tderpy.image.src = \"images/easteregg.gif\";\n\tderpy.image.height = derpy.height;\n\tderpy.image.width = derpy.width;\n\tderpy.image.style.position = \"absolute\";\n\tderpy.image.style.top = \"0px\";\n\tderpy.image.style.left = \"0px\";\n\tderpy.div.appendChild(derpy.image);\n\t\n\tderpy.initPosition();\n\t\n\tderpy.update = function(time) {\n\t\tFloatable.prototype.update.call(derpy, time);\n\t\tderpy.velocity.x += Math.random() * 0.3 - 0.15;\n\t\tif (derpy.velocity.x > 0.1) {\n\t\t\t$(derpy.image).css({\n\t\t\t\t\"-moz-transform\": \"scaleX(-1)\",\n\t\t\t\t\"-o-transform\": \"scaleX(-1)\",\n\t\t\t\t\"-webkit-transform\": \"scaleX(-1)\",\n\t\t\t\t\"transform\": \"scaleX(-1)\"\n\t\t\t});\n\t\t}\n\t\tif (derpy.velocity.x < -0.1) {\n\t\t\t$(derpy.image).css({\n\t\t\t\t\"-moz-transform\": \"scaleX(1)\",\n\t\t\t\t\"-o-transform\": \"scaleX(1)\",\n\t\t\t\t\"-webkit-transform\": \"scaleX(1)\",\n\t\t\t\t\"transform\": \"scaleX(1)\"\n\t\t\t});\n\t\t}\n\t};\n};\nnew Konami(easterSuccess);\n","// Set debugmode to true and transactions/trades will be\n// randomly generated, and no outside connections will be made.\nvar DEBUG_MODE = false;\n\nvar DONATION_ADDRESS;\nvar SOUND_DONATION_ADDRESS;\n\nvar globalMute = false;\n\nvar instanceId = 0;\nvar pageDivId = \"pageDiv\";\n\nvar last_update = 0;\n\nvar updateTargets = [];\n\nvar transaction_count = 0;\n\n// Preload images\nvar bubbleImage = new Image();\nbubbleImage.src = \"images/bubble.png\";\nvar blockImage = new Image();\nblockImage.src = \"images/block.png\";\n\nvar debugSpawner;\n\nvar updateLayoutWidth = function() {\n\t$(\".chartMask\").css(\"visibility\", \"visible\");\n};\n\nvar updateLayoutHeight = function() {\n\tvar newHeight = window.innerHeight;\n\tif ($(\"#header\").css(\"display\") != \"none\") newHeight -= $(\"#header\").outerHeight();\n\t$(\"#pageSplitter\").height(newHeight);\n};\n\n$(document).ready(function() {\n\n\tprevChartWidth = $(\"#pageSplitter\").width() / 2;\n\t\n\t$(\"#chartCell\").hide();\n\t\n\tDONATION_ADDRESS = $(\"#donationAddress\").html();\n\t// Because the user has javascript running:\n\t$(\"#noJavascript\").css(\"display\", \"none\");\n\n\t// Initialize draggable vertical page splitter\n\tupdateLayoutHeight();\n\t\n\tStatusBox.init(DEBUG_MODE);\n\n\t$(\".clickSuppress\").click(function() {\n\t\t$(\".clickSuppress\").parent().slideUp(300);\n\t});\n\n\t// Create a bubble spawner for testing\n\tdebugSpawner = function() {\n\t\t// Generate some test bubbles\n\t\tif (Math.random() <= 0.1) {\n\t\t\t// Try to simulate the transaction spread\n\t\t\tvar volume;\n\t\t\tvar order = Math.random();\n\t\t\tif (order < 0.6) {\n\t\t\t\tvolume = Math.random();\n\t\t\t} else if (order < 0.8) {\n\t\t\t\tvolume = Math.random() * 10;\n\t\t\t} else if (order < 0.95) {\n\t\t\t\tvolume = Math.random() * 100;\n\t\t\t} else {\n\t\t\t\tvolume = Math.random() * 1000;\n\t\t\t}\n\n\t\t\tif (Math.random() < 0.5)\n\t\t\t\tnew Transaction(volume, false);\n\t\t\telse\n\t\t\t\tnew Transaction(volume, false, volume * 75, 'USD');\n\t\t}\n\t};\n\t// Spam the following line into console, it's kind of fun.\n\t// new Block(228158, 270, 100 * satoshi, 153 * 1024);\n\t\n\tswitchExchange(\"bitstamp\");\n\t\n\t// Attach mouseover qr\n\t$(\"#donationAddress\").qr();\n\t\n});\n\n// Function for handling interface show/hide\nvar toggleInterface = function() {\n\tif ($(\".interface:hidden\").length === 0) {\n\t\t$(\".interface\").fadeOut(500, updateLayoutHeight);\n\t\t$(\"#hideInterface\").html(\"[ Show Interface ]\");\n\t\t$(\"#hideInterface\").css(\"opacity\", \"0.5\");\n\t} else {\n\t\t$(\".interface\").fadeIn(500);\n\t\t$(\"#hideInterface\").html(\"[ Hide Interface ]\");\n\t\t$(\"#hideInterface\").css(\"opacity\", \"1\");\n\t\tupdateLayoutHeight();\n\t}\n};\n\nvar globalUpdate = function(time) {\n\twindow.requestAnimationFrame(globalUpdate);\n\tvar delta = time - last_update;\n\tlast_update = time;\n\tfor (var i = 0; i < updateTargets.length; i++) {\n\t\tupdateTargets[i].update(delta);\n\t}\n};\n\n$(window).bind(\"load\", function() {\n\tif (DEBUG_MODE) {\n\t\tsetInterval(debugSpawner, 100);\n\t} else {\n\t\tif ($(\"#blockchainCheckBox\").prop(\"checked\"))\n\t\t\tTransactionSocket.init();\n\t\tif ($(\"#mtgoxCheckBox\").prop(\"checked\"))\n\t\t\tTradeSocket.init();\n\t}\n\n\twindow.requestAnimationFrame(globalUpdate);\n\t\n\tSound.loadup();\n\tSound.init();\n});\n\nvar endResize = function() {\n $(\".chartMask\").css(\"visibility\", \"hidden\");\n\tfor (var i = 0; i < updateTargets.length; i++) {\n\t\tupdateTargets[i].updateContainerSize();\n\t}\n};\n\nvar hideChart = function() {\n\t$(\"#chartElement\").hide();\n\t$(\"#showChart\").show();\n\tprevChartWidth = $(\"#chartCell\").width();\n\t$(\"#chartCell\").width(0);\n\t$(\"#chartCell\").hide();\n\t$(\"#pageSplitter\").colResizable({\n\t\tdisable: true\n\t});\n};\n\nvar showChart = function() {\n\t$(\"#chartElement\").show();\n\t$(\"#showChart\").hide();\n\t$(\"#chartCell\").width(prevChartWidth);\n\t$(\"#chartCell\").show();\n\t$(window).trigger(\"resize\");\n\tif ($(\"#bitcoinChart\").length === 0) {\n\t\t// Load the iframe\n\t\t$(\"#chartHolder\").html('<iframe id=\"bitcoinChart\" scrolling=\"no\" frameBorder=\"0\" src=\"http://bitcoin.clarkmoody.com/widget/chart/zeroblock/\"></iframe>');\n\t}\n\t$(\"#pageSplitter\").colResizable({\n\t\tliveDrag: true,\n\t\tonDrag: updateLayoutWidth,\n\t\tonResize: endResize\n\t});\n};\n\n$(window).resize(function() {\n updateLayoutHeight();\n});\n\nwindow.onbeforeunload = function(e) {\n\tclearInterval(globalUpdate);\n\tTransactionSocket.close();\n\tTradeSocket.close();\n};\n\nfunction zerocalc(){\n\tvar btcprice = $(\"#rate_btc\").html();\n\tvar zerobtcprice = $(\"#rate_zero\").html();\n\t$(\"#rate_zero_usd\").html((parseFloat(btcprice) * parseFloat(zerobtcprice)).toFixed(4));\n}\n\n","var rateboxTimeout;\nvar currentExchange;\nvar ratebox_ms = 3000; // 3 second update interval\nvar globalRate = -1; // set upon first rate received\nvar globalRateZerToBtc = -1; // set upon first rate received\n\nfunction setGlobalRate(rate,cur,accu) {\n if (globalRate === -1) {\n var checkbox = $(\"#showDollarCheckBox\");\n checkbox.prop(\"disabled\", false);\n checkbox.parent().removeClass(\"disabled\");\n }\n $(\"#rate_\"+cur).html(parseFloat(rate).toFixed(accu));\n globalRate = rate;\n zerocalc(); \n}\n\nrateboxGetRate = function() {\n\t$.getJSON(\"https://blockchain.info/ticker?cors=true\", function(data) {\n setGlobalRate(data.USD.last,'btc',2);\n });\n $.getJSON('https://api.coinmarketcap.com/v1/ticker/zero/?convert=BTC', function(data) {\n setGlobalRate(data.Data.LastPrice,'zero',8);\n globalRateZerToBtc = data.Data.LastPrice;\n }); \n \n};\n\n$(document).ready(function() { \n $.ajaxSetup ({ \n cache: false \n }); \n\n //cryptopia API query \n setInterval(function(){\n $.getJSON('https://api.coinmarketcap.com/v1/ticker/zero/?convert=BTC', function(data) {\n setGlobalRate(data.Data.LastPrice,'zero','8');\n globalRateZerToBtc = data.Data.LastPrice;\n if (rateboxTimeout) clearTimeout(rateboxTimeout);\n });\n }, 60000);\n \n\t// Bitstamp websocket API\n var pusher = new Pusher('de504dc5763aeef9ff52');\n var channel = pusher.subscribe('live_trades');\n channel.bind('trade', function(ticker) {\n setGlobalRate(ticker.price,'btc','2');\n if (rateboxTimeout) clearTimeout(rateboxTimeout);\n }); \n});\n\nswitchExchange = function(exchangeName) {\n\tclearTimeout(rateboxTimeout);\n\tcurrentExchange = exchangeName;\n\t$(\"#rate_btc, #rate_zero\").html(\"---\");\n\t\n\tif (exchangeName == \"bitstamp\") {\n\t\t$(\"#bitstampRate\").css(\"color\", \"white\");\n\t\t$(\"#mtgoxRate\").css(\"color\", \"gray\");\n\t} else if (exchangeName == \"mtgox\") {\n\t\t$(\"#mtgoxRate\").css(\"color\", \"white\");\n\t\t$(\"#bitstampRate\").css(\"color\", \"gray\");\n\t}\n\t\n\trateboxGetRate();\n};\n","var satoshi = 100000000;\nvar DELAY_CAP = 20000;\nvar lastBlockHeight = 0;\n\nvar provider_name = \"zerocurrency.io\";\n\n\nvar transactionSocketDelay = 1000;\n\n/** @constructor */\nfunction TransactionSocket() {\n\n}\n\nfunction dump(obj) {\n\tvar out = '';\n\tfor (var i in obj) {\n\t\tout += i + \": \" + obj[i] + \"\\n\";\n\t}\n alert(out);\n}\n\nTransactionSocket.init = function() {\n\t// Terminate previous connection, if any\n\tif (TransactionSocket.connection)\n\t\tTransactionSocket.connection.close();\n\n\tif ('WebSocket' in window) {\t\t\n\t\tvar connection = io(\"insight.zerocurrency.io:3001\");\t\t\n\t\tTransactionSocket.connection = connection;\n\n//* inserted\n\t\teventToListenTo = 'tx';\n\t\troom = 'inv';\n\t\t \n\t\tconnection.on('connect', function() {\n\t\t // Join the room.\n\t\t StatusBox.connected(\"blockchain\");\n\t\t connection.emit('subscribe', room);\n\t\t});\n\t\tconnection.on(eventToListenTo, function(data) {\n\t\t console.log(\"New transaction received: \" + data.txid);\n\t\t console.log(\"Transaction amount: \" + data.valueOut);\n\t\t var bitcoins = data.valueOut;\n\t\t\t\tnew Transaction(bitcoins, true);\n\t\t});\n\n// end inserted\t\t*/\n\t\tStatusBox.reconnecting(\"blockchain\");\n\t\tconnection.onopen = function() {\n\t\t\tconsole.log('zero.cryptonode.cloud1: Connection open!');\n\t\t\tStatusBox.connected(\"blockchain\");\n\t\t\tvar newTransactions = {\n\t\t\t\t\"op\" : \"unconfirmed_sub\"\n\t\t\t};\n\t\t\tvar newBlocks = {\n\t\t\t\t\"op\" : \"blocks_sub\"\n\t\t\t};\n\t\t\tconnection.send(JSON.stringify(newTransactions));\n\t\t\tconnection.send(JSON.stringify(newBlocks));\n\t\t\tconnection.send(JSON.stringify({\n\t\t\t\t\"op\" : \"ping_tx\"\n\t\t\t}));\n\t\t\t// Display the latest transaction so the user sees something.\n\t\t};\n\t\tconnection.onclose = function() {\n\t\t\tconsole.log('Bzero.cryptonode.cloud2: Connection closed');\n\t\t\tif ($(\"#blockchainCheckBox\").prop(\"checked\"))\n\t\t\t\tStatusBox.reconnecting(\"blockchain\");\n\t\t\telse\n\t\t\t\tStatusBox.closed(\"blockchain\");\n\t\t};\n\t\tconnection.onerror = function(error) {\n\t\t\tconsole.log('zero.cryptonode.cloud3: Connection Error: ' + error);\n\t\t};\n\n\t\tconnection.onmessage = function(e) {\n\t\t\tvar data = JSON.parse(e.data);\n\t\t\t\n\t\t\tif (data.op == \"no_data\") {\n\t\t\t TransactionSocket.close();\n\t\t\t setTimeout(TransactionSocket.init, transactionSocketDelay);\n\t\t\t transactionSocketDelay *= 2;\n\t\t\t console.log(\"connection borked, reconnecting\");\n\t\t\t}\n\n\t\t\t// New Transaction\n\t\t//\tif (data.op == \"utx\") {\n\n\t\t\tif( data.txid !==undefined){\n\t\t\t\tvar transacted = 0;\n\n\t\t\t\tfor (var i = 0; i < data.x.out.length; i++) {\n\t\t\t\t\ttransacted += data.x.out[i].value;\n\t\t\t\t}\n\n\t\t\t\t//var bitcoins = transacted / satoshi;\n\t\t\t\tvar bitcoins = data.valueOut;\n\t\t\t\tnew Transaction(bitcoins, true);\n\t\t\t\tconsole.log(\"Transaction: \" + bitcoins + \" BTC\");\n\n\t\t\t\tvar donation = false;\n var soundDonation = false;\n\t\t\t\t//var outputs = data.x.out;\n\t\t\t\t//for (var j = 0; j < outputs.length; j++) {\n\t\t\t\t//\tif ((outputs[j].addr) == DONATION_ADDRESS) {\n\t\t\t\t\t\t//bitcoins = data.x.out[j].value / satoshi;\n\t\t\t\t\t\t//new Transaction(bitcoins, true);\n\t\t\t\t\t\t//return;\n\t\t\t\t\t//}\n\t\t\t\t//}\n\n if (transaction_count === 0) {\n new Transaction(bitcoins);\n } else {\n\t\t\t\t setTimeout(function() {\n\t\t\t\t\t new Transaction(bitcoins);\n\t\t\t\t }, Math.random() * DELAY_CAP);\n\t\t\t\t}\n\n\t\t\t} else if (data.op == \"block\") {\n\t\t\t\tvar blockHeight = data.x.height;\n\t\t\t\tvar transactions = data.x.nTx;\n\t\t\t\tvar volumeSent = data.x.estimatedBTCSent;\n\t\t\t\tvar blockSize = data.x.size;\n\t\t\t\t// Filter out the orphaned blocks.\n\t\t\t\tif (blockHeight > lastBlockHeight) {\n\t\t\t\t\tlastBlockHeight = blockHeight;\n\t\t\t\t\tconsole.log(\"New Block\");\n\t\t\t\t\tnew Block(blockHeight, transactions, volumeSent, blockSize);\n\t\t\t\t}\n\t\t\t}\n\n\t\t};\n\t} else {\n\t\t//WebSockets are not supported.\n\t\tconsole.log(\"No websocket support.\");\n\t\tStatusBox.nosupport(\"blockchain\");\n\t}\n};\n\nTransactionSocket.close = function() {\n\tif (TransactionSocket.connection)\n\t\tTransactionSocket.connection.close();\n\tStatusBox.closed(\"blockchain\");\n};\n","var globalVolume = 50;\nvar globalScalePitch;\nvar globalBank;\nvar globalShowDollar = false;\n//init volume at 50%\nHowler.volume(globalVolume * 0.01);\n\nfunction Sound() {\n\n}\n\nvar soundBank = [];\n\t// the second number is the number of sound files available\n\tsoundBank[0] = [\"celesta\", 22];\n\tsoundBank[1] = [\"planet\", 33];\n\tsoundBank[2] = [\"wikki\", 13];\n\nfunction zeroPad(num, places) {\n\tvar zero = places - num.toString().length + 1;\n\treturn Array(+(zero > 0 && zero)).join(\"0\") + num;\n}\n\t\nSound.loadup = function(){\n\tvar newSound;\n\tvar istring;\n\n\t// sound0 = celesta\n\tsound0 = []; \n\n // sound1 = planet\n\tsound1 = []; \n\n // sound2 = celestaB\n\tsound2 = []; \n\n\t// String swells0, for blocks\n\tswells0 = [];\n\t\n\t// String swells1, for blocks\n\tswells1 = [];\n\n // String swells2, for blocks\n\tswells2 = [];\n\t\n\t// These variables are populated (and their sounds loaded) by the Sound.change function below.\n};\n\n\n\nSound.init = function() {\n\n\n\t// Initialize sound toggle button\n\t$(\"#volumeControl\").click(function() {\n\t\tif (!globalMute) {\n\t\t\tglobalMute = true;\n\t\t\tHowler.mute();\n\t\t\t$(\"#volumeControl\").css(\"background-position\", \"0 0\");\n\t\t} else {\n\t\t\tglobalMute = false;\n\t\t\tHowler.unmute();\n\t\t\t$(\"#volumeControl\").css(\"background-position\", \"0 -46px\");\n\t\t}\n\t});\n \n\t// Initialize sound slider\n\t$(\"#volumeSlider\").noUiSlider({\n\t\trange : {\n\t\t\t'min': 0,\n\t\t\t'max': 100\n\t\t},\n\t\tstart : 50,\n\t\thandles : 1,\n\t\tstep : 1,\n\t\torientation : \"vertical\"\n\t}).on('slide', function() {\n\t\t\tglobalVolume = 100 - $(this).val();\n\t\t\tHowler.volume(globalVolume * 0.01);\n\t});\n\t\n\tglobalScalePitch = $(\"#scalePitchCheckBox\").attr(\"checked\");\n\tSound.change(0);\n};\n\nSound.change = function(instrument_number) {\n\tvar musicianString = \"Donate to instrument creator: \";\n\tvar i;\n\t// INSTRUMENT 0\n\tif (instrument_number === 0 ) {\n\t\t// Load sound and swells if not already loaded\n\t\tif (sound0.length === 0) {\n\t\t\tfor (i = 1; i <= 22; i++) {\n\t\t\t\tistring = zeroPad(i, 3);\n\t\t\t\tnewSound = new Howl({\n\t\t\t\t\t\turls: [\"sounds/celesta/\" + \"celesta\" + istring + \".ogg\",\n\t\t\t\t\t\t\t \"sounds/celesta/\" + \"celesta\" + istring + \".mp3\"],\n\t\t\t\t\t\tautoplay: false\n\t\t\t\t});\n\t\t\t\tsound0.push(newSound);\n\t\t\t}\n\t\t}\n\t\tif (swells0.length === 0) {\n\t\t\tfor (i = 1; i <= 3; i++) {\n\t\t\t\tnewSound = new Howl({\n\t\t\t\t\turls: [\"sounds/swells0/swell\" + i +\".ogg\",\n\t\t\t\t\t\t\t\"sounds/swells0/swell\" + i +\".mp3\"],\n\t\t\t\t\tautoplay: false\n\t\t\t\t});\n\t\t\t\tswells0.push(newSound);\n\t\t\t}\n\t\t}\n\t\tcurrentSound = sound0;\n\t\tcurrentSwells = swells0;\n\t\t$('#musicianDonation').text(\"\");\n\t}\n\t// INSTRUMENT 1\n\telse if (instrument_number === 1) {\n\t // Load sound and swells if not already loaded\n\t\tif (sound1.length === 0) {\n\t\t\tfor (i = 1; i <= 33; i++) {\n\t\t\t\tistring = zeroPad(i, 3);\n\t\t\t\tnewSound = new Howl({\n\t\t\t\t\t\turls: [\"sounds/planet/\" + \"planet\" + istring + \".ogg\",\n\t\t\t\t\t\t\t \"sounds/planet/\" + \"planet\" + istring + \".mp3\"],\n\t\t\t\t\t\tautoplay: false\n\t\t\t\t});\n\t\t\t\tsound1.push(newSound);\n\t\t\t}\n\t\t}\n if (swells1.length === 0) {\n\t\t\tfor (i = 1; i <= 3; i++) {\n\t\t\t\tnewSound = new Howl({\n\t\t\t\t\turls: [\"sounds/swells1/planetswell\" + i +\".ogg\",\n\t\t\t\t\t\t\t\"sounds/swells1/planetswell\" + i +\".mp3\"],\n\t\t\t\t\tautoplay: false\n\t\t\t\t});\n\t\t\t\tswells1.push(newSound);\n\t\t\t}\n\t\t}\n\t\tcurrentSound = sound1;\n\t\tcurrentSwells = swells1;\n\t\tSOUND_DONATION_ADDRESS = \"144b31mmaWQVDQFiUPo6HEzxc2Dm83WXrW\";\n\t\t$('#musicianDonation').html(musicianString + \"<span>\" + SOUND_DONATION_ADDRESS + \"</span>\");\n\t}\n // INSTRUMENT 2\n\telse if (instrument_number === 2) {\n\t\t// Load sound and swells if not already loaded\n\t\tif (sound2.length === 0) {\n\t\t\tfor (i = 1; i <= 13; i++) {\n\t\t\t\tistring = zeroPad(i, 3);\n\t\t\t\tnewSound = new Howl({\n\t\t\t\t\t\turls: [\"sounds/wikki/\" + \"wikki\" + istring + \".ogg\",\n\t\t\t\t\t\t\t \"sounds/wikki/\" + \"wikki\" + istring + \".mp3\"],\n\t\t\t\t\t\tautoplay: false\n\t\t\t\t});\n\t\t\t\tsound2.push(newSound);\n\t\t\t}\n\t\t}\n\t\tif (swells2.length === 0) {\n\t\t\tfor (i = 1; i <= 3; i++) {\n\t\t\t\tnewSound = new Howl({\n\t\t\t\t\turls: [\"sounds/swells2/wikkiswell\" + i +\".ogg\",\n\t\t\t\t\t\t\t\"sounds/swells2/wikkiswell\" + i +\".mp3\"],\n\t\t\t\t\tautoplay: false\n\t\t\t\t});\n\t\t\t\tswells2.push(newSound);\n\t\t\t}\n\t\t}\n\t currentSound = sound2;\n\t\tcurrentSwells = swells2;\n\t\tSOUND_DONATION_ADDRESS = \"1JFaYRGkDmhpSTbFKwqDWKr2ncvvrgYEAV\";\n\t\t$('#musicianDonation').html(musicianString + \"<span>\" + SOUND_DONATION_ADDRESS + \"</span>\");\n\t\t}\n};\n\nvar currentNotes = 0;\nvar noteTimeout = 500;\n\nSound.playRandomAtVolume = function(volume) {\n\tif (globalMute)\n\t\treturn;\n\t\t\n\tvar randomPitch = Math.floor(Math.random() * 100);\n\tSound.playPitchAtVolume(volume, randomPitch);\n};\n\nSound.playPitchAtVolume = function(volume, pitch) {\n\tif (globalMute)\n\t\treturn;\n\t// Find the index corresponding to the requested pitch\n\tvar index = Math.floor(pitch / 100.0 * currentSound.length);\n\t//console.log(\"Pitch: \" + pitch);\n\t\n\t// Here we fuzz the index a bit to prevent the same sound\n\t// from being heard over and over again, which gets annoying\n\tvar fuzz = Math.floor(Math.random() * 4) - 2;\n\tindex += fuzz;\n\tindex = Math.min(currentSound.length - 1, index);\n\tindex = Math.max(0, index);\n\t\n\t//console.log(\"Fuzz: \" + fuzz);\n\t//console.log(\"Index: \" + index);\n\t\n\n\t//var readyState = currentSound[index].get(\"readyState\");\n\tif (currentNotes < 5) {\n currentSound[index].volume(volume);\n\t\tcurrentSound[index].play();\n\t\tcurrentNotes++;\n\t\tsetTimeout(function() {\n\t\t\tcurrentNotes--;\n\t\t}, noteTimeout);\n\t}\n};\n\nvar lastBlockSound = -1;\nSound.playRandomSwell = function() {\n\tif (globalMute)\n\t\treturn;\n\n\tvar randomIndex;\n\tdo {\n\t\trandomIndex = Math.floor(Math.random() * currentSwells.length);\n\t} while (randomIndex == lastBlockSound);\n\n\tlastBlockSound = randomIndex;\n\n\t//var readyState = this.swells[randomIndex].get(\"readyState\");\n\t//if (readyState >= 2)\n\tcurrentSwells[randomIndex].play();\n};\n","var CONNECTED = \"Connected.\";\nvar CONNECTING = \"Connecting...\";\nvar NO_SUPPORT = \"No browser support.\";\nvar CLOSED = \"Click to connect.\";\n\nvar provider_name = \"\";\n\nfunction StatusBox() {\n\n}\n\nStatusBox.init = function(debugmode) {\n\tStatusBox.blockchain = $(\"#blockchainStatus\");\n\tStatusBox.mtgox = $(\"#mtgoxStatus\");\n\n\tif (debugmode) {\n\t\tStatusBox.blockchain.html(\"\");\n\t\tStatusBox.mtgox.html(\"Debug mode.\");\n\t}\n\n\tif ($(\"#blockchainCheckBox\").is(\":checked\"))\n\t\tStatusBox.reconnecting(\"blockchain\");\n\telse\n\t\tStatusBox.closed(\"blockchain\");\n\n\tif ($(\"#mtgoxCheckBox\").is(\":checked\"))\n\t\tStatusBox.reconnecting(\"mtgox\");\n\telse\n\t\tStatusBox.closed(\"mtgox\");\n};\n// \"type\" can be either \"blockchain\" or \"mtgox\"\nStatusBox.connected = function(type) {\n\tif (type == \"blockchain\")\n\t\tStatusBox.blockchain.html('Zero Network ' + provider_name + ': <span style=\"color: green;\">' + CONNECTED + '</span>');\n\tif (type == \"mtgox\")\n\t\tStatusBox.mtgox.html('Mt.Gox Trades: <span style=\"color: green;\">' + CONNECTED + '</span>');\n};\n\nStatusBox.reconnecting = function(type) {\n\tif (type == \"blockchain\")\n\t\tStatusBox.blockchain.html('Zero Network ' + provider_name + ': <span style=\"color: yellow;\">' + CONNECTING + '</span>');\n\tif (type == \"mtgox\")\n\t\tStatusBox.mtgox.html('Mt.Gox Trades: <span style=\"color: yellow;\">' + CONNECTING + '</span>');\n};\n\nStatusBox.nosupport = function(type) {\n\tif (type == \"blockchain\")\n\t\tStatusBox.blockchain.html('Zero Network ' + provider_name + ': <span style=\"color: red;\">' + NO_SUPPORT + '</span>');\n\tif (type == \"mtgox\")\n\t\tStatusBox.mtgox.html('Mt.Gox Trades: <span style=\"color: red;\">' + NO_SUPPORT + '</span>');\n};\n\nStatusBox.closed = function(type) {\n\tif (type == \"blockchain\")\n\t\tStatusBox.blockchain.html('Zero Network ' + provider_name + ': <span style=\"color: gray;\">' + CLOSED + '</span>');\n\tif (type == \"mtgox\")\n\t\tStatusBox.mtgox.html('Mt.Gox Trades: <span style=\"color: gray;\">' + CLOSED + '</span>');\n};\n","/** \n * @constructor\n * @extends Floatable\n */\nfunction Transaction(bitcoins, highlight, currency, currencyName) {\n\tif (document.visibilityState === \"visible\") {\n\t\tFloatable.call(this);\n\n\t\tthis.area = bitcoins * 100 + 3000;\n\t\tthis.width = this.height = Math.sqrt(this.area / Math.PI) * 2;\n\n\t\tthis.addImage(bubbleImage, this.width, this.height);\n\t\n\t var bitcoinVal = bitcoins.toFixed(2);\n\t var bitcoinString;\n\t \n\t if(globalShowDollar === true) {\n \t\tbitcoinString = \"$\" + (bitcoins*globalRate*globalRateZerToBtc).toFixed(2);\n \t} else if (bitcoinVal === \"0.00\") {\n\t bitcoinString = \"<<span class='bitcoinsymbol'>Ƶ</span>0.01\";\n\t } else {\n\t bitcoinString = \"<span class='bitcoinsymbol'>Ƶ</span>\" + bitcoinVal;\n\t }\n\t\n\t\tif (!highlight) {\n\t\t\tthis.addText(bitcoinString);\n\t\t} else {\t\t\t\n\t\t\tthis.addText('<span style=\"color: yellow;\">' + bitcoinString + '</span>');\n\t\t}\n\t\tif (currency && currencyName) {\n\t\t\tthis.addText('<br />' + currency.toFixed(2) + ' ' + currencyName);\n\t\t}\n\t\tthis.initPosition();\n\t\t\n\t\t// Sound\n\t var maxBitcoins = 1000;\n\t var minVolume = 0.3;\n\t var maxVolume = 0.7;\n\t var volume = bitcoins / (maxBitcoins / (maxVolume - minVolume)) + minVolume;\n\t if (volume > maxVolume)\n\t\t volume = maxVolume;\n\t\n\t var maxPitch = 100.0;\n\t // We need to use a log that makes it so that maxBitcoins reaches the maximum pitch.\n\t // Well, the opposite of the maximum pitch. Anyway. So we solve:\n\t // maxPitch = log(maxBitcoins + logUsed) / log(logUsed)\n\t // For maxPitch = 100 (for 100%) and maxBitcoins = 1000, that gives us...\n\t var logUsed = 1.0715307808111486871978099;\n\t // So we find the smallest value between log(bitcoins + logUsed) / log(logUsed) and our max pitch...\n\t var pitch = Math.min(maxPitch, Math.log(bitcoins + logUsed) / Math.log(logUsed));\n\t // ...we invert it so that a bigger transaction = a deeper noise...\n\t pitch = maxPitch - pitch;\n\t // ...and we play the sound!\n\t if(globalScalePitch) {\n\t\t Sound.playPitchAtVolume(volume, pitch);\n\t } else {\n\t\t Sound.playRandomAtVolume(volume);\n\t }\n\t \n\t transaction_count++;\n\t \n\t if (transaction_count === 1) {\n\t document.getElementById(\"waitingForTransactions\").style.opacity = \"0\";\n\t }\n\t\t\n\t}\n\n}\n\nextend(Floatable, Transaction);\n","/*\n * Konami-JS ~ \n * :: Now with support for touch events and multiple instances for \n * :: those situations that call for multiple easter eggs!\n * Code: http://konami-js.googlecode.com/\n * Examples: http://www.snaptortoise.com/konami-js\n * Copyright (c) 2009 George Mandis (georgemandis.com, snaptortoise.com)\n * Version: 1.4.2 (9/2/2013)\n * Licensed under the MIT License (http://opensource.org/licenses/MIT)\n * Tested in: Safari 4+, Google Chrome 4+, Firefox 3+, IE7+, Mobile Safari 2.2.1 and Dolphin Browser\n */\n\nvar Konami = function (callback) {\n\tvar konami = {\n\t\taddEvent: function (obj, type, fn, ref_obj) {\n\t\t\tif (obj.addEventListener)\n\t\t\t\tobj.addEventListener(type, fn, false);\n\t\t\telse if (obj.attachEvent) {\n\t\t\t\t// IE\n\t\t\t\tobj[\"e\" + type + fn] = fn;\n\t\t\t\tobj[type + fn] = function () {\n\t\t\t\t\tobj[\"e\" + type + fn](window.event, ref_obj);\n\t\t\t\t}\n\t\t\t\tobj.attachEvent(\"on\" + type, obj[type + fn]);\n\t\t\t}\n\t\t},\n\t\tinput: \"\",\n\t\tpattern: \"38384040373937396665\",\n\t\tload: function (link) {\n\t\t\tthis.addEvent(document, \"keydown\", function (e, ref_obj) {\n\t\t\t\tif (ref_obj) konami = ref_obj; // IE\n\t\t\t\tkonami.input += e ? e.keyCode : event.keyCode;\n\t\t\t\tif (konami.input.length > konami.pattern.length)\n\t\t\t\t\tkonami.input = konami.input.substr((konami.input.length - konami.pattern.length));\n\t\t\t\tif (konami.input == konami.pattern) {\n\t\t\t\t\tkonami.code(link);\n\t\t\t\t\tkonami.input = \"\";\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}, this);\n\t\t\tthis.iphone.load(link);\n\t\t},\n\t\tcode: function (link) {\n\t\t\twindow.location = link\n\t\t},\n\t\tiphone: {\n\t\t\tstart_x: 0,\n\t\t\tstart_y: 0,\n\t\t\tstop_x: 0,\n\t\t\tstop_y: 0,\n\t\t\ttap: false,\n\t\t\tcapture: false,\n\t\t\torig_keys: \"\",\n\t\t\tkeys: [\"UP\", \"UP\", \"DOWN\", \"DOWN\", \"LEFT\", \"RIGHT\", \"LEFT\", \"RIGHT\", \"TAP\", \"TAP\"],\n\t\t\tcode: function (link) {\n\t\t\t\tkonami.code(link);\n\t\t\t},\n\t\t\tload: function (link) {\n\t\t\t\tthis.orig_keys = this.keys;\n\t\t\t\tkonami.addEvent(document, \"touchmove\", function (e) {\n\t\t\t\t\tif (e.touches.length == 1 && konami.iphone.capture == true) {\n\t\t\t\t\t\tvar touch = e.touches[0];\n\t\t\t\t\t\tkonami.iphone.stop_x = touch.pageX;\n\t\t\t\t\t\tkonami.iphone.stop_y = touch.pageY;\n\t\t\t\t\t\tkonami.iphone.tap = false;\n\t\t\t\t\t\tkonami.iphone.capture = false;\n\t\t\t\t\t\tkonami.iphone.check_direction();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tkonami.addEvent(document, \"touchend\", function (evt) {\n\t\t\t\t\tif (konami.iphone.tap == true) konami.iphone.check_direction(link);\n\t\t\t\t}, false);\n\t\t\t\tkonami.addEvent(document, \"touchstart\", function (evt) {\n\t\t\t\t\tkonami.iphone.start_x = evt.changedTouches[0].pageX;\n\t\t\t\t\tkonami.iphone.start_y = evt.changedTouches[0].pageY;\n\t\t\t\t\tkonami.iphone.tap = true;\n\t\t\t\t\tkonami.iphone.capture = true;\n\t\t\t\t});\n\t\t\t},\n\t\t\tcheck_direction: function (link) {\n\t\t\t\tx_magnitude = Math.abs(this.start_x - this.stop_x);\n\t\t\t\ty_magnitude = Math.abs(this.start_y - this.stop_y);\n\t\t\t\tx = ((this.start_x - this.stop_x) < 0) ? \"RIGHT\" : \"LEFT\";\n\t\t\t\ty = ((this.start_y - this.stop_y) < 0) ? \"DOWN\" : \"UP\";\n\t\t\t\tresult = (x_magnitude > y_magnitude) ? x : y;\n\t\t\t\tresult = (this.tap == true) ? \"TAP\" : result;\n\n\t\t\t\tif (result == this.keys[0]) this.keys = this.keys.slice(1, this.keys.length);\n\t\t\t\tif (this.keys.length == 0) {\n\t\t\t\t\tthis.keys = this.orig_keys;\n\t\t\t\t\tthis.code(link);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\ttypeof callback === \"string\" && konami.load(callback);\n\tif (typeof callback === \"function\") {\n\t\tkonami.code = callback;\n\t\tkonami.load();\n\t}\n\n\treturn konami;\n};\n","/*!\n * howler.js v1.1.25\n * howlerjs.com\n *\n * (c) 2013-2014, James Simpson of GoldFire Studios\n * goldfirestudios.com\n *\n * MIT License\n */\n\n(function() {\n // setup\n var cache = {};\n\n // setup the audio context\n var ctx = null,\n usingWebAudio = true,\n noAudio = false;\n try {\n if (typeof AudioContext !== 'undefined') {\n ctx = new AudioContext();\n } else if (typeof webkitAudioContext !== 'undefined') {\n ctx = new webkitAudioContext();\n } else {\n usingWebAudio = false;\n }\n } catch(e) {\n usingWebAudio = false;\n }\n\n if (!usingWebAudio) {\n if (typeof Audio !== 'undefined') {\n try {\n new Audio();\n } catch(e) {\n noAudio = true;\n }\n } else {\n noAudio = true;\n }\n }\n\n // create a master gain node\n if (usingWebAudio) {\n var masterGain = (typeof ctx.createGain === 'undefined') ? ctx.createGainNode() : ctx.createGain();\n masterGain.gain.value = 1;\n masterGain.connect(ctx.destination);\n }\n\n // create global controller\n var HowlerGlobal = function(codecs) {\n this._volume = 1;\n this._muted = false;\n this.usingWebAudio = usingWebAudio;\n this.ctx = ctx;\n this.noAudio = noAudio;\n this._howls = [];\n this._codecs = codecs;\n this.iOSAutoEnable = true;\n };\n HowlerGlobal.prototype = {\n /**\n * Get/set the global volume for all sounds.\n * @param {Float} vol Volume from 0.0 to 1.0.\n * @return {Howler/Float} Returns self or current volume.\n */\n volume: function(vol) {\n var self = this;\n\n // make sure volume is a number\n vol = parseFloat(vol);\n\n if (vol >= 0 && vol <= 1) {\n self._volume = vol;\n\n if (usingWebAudio) {\n masterGain.gain.value = vol;\n }\n\n // loop through cache and change volume of all nodes that are using HTML5 Audio\n for (var key in self._howls) {\n if (self._howls.hasOwnProperty(key) && self._howls[key]._webAudio === false) {\n // loop through the audio nodes\n for (var i=0; i<self._howls[key]._audioNode.length; i++) {\n self._howls[key]._audioNode[i].volume = self._howls[key]._volume * self._volume;\n }\n }\n }\n\n return self;\n }\n\n // return the current global volume\n return (usingWebAudio) ? masterGain.gain.value : self._volume;\n },\n\n /**\n * Mute all sounds.\n * @return {Howler}\n */\n mute: function() {\n this._setMuted(true);\n\n return this;\n },\n\n /**\n * Unmute all sounds.\n * @return {Howler}\n */\n unmute: function() {\n this._setMuted(false);\n\n return this;\n },\n\n /**\n * Handle muting and unmuting globally.\n * @param {Boolean} muted Is muted or not.\n */\n _setMuted: function(muted) {\n var self = this;\n\n self._muted = muted;\n\n if (usingWebAudio) {\n masterGain.gain.value = muted ? 0 : self._volume;\n }\n\n for (var key in self._howls) {\n if (self._howls.hasOwnProperty(key) && self._howls[key]._webAudio === false) {\n // loop through the audio nodes\n for (var i=0; i<self._howls[key]._audioNode.length; i++) {\n self._howls[key]._audioNode[i].muted = muted;\n }\n }\n }\n },\n\n /**\n * Check for codec support.\n * @param {String} ext Audio file extention.\n * @return {Boolean}\n */\n codecs: function(ext) {\n return this._codecs[ext];\n },\n\n /**\n * iOS will only allow audio to be played after a user interaction.\n * Attempt to automatically unlock audio on the first user interaction.\n * Concept from: http://paulbakaus.com/tutorials/html5/web-audio-on-ios/\n * @return {Howler}\n */\n _enableiOSAudio: function() {\n var self = this;\n\n // only run this on iOS if audio isn't already eanbled\n if (ctx && (self._iOSEnabled || !/iPhone|iPad|iPod/i.test(navigator.userAgent))) {\n return;\n }\n\n self._iOSEnabled = false;\n\n // call this method on touch start to create and play a buffer,\n // then check if the audio actually played to determine if\n // audio has now been unlocked on iOS\n var unlock = function() {\n // create an empty buffer\n var buffer = ctx.createBuffer(1, 1, 22050);\n var source = ctx.createBufferSource();\n source.buffer = buffer;\n source.connect(ctx.destination);\n\n // play the empty buffer\n if (typeof source.start === 'undefined') {\n source.noteOn(0);\n } else {\n source.start(0);\n }\n\n // setup a timeout to check that we are unlocked on the next event loop\n setTimeout(function() {\n if ((source.playbackState === source.PLAYING_STATE || source.playbackState === source.FINISHED_STATE)) {\n // update the unlocked state and prevent this check from happening again\n self._iOSEnabled = true;\n self.iOSAutoEnable = false;\n\n // remove the touch start listener\n window.removeEventListener('touchstart', unlock, false);\n }\n }, 0);\n };\n\n // setup a touch start listener to attempt an unlock in\n window.addEventListener('touchstart', unlock, false);\n\n return self;\n }\n };\n\n // check for browser codec support\n var audioTest = null;\n var codecs = {};\n if (!noAudio) {\n audioTest = new Audio();\n codecs = {\n mp3: !!audioTest.canPlayType('audio/mpeg;').replace(/^no$/, ''),\n opus: !!audioTest.canPlayType('audio/ogg; codecs=\"opus\"').replace(/^no$/, ''),\n ogg: !!audioTest.canPlayType('audio/ogg; codecs=\"vorbis\"').replace(/^no$/, ''),\n wav: !!audioTest.canPlayType('audio/wav; codecs=\"1\"').replace(/^no$/, ''),\n aac: !!audioTest.canPlayType('audio/aac;').replace(/^no$/, ''),\n m4a: !!(audioTest.canPlayType('audio/x-m4a;') || audioTest.canPlayType('audio/m4a;') || audioTest.canPlayType('audio/aac;')).replace(/^no$/, ''),\n mp4: !!(audioTest.canPlayType('audio/x-mp4;') || audioTest.canPlayType('audio/mp4;') || audioTest.canPlayType('audio/aac;')).replace(/^no$/, ''),\n weba: !!audioTest.canPlayType('audio/webm; codecs=\"vorbis\"').replace(/^no$/, '')\n };\n }\n\n // allow access to the global audio controls\n var Howler = new HowlerGlobal(codecs);\n\n // setup the audio object\n var Howl = function(o) {\n var self = this;\n\n // setup the defaults\n self._autoplay = o.autoplay || false;\n self._buffer = o.buffer || false;\n self._duration = o.duration || 0;\n self._format = o.format || null;\n self._loop = o.loop || false;\n self._loaded = false;\n self._sprite = o.sprite || {};\n self._src = o.src || '';\n self._pos3d = o.pos3d || [0, 0, -0.5];\n self._volume = o.volume !== undefined ? o.volume : 1;\n self._urls = o.urls || [];\n self._rate = o.rate || 1;\n\n // allow forcing of a specific panningModel ('equalpower' or 'HRTF'),\n // if none is specified, defaults to 'equalpower' and switches to 'HRTF'\n // if 3d sound is used\n self._model = o.model || null;\n\n // setup event functions\n self._onload = [o.onload || function() {}];\n self._onloaderror = [o.onloaderror || function() {}];\n self._onend = [o.onend || function() {}];\n self._onpause = [o.onpause || function() {}];\n self._onplay = [o.onplay || function() {}];\n\n self._onendTimer = [];\n\n // Web Audio or HTML5 Audio?\n self._webAudio = usingWebAudio && !self._buffer;\n\n // check if we need to fall back to HTML5 Audio\n self._audioNode = [];\n if (self._webAudio) {\n self._setupAudioNode();\n }\n\n // automatically try to enable audio on iOS\n if (typeof ctx !== 'undefined' && ctx && Howler.iOSAutoEnable) {\n Howler._enableiOSAudio();\n }\n\n // add this to an array of Howl's to allow global control\n Howler._howls.push(self);\n\n // load the track\n self.load();\n };\n\n // setup all of the methods\n Howl.prototype = {\n /**\n * Load an audio file.\n * @return {Howl}\n */\n load: function() {\n var self = this,\n url = null;\n\n // if no audio is available, quit immediately\n if (noAudio) {\n self.on('loaderror');\n return;\n }\n\n // loop through source URLs and pick the first one that is compatible\n for (var i=0; i<self._urls.length; i++) {\n var ext, urlItem;\n\n if (self._format) {\n // use specified audio format if available\n ext = self._format;\n } else {\n // figure out the filetype (whether an extension or base64 data)\n urlItem = self._urls[i];\n ext = /^data:audio\\/([^;,]+);/i.exec(urlItem);\n if (!ext) {\n ext = /\\.([^.]+)$/.exec(urlItem.split('?', 1)[0]);\n }\n\n if (ext) {\n ext = ext[1].toLowerCase();\n } else {\n self.on('loaderror');\n return;\n }\n }\n\n if (codecs[ext]) {\n url = self._urls[i];\n break;\n }\n }\n\n if (!url) {\n self.on('loaderror');\n return;\n }\n\n self._src = url;\n\n if (self._webAudio) {\n loadBuffer(self, url);\n } else {\n var newNode = new Audio();\n\n // listen for errors with HTML5 audio (http://dev.w3.org/html5/spec-author-view/spec.html#mediaerror)\n newNode.addEventListener('error', function () {\n if (newNode.error && newNode.error.code === 4) {\n HowlerGlobal.noAudio = true;\n }\n\n self.on('loaderror', {type: newNode.error ? newNode.error.code : 0});\n }, false);\n\n self._audioNode.push(newNode);\n\n // setup the new audio node\n newNode.src = url;\n newNode._pos = 0;\n newNode.preload = 'auto';\n newNode.volume = (Howler._muted) ? 0 : self._volume * Howler.volume();\n\n // setup the event listener to start playing the sound\n // as soon as it has buffered enough\n var listener = function() {\n // round up the duration when using HTML5 Audio to account for the lower precision\n self._duration = Math.ceil(newNode.duration * 10) / 10;\n\n // setup a sprite if none is defined\n if (Object.getOwnPropertyNames(self._sprite).length === 0) {\n self._sprite = {_default: [0, self._duration * 1000]};\n }\n\n if (!self._loaded) {\n self._loaded = true;\n self.on('load');\n }\n\n if (self._autoplay) {\n self.play();\n }\n\n // clear the event listener\n newNode.removeEventListener('canplaythrough', listener, false);\n };\n newNode.addEventListener('canplaythrough', listener, false);\n newNode.load();\n }\n\n return self;\n },\n\n /**\n * Get/set the URLs to be pulled from to play in this source.\n * @param {Array} urls Arry of URLs to load from\n * @return {Howl} Returns self or the current URLs\n */\n urls: function(urls) {\n var self = this;\n\n if (urls) {\n self.stop();\n self._urls = (typeof urls === 'string') ? [urls] : urls;\n self._loaded = false;\n self.load();\n\n return self;\n } else {\n return self._urls;\n }\n },\n\n /**\n * Play a sound from the current time (0 by default).\n * @param {String} sprite (optional) Plays from the specified position in the sound sprite definition.\n * @param {Function} callback (optional) Returns the unique playback id for this sound instance.\n * @return {Howl}\n */\n play: function(sprite, callback) {\n var self = this;\n\n // if no sprite was passed but a callback was, update the variables\n if (typeof sprite === 'function') {\n callback = sprite;\n }\n\n // use the default sprite if none is passed\n if (!sprite || typeof sprite === 'function') {\n sprite = '_default';\n }\n\n // if the sound hasn't been loaded, add it to the event queue\n if (!self._loaded) {\n self.on('load', function() {\n self.play(sprite, callback);\n });\n\n return self;\n }\n\n // if the sprite doesn't exist, play nothing\n if (!self._sprite[sprite]) {\n if (typeof callback === 'function') callback();\n return self;\n }\n\n // get the node to playback\n self._inactiveNode(function(node) {\n // persist the sprite being played\n node._sprite = sprite;\n\n // determine where to start playing from\n var pos = (node._pos > 0) ? node._pos : self._sprite[sprite][0] / 1000;\n\n // determine how long to play for\n var duration = 0;\n if (self._webAudio) {\n duration = self._sprite[sprite][1] / 1000 - node._pos;\n if (node._pos > 0) {\n pos = self._sprite[sprite][0] / 1000 + pos;\n }\n } else {\n duration = self._sprite[sprite][1] / 1000 - (pos - self._sprite[sprite][0] / 1000);\n }\n\n // determine if this sound should be looped\n var loop = !!(self._loop || self._sprite[sprite][2]);\n\n // set timer to fire the 'onend' event\n var soundId = (typeof callback === 'string') ? callback : Math.round(Date.now() * Math.random()) + '',\n timerId;\n (function() {\n var data = {\n id: soundId,\n sprite: sprite,\n loop: loop\n };\n timerId = setTimeout(function() {\n // if looping, restart the track\n if (!self._webAudio && loop) {\n self.stop(data.id).play(sprite, data.id);\n }\n\n // set web audio node to paused at end\n if (self._webAudio && !loop) {\n self._nodeById(data.id).paused = true;\n self._nodeById(data.id)._pos = 0;\n\n // clear the end timer\n self._clearEndTimer(data.id);\n }\n\n // end the track if it is HTML audio and a sprite\n if (!self._webAudio && !loop) {\n self.stop(data.id);\n }\n\n // fire ended event\n self.on('end', soundId);\n }, duration * 1000);\n\n // store the reference to the timer\n self._onendTimer.push({timer: timerId, id: data.id});\n })();\n\n if (self._webAudio) {\n var loopStart = self._sprite[sprite][0] / 1000,\n loopEnd = self._sprite[sprite][1] / 1000;\n\n // set the play id to this node and load into context\n node.id = soundId;\n node.paused = false;\n refreshBuffer(self, [loop, loopStart, loopEnd], soundId);\n self._playStart = ctx.currentTime;\n node.gain.value = self._volume;\n\n if (typeof node.bufferSource.start === 'undefined') {\n node.bufferSource.noteGrainOn(0, pos, duration);\n } else {\n node.bufferSource.start(0, pos, duration);\n }\n } else {\n if (node.readyState === 4 || !node.readyState && navigator.isCocoonJS) {\n node.readyState = 4;\n node.id = soundId;\n node.currentTime = pos;\n node.muted = Howler._muted || node.muted;\n node.volume = self._volume * Howler.volume();\n setTimeout(function() { node.play(); }, 0);\n } else {\n self._clearEndTimer(soundId);\n\n (function(){\n var sound = self,\n playSprite = sprite,\n fn = callback,\n newNode = node;\n var listener = function() {\n sound.play(playSprite, fn);\n\n // clear the event listener\n newNode.removeEventListener('canplaythrough', listener, false);\n };\n newNode.addEventListener('canplaythrough', listener, false);\n })();\n\n return self;\n }\n }\n\n // fire the play event and send the soundId back in the callback\n self.on('play');\n if (typeof callback === 'function') callback(soundId);\n\n return self;\n });\n\n return self;\n },\n\n /**\n * Pause playback and save the current position.\n * @param {String} id (optional) The play instance ID.\n * @return {Howl}\n */\n pause: function(id) {\n var self = this;\n\n // if the sound hasn't been loaded, add it to the event queue\n if (!self._loaded) {\n self.on('play', function() {\n self.pause(id);\n });\n\n return self;\n }\n\n // clear 'onend' timer\n self._clearEndTimer(id);\n\n var activeNode = (id) ? self._nodeById(id) : self._activeNode();\n if (activeNode) {\n activeNode._pos = self.pos(null, id);\n\n if (self._webAudio) {\n // make sure the sound has been created\n if (!activeNode.bufferSource || activeNode.paused) {\n return self;\n }\n\n activeNode.paused = true;\n if (typeof activeNode.bufferSource.stop === 'undefined') {\n activeNode.bufferSource.noteOff(0);\n } else {\n activeNode.bufferSource.stop(0);\n }\n } else {\n activeNode.pause();\n }\n }\n\n self.on('pause');\n\n return self;\n },\n\n /**\n * Stop playback and reset to start.\n * @param {String} id (optional) The play instance ID.\n * @return {Howl}\n */\n stop: function(id) {\n var self = this;\n\n // if the sound hasn't been loaded, add it to the event queue\n if (!self._loaded) {\n self.on('play', function() {\n self.stop(id);\n });\n\n return self;\n }\n\n // clear 'onend' timer\n self._clearEndTimer(id);\n\n var activeNode = (id) ? self._nodeById(id) : self._activeNode();\n if (activeNode) {\n activeNode._pos = 0;\n\n if (self._webAudio) {\n // make sure the sound has been created\n if (!activeNode.bufferSource || activeNode.paused) {\n return self;\n }\n\n activeNode.paused = true;\n\n if (typeof activeNode.bufferSource.stop === 'undefined') {\n activeNode.bufferSource.noteOff(0);\n } else {\n activeNode.bufferSource.stop(0);\n }\n } else if (!isNaN(activeNode.duration)) {\n activeNode.pause();\n activeNode.currentTime = 0;\n }\n }\n\n return self;\n },\n\n /**\n * Mute this sound.\n * @param {String} id (optional) The play instance ID.\n * @return {Howl}\n */\n mute: function(id) {\n var self = this;\n\n // if the sound hasn't been loaded, add it to the event queue\n if (!self._loaded) {\n self.on('play', function() {\n self.mute(id);\n });\n\n return self;\n }\n\n var activeNode = (id) ? self._nodeById(id) : self._activeNode();\n if (activeNode) {\n if (self._webAudio) {\n activeNode.gain.value = 0;\n } else {\n activeNode.muted = true;\n }\n }\n\n return self;\n },\n\n /**\n * Unmute this sound.\n * @param {String} id (optional) The play instance ID.\n * @return {Howl}\n */\n unmute: function(id) {\n var self = this;\n\n // if the sound hasn't been loaded, add it to the event queue\n if (!self._loaded) {\n self.on('play', function() {\n self.unmute(id);\n });\n\n return self;\n }\n\n var activeNode = (id) ? self._nodeById(id) : self._activeNode();\n if (activeNode) {\n if (self._webAudio) {\n activeNode.gain.value = self._volume;\n } else {\n activeNode.muted = false;\n }\n }\n\n return self;\n },\n\n /**\n * Get/set volume of this sound.\n * @param {Float} vol Volume from 0.0 to 1.0.\n * @param {String} id (optional) The play instance ID.\n * @return {Howl/Float} Returns self or current volume.\n */\n volume: function(vol, id) {\n var self = this;\n\n // make sure volume is a number\n vol = parseFloat(vol);\n\n if (vol >= 0 && vol <= 1) {\n self._volume = vol;\n\n // if the sound hasn't been loaded, add it to the event queue\n if (!self._loaded) {\n self.on('play', function() {\n self.volume(vol, id);\n });\n\n return self;\n }\n\n var activeNode = (id) ? self._nodeById(id) : self._activeNode();\n if (activeNode) {\n if (self._webAudio) {\n activeNode.gain.value = vol;\n } else {\n activeNode.volume = vol * Howler.volume();\n }\n }\n\n return self;\n } else {\n return self._volume;\n }\n },\n\n /**\n * Get/set whether to loop the sound.\n * @param {Boolean} loop To loop or not to loop, that is the question.\n * @return {Howl/Boolean} Returns self or current looping value.\n */\n loop: function(loop) {\n var self = this;\n\n if (typeof loop === 'boolean') {\n self._loop = loop;\n\n return self;\n } else {\n return self._loop;\n }\n },\n\n /**\n * Get/set sound sprite definition.\n * @param {Object} sprite Example: {spriteName: [offset, duration, loop]}\n * @param {Integer} offset Where to begin playback in milliseconds\n * @param {Integer} duration How long to play in milliseconds\n * @param {Boolean} loop (optional) Set true to loop this sprite\n * @return {Howl} Returns current sprite sheet or self.\n */\n sprite: function(sprite) {\n var self = this;\n\n if (typeof sprite === 'object') {\n self._sprite = sprite;\n\n return self;\n } else {\n return self._sprite;\n }\n },\n\n /**\n * Get/set the position of playback.\n * @param {Float} pos The position to move current playback to.\n * @param {String} id (optional) The play instance ID.\n * @return {Howl/Float} Returns self or current playback position.\n */\n pos: function(pos, id) {\n var self = this;\n\n // if the sound hasn't been loaded, add it to the event queue\n if (!self._loaded) {\n self.on('load', function() {\n self.pos(pos);\n });\n\n return typeof pos === 'number' ? self : self._pos || 0;\n }\n\n // make sure we are dealing with a number for pos\n pos = parseFloat(pos);\n\n var activeNode = (id) ? self._nodeById(id) : self._activeNode();\n if (activeNode) {\n if (pos >= 0) {\n self.pause(id);\n activeNode._pos = pos;\n self.play(activeNode._sprite, id);\n\n return self;\n } else {\n return self._webAudio ? activeNode._pos + (ctx.currentTime - self._playStart) : activeNode.currentTime;\n }\n } else if (pos >= 0) {\n return self;\n } else {\n // find the first inactive node to return the pos for\n for (var i=0; i<self._audioNode.length; i++) {\n if (self._audioNode[i].paused && self._audioNode[i].readyState === 4) {\n return (self._webAudio) ? self._audioNode[i]._pos : self._audioNode[i].currentTime;\n }\n }\n }\n },\n\n /**\n * Get/set the 3D position of the audio source.\n * The most common usage is to set the 'x' position\n * to affect the left/right ear panning. Setting any value higher than\n * 1.0 will begin to decrease the volume of the sound as it moves further away.\n * NOTE: This only works with Web Audio API, HTML5 Audio playback\n * will not be affected.\n * @param {Float} x The x-position of the playback from -1000.0 to 1000.0\n * @param {Float} y The y-position of the playback from -1000.0 to 1000.0\n * @param {Float} z The z-position of the playback from -1000.0 to 1000.0\n * @param {String} id (optional) The play instance ID.\n * @return {Howl/Array} Returns self or the current 3D position: [x, y, z]\n */\n pos3d: function(x, y, z, id) {\n var self = this;\n\n // set a default for the optional 'y' & 'z'\n y = (typeof y === 'undefined' || !y) ? 0 : y;\n z = (typeof z === 'undefined' || !z) ? -0.5 : z;\n\n // if the sound hasn't been loaded, add it to the event queue\n if (!self._loaded) {\n self.on('play', function() {\n self.pos3d(x, y, z, id);\n });\n\n return self;\n }\n\n if (x >= 0 || x < 0) {\n if (self._webAudio) {\n var activeNode = (id) ? self._nodeById(id) : self._activeNode();\n if (activeNode) {\n self._pos3d = [x, y, z];\n activeNode.panner.setPosition(x, y, z);\n activeNode.panner.panningModel = self._model || 'HRTF';\n }\n }\n } else {\n return self._pos3d;\n }\n\n return self;\n },\n\n /**\n * Fade a currently playing sound between two volumes.\n * @param {Number} from The volume to fade from (0.0 to 1.0).\n * @param {Number} to The volume to fade to (0.0 to 1.0).\n * @param {Number} len Time in milliseconds to fade.\n * @param {Function} callback (optional) Fired when the fade is complete.\n * @param {String} id (optional) The play instance ID.\n * @return {Howl}\n */\n fade: function(from, to, len, callback, id) {\n var self = this,\n diff = Math.abs(from - to),\n dir = from > to ? 'down' : 'up',\n steps = diff / 0.01,\n stepTime = len / steps;\n\n // if the sound hasn't been loaded, add it to the event queue\n if (!self._loaded) {\n self.on('load', function() {\n self.fade(from, to, len, callback, id);\n });\n\n return self;\n }\n\n // set the volume to the start position\n self.volume(from, id);\n\n for (var i=1; i<=steps; i++) {\n (function() {\n var change = self._volume + (dir === 'up' ? 0.01 : -0.01) * i,\n vol = Math.round(1000 * change) / 1000,\n toVol = to;\n\n setTimeout(function() {\n self.volume(vol, id);\n\n if (vol === toVol) {\n if (callback) callback();\n }\n }, stepTime * i);\n })();\n }\n },\n\n /**\n * [DEPRECATED] Fade in the current sound.\n * @param {Float} to Volume to fade to (0.0 to 1.0).\n * @param {Number} len Time in milliseconds to fade.\n * @param {Function} callback\n * @return {Howl}\n */\n fadeIn: function(to, len, callback) {\n return this.volume(0).play().fade(0, to, len, callback);\n },\n\n /**\n * [DEPRECATED] Fade out the current sound and pause when finished.\n * @param {Float} to Volume to fade to (0.0 to 1.0).\n * @param {Number} len Time in milliseconds to fade.\n * @param {Function} callback\n * @param {String} id (optional) The play instance ID.\n * @return {Howl}\n */\n fadeOut: function(to, len, callback, id) {\n var self = this;\n\n return self.fade(self._volume, to, len, function() {\n if (callback) callback();\n self.pause(id);\n\n // fire ended event\n self.on('end');\n }, id);\n },\n\n /**\n * Get an audio node by ID.\n * @return {Howl} Audio node.\n */\n _nodeById: function(id) {\n var self = this,\n node = self._audioNode[0];\n\n // find the node with this ID\n for (var i=0; i<self._audioNode.length; i++) {\n if (self._audioNode[i].id === id) {\n node = self._audioNode[i];\n break;\n }\n }\n\n return node;\n },\n\n /**\n * Get the first active audio node.\n * @return {Howl} Audio node.\n */\n _activeNode: function() {\n var self = this,\n node = null;\n\n // find the first playing node\n for (var i=0; i<self._audioNode.length; i++) {\n if (!self._audioNode[i].paused) {\n node = self._audioNode[i];\n break;\n }\n }\n\n // remove excess inactive nodes\n self._drainPool();\n\n return node;\n },\n\n /**\n * Get the first inactive audio node.\n * If there is none, create a new one and add it to the pool.\n * @param {Function} callback Function to call when the audio node is ready.\n */\n _inactiveNode: function(callback) {\n var self = this,\n node = null;\n\n // find first inactive node to recycle\n for (var i=0; i<self._audioNode.length; i++) {\n if (self._audioNode[i].paused && self._audioNode[i].readyState === 4) {\n // send the node back for use by the new play instance\n callback(self._audioNode[i]);\n node = true;\n break;\n }\n }\n\n // remove excess inactive nodes\n self._drainPool();\n\n if (node) {\n return;\n }\n\n // create new node if there are no inactives\n var newNode;\n if (self._webAudio) {\n newNode = self._setupAudioNode();\n callback(newNode);\n } else {\n self.load();\n newNode = self._audioNode[self._audioNode.length - 1];\n\n // listen for the correct load event and fire the callback\n var listenerEvent = navigator.isCocoonJS ? 'canplaythrough' : 'loadedmetadata';\n var listener = function() {\n newNode.removeEventListener(listenerEvent, listener, false);\n callback(newNode);\n };\n newNode.addEventListener(listenerEvent, listener, false);\n }\n },\n\n /**\n * If there are more than 5 inactive audio nodes in the pool, clear out the rest.\n */\n _drainPool: function() {\n var self = this,\n inactive = 0,\n i;\n\n // count the number of inactive nodes\n for (i=0; i<self._audioNode.length; i++) {\n if (self._audioNode[i].paused) {\n inactive++;\n }\n }\n\n // remove excess inactive nodes\n for (i=self._audioNode.length-1; i>=0; i--) {\n if (inactive <= 5) {\n break;\n }\n\n if (self._audioNode[i].paused) {\n // disconnect the audio source if using Web Audio\n if (self._webAudio) {\n self._audioNode[i].disconnect(0);\n }\n\n inactive--;\n self._audioNode.splice(i, 1);\n }\n }\n },\n\n /**\n * Clear 'onend' timeout before it ends.\n * @param {String} soundId The play instance ID.\n */\n _clearEndTimer: function(soundId) {\n var self = this,\n index = 0;\n\n // loop through the timers to find the one associated with this sound\n for (var i=0; i<self._onendTimer.length; i++) {\n if (self._onendTimer[i].id === soundId) {\n index = i;\n break;\n }\n }\n\n var timer = self._onendTimer[index];\n if (timer) {\n clearTimeout(timer.timer);\n self._onendTimer.splice(index, 1);\n }\n },\n\n /**\n * Setup the gain node and panner for a Web Audio instance.\n * @return {Object} The new audio node.\n */\n _setupAudioNode: function() {\n var self = this,\n node = self._audioNode,\n index = self._audioNode.length;\n\n // create gain node\n node[index] = (typeof ctx.createGain === 'undefined') ? ctx.createGainNode() : ctx.createGain();\n node[index].gain.value = self._volume;\n node[index].paused = true;\n node[index]._pos = 0;\n node[index].readyState = 4;\n node[index].connect(masterGain);\n\n // create the panner\n node[index].panner = ctx.createPanner();\n node[index].panner.panningModel = self._model || 'equalpower';\n node[index].panner.setPosition(self._pos3d[0], self._pos3d[1], self._pos3d[2]);\n node[index].panner.connect(node[index]);\n\n return node[index];\n },\n\n /**\n * Call/set custom events.\n * @param {String} event Event type.\n * @param {Function} fn Function to call.\n * @return {Howl}\n */\n on: function(event, fn) {\n var self = this,\n events = self['_on' + event];\n\n if (typeof fn === 'function') {\n events.push(fn);\n } else {\n for (var i=0; i<events.length; i++) {\n if (fn) {\n events[i].call(self, fn);\n } else {\n events[i].call(self);\n }\n }\n }\n\n return self;\n },\n\n /**\n * Remove a custom event.\n * @param {String} event Event type.\n * @param {Function} fn Listener to remove.\n * @return {Howl}\n */\n off: function(event, fn) {\n var self = this,\n events = self['_on' + event],\n fnString = fn ? fn.toString() : null;\n\n if (fnString) {\n // loop through functions in the event for comparison\n for (var i=0; i<events.length; i++) {\n if (fnString === events[i].toString()) {\n events.splice(i, 1);\n break;\n }\n }\n } else {\n self['_on' + event] = [];\n }\n\n return self;\n },\n\n /**\n * Unload and destroy the current Howl object.\n * This will immediately stop all play instances attached to this sound.\n */\n unload: function() {\n var self = this;\n\n // stop playing any active nodes\n var nodes = self._audioNode;\n for (var i=0; i<self._audioNode.length; i++) {\n // stop the sound if it is currently playing\n if (!nodes[i].paused) {\n self.stop(nodes[i].id);\n self.on('end', nodes[i].id);\n }\n\n if (!self._webAudio) {\n // remove the source if using HTML5 Audio\n nodes[i].src = '';\n } else {\n // disconnect the output from the master gain\n nodes[i].disconnect(0);\n }\n }\n\n // make sure all timeouts are cleared\n for (i=0; i<self._onendTimer.length; i++) {\n clearTimeout(self._onendTimer[i].timer);\n }\n\n // remove the reference in the global Howler object\n var index = Howler._howls.indexOf(self);\n if (index !== null && index >= 0) {\n Howler._howls.splice(index, 1);\n }\n\n // delete this sound from the cache\n delete cache[self._src];\n self = null;\n }\n\n };\n\n // only define these functions when using WebAudio\n if (usingWebAudio) {\n\n /**\n * Buffer a sound from URL (or from cache) and decode to audio source (Web Audio API).\n * @param {Object} obj The Howl object for the sound to load.\n * @param {String} url The path to the sound file.\n */\n var loadBuffer = function(obj, url) {\n // check if the buffer has already been cached\n if (url in cache) {\n // set the duration from the cache\n obj._duration = cache[url].duration;\n\n // load the sound into this object\n loadSound(obj);\n return;\n }\n \n if (/^data:[^;]+;base64,/.test(url)) {\n // Decode base64 data-URIs because some browsers cannot load data-URIs with XMLHttpRequest.\n var data = atob(url.split(',')[1]);\n var dataView = new Uint8Array(data.length);\n for (var i=0; i<data.length; ++i) {\n dataView[i] = data.charCodeAt(i);\n }\n \n decodeAudioData(dataView.buffer, obj, url);\n } else {\n // load the buffer from the URL\n var xhr = new XMLHttpRequest();\n xhr.open('GET', url, true);\n xhr.responseType = 'arraybuffer';\n xhr.onload = function() {\n decodeAudioData(xhr.response, obj, url);\n };\n xhr.onerror = function() {\n // if there is an error, switch the sound to HTML Audio\n if (obj._webAudio) {\n obj._buffer = true;\n obj._webAudio = false;\n obj._audioNode = [];\n delete obj._gainNode;\n delete cache[url];\n obj.load();\n }\n };\n try {\n xhr.send();\n } catch (e) {\n xhr.onerror();\n }\n }\n };\n\n /**\n * Decode audio data from an array buffer.\n * @param {ArrayBuffer} arraybuffer The audio data.\n * @param {Object} obj The Howl object for the sound to load.\n * @param {String} url The path to the sound file.\n */\n var decodeAudioData = function(arraybuffer, obj, url) {\n // decode the buffer into an audio source\n ctx.decodeAudioData(\n arraybuffer,\n function(buffer) {\n if (buffer) {\n cache[url] = buffer;\n loadSound(obj, buffer);\n }\n },\n function(err) {\n obj.on('loaderror');\n }\n );\n };\n\n /**\n * Finishes loading the Web Audio API sound and fires the loaded event\n * @param {Object} obj The Howl object for the sound to load.\n * @param {Objecct} buffer The decoded buffer sound source.\n */\n var loadSound = function(obj, buffer) {\n // set the duration\n obj._duration = (buffer) ? buffer.duration : obj._duration;\n\n // setup a sprite if none is defined\n if (Object.getOwnPropertyNames(obj._sprite).length === 0) {\n obj._sprite = {_default: [0, obj._duration * 1000]};\n }\n\n // fire the loaded event\n if (!obj._loaded) {\n obj._loaded = true;\n obj.on('load');\n }\n\n if (obj._autoplay) {\n obj.play();\n }\n };\n\n /**\n * Load the sound back into the buffer source.\n * @param {Object} obj The sound to load.\n * @param {Array} loop Loop boolean, pos, and duration.\n * @param {String} id (optional) The play instance ID.\n */\n var refreshBuffer = function(obj, loop, id) {\n // determine which node to connect to\n var node = obj._nodeById(id);\n\n // setup the buffer source for playback\n node.bufferSource = ctx.createBufferSource();\n node.bufferSource.buffer = cache[obj._src];\n node.bufferSource.connect(node.panner);\n node.bufferSource.loop = loop[0];\n if (loop[0]) {\n node.bufferSource.loopStart = loop[1];\n node.bufferSource.loopEnd = loop[1] + loop[2];\n }\n node.bufferSource.playbackRate.value = obj._rate;\n };\n\n }\n\n /**\n * Add support for AMD (Asynchronous Module Definition) libraries such as require.js.\n */\n if (typeof define === 'function' && define.amd) {\n define(function() {\n return {\n Howler: Howler,\n Howl: Howl\n };\n });\n }\n\n /**\n * Add support for CommonJS libraries such as browserify.\n */\n if (typeof exports !== 'undefined') {\n exports.Howler = Howler;\n exports.Howl = Howl;\n }\n\n // define globally in case AMD is not available or available but not used\n\n if (typeof window !== 'undefined') {\n window.Howler = Howler;\n window.Howl = Howl;\n }\n\n})();\n","/**\n * jquery-qr ( //http://github.com/farmisen/jquery-qr/ ) \n * Copyright (c) Fabrice Armisen 2010\n * Licensed under the MIT license ( http://www.opensource.org/licenses/mit-license.php )\n *\n * Modified by Maximillian Laumeister for BitListen.com\n */\n \n (function ($) {\n\n $.fn.qr = function (options) {\n\n return this.each(function () {\n\n var settings = {\n 'size': '230',\n 'delay': '0'\n };\n\n if (options) {\n $.extend(settings, options);\n }\n\n var $this = $(this);\n\n $this.qr_div = createQR($this.attr('qrtarget'), settings.size);\n\n $this.mouseenter(function (event) {\n $this.qr_timeout_id = window.setTimeout(function () {\n $($this.qr_div).css({\n 'display': 'block',\n 'top': event.pageY + 5,\n 'left': event.pageX + 15\n });\n }, settings.delay);\n\n });\n\n $this.mouseleave(function (event) {\n if ($this.qr_timeout_id != null) {\n window.clearTimeout($this.qr_timeout_id);\n $this.qr_timeout_id = null;\n }\n $($this.qr_div).css({\n display: \"none\"\n });\n\n });\n }); //each\n\n function createQR(href, size) {\n var url = escape(href);\n while (url.indexOf('/') != -1) url = url.replace('/', '%2f');\n\n var qr = document.createElement(\"div\");\n $qr = $(qr)\n $qr.css({\n 'background': \"url('https://chart.apis.google.com/chart?cht=qr&chs=\" + size + \"x\" + size + \"&chl=\" + url + \"') no-repeat\",\n 'width': size + 'px',\n 'height': size + 'px',\n 'display': \"none\",\n \"border-style\": \"solid\",\n 'border-width': \"1px\",\n 'position': 'absolute',\n 'z-index': '1000'\n });\n $('body').append($qr);\n return qr;\n }\n\n };\n})(jQuery);","/*! $.noUiSlider - WTFPL - refreshless.com/nouislider/ */\n\n/*jslint browser: true */\n/*jslint devel: true */\n/*jslint continue: true */\n/*jslint plusplus: true */\n/*jslint sub: true */\n/*jslint white: true */\n\n// ==ClosureCompiler==\n// @externs_url http://refreshless.com/externs/jquery-1.8.js\n// @compilation_level ADVANCED_OPTIMIZATIONS\n// @warning_level VERBOSE\n// ==/ClosureCompiler==\n\n(function( $ ){\n\n\t'use strict';\n\n\tvar\n\t// Cache the document selector;\n/** @const */ doc = $(document),\n\t// Namespace for binding and unbinding slider events;\n/** @const */ namespace = '.nui',\n\t// Copy of the current value function;\n/** @const */ $val = $.fn.val,\n\t// Determine the events to bind. IE11 implements pointerEvents without\n\t// a prefix, which breaks compatibility with the IE10 implementation.\n/** @const */ actions = window.navigator.pointerEnabled ? {\n\t\tstart: 'pointerdown',\n\t\tmove: 'pointermove',\n\t\tend: 'pointerup'\n\t} : window.navigator.msPointerEnabled ? {\n\t\tstart: 'MSPointerDown',\n\t\tmove: 'MSPointerMove',\n\t\tend: 'MSPointerUp'\n\t} : {\n\t\tstart: 'mousedown touchstart',\n\t\tmove: 'mousemove touchmove',\n\t\tend: 'mouseup touchend'\n\t},\n\t// Re-usable list of classes;\n/** @const */ Classes = [\n/* 0 */ 'noUi-target'\n/* 1 */ ,'noUi-base'\n/* 2 */ ,'noUi-origin'\n/* 3 */ ,'noUi-handle'\n/* 4 */ ,'noUi-horizontal'\n/* 5 */ ,'noUi-vertical'\n/* 6 */ ,'noUi-background'\n/* 7 */ ,'noUi-connect'\n/* 8 */ ,'noUi-ltr'\n/* 9 */ ,'noUi-rtl'\n/* 10 */ ,'noUi-dragable'\n/* 11 */ ,''\n/* 12 */ ,'noUi-state-drag'\n/* 13 */ ,''\n/* 14 */ ,'noUi-state-tap'\n/* 15 */ ,'noUi-active'\n/* 16 */ ,'noUi-extended'\n/* 17 */ ,'noUi-stacking'\n\t],\n/** @const */ Formatting = [\n/* 0 */ 'decimals'\n/* 1 */ ,'mark'\n/* 2 */ ,'thousand'\n/* 3 */ ,'prefix'\n/* 4 */ ,'postfix'\n/* 5 */ ,'encoder'\n/* 6 */ ,'decoder'\n/* 7 */ ,'negative'\n/* 8 */ ,'negativeBefore'\n\t],\n/** @const */ FormatDefaults = [\n/* 0 */ 2\n/* 1 */ ,'.'\n/* 2 */ ,''\n/* 3 */ ,''\n/* 4 */ ,''\n/* 5 */ ,function(a){ return a; }\n/* 6 */ ,function(a){ return a; }\n/* 7 */ ,'-'\n/* 8 */ ,''\n\t];\n\n\n// Error handling\n\n\tfunction throwError( message ){\n\t\tthrow new RangeError('noUiSlider: ' + message);\n\t}\n\n\t// Throw an error if formatting options are incompatible.\n\tfunction throwEqualError( F, a, b ) {\n\t\tif ( (F[a] || F[b]) && (F[a] === F[b]) ) {\n\t\t\tthrowError(\"(Link) '\"+a+\"' can't match '\"+b+\"'.'\");\n\t\t}\n\t}\n\n\n// General helpers\n\n\t// Limits a value to 0 - 100\n\tfunction limit ( a ) {\n\t\treturn Math.max(Math.min(a, 100), 0);\n\t}\n\n\t// Round a value to the closest 'to'.\n\tfunction closest ( value, to ) {\n\t\treturn Math.round(value / to) * to;\n\t}\n\n\t// Determine the size of a sub-range in relation to a full range.\n\tfunction subRangeRatio ( pa, pb ) {\n\t\treturn (100 / (pb - pa));\n\t}\n\n\n// Type validation\n\n\tfunction typeMatch ( a, b ) {\n\t\treturn (typeof a) === (typeof b);\n\t}\n\n\t// Test in an object is an instance of jQuery or Zepto.\n\tfunction isInstance ( a ) {\n\t\treturn a instanceof $ || ( $['zepto'] && $['zepto']['isZ'](a) );\n\t}\n\n\t// Checks whether a value is numerical.\n\tfunction isNumeric ( a ) {\n\t\treturn typeof a === 'number' && !isNaN( a ) && isFinite( a );\n\t}\n\n\t// Wraps a variable as an array, if it isn't one yet.\n\tfunction asArray ( a ) {\n\t\treturn $.isArray(a) ? a : [a];\n\t}\n\n\n// Class handling\n\n\t// Sets a class and removes it after [duration] ms.\n\tfunction addClassFor ( element, className, duration ) {\n\t\telement.addClass(className);\n\t\tsetTimeout(function(){\n\t\t\telement.removeClass(className);\n\t\t}, duration);\n\t}\n\n\t// Tests if element has a class, adds it if not. Returns original state.\n\tfunction getsClass ( element, className ) {\n\n\t\tvar has = element.hasClass(className);\n\n\t\tif ( !has ) {\n\t\t\telement.addClass( className );\n\t\t}\n\n\t\treturn has;\n\t}\n\n\n// Value calculation\n\n\t// (percentage) How many percent is this value of this range?\n\tfunction fromPercentage ( range, value ) {\n\t\treturn (value * 100) / ( range[1] - range[0] );\n\t}\n\n\t// (percentage) Where is this value on this range?\n\tfunction toPercentage ( range, value ) {\n\t\treturn fromPercentage( range, range[0] < 0 ?\n\t\t\tvalue + Math.abs(range[0]) :\n\t\t\t\tvalue - range[0] );\n\t}\n\n\t// (value) How much is this percentage on this range?\n\tfunction isPercentage ( range, value ) {\n\t\treturn ((value * ( range[1] - range[0] )) / 100) + range[0];\n\t}\n\n\t// (percentage)\n\tfunction toStepping ( options, value ) {\n\n\t\tif ( value >= options.xVal.slice(-1)[0] ){\n\t\t\treturn 100;\n\t\t}\n\n\t\tvar j = 1, va, vb, pa, pb;\n\t\twhile ( value >= options.xVal[j] ){\n\t\t\tj++;\n\t\t}\n\n\t\tva = options.xVal[j-1];\n\t\tvb = options.xVal[j];\n\t\tpa = options.xPct[j-1];\n\t\tpb = options.xPct[j];\n\n\t\treturn pa + (toPercentage([va, vb], value) / subRangeRatio (pa, pb));\n\t}\n\n\t// (value)\n\tfunction fromStepping ( options, value ) {\n\n\t\t// There is no range group that fits 100\n\t\tif ( value >= 100 ){\n\t\t\treturn options.xVal.slice(-1)[0];\n\t\t}\n\n\t\tvar j = 1, va, vb, pa, pb;\n\t\twhile ( value >= options.xPct[j] ){\n\t\t\tj++;\n\t\t}\n\n\t\tva = options.xVal[j-1];\n\t\tvb = options.xVal[j];\n\t\tpa = options.xPct[j-1];\n\t\tpb = options.xPct[j];\n\n\t\treturn isPercentage([va, vb], (value - pa) * subRangeRatio (pa, pb));\n\t}\n\n\t// (percentage) Get the step that applies at a certain value.\n\tfunction getStep ( options, value ){\n\n\t\tvar j = 1, a, b;\n\t\twhile ( value >= options.xPct[j] ){\n\t\t\tj++;\n\t\t}\n\n\t\tif ( options.snap ) {\n\n\t\t\ta = options.xPct[j-1];\n\t\t\tb = options.xPct[j];\n\n\t\t\tif ((value - a) > ((b-a)/2)){\n\t\t\t\treturn b;\n\t\t\t}\n\n\t\t\treturn a;\n\t\t}\n\n\t\tif ( !options.xSteps[j-1] ){\n\t\t\treturn value;\n\t\t}\n\n\t\treturn options.xPct[j-1] + closest(\n\t\t\tvalue - options.xPct[j-1],\n\t\t\toptions.xSteps[j-1]\n\t\t);\n\t}\n\n\n// Event handling\n\n\t// Provide a clean event with standardized offset values.\n\tfunction fixEvent ( e ) {\n\n\t\t// Prevent scrolling and panning on touch events, while\n\t\t// attempting to slide. The tap event also depends on this.\n\t\te.preventDefault();\n\n\t\t// Filter the event to register the type, which can be\n\t\t// touch, mouse or pointer. Offset changes need to be\n\t\t// made on an event specific basis.\n\t\tvar touch = e.type.indexOf('touch') === 0\n\t\t\t,mouse = e.type.indexOf('mouse') === 0\n\t\t\t,pointer = e.type.indexOf('pointer') === 0\n\t\t\t,x,y, event = e;\n\n\t\t// IE10 implemented pointer events with a prefix;\n\t\tif ( e.type.indexOf('MSPointer') === 0 ) {\n\t\t\tpointer = true;\n\t\t}\n\n\t\t// Get the originalEvent, if the event has been wrapped\n\t\t// by jQuery. Zepto doesn't wrap the event.\n\t\tif ( e.originalEvent ) {\n\t\t\te = e.originalEvent;\n\t\t}\n\n\t\tif ( touch ) {\n\t\t\t// noUiSlider supports one movement at a time,\n\t\t\t// so we can select the first 'changedTouch'.\n\t\t\tx = e.changedTouches[0].pageX;\n\t\t\ty = e.changedTouches[0].pageY;\n\t\t}\n\n\t\tif ( mouse || pointer ) {\n\n\t\t\t// Polyfill the pageXOffset and pageYOffset\n\t\t\t// variables for IE7 and IE8;\n\t\t\tif( !pointer && window.pageXOffset === undefined ){\n\t\t\t\twindow.pageXOffset = document.documentElement.scrollLeft;\n\t\t\t\twindow.pageYOffset = document.documentElement.scrollTop;\n\t\t\t}\n\n\t\t\tx = e.clientX + window.pageXOffset;\n\t\t\ty = e.clientY + window.pageYOffset;\n\t\t}\n\n\t\tevent.points = [x, y];\n\t\tevent.cursor = mouse;\n\n\t\treturn event;\n\t}\n\n\n// Organize formatting in an object.\n\n\t/** @constructor */\n\tfunction Format( options ){\n\n\t\t// If no settings where provided, the defaults will be loaded.\n\t\tif ( options === undefined ){\n\t\t\toptions = {};\n\t\t}\n\n\t\tif ( typeof options !== 'object' ){\n\t\t\tthrowError(\"(Format) 'format' option must be an object.\");\n\t\t}\n\n\t\tvar settings = {};\n\n\t\t// Copy all values into a new object.\n\t\t$(Formatting).each(function(i, val){\n\n\t\t\tif ( options[val] === undefined ){\n\n\t\t\t\tsettings[val] = FormatDefaults[i];\n\n\t\t\t// When we aren't loading defaults, validate the entry.\n\t\t\t} else if ( typeMatch(options[val], FormatDefaults[i]) ) {\n\n\t\t\t\t// Support for up to 7 decimals.\n\t\t\t\t// More can't be guaranteed due to floating point issues.\n\t\t\t\tif ( val === 'decimals' ){\n\t\t\t\t\tif ( options[val] < 0 || options[val] > 7 ){\n\t\t\t\t\t\tthrowError(\"(Format) 'format.decimals' option must be between 0 and 7.\");\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tsettings[val] = options[val];\n\n\t\t\t// If the value isn't valid, emit an error.\n\t\t\t} else {\n\t\t\t\tthrowError(\"(Format) 'format.\"+val+\"' must be a \" + typeof FormatDefaults[i] + \".\");\n\t\t\t}\n\t\t});\n\n\t\t// Some values can't be extracted from a\n\t\t// string if certain combinations are present.\n\t\tthrowEqualError(settings, 'mark', 'thousand');\n\t\tthrowEqualError(settings, 'prefix', 'negative');\n\t\tthrowEqualError(settings, 'prefix', 'negativeBefore');\n\n\t\tthis.settings = settings;\n\t}\n\n\t// Shorthand for internal value get\n\tFormat.prototype.v = function ( a ) {\n\t\treturn this.settings[a];\n\t};\n\n\tFormat.prototype.to = function ( number ) {\n\n\t\tfunction reverse ( a ) {\n\t\t\treturn a.split('').reverse().join('');\n\t\t}\n\n\t\tnumber = this.v('encoder')( number );\n\n\t\tvar negative = '', preNegative = '', base = '', mark = '';\n\n\t\tif ( number < 0 ) {\n\t\t\tnegative = this.v('negative');\n\t\t\tpreNegative = this.v('negativeBefore');\n\t\t}\n\n\t\t// Round to proper decimal count\n\t\tnumber = Math.abs(number).toFixed( this.v('decimals') ).toString();\n\t\tnumber = number.split('.');\n\n\t\t// Rounding away decimals might cause a value of -0\n\t\t// when using very small ranges. Remove those cases.\n\t\tif ( parseFloat(number) === 0 ) {\n\t\t\tnumber[0] = '0';\n\t\t}\n\n\t\t// Group numbers in sets of three.\n\t\tif ( this.v('thousand') ) {\n\t\t\tbase = reverse(number[0]).match(/.{1,3}/g);\n\t\t\tbase = reverse(base.join(reverse( this.v('thousand') )));\n\t\t} else {\n\t\t\tbase = number[0];\n\t\t}\n\n\t\t// Ignore the decimal separator if decimals are set to 0.\n\t\tif ( this.v('mark') && number.length > 1 ) {\n\t\t\tmark = this.v('mark') + number[1];\n\t\t}\n\n\t\t// Return the finalized formatted number.\n\t\treturn preNegative +\n\t\t\tthis.v('prefix') +\n\t\t\tnegative +\n\t\t\tbase +\n\t\t\tmark +\n\t\t\tthis.v('postfix');\n\t};\n\n\tFormat.prototype.from = function ( input ) {\n\n\t\tfunction esc(s){\n\t\t\treturn s.replace(/[\\-\\/\\\\\\^$*+?.()|\\[\\]{}]/g, '\\\\$&');\n\t\t}\n\n\t\tvar isNeg;\n\t\t// The set request might want to ignore this handle.\n\t\t// Test for 'undefined' too, as a two-handle slider\n\t\t// can still be set with an integer.\n\t\tif( input === null || input === undefined ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Remove formatting and set period for float parsing.\n\t\tinput = input.toString();\n\n\t\t// Replace the preNegative indicator.\n\t\tisNeg = input.replace(new RegExp('^' + esc( this.v('negativeBefore') )), '');\n\n\t\t// Check if the value changed by removing the negativeBefore symbol.\n\t\tif( input !== isNeg ) {\n\t\t\tinput = isNeg;\n\t\t\tisNeg = '-';\n\t\t} else {\n\t\t\tisNeg = '';\n\t\t}\n\n\t\t// If prefix is set and the number is actually prefixed.\n\t\tinput = input.replace(new RegExp('^'+esc( this.v('prefix') )), '');\n\n\t\t// Only replace if a negative sign is set.\n\t\tif ( this.v['negative'] ) {\n\n\t\t\t// Reset isNeg to prevent double '-' insertion.\n\t\t\tisNeg = '';\n\n\t\t\t// Reset the negative sign to '-'\n\t\t\tinput = input.replace(new RegExp('^'+esc( this.v('negative') )), '-');\n\t\t}\n\n\t\t// Clean the input string\n\t\tinput = input\n\t\t// If postfix is set and the number is postfixed.\n\t\t\t.replace( new RegExp(esc( this.v('postfix') ) + '$'), '')\n\t\t// Remove the separator every three digits.\n\t\t\t.replace( new RegExp(esc( this.v('thousand') ), 'g'), '')\n\t\t// Set the decimal separator back to period.\n\t\t\t.replace( this.v('mark'), '.');\n\n\t\t// Run the user defined decoder. Returns input by default.\n\t\tinput = this.v('decoder')( parseFloat( isNeg + input ) );\n\n\t\t// Ignore invalid input\n\t\tif (isNaN( input )) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn input;\n\t};\n\n\n// Serialization target\n\n/** @constructor */\n\tfunction Link( entry, update ){\n\n\t\t// Make sure Link isn't called as a function, in which case\n\t\t// the 'this' scope would be the window.\n\t\tif ( !(this instanceof Link) ) {\n\t\t\tthrow new Error( \"Link: \" +\n\t\t\t\t\"Don't use Link as a function. \" +\n\t\t\t\t\"Use the 'new' keyword.\");\n\t\t}\n\n\t\tif ( !entry ) {\n\t\t\tthrow new RangeError(\"Link: missing parameters.\");\n\t\t}\n\n\t\t// Write all formatting to this object.\n\t\t// No validation needed, as we'll merge these with the parent\n\t\t// format options first.\n\t\tthis.formatting = entry['format'] || {};\n\n\t\t// Store the update option.\n\t\tthis.update = !update;\n\n\t\t// In IE < 9, .bind() isn't available, need this link in .change().\n\tvar that = this,\n\n\t\t// Get values from the input.\n\t\ttarget = entry['target'] || function(){},\n\t\tmethod = entry['method'],\n\n\t\t// Find the type of this link.\n\t\tisTooltip = ( typeof target === 'string' && target.indexOf('-tooltip-') === 0 ),\n\t\tisHidden = ( typeof target === 'string' && target.indexOf('-') !== 0 ),\n\t\tisMethod = ( typeof target === 'function' ),\n\t\tis$ = ( isInstance(target) ),\n\t\tisInput = ( is$ && target.is('input, select, textarea') ),\n\t\tmethodIsFunction = ( is$ && typeof method === 'function' ),\n\t\tmethodIsName = ( is$ && typeof method === 'string' && target[method] );\n\n\t\t// If target is a string, a new hidden input will be created.\n\t\tif ( isTooltip ) {\n\n\t\t\t// By default, use the 'html' method.\n\t\t\tthis.method = method || 'html';\n\n\t\t\t// Use jQuery to create the element\n\t\t\tthis.el = $( target.replace('-tooltip-', '') || '<div/>' )[0];\n\n\t\t\treturn;\n\t\t}\n\n\t\t// If the string doesn't begin with '-', which is reserved, add a new hidden input.\n\t\tif ( isHidden ) {\n\n\t\t\tthis.method = 'val';\n\n\t\t\tthis.el = document.createElement('input');\n\t\t\tthis.el.name = target;\n\t\t\tthis.el.type = 'hidden';\n\n\t\t\treturn;\n\t\t}\n\n\t\t// The target can also be a function, which will be called.\n\t\tif ( isMethod ) {\n\t\t\tthis.target = false;\n\t\t\tthis.method = target;\n\t\t\treturn;\n\t\t}\n\n\t\t// If the target is and $ element.\n\t\tif ( is$ ) {\n\n\t\t\t// The method must exist on the element.\n\t\t\tif ( method && ( methodIsFunction || methodIsName ) ) {\n\t\t\t\tthis.target = target;\n\t\t\t\tthis.method = method;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a jQuery/Zepto input element is provided, but no method is set,\n\t\t\t// the element can assume it needs to respond to 'change'...\n\t\t\tif ( !method && isInput ) {\n\n\t\t\t\t// Default to .val if this is an input element.\n\t\t\t\tthis.method = 'val';\n\t\t\t\tthis.target = target;\n\n\t\t\t\t// Set the slider to a new value on change.\n\t\t\t\tthis.target.on('change', function( e ){\n\n\t\t\t\t\t// Returns null array.\n\t\t\t\t\tfunction at(a,b,c){\n\t\t\t\t\t\treturn [c?a:b, c?b:a];\n\t\t\t\t\t}\n\n\t\t\t\t\tvar output = at(null, $(e.target).val(), that.N);\n\n\t\t\t\t\tthat.obj.val(output, { 'link': that });\n\t\t\t\t});\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// ... or not.\n\t\t\tif ( !method && !isInput ) {\n\n\t\t\t\t// Default arbitrarily to 'html'.\n\t\t\t\tthis.method = 'html';\n\t\t\t\tthis.target = target;\n\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tthrow new RangeError(\"Link: Invalid Link.\");\n\t}\n\n\t// Provides external items with the slider value.\n\tLink.prototype.write = function ( options, value, handle, slider, update ) {\n\n\t\t// Don't synchronize this Link.\n\t\tif ( this.update && update === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Convert the value to the slider stepping/range.\n\t\tvalue = fromStepping( options, value );\n\n\t\t// Format values for display.\n\t\tvalue = this.format( value );\n\n\t\t// Store the numerical value.\n\t\tthis.saved = value;\n\n\t\t// Branch between serialization to a function or an object.\n\t\tif ( typeof this.method === 'function' ) {\n\t\t\t// When target is undefined, the target was a function.\n\t\t\t// In that case, provided the slider as the calling scope.\n\t\t\t// Use [0] to get the DOM element, not the $ instance.\n\t\t\tthis.method.call( this.target[0] || slider[0], value, handle, slider );\n\t\t} else {\n\t\t\tthis.target[ this.method ]( value, handle, slider );\n\t\t}\n\t};\n\n\t// Parses slider value to user defined display.\n\tLink.prototype.format = function ( a ) {\n\t\treturn this.formatting.to(a);\n\t};\n\n\t// Converts a formatted value back to a real number.\n\tLink.prototype.valueOf = function ( a ) {\n\t\treturn this.formatting.from(a);\n\t};\n\n\n// Input validation\n\n\tfunction testStep ( parsed, entry ) {\n\n\t\tif ( !isNumeric( entry ) ) {\n\t\t\tthrowError(\"'step' is not numeric.\");\n\t\t}\n\n\t\t// The step option can still be used to set stepping\n\t\t// for linear sliders. Overwritten if set in 'range'.\n\t\tparsed.xSteps[0] = entry;\n\t}\n\n\tfunction testRange ( parsed, entry ) {\n\n\t\t// Filter incorrect input.\n\t\tif ( typeof entry !== 'object' || $.isArray(entry) ) {\n\t\t\tthrowError(\"'range' is not an object.\");\n\t\t}\n\n\t\t// Loop all entries.\n\t\t$.each( entry, function ( index, value ) {\n\n\t\t\tvar percentage;\n\n\t\t\t// Wrap numerical input in an array.\n\t\t\tif ( typeof value === \"number\" ) {\n\t\t\t\tvalue = [value];\n\t\t\t}\n\n\t\t\t// Reject any invalid input.\n\t\t\tif ( !$.isArray( value ) ){\n\t\t\t\tthrowError(\"'range' contains invalid value.\");\n\t\t\t}\n\n\t\t\t// Covert min/max syntax to 0 and 100.\n\t\t\tif ( index === 'min' ) {\n\t\t\t\tpercentage = 0;\n\t\t\t} else if ( index === 'max' ) {\n\t\t\t\tpercentage = 100;\n\t\t\t} else {\n\t\t\t\tpercentage = parseFloat( index );\n\t\t\t}\n\n\t\t\t// Check for correct input.\n\t\t\tif ( !isNumeric( percentage ) || !isNumeric( value[0] ) ) {\n\t\t\t\tthrowError(\"'range' value isn't numeric.\");\n\t\t\t}\n\n\t\t\t// Store values.\n\t\t\tparsed.xPct.push( percentage );\n\t\t\tparsed.xVal.push( value[0] );\n\n\t\t\t// NaN will evaluate to false too, but to keep\n\t\t\t// logging clear, set step explicitly. Make sure\n\t\t\t// not to override the 'step' setting with false.\n\t\t\tif ( !percentage ) {\n\t\t\t\tif ( !isNaN( value[1] ) ) {\n\t\t\t\t\tparsed.xSteps[0] = value[1];\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tparsed.xSteps.push( isNaN(value[1]) ? false : value[1] );\n\t\t\t}\n\t\t});\n\n\t\t$.each(parsed.xSteps, function(i,n){\n\n\t\t\t// Ignore 'false' stepping.\n\t\t\tif ( !n ) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// Check if step fits. Not required, but this might serve some goal.\n\t\t\t// !((parsed.xVal[i+1] - parsed.xVal[i]) % n);\n\n\t\t\t// Factor to range ratio\n\t\t\tparsed.xSteps[i] = fromPercentage([\n\t\t\t\t parsed.xVal[i]\n\t\t\t\t,parsed.xVal[i+1]\n\t\t\t], n) / subRangeRatio (\n\t\t\t\tparsed.xPct[i],\n\t\t\t\tparsed.xPct[i+1] );\n\t\t});\n\t}\n\n\tfunction testStart ( parsed, entry ) {\n\n\t\tif ( typeof entry === \"number\" ) {\n\t\t\tentry = [entry];\n\t\t}\n\n\t\t// Validate input. Values aren't tested, the internal Link will do\n\t\t// that and provide a valid location.\n\t\tif ( !$.isArray( entry ) || !entry.length || entry.length > 2 ) {\n\t\t\tthrowError(\"'start' option is incorrect.\");\n\t\t}\n\n\t\t// Store the number of handles.\n\t\tparsed.handles = entry.length;\n\n\t\t// When the slider is initialized, the .val method will\n\t\t// be called with the start options.\n\t\tparsed.start = entry;\n\t}\n\n\tfunction testSnap ( parsed, entry ) {\n\n\t\t// Enforce 100% stepping within subranges.\n\t\tparsed.snap = entry;\n\n\t\tif ( typeof entry !== 'boolean' ){\n\t\t\tthrowError(\"'snap' option must be a boolean.\");\n\t\t}\n\t}\n\n\tfunction testConnect ( parsed, entry ) {\n\n\t\tif ( entry === 'lower' && parsed.handles === 1 ) {\n\t\t\tparsed.connect = 1;\n\t\t} else if ( entry === 'upper' && parsed.handles === 1 ) {\n\t\t\tparsed.connect = 2;\n\t\t} else if ( entry === true && parsed.handles === 2 ) {\n\t\t\tparsed.connect = 3;\n\t\t} else if ( entry === false ) {\n\t\t\tparsed.connect = 0;\n\t\t} else {\n\t\t\tthrowError(\"'connect' option was doesn't match handle count.\");\n\t\t}\n\t}\n\n\tfunction testOrientation ( parsed, entry ) {\n\n\t\t// Set orientation to an a numerical value for easy\n\t\t// array selection.\n\t\tswitch ( entry ){\n\t\t case 'horizontal':\n\t\t\tparsed.ort = 0;\n\t\t\tbreak;\n\t\t case 'vertical':\n\t\t\tparsed.ort = 1;\n\t\t\tbreak;\n\t\t default:\n\t\t\tthrowError(\"'orientation' option is invalid.\");\n\t\t}\n\t}\n\n\tfunction testMargin ( parsed, entry ) {\n\n\t\tif ( parsed.xPct.length > 2 ) {\n\t\t\tthrowError(\"'margin' option is only supported on linear sliders.\");\n\t\t}\n\n\t\t// Parse value to range and store. As xVal is checked\n\t\t// to be no bigger than 2, use it as range.\n\t\tparsed.margin = fromPercentage(parsed.xVal, entry);\n\n\t\tif ( !isNumeric(entry) ){\n\t\t\tthrowError(\"'margin' option must be numeric.\");\n\t\t}\n\t}\n\n\tfunction testDirection ( parsed, entry ) {\n\n\t\t// Set direction as a numerical value for easy parsing.\n\t\t// Invert connection for RTL sliders, so that the proper\n\t\t// handles get the connect/background classes.\n\t\tswitch ( entry ) {\n\t\t case 'ltr':\n\t\t\tparsed.dir = 0;\n\t\t\tbreak;\n\t\t case 'rtl':\n\t\t\tparsed.dir = 1;\n\t\t\tparsed.connect = [0,2,1,3][parsed.connect];\n\t\t\tbreak;\n\t\t default:\n\t\t\tthrowError(\"'direction' option was not recognized.\");\n\t\t}\n\t}\n\n\tfunction testBehaviour ( parsed, entry ) {\n\n\t\t// Make sure the input is a string.\n\t\tif ( typeof entry !== 'string' ) {\n\t\t\tthrowError(\"'behaviour' must be a string containing options.\");\n\t\t}\n\n\t\t// Check if the string contains any keywords.\n\t\t// None are required.\n\t\tvar tap = entry.indexOf('tap') >= 0,\n\t\t\textend = entry.indexOf('extend') >= 0,\n\t\t\tdrag = entry.indexOf('drag') >= 0,\n\t\t\tfixed = entry.indexOf('fixed') >= 0,\n\t\t\tsnap = entry.indexOf('snap') >= 0;\n\n\t\tparsed.events = {\n\t\t\ttap: tap || snap,\n\t\t\textend: extend,\n\t\t\tdrag: drag,\n\t\t\tfixed: fixed,\n\t\t\tsnap: snap\n\t\t};\n\t}\n\n\tfunction testSerialization ( parsed, entry, sliders ) {\n\n\t\tparsed.ser = [ entry['lower'], entry['upper'] ];\n\t\tparsed.formatting = new Format( entry['format'] );\n\n\t\t$.each( parsed.ser, function( i, a ){\n\n\t\t\t// Check if the provided option is an array.\n\t\t\tif ( !$.isArray(a) ) {\n\t\t\t\tthrowError(\"'serialization.\"+(!i?'lower':'upper')+\"' must be an array.\");\n\t\t\t}\n\n\t\t\t$.each(a, function(){\n\n\t\t\t\t// Check if entry is a Link.\n\t\t\t\tif ( !(this instanceof Link) ) {\n\t\t\t\t\tthrowError(\"'serialization.\"+(!i?'lower':'upper')+\"' can only contain Link instances.\");\n\t\t\t\t}\n\n\t\t\t\t// Assign other properties.\n\t\t\t\tthis.N = i;\n\t\t\t\tthis.obj = sliders;\n\t\t\t\tthis.scope = this.scope || sliders;\n\n\t\t\t\t// Run internal validator.\n\t\t\t\tthis.formatting = new Format($.extend({}\n\t\t\t\t\t,entry['format']\n\t\t\t\t\t,this.formatting\n\t\t\t\t));\n\t\t\t});\n\t\t});\n\n\t\t// If the slider has two handles and is RTL,\n\t\t// reverse the serialization input. For one handle,\n\t\t// lower is still lower.\n\t\tif ( parsed.dir && parsed.handles > 1 ) {\n\t\t\tparsed.ser.reverse();\n\t\t}\n\t}\n\n\t// Test all developer settings and parse to assumption-safe values.\n\tfunction test ( options, sliders ){\n\n\t/*\tEvery input option is tested and parsed. This'll prevent\n\t\tendless validation in internal methods. These tests are\n\t\tstructured with an item for every option available. An\n\t\toption can be marked as required by setting the 'r' flag.\n\t\tThe testing function is provided with three arguments:\n\t\t\t- The provided value for the option;\n\t\t\t- A reference to the options object;\n\t\t\t- The name for the option;\n\n\t\tThe testing function returns false when an error is detected,\n\t\tor true when everything is OK. It can also modify the option\n\t\tobject, to make sure all values can be correctly looped elsewhere. */\n\n\t\tvar parsed = {\n\t\t\t xPct: []\n\t\t\t,xVal: []\n\t\t\t,xSteps: [ false ]\n\t\t\t,margin: 0\n\t\t}, tests;\n\n\t\ttests = {\n\t\t\t'step': { r: false, t: testStep },\n\t\t\t'range': { r: true, t: testRange },\n\t\t\t'start': { r: true, t: testStart },\n\t\t\t'snap': { r: false, t: testSnap },\n\t\t\t'connect': { r: true, t: testConnect },\n\t\t\t'orientation': { r: false, t: testOrientation },\n\t\t\t'margin': { r: false, t: testMargin },\n\t\t\t'direction': { r: true, t: testDirection },\n\t\t\t'behaviour': { r: true, t: testBehaviour },\n\t\t\t'serialization': { r: true, t: testSerialization }\n\t\t};\n\n\t\t// Set defaults where applicable.\n\t\toptions = $.extend({\n\t\t\t 'connect': false\n\t\t\t,'direction': 'ltr'\n\t\t\t,'behaviour': 'tap'\n\t\t\t,'orientation': 'horizontal'\n\t\t}, options);\n\n\t\t// Make sure the test for serialization runs.\n\t\toptions['serialization'] = $.extend({\n\t\t\t 'lower': []\n\t\t\t,'upper': []\n\t\t\t,'format': {}\n\t\t}, options['serialization']);\n\n\t\t// Run all options through a testing mechanism to ensure correct\n\t\t// input. It should be noted that options might get modified to\n\t\t// be handled properly. E.g. wrapping integers in arrays.\n\t\t$.each( tests, function( name, test ){\n\n\t\t\tif ( options[name] === undefined ) {\n\t\t\t\tif ( test.r ) {\n\t\t\t\t\tthrowError(\"'\" + name + \"' is required.\");\n\t\t\t\t} else {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttest.t( parsed, options[name], sliders );\n\t\t});\n\n\t\t// Pre-define the styles.\n\t\tparsed.style = parsed.ort ? 'top' : 'left';\n\n\t\treturn parsed;\n\t}\n\n\n// DOM additions\n\n\t// Append a handle to the base.\n\tfunction addHandle ( options, index ) {\n\n\t\tvar handle = $('<div><div/></div>').addClass( Classes[2] ),\n\t\t\tadditions = [ '-lower', '-upper' ];\n\n\t\tif ( options.dir ) {\n\t\t\tadditions.reverse();\n\t\t}\n\n\t\thandle.children().addClass(\n\t\t\tClasses[3] + \" \" + Classes[3]+additions[index]\n\t\t);\n\n\t\treturn handle;\n\t}\n\n\t// Create a copy of an element-creating Link.\n\tfunction addElement ( handle, link ) {\n\n\t\t// If the Link requires creation of a new element,\n\t\t// create this element and return a new Link instance.\n\t\tif ( link.el ) {\n\t\t\tlink = new Link({\n\t\t\t\t'target': $(link.el).clone().appendTo( handle ),\n\t\t\t\t'method': link.method,\n\t\t\t\t'format': link.formatting\n\t\t\t}, true);\n\t\t}\n\n\t\t// Otherwise, return the reference.\n\t\treturn link;\n\t}\n\n\t// Loop all links for a handle.\n\tfunction addElements ( elements, handle, formatting ) {\n\n\t\tvar index, list = [];\n\n\t\t// Use the Link interface to provide unified\n\t\t// formatting for the .val() method.\n\t\tlist.push(\n\t\t\tnew Link({\n\t\t\t\t'format': formatting\n\t\t\t}, true)\n\t\t);\n\n\t\t// Loop all links in either 'lower' or 'upper'.\n\t\tfor ( index = 0; index < elements.length; index++ ) {\n\t\t\tlist.push(addElement(handle, elements[index]));\n\t\t}\n\n\t\treturn list;\n\t}\n\n\t// Go over all Links and assign them to a handle.\n\tfunction addLinks ( options, handles ) {\n\n\t\tvar index, links = [];\n\n\t\t// Copy the links into a new array, instead of modifying\n\t\t// the 'options.ser' list. This allows replacement of the invalid\n\t\t// '.el' Links, while the others are still passed by reference.\n\t\tfor ( index = 0; index < options.handles; index++ ) {\n\n\t\t\t// Append a new array.\n\t\t\tlinks[index] = addElements(\n\t\t\t\toptions.ser[index],\n\t\t\t\thandles[index].children(),\n\t\t\t\toptions.formatting\n\t\t\t);\n\t\t}\n\n\t\treturn links;\n\t}\n\n\t// Add the proper connection classes.\n\tfunction addConnection ( connect, target, handles ) {\n\n\t\t// Apply the required connection classes to the elements\n\t\t// that need them. Some classes are made up for several\n\t\t// segments listed in the class list, to allow easy\n\t\t// renaming and provide a minor compression benefit.\n\t\tswitch ( connect ) {\n\t\t\tcase 1:\ttarget.addClass( Classes[7] );\n\t\t\t\t\thandles[0].addClass( Classes[6] );\n\t\t\t\t\tbreak;\n\t\t\tcase 3: handles[1].addClass( Classes[6] );\n\t\t\t\t\t/* falls through */\n\t\t\tcase 2: handles[0].addClass( Classes[7] );\n\t\t\t\t\t/* falls through */\n\t\t\tcase 0: target.addClass(Classes[6]);\n\t\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Add handles and loop Link elements.\n\tfunction addHandles ( options, base ) {\n\n\t\tvar index, handles = [];\n\n\t\t// Append handles.\n\t\tfor ( index = 0; index < options.handles; index++ ) {\n\n\t\t\t// Keep a list of all added handles.\n\t\t\thandles.push( addHandle( options, index ).appendTo(base) );\n\t\t}\n\n\t\treturn handles;\n\t}\n\n\t// Initialize a single slider.\n\tfunction addSlider ( options, target ) {\n\n\t\t// Apply classes and data to the target.\n\t\ttarget.addClass([\n\t\t\tClasses[0],\n\t\t\tClasses[8 + options.dir],\n\t\t\tClasses[4 + options.ort]\n\t\t].join(' '));\n\n\t\treturn $('<div/>').appendTo(target).addClass( Classes[1] );\n\t}\n\n\n// Slider scope\n\nfunction closure ( target, options, originalOptions ){\n\n// Internal variables\n\n\t// All variables local to 'closure' are marked $.\n\tvar $Target = $(target),\n\t\t$Locations = [-1, -1],\n\t\t$Base,\n\t\t$Serialization,\n\t\t$Handles;\n\n\t// Shorthand for base dimensions.\n\tfunction baseSize ( ) {\n\t\treturn $Base[['width', 'height'][options.ort]]();\n\t}\n\n\n// External event handling\n\n\tfunction fireEvents ( events ) {\n\n\t\t// Use the external api to get the values.\n\t\t// Wrap the values in an array, as .trigger takes\n\t\t// only one additional argument.\n\t\tvar index, values = [ $Target.val() ];\n\n\t\tfor ( index = 0; index < events.length; index++ ){\n\t\t\t$Target.trigger(events[index], values);\n\t\t}\n\t}\n\n\n// Handle placement\n\n\t// Test suggested values and apply margin, step.\n\tfunction setHandle ( handle, to, delimit ) {\n\n\t\tvar n = handle[0] !== $Handles[0][0] ? 1 : 0,\n\t\t\tlower = $Locations[0] + options.margin,\n\t\t\tupper = $Locations[1] - options.margin;\n\n\t\t// Don't delimit range dragging.\n\t\tif ( delimit && $Handles.length > 1 ) {\n\t\t\tto = n ? Math.max( to, lower ) : Math.min( to, upper );\n\t\t}\n\n\t\t// Handle the step option.\n\t\tif ( to < 100 ){\n\t\t\tto = getStep(options, to);\n\t\t}\n\n\t\t// Limit to 0/100 for .val input, trim anything beyond 7 digits, as\n\t\t// JavaScript has some issues in its floating point implementation.\n\t\tto = limit(parseFloat(to.toFixed(7)));\n\n\t\t// Return falsy if handle can't move. False for 0 or 100 limit,\n\t\t// '0' for limiting by another handle.\n\t\tif ( to === $Locations[n] ) {\n\t\t\tif ( $Handles.length === 1 ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn ( to === lower || to === upper ) ? 0 : false;\n\t\t}\n\n\t\t// Set the handle to the new position.\n\t\thandle.css( options.style, to + '%' );\n\n\t\t// Force proper handle stacking\n\t\tif ( handle.is(':first-child') ) {\n\t\t\thandle.toggleClass(Classes[17], to > 50 );\n\t\t}\n\n\t\t// Update locations.\n\t\t$Locations[n] = to;\n\n\t\t// Invert the value if this is a right-to-left slider.\n\t\tif ( options.dir ) {\n\t\t\tto = 100 - to;\n\t\t}\n\n\t\t// Write values to serialization Links.\n\t\t// Convert the value to the correct relative representation.\n\t\t$($Serialization[n]).each(function(){\n\t\t\tthis.write( options, to, handle.children(), $Target );\n\t\t});\n\n\t\treturn true;\n\t}\n\n\t// Delimit proposed values for handle positions.\n\tfunction getPositions ( a, b, delimit ) {\n\n\t\t// Add movement to current position.\n\t\tvar c = a + b[0], d = a + b[1];\n\n\t\t// Only alter the other position on drag,\n\t\t// not on standard sliding.\n\t\tif ( delimit ) {\n\t\t\tif ( c < 0 ) {\n\t\t\t\td += Math.abs(c);\n\t\t\t}\n\t\t\tif ( d > 100 ) {\n\t\t\t\tc -= ( d - 100 );\n\t\t\t}\n\n\t\t\t// Limit values to 0 and 100.\n\t\t\treturn [limit(c), limit(d)];\n\t\t}\n\n\t\treturn [c,d];\n\t}\n\n\t// Handles movement by tapping.\n\tfunction jump ( handle, to, instant ) {\n\n\t\tif ( !instant ) {\n\t\t\t// Flag the slider as it is now in a transitional state.\n\t\t\t// Transition takes 300 ms, so re-enable the slider afterwards.\n\t\t\taddClassFor( $Target, Classes[14], 300 );\n\t\t}\n\n\t\t// Move the handle to the new position.\n\t\tsetHandle( handle, to, false );\n\n\t\tfireEvents(['slide', 'set', 'change']);\n\t}\n\n\n// Events\n\n\t// Handler for attaching events trough a proxy.\n\tfunction attach ( events, element, callback, data ) {\n\n\t\t// Add the noUiSlider namespace to all events.\n\t\tevents = events.replace( /\\s/g, namespace + ' ' ) + namespace;\n\n\t\t// Bind a closure on the target.\n\t\treturn element.on( events, function( e ){\n\n\t\t\t// jQuery and Zepto handle unset attributes differently.\n\t\t\tvar disabled = $Target.attr('disabled');\n\t\t\t\tdisabled = !( disabled === undefined || disabled === null );\n\n\t\t\t// Test if there is anything that should prevent an event\n\t\t\t// from being handled, such as a disabled state or an active\n\t\t\t// 'tap' transition.\n\t\t\tif( $Target.hasClass( Classes[14] ) || disabled ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\te = fixEvent(e);\n\t\t\te.calcPoint = e.points[ options.ort ];\n\n\t\t\t// Call the event handler with the event [ and additional data ].\n\t\t\tcallback ( e, data );\n\t\t});\n\t}\n\n\t// Handle movement on document for handle and range drag.\n\tfunction move ( event, data ) {\n\n\t\tvar handles = data.handles || $Handles, positions, state = false,\n\t\t\tproposal = ((event.calcPoint - data.start) * 100) / baseSize(),\n\t\t\th = handles[0][0] !== $Handles[0][0] ? 1 : 0;\n\n\t\t// Calculate relative positions for the handles.\n\t\tpositions = getPositions( proposal, data.positions, handles.length > 1);\n\n\t\tstate = setHandle ( handles[0], positions[h], handles.length === 1 );\n\n\t\tif ( handles.length > 1 ) {\n\t\t\tstate = setHandle ( handles[1], positions[h?0:1], false ) || state;\n\t\t}\n\n\t\t// Fire the 'slide' event if any handle moved.\n\t\tif ( state ) {\n\t\t\tfireEvents(['slide']);\n\t\t}\n\t}\n\n\t// Unbind move events on document, call callbacks.\n\tfunction end ( event ) {\n\n\t\t// The handle is no longer active, so remove the class.\n\t\t$('.' + Classes[15]).removeClass(Classes[15]);\n\n\t\t// Remove cursor styles and text-selection events bound to the body.\n\t\tif ( event.cursor ) {\n\t\t\t$('body').css('cursor', '').off( namespace );\n\t\t}\n\n\t\t// Unbind the move and end events, which are added on 'start'.\n\t\tdoc.off( namespace );\n\n\t\t// Remove dragging class.\n\t\t$Target.removeClass(Classes[12]);\n\n\t\t// Fire the change and set events.\n\t\tfireEvents(['set', 'change']);\n\t}\n\n\t// Bind move events on document.\n\tfunction start ( event, data ) {\n\n\t\t// Mark the handle as 'active' so it can be styled.\n\t\tif( data.handles.length === 1 ) {\n\t\t\tdata.handles[0].children().addClass(Classes[15]);\n\t\t}\n\n\t\t// A drag should never propagate up to the 'tap' event.\n\t\tevent.stopPropagation();\n\n\t\t// Attach the move event.\n\t\tattach ( actions.move, doc, move, {\n\t\t\tstart: event.calcPoint,\n\t\t\thandles: data.handles,\n\t\t\tpositions: [\n\t\t\t\t$Locations[0],\n\t\t\t\t$Locations[$Handles.length - 1]\n\t\t\t]\n\t\t});\n\n\t\t// Unbind all movement when the drag ends.\n\t\tattach ( actions.end, doc, end, null );\n\n\t\t// Text selection isn't an issue on touch devices,\n\t\t// so adding cursor styles can be skipped.\n\t\tif ( event.cursor ) {\n\n\t\t\t// Prevent the 'I' cursor and extend the range-drag cursor.\n\t\t\t$('body').css('cursor', $(event.target).css('cursor'));\n\n\t\t\t// Mark the target with a dragging state.\n\t\t\tif ( $Handles.length > 1 ) {\n\t\t\t\t$Target.addClass(Classes[12]);\n\t\t\t}\n\n\t\t\t// Prevent text selection when dragging the handles.\n\t\t\t$('body').on('selectstart' + namespace, false);\n\t\t}\n\t}\n\n\t// Move closest handle to tapped location.\n\tfunction tap ( event ) {\n\n\t\tvar location = event.calcPoint, total = 0, to;\n\n\t\t// The tap event shouldn't propagate up and cause 'edge' to run.\n\t\tevent.stopPropagation();\n\n\t\t// Add up the handle offsets.\n\t\t$.each( $Handles, function(){\n\t\t\ttotal += this.offset()[ options.style ];\n\t\t});\n\n\t\t// Find the handle closest to the tapped position.\n\t\ttotal = ( location < total/2 || $Handles.length === 1 ) ? 0 : 1;\n\n\t\tlocation -= $Base.offset()[ options.style ];\n\n\t\t// Calculate the new position.\n\t\tto = ( location * 100 ) / baseSize();\n\n\t\t// Find the closest handle and calculate the tapped point.\n\t\t// The set handle to the new position.\n\t\tjump( $Handles[total], to, options.events.snap );\n\n\t\tif ( options.events.snap ) {\n\t\t\tstart(event, { handles: [$Handles[total]] });\n\t\t}\n\t}\n\n\t// Move handle to edges when target gets tapped.\n\tfunction edge ( event ) {\n\n\t\tvar i = event.calcPoint < $Base.offset()[ options.style ],\n\t\t\tto = i ? 0 : 100;\n\n\t\ti = i ? 0 : $Handles.length - 1;\n\n\t\tjump( $Handles[i], to, false );\n\t}\n\n\t// Attach events to several slider parts.\n\tfunction events ( behaviour ) {\n\n\t\tvar i, drag;\n\n\t\t// Attach the standard drag event to the handles.\n\t\tif ( !behaviour.fixed ) {\n\n\t\t\tfor ( i = 0; i < $Handles.length; i++ ) {\n\n\t\t\t\t// These events are only bound to the visual handle\n\t\t\t\t// element, not the 'real' origin element.\n\t\t\t\tattach ( actions.start, $Handles[i].children(), start, {\n\t\t\t\t\thandles: [ $Handles[i] ]\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Attach the tap event to the slider base.\n\t\tif ( behaviour.tap ) {\n\t\t\tattach ( actions.start, $Base, tap, {\n\t\t\t\thandles: $Handles\n\t\t\t});\n\t\t}\n\n\t\t// Extend tapping behaviour to target\n\t\tif ( behaviour.extend ) {\n\n\t\t\t$Target.addClass( Classes[16] );\n\n\t\t\tif ( behaviour.tap ) {\n\t\t\t\tattach ( actions.start, $Target, edge, {\n\t\t\t\t\thandles: $Handles\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Make the range dragable.\n\t\tif ( behaviour.drag ){\n\n\t\t\tdrag = $Base.find( '.' + Classes[7] ).addClass( Classes[10] );\n\n\t\t\t// When the range is fixed, the entire range can\n\t\t\t// be dragged by the handles. The handle in the first\n\t\t\t// origin will propagate the start event upward,\n\t\t\t// but it needs to be bound manually on the other.\n\t\t\tif ( behaviour.fixed ) {\n\t\t\t\tdrag = drag.add($Base.children().not( drag ).children());\n\t\t\t}\n\n\t\t\tattach ( actions.start, drag, start, {\n\t\t\t\thandles: $Handles\n\t\t\t});\n\t\t}\n\t}\n\n\n// Initialize slider\n\n\t// Throw an error if the slider was already initialized.\n\tif ( !$Target.is(':empty') ) {\n\t\tthrow new Error('Slider was already initialized.');\n\t}\n\n\t// Create the base element, initialise HTML and set classes.\n\t// Add handles and links.\n\t$Base = addSlider( options, $Target );\n\t$Handles = addHandles( options, $Base );\n\t$Serialization = addLinks( options, $Handles );\n\n\t// Set the connect classes.\n\taddConnection ( options.connect, $Target, $Handles );\n\n\t// Attach user events.\n\tevents( options.events );\n\n\n// Methods\n\n\t// Set the slider value.\n\ttarget.vSet = function ( values, callback, link, update, animate ){\n\n\t\tvar i, to;\n\n\t\t// The RTL settings is implemented by reversing the front-end,\n\t\t// internal mechanisms are the same.\n\t\tif ( options.dir && options.handles > 1 ) {\n\t\t\tvalues.reverse();\n\t\t}\n\n\t\t// Animation is optional.\n\t\tif ( animate ) {\n\t\t\taddClassFor( $Target, Classes[14], 300 );\n\t\t}\n\n\t\t// If there are multiple handles to be set run the setting\n\t\t// mechanism twice for the first handle, to make sure it\n\t\t// can be bounced of the second one properly.\n\t\tfor ( i = 0; i < ( $Handles.length > 1 ? 3 : 1 ); i++ ) {\n\n\t\t\tto = link || $Serialization[i%2][0];\n\t\t\tto = to.valueOf( values[i%2] );\n\n\t\t\tif ( to === false ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Calculate the new handle position\n\t\t\tto = toStepping( options, to );\n\n\t\t\t// Invert the value if this is a right-to-left slider.\n\t\t\tif ( options.dir ) {\n\t\t\t\tto = 100 - to;\n\t\t\t}\n\n\t\t\t// Force delimitation.\n\t\t\tif ( setHandle( $Handles[i%2], to, true ) === true ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Reset the input if it doesn't match the slider.\n\t\t\t$($Serialization[i%2]).each(function(){\n\t\t\t\tthis.write(\n\t\t\t\t\toptions,\n\t\t\t\t\t$Locations[i%2],\n\t\t\t\t\t$Handles[i%2].children(),\n\t\t\t\t\t$Target,\n\t\t\t\t\tupdate\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\n\t\t// Optionally fire the 'set' event.\n\t\tif( callback === true ) {\n\t\t\tfireEvents(['set']);\n\t\t}\n\n\t\treturn this;\n\t};\n\n\t// Get the slider value.\n\ttarget.vGet = function ( ){\n\n\t\tvar i, retour = [];\n\n\t\t// Get the value from all handles.\n\t\tfor ( i = 0; i < options.handles; i++ ){\n\t\t\tretour[i] = $Serialization[i][0].saved;\n\t\t}\n\n\t\t// If only one handle is used, return a single value.\n\t\tif ( retour.length === 1 ){\n\t\t\treturn retour[0];\n\t\t}\n\n\t\tif ( options.dir && options.handles > 1 ) {\n\t\t\treturn retour.reverse();\n\t\t}\n\n\t\treturn retour;\n\t};\n\n\t// Destroy the slider and unbind all events.\n\ttarget.destroy = function ( ){\n\n\t\t// Loop all linked serialization objects and unbind all\n\t\t// events in the noUiSlider namespace.\n\t\t$.each($Serialization, function(){\n\t\t\t$.each(this, function(){\n\t\t\t\t// Won't remove 'change' when bound implicitly.\n\t\t\t\tif ( this.target ) {\n\t\t\t\t\tthis.target.off( namespace );\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\t// Unbind events on the slider, remove all classes and child elements.\n\t\t$(this).off(namespace)\n\t\t\t.removeClass(Classes.join(' '))\n\t\t\t.empty();\n\n\t\t// Return the original options from the closure.\n\t\treturn originalOptions;\n\t};\n\n\n// Value setting\n\n\t// Use the public value method to set the start values.\n\t$Target.val( options.start );\n}\n\n\n// Access points\n\n\t// Run the standard initializer\n\tfunction initialize ( originalOptions ) {\n\n\t\t// Throw error if group is empty.\n\t\tif ( !this.length ){\n\t\t\tthrowError(\"Can't initialize slider on empty selection.\");\n\t\t}\n\n\t\t// Test the options once, not for every slider.\n\t\tvar options = test( originalOptions, this );\n\n\t\t// Loop all items, and provide a new closed-scope environment.\n\t\treturn this.each(function(){\n\t\t\tclosure(this, options, originalOptions);\n\t\t});\n\t}\n\n\t// Destroy the slider, then re-enter initialization.\n\tfunction rebuild ( options ) {\n\n\t\treturn this.each(function(){\n\n\t\t\t// Get the current values from the slider,\n\t\t\t// including the initialization options.\n\t\t\tvar values = $(this).val(),\n\t\t\t\toriginalOptions = this.destroy(),\n\n\t\t\t\t// Extend the previous options with the newly provided ones.\n\t\t\t\tnewOptions = $.extend( {}, originalOptions, options );\n\n\t\t\t// Run the standard initializer.\n\t\t\t$(this).noUiSlider( newOptions );\n\n\t\t\t// If the start option hasn't changed,\n\t\t\t// reset the previous values.\n\t\t\tif ( originalOptions.start === newOptions.start ) {\n\t\t\t\t$(this).val(values);\n\t\t\t}\n\t\t});\n\t}\n\n\n\t// Expose serialization constructor.\n\t/** @expose */\n\t$.noUiSlider = { 'Link': Link };\n\n\t// Extend jQuery/Zepto with the noUiSlider method.\n\t/** @expose */\n\t$.fn.noUiSlider = function ( options, re ) {\n\t\treturn ( re ? rebuild : initialize ).call(this, options);\n\t};\n\n\t$.fn.val = function ( ) {\n\n\t\t// Convert the function arguments to an array.\n\t\tvar args = Array.prototype.slice.call( arguments, 0 ),\n\t\t\tset, link, update, animate;\n\n\t\t// Test if there are arguments, and if not, call the 'get' method.\n\t\tif ( !args.length ) {\n\n\t\t\t// Determine whether to use the native val method.\n\t\t\tif ( this.hasClass(Classes[0]) ) {\n\t\t\t\treturn this[0].vGet();\n\t\t\t}\n\n\t\t\treturn $val.apply( this );\n\t\t}\n\n\t\t// Extract modifiers for value method.\n\t\tif ( typeof args[1] === 'object' ) {\n\t\t\tset = args[1]['set'];\n\t\t\tlink = args[1]['link'];\n\t\t\tupdate = args[1]['update'];\n\t\t\tanimate = args[1]['animate'];\n\n\t\t// Support the 'true' option.\n\t\t} else if ( args[1] === true ) {\n\t\t\tset = true;\n\t\t}\n\n\t\t// Loop all individual items, and handle setting appropriately.\n\t\treturn this.each(function(){\n\n\t\t\tif ( $(this).hasClass(Classes[0]) ) {\n\t\t\t\tthis.vSet( asArray(args[0]), set, link, update, animate );\n\t\t\t} else {\n\t\t\t\t$val.apply( $(this), args );\n\t\t\t}\n\t\t});\n\t};\n\n}( window['jQuery'] || window['Zepto'] ));\n","/**\n * Provides requestAnimationFrame in a cross browser way.\n * @author paulirish / http://paulirish.com/\n */\n \nif ( !window.requestAnimationFrame ) {\n \n\twindow.requestAnimationFrame = ( function() {\n \n\t\treturn window.webkitRequestAnimationFrame ||\n\t\twindow.mozRequestAnimationFrame ||\n\t\twindow.oRequestAnimationFrame ||\n\t\twindow.msRequestAnimationFrame ||\n\t\tfunction( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element ) {\n \n\t\t\twindow.setTimeout( callback, 1000 / 60 );\n \n\t\t};\n \n\t} )();\n \n}\n\n/*!\n * isVis - v0.5.5 Aug 2011 - Page Visibility API Polyfill\n * Copyright (c) 2011 Addy Osmani\n * Dual licensed under the MIT and GPL licenses.\n */\n(function () {\n\n window.visibly = {\n b: null,\n q: document,\n p: undefined,\n prefixes: ['webkit', 'ms'],\n props: ['VisibilityState', 'visibilitychange', 'Hidden'],\n m: ['focus', 'blur'],\n visibleCallbacks: [],\n hiddenCallbacks: [],\n _callbacks: [],\n\n onVisible: function ( _callback ) {\n this.visibleCallbacks.push(_callback);\n },\n onHidden: function ( _callback ) {\n this.hiddenCallbacks.push(_callback);\n },\n isSupported: function () {\n return (this._supports(0) || this._supports(1));\n },\n _supports: function ( index ) {\n return ((this.prefixes[index] + this.props[2]) in this.q);\n },\n runCallbacks: function ( index ) {\n if ( index ) {\n this._callbacks = (index == 1) ? this.visibleCallbacks : this.hiddenCallbacks;\n for (var i = 0; i < this._callbacks.length; i++) {\n this._callbacks[i]();\n }\n }\n },\n _visible: function () {\n window.visibly.runCallbacks(1);\n },\n _hidden: function () {\n window.visibly.runCallbacks(2);\n },\n _nativeSwitch: function () {\n ((this.q[this.b + this.props[2]]) === true) ? this._hidden() : this._visible();\n },\n listen: function () {\n\n try { /*if no native page visibility support found..*/\n if (!(this.isSupported())) {\n if (document.addEventListener) { /*for browsers without focusin/out support eg. firefox, opera use focus/blur*/\n\t\t\t\t\t\t/*window used instead of doc as Opera complains otherwise*/\n window.addEventListener(this.m[0], this._visible, 1);\n window.addEventListener(this.m[1], this._hidden, 1);\n } else { /*IE <10s most reliable focus events are onfocusin/onfocusout*/\n this.q.attachEvent('onfocusin', this._visible);\n this.q.attachEvent('onfocusout', this._hidden);\n }\n } else { /*switch support based on prefix*/\n this.b = (this._supports(0) == this.p) ? this.prefixes[1] : this.prefixes[0];\n this.q.addEventListener(this.b + this.props[1], function () {\n window.visibly._nativeSwitch.apply(window.visibly, arguments);\n }, 1);\n }\n } catch (e) {}\n },\n init: function () {\n this.listen();\n }\n }\n\n this.visibly.init();\n\n})();\n","// MIT License:\n//\n// Copyright (c) 2010-2012, Joe Walnes\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\n/**\n * This behaves like a WebSocket in every way, except if it fails to connect,\n * or it gets disconnected, it will repeatedly poll until it succesfully connects\n * again.\n *\n * It is API compatible, so when you have:\n * ws = new WebSocket('ws://....');\n * you can replace with:\n * ws = new ReconnectingWebSocket('ws://....');\n *\n * The event stream will typically look like:\n * onconnecting\n * onopen\n * onmessage\n * onmessage\n * onclose // lost connection\n * onconnecting\n * onopen // sometime later...\n * onmessage\n * onmessage\n * etc... \n *\n * It is API compatible with the standard WebSocket API.\n *\n * Latest version: https://github.com/joewalnes/reconnecting-websocket/\n * - Joe Walnes\n */\n(function (global, factory) {\n if (typeof define === 'function' && define.amd) {\n define([], factory);\n } else if (typeof module !== 'undefined' && module.exports){\n module.exports = factory();\n } else {\n global.ReconnectingWebSocket = factory();\n }\n})(this, function () {\n\n function ReconnectingWebSocket(url, protocols) {\n protocols = protocols || [];\n\n // These can be altered by calling code.\n this.debug = false;\n this.reconnectInterval = 1000;\n this.reconnectDecay = 1.5;\n this.reconnectAttempts = 0;\n this.timeoutInterval = 2000;\n\n var self = this;\n var ws;\n var forcedClose = false;\n var timedOut = false;\n \n this.url = url;\n this.protocols = protocols;\n this.readyState = WebSocket.CONNECTING;\n this.URL = url; // Public API\n\n this.onopen = function(event) {\n };\n\n this.onclose = function(event) {\n };\n\n this.onconnecting = function(event) {\n };\n\n this.onmessage = function(event) {\n };\n\n this.onerror = function(event) {\n };\n\n function connect(reconnectAttempt) {\n ws = new WebSocket(url, protocols);\n \n self.onconnecting();\n if (self.debug || ReconnectingWebSocket.debugAll) {\n console.debug('ReconnectingWebSocket', 'attempt-connect', url);\n }\n \n var localWs = ws;\n var timeout = setTimeout(function() {\n if (self.debug || ReconnectingWebSocket.debugAll) {\n console.debug('ReconnectingWebSocket', 'connection-timeout', url);\n }\n timedOut = true;\n localWs.close();\n timedOut = false;\n }, self.timeoutInterval);\n \n ws.onopen = function(event) {\n clearTimeout(timeout);\n if (self.debug || ReconnectingWebSocket.debugAll) {\n console.debug('ReconnectingWebSocket', 'onopen', url);\n }\n self.readyState = WebSocket.OPEN;\n reconnectAttempt = false;\n self.reconnectAttempts = 0;\n self.onopen(event);\n };\n \n ws.onclose = function(event) {\n clearTimeout(timeout);\n ws = null;\n if (forcedClose) {\n self.readyState = WebSocket.CLOSED;\n self.onclose(event);\n } else {\n self.readyState = WebSocket.CONNECTING;\n self.onconnecting();\n if (!reconnectAttempt && !timedOut) {\n if (self.debug || ReconnectingWebSocket.debugAll) {\n console.debug('ReconnectingWebSocket', 'onclose', url);\n }\n self.onclose(event);\n }\n setTimeout(function() {\n self.reconnectAttempts++;\n connect(true);\n }, self.reconnectInterval * Math.pow(self.reconnectDecay, self.reconnectAttempts));\n }\n };\n ws.onmessage = function(event) {\n if (self.debug || ReconnectingWebSocket.debugAll) {\n console.debug('ReconnectingWebSocket', 'onmessage', url, event.data);\n }\n self.onmessage(event);\n };\n ws.onerror = function(event) {\n if (self.debug || ReconnectingWebSocket.debugAll) {\n console.debug('ReconnectingWebSocket', 'onerror', url, event);\n }\n self.onerror(event);\n };\n }\n connect(false);\n\n this.send = function(data) {\n if (ws) {\n if (self.debug || ReconnectingWebSocket.debugAll) {\n console.debug('ReconnectingWebSocket', 'send', url, data);\n }\n return ws.send(data);\n } else {\n throw 'INVALID_STATE_ERR : Pausing to reconnect websocket';\n }\n };\n\n this.close = function() {\n forcedClose = true;\n if (ws) {\n ws.close();\n }\n };\n\n /**\n * Additional public API method to refresh the connection if still open (close, re-open).\n * For example, if the app suspects bad data / missed heart beats, it can try to refresh.\n */\n this.refresh = function() {\n if (ws) {\n ws.close();\n }\n };\n }\n\n /**\n * Setting this to true is the equivalent of setting all instances of ReconnectingWebSocket.debug to true.\n */\n ReconnectingWebSocket.debugAll = false;\n\n return ReconnectingWebSocket;\n});\n"]}